Changeset 177223 in webkit


Ignore:
Timestamp:
Dec 12, 2014 6:19:21 AM (9 years ago)
Author:
stavila@adobe.com
Message:

[SVG Masking] Enable the use of <mask> elements for -webkit-mask-image
https://bugs.webkit.org/show_bug.cgi?id=139294

Reviewed by Simon Fraser.

Source/WebCore:

This patch links together all parts required for the functionality which improves
the -webkit-mask-image property by allowing it to reference a <mask> element defined
in an inline or external SVG document.
Support for this new functionality has been added in a previous patch, under issue
https://bugs.webkit.org/show_bug.cgi?id=139092. A more detailed description of how
the new functionality works can be found in the ChangeLog for that commit.
The containsSVGDocument in ScrollView has been removed because it was added in the
previous patch but is no longer required.

Tests: css3/masking/mask-base64.html

css3/masking/mask-multiple-values.html
css3/masking/mask-svg-clipped-fragmentId.html
css3/masking/mask-svg-fragmentId.html
css3/masking/mask-svg-inline-fragmentId.html
css3/masking/mask-svg-inline-invalid-fragmentId.html
css3/masking/mask-svg-invalid-fragmentId.html
css3/masking/mask-svg-no-fragmentId-tiled.html
css3/masking/mask-svg-no-fragmentId.html
css3/masking/mask-svg-script-entire-svg-to-mask.html
css3/masking/mask-svg-script-mask-to-entire-svg.html
css3/masking/mask-svg-script-mask-to-none.html
css3/masking/mask-svg-script-mask-to-png.html
css3/masking/mask-svg-script-none-to-mask.html
css3/masking/mask-svg-script-none-to-png.html
css3/masking/mask-svg-script-png-to-mask.html
css3/masking/mask-svg-script-png-to-none.html

  • css/CSSComputedStyleDeclaration.cpp:

(WebCore::ComputedStyleExtractor::propertyValue):

  • css/CSSParser.cpp:

(WebCore::CSSParser::parseFillShorthand):
(WebCore::CSSParser::parseFillProperty):
(WebCore::CSSParser::parseMaskImage):

  • css/CSSParser.h:
  • css/DeprecatedStyleBuilder.cpp:

(WebCore::DeprecatedStyleBuilder::DeprecatedStyleBuilder):

  • css/StyleResolver.cpp:

(WebCore::StyleResolver::adjustStyleForMaskImages):
(WebCore::StyleResolver::applyProperty):
(WebCore::StyleResolver::loadPendingSVGDocuments):
(WebCore::StyleResolver::createMaskImageOperations):
(WebCore::StyleResolver::loadPendingImages):

  • page/animation/CSSPropertyAnimation.cpp:

(WebCore::blendFunc):
(WebCore::MaskImagePropertyWrapper::MaskImagePropertyWrapper):
(WebCore::MaskImagePropertyWrapper::equals):
(WebCore::CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap):

  • platform/graphics/MaskImageOperation.cpp:

(WebCore::MaskImageOperation::~MaskImageOperation):

  • rendering/RenderBox.cpp:

(WebCore::RenderBox::maskClipRect):

  • rendering/RenderBox.h:
  • rendering/RenderBoxModelObject.cpp:

(WebCore::RenderBoxModelObject::paintFillLayerExtended):
(WebCore::RenderBoxModelObject::calculateFillTileSize):
(WebCore::RenderBoxModelObject::calculateBackgroundImageGeometry):

  • rendering/RenderElement.cpp:

(WebCore::RenderElement::~RenderElement):
(WebCore::RenderElement::updateFillImages):

  • rendering/RenderLayer.cpp:

(WebCore::RenderLayer::calculateClipRects):

  • rendering/RenderLayer.h:
  • rendering/style/FillLayer.h:
  • rendering/style/RenderStyle.cpp:

(WebCore::RenderStyle::setMaskImage):

  • rendering/style/RenderStyle.h:

LayoutTests:

Added tests for different situations using URLs with fragment id
for the -webkit-mask-image property.

  • css3/masking/mask-base64-expected.html: Added.
  • css3/masking/mask-base64.html: Added.
  • css3/masking/mask-multiple-values-expected.html: Added.
  • css3/masking/mask-multiple-values.html: Added.
  • css3/masking/mask-repeat-space-padding-expected.html:
  • css3/masking/mask-repeat-space-padding.html:
  • css3/masking/mask-svg-clipped-fragmentId-expected.html: Added.
  • css3/masking/mask-svg-clipped-fragmentId.html: Added.
  • css3/masking/mask-svg-fragmentId-expected.html: Added.
  • css3/masking/mask-svg-fragmentId.html: Added.
  • css3/masking/mask-svg-inline-fragmentId-expected.html: Added.
  • css3/masking/mask-svg-inline-fragmentId.html: Added.
  • css3/masking/mask-svg-inline-invalid-fragmentId-expected.html: Added.
  • css3/masking/mask-svg-inline-invalid-fragmentId.html: Added.
  • css3/masking/mask-svg-invalid-fragmentId-expected.html: Added.
  • css3/masking/mask-svg-invalid-fragmentId.html: Added.
  • css3/masking/mask-svg-no-fragmentId-expected.html: Added.
  • css3/masking/mask-svg-no-fragmentId-tiled-expected.html: Added.
  • css3/masking/mask-svg-no-fragmentId-tiled.html: Added.
  • css3/masking/mask-svg-no-fragmentId.html: Added.
  • css3/masking/mask-svg-script-entire-svg-to-mask-expected.html: Added.
  • css3/masking/mask-svg-script-entire-svg-to-mask.html: Added.
  • css3/masking/mask-svg-script-mask-to-entire-svg-expected.html: Added.
  • css3/masking/mask-svg-script-mask-to-entire-svg.html: Added.
  • css3/masking/mask-svg-script-mask-to-none-expected.html: Added.
  • css3/masking/mask-svg-script-mask-to-none.html: Added.
  • css3/masking/mask-svg-script-mask-to-png-expected.html: Added.
  • css3/masking/mask-svg-script-mask-to-png.html: Added.
  • css3/masking/mask-svg-script-none-to-mask-expected.html: Added.
  • css3/masking/mask-svg-script-none-to-mask.html: Added.
  • css3/masking/mask-svg-script-none-to-png-expected.html: Added.
  • css3/masking/mask-svg-script-none-to-png.html: Added.
  • css3/masking/mask-svg-script-png-to-mask-expected.html: Added.
  • css3/masking/mask-svg-script-png-to-mask.html: Added.
  • css3/masking/mask-svg-script-png-to-none-expected.html: Added.
  • css3/masking/mask-svg-script-png-to-none.html: Added.
  • css3/masking/resources/masks.svg: Added.
Location:
trunk
Files:
34 added
29 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r177219 r177223  
     12014-12-12  Radu Stavila  <stavila@adobe.com>
     2
     3        [SVG Masking] Enable the use of <mask> elements for -webkit-mask-image
     4        https://bugs.webkit.org/show_bug.cgi?id=139294
     5
     6        Reviewed by Simon Fraser.
     7
     8        Added tests for different situations using URLs with fragment id
     9        for the -webkit-mask-image property.
     10
     11        * css3/masking/mask-base64-expected.html: Added.
     12        * css3/masking/mask-base64.html: Added.
     13        * css3/masking/mask-multiple-values-expected.html: Added.
     14        * css3/masking/mask-multiple-values.html: Added.
     15        * css3/masking/mask-repeat-space-padding-expected.html:
     16        * css3/masking/mask-repeat-space-padding.html:
     17        * css3/masking/mask-svg-clipped-fragmentId-expected.html: Added.
     18        * css3/masking/mask-svg-clipped-fragmentId.html: Added.
     19        * css3/masking/mask-svg-fragmentId-expected.html: Added.
     20        * css3/masking/mask-svg-fragmentId.html: Added.
     21        * css3/masking/mask-svg-inline-fragmentId-expected.html: Added.
     22        * css3/masking/mask-svg-inline-fragmentId.html: Added.
     23        * css3/masking/mask-svg-inline-invalid-fragmentId-expected.html: Added.
     24        * css3/masking/mask-svg-inline-invalid-fragmentId.html: Added.
     25        * css3/masking/mask-svg-invalid-fragmentId-expected.html: Added.
     26        * css3/masking/mask-svg-invalid-fragmentId.html: Added.
     27        * css3/masking/mask-svg-no-fragmentId-expected.html: Added.
     28        * css3/masking/mask-svg-no-fragmentId-tiled-expected.html: Added.
     29        * css3/masking/mask-svg-no-fragmentId-tiled.html: Added.
     30        * css3/masking/mask-svg-no-fragmentId.html: Added.
     31        * css3/masking/mask-svg-script-entire-svg-to-mask-expected.html: Added.
     32        * css3/masking/mask-svg-script-entire-svg-to-mask.html: Added.
     33        * css3/masking/mask-svg-script-mask-to-entire-svg-expected.html: Added.
     34        * css3/masking/mask-svg-script-mask-to-entire-svg.html: Added.
     35        * css3/masking/mask-svg-script-mask-to-none-expected.html: Added.
     36        * css3/masking/mask-svg-script-mask-to-none.html: Added.
     37        * css3/masking/mask-svg-script-mask-to-png-expected.html: Added.
     38        * css3/masking/mask-svg-script-mask-to-png.html: Added.
     39        * css3/masking/mask-svg-script-none-to-mask-expected.html: Added.
     40        * css3/masking/mask-svg-script-none-to-mask.html: Added.
     41        * css3/masking/mask-svg-script-none-to-png-expected.html: Added.
     42        * css3/masking/mask-svg-script-none-to-png.html: Added.
     43        * css3/masking/mask-svg-script-png-to-mask-expected.html: Added.
     44        * css3/masking/mask-svg-script-png-to-mask.html: Added.
     45        * css3/masking/mask-svg-script-png-to-none-expected.html: Added.
     46        * css3/masking/mask-svg-script-png-to-none.html: Added.
     47        * css3/masking/resources/masks.svg: Added.
     48
    1492014-12-12  Zalan Bujtas  <zalan@apple.com>
    250
  • trunk/LayoutTests/css3/masking/mask-base64-expected.html

    r177222 r177223  
    33    <head>
    44        <style>
    5             #back {
    6                 width: 600px;
    7                 height: 500px;
    8                 background-color: green;
     5            p {
     6                margin: 0px;
    97            }
    108            #front {
    11                 width: 400px;
    12                 height: 300px;
    13                 background-color: red;
    14                 border: 50px solid blue;
    15                 padding: 50px;
     9                width: 200px;
     10                height: 160px;
     11                background-color: green;
    1612                -webkit-mask-repeat: no-repeat;
    17                 -webkit-mask-origin: padding-box;
    18                 -webkit-mask-clip: padding-box;
     13                -webkit-mask-origin: content-box;
     14                -webkit-mask-clip: content-box;
    1915            }
    2016        </style>
    2117        <script>
    22             var sizeX = 100, sizeY = 80, spaceX = 0, spaceY = 0, width = 700, height = 600;
     18            var sizeX = 50, sizeY = 40, spaceX = 0, spaceY = 0, width = 200, height = 160;
    2319
    2420            var urls = Array(), size = Array(), position = Array();
     
    2723                for (var x = 0; x < width; x += sizeX + spaceX) {
    2824                    for (var y = 0; y < height; y += sizeY + spaceY) {
    29                         urls.push("url(resources/circle.png)");
     25                        urls.push("url(resources/circle.svg)");
    3026                        size.push(sizeX + "px " + sizeY + "px");
    3127                        position.push(x + "px " + y + "px");
     
    4339
    4440    <body onload="addMasks()">
    45         <div id="back">
    46             <div id="front" />
    47         </div>
     41        <p><a href="https://bugs.webkit.org/show_bug.cgi?id=129682">Bug 129682</a> - On success, you should see a 4x4 grid of green circles.</p>
     42        <p>This test sets the mask-image value using base64.</p>
     43        <div id="front"></div>
    4844    </body>
    4945</html>
  • trunk/LayoutTests/css3/masking/mask-repeat-space-padding-expected.html

    r177169 r177223  
    2727                for (var x = 0; x < width; x += sizeX + spaceX) {
    2828                    for (var y = 0; y < height; y += sizeY + spaceY) {
    29                         urls.push("url(resources/circle.png)");
     29                        urls.push("url(resources/circle.svg)");
    3030                        size.push(sizeX + "px " + sizeY + "px");
    3131                        position.push(x + "px " + y + "px");
  • trunk/LayoutTests/css3/masking/mask-repeat-space-padding.html

    r177169 r177223  
    1414                border: 50px solid blue;
    1515                padding: 50px;
    16                 -webkit-mask-image: url("resources/circle.png");
     16                -webkit-mask-image: url("resources/circle.svg");
    1717                -webkit-mask-size: 100px;
    1818                -webkit-mask-repeat: space;
  • trunk/Source/WebCore/ChangeLog

    r177221 r177223  
     12014-12-12  Radu Stavila  <stavila@adobe.com>
     2
     3        [SVG Masking] Enable the use of <mask> elements for -webkit-mask-image
     4        https://bugs.webkit.org/show_bug.cgi?id=139294
     5
     6        Reviewed by Simon Fraser.
     7
     8        This patch links together all parts required for the functionality which improves
     9        the -webkit-mask-image property by allowing it to reference a <mask> element defined
     10        in an inline or external SVG document.
     11        Support for this new functionality has been added in a previous patch, under issue
     12        https://bugs.webkit.org/show_bug.cgi?id=139092. A more detailed description of how
     13        the new functionality works can be found in the ChangeLog for that commit.
     14        The containsSVGDocument in ScrollView has been removed because it was added in the
     15        previous patch but is no longer required.
     16
     17        Tests: css3/masking/mask-base64.html
     18               css3/masking/mask-multiple-values.html
     19               css3/masking/mask-svg-clipped-fragmentId.html
     20               css3/masking/mask-svg-fragmentId.html
     21               css3/masking/mask-svg-inline-fragmentId.html
     22               css3/masking/mask-svg-inline-invalid-fragmentId.html
     23               css3/masking/mask-svg-invalid-fragmentId.html
     24               css3/masking/mask-svg-no-fragmentId-tiled.html
     25               css3/masking/mask-svg-no-fragmentId.html
     26               css3/masking/mask-svg-script-entire-svg-to-mask.html
     27               css3/masking/mask-svg-script-mask-to-entire-svg.html
     28               css3/masking/mask-svg-script-mask-to-none.html
     29               css3/masking/mask-svg-script-mask-to-png.html
     30               css3/masking/mask-svg-script-none-to-mask.html
     31               css3/masking/mask-svg-script-none-to-png.html
     32               css3/masking/mask-svg-script-png-to-mask.html
     33               css3/masking/mask-svg-script-png-to-none.html
     34
     35        * css/CSSComputedStyleDeclaration.cpp:
     36        (WebCore::ComputedStyleExtractor::propertyValue):
     37        * css/CSSParser.cpp:
     38        (WebCore::CSSParser::parseFillShorthand):
     39        (WebCore::CSSParser::parseFillProperty):
     40        (WebCore::CSSParser::parseMaskImage):
     41        * css/CSSParser.h:
     42        * css/DeprecatedStyleBuilder.cpp:
     43        (WebCore::DeprecatedStyleBuilder::DeprecatedStyleBuilder):
     44        * css/StyleResolver.cpp:
     45        (WebCore::StyleResolver::adjustStyleForMaskImages):
     46        (WebCore::StyleResolver::applyProperty):
     47        (WebCore::StyleResolver::loadPendingSVGDocuments):
     48        (WebCore::StyleResolver::createMaskImageOperations):
     49        (WebCore::StyleResolver::loadPendingImages):
     50        * page/animation/CSSPropertyAnimation.cpp:
     51        (WebCore::blendFunc):
     52        (WebCore::MaskImagePropertyWrapper::MaskImagePropertyWrapper):
     53        (WebCore::MaskImagePropertyWrapper::equals):
     54        (WebCore::CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap):
     55        * platform/graphics/MaskImageOperation.cpp:
     56        (WebCore::MaskImageOperation::~MaskImageOperation):
     57        * rendering/RenderBox.cpp:
     58        (WebCore::RenderBox::maskClipRect):
     59        * rendering/RenderBox.h:
     60        * rendering/RenderBoxModelObject.cpp:
     61        (WebCore::RenderBoxModelObject::paintFillLayerExtended):
     62        (WebCore::RenderBoxModelObject::calculateFillTileSize):
     63        (WebCore::RenderBoxModelObject::calculateBackgroundImageGeometry):
     64        * rendering/RenderElement.cpp:
     65        (WebCore::RenderElement::~RenderElement):
     66        (WebCore::RenderElement::updateFillImages):
     67        * rendering/RenderLayer.cpp:
     68        (WebCore::RenderLayer::calculateClipRects):
     69        * rendering/RenderLayer.h:
     70        * rendering/style/FillLayer.h:
     71        * rendering/style/RenderStyle.cpp:
     72        (WebCore::RenderStyle::setMaskImage):
     73        * rendering/style/RenderStyle.h:
     74
    1752014-12-12  Csaba Osztrogonác  <ossy@webkit.org>
    276
  • trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp

    r177200 r177223  
    17951795        case CSSPropertyBackgroundColor:
    17961796            return cssValuePool().createColorValue(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor).rgb() : style->backgroundColor().rgb());
    1797         case CSSPropertyBackgroundImage:
    1798         case CSSPropertyWebkitMaskImage: {
    1799             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskImage ? style->maskLayers() : style->backgroundLayers();
     1797        case CSSPropertyBackgroundImage: {
     1798            const FillLayer* layers = style->backgroundLayers();
    18001799            if (!layers)
    18011800                return cssValuePool().createIdentifierValue(CSSValueNone);
     
    18121811                if (currLayer->image())
    18131812                    list->append(*currLayer->image()->cssValue());
     1813                else
     1814                    list->append(cssValuePool().createIdentifierValue(CSSValueNone));
     1815            }
     1816            return list.release();
     1817        }
     1818        case CSSPropertyWebkitMaskImage: {
     1819            const FillLayer* layers = style->maskLayers();
     1820            if (!layers)
     1821                return cssValuePool().createIdentifierValue(CSSValueNone);
     1822
     1823            if (!layers->next()) {
     1824                if (layers->maskImage().get())
     1825                    return layers->maskImage()->cssValue();
     1826
     1827                return cssValuePool().createIdentifierValue(CSSValueNone);
     1828            }
     1829
     1830            RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
     1831            for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
     1832                if (currLayer->maskImage().get())
     1833                    list->append(*currLayer->maskImage()->cssValue());
    18141834                else
    18151835                    list->append(cssValuePool().createIdentifierValue(CSSValueNone));
  • trunk/Source/WebCore/css/CSSParser.cpp

    r177169 r177223  
    8484#include "WebKitCSSFilterValue.h"
    8585#include "WebKitCSSRegionRule.h"
     86#include "WebKitCSSResourceValue.h"
    8687#include "WebKitCSSTransformValue.h"
    8788#include <bitset>
     
    33593360                CSSPropertyID propId1, propId2;
    33603361                CSSParserValue& parserValue = *m_valueList->current();
     3362
    33613363                if (parseFillProperty(properties[i], propId1, propId2, val1, val2)) {
    33623364                    parsedProperty[i] = found = true;
     
    44474449                    break;
    44484450                case CSSPropertyBackgroundImage:
     4451                    if (parseFillImage(*m_valueList, currValue))
     4452                        m_valueList->next();
     4453                    break;
    44494454                case CSSPropertyWebkitMaskImage:
    4450                     if (parseFillImage(*m_valueList, currValue))
     4455                    if (parseMaskImage(*m_valueList, currValue))
    44514456                        m_valueList->next();
    44524457                    break;
     
    94289433}
    94299434
     9435bool CSSParser::parseMaskImage(CSSParserValueList& valueList, RefPtr<CSSValue>& outValue)
     9436{
     9437    outValue = nullptr;
     9438    CSSParserValue* value = valueList.current();
     9439    if (value->id == CSSValueNone)
     9440        outValue = WebKitCSSResourceValue::create(cssValuePool().createIdentifierValue(CSSValueNone));
     9441    else if (value->unit == CSSPrimitiveValue::CSS_URI)
     9442        outValue = WebKitCSSResourceValue::create(CSSPrimitiveValue::create(completeURL(value->string), CSSPrimitiveValue::CSS_URI));
     9443    else {
     9444        RefPtr<CSSValue> fillImageValue;
     9445        if (parseFillImage(valueList, fillImageValue))
     9446            outValue = WebKitCSSResourceValue::create(fillImageValue);
     9447    }
     9448
     9449    return outValue.get();
     9450}
     9451
    94309452#if ENABLE(CSS_REGIONS)
    94319453static bool validFlowName(const String& flowName)
  • trunk/Source/WebCore/css/CSSParser.h

    r177169 r177223  
    118118    PassRefPtr<CSSValue> parseBackgroundColor();
    119119
     120    // FIXME: Maybe these two methods could be combined into one.
     121    bool parseMaskImage(CSSParserValueList&, RefPtr<CSSValue>&);
    120122    bool parseFillImage(CSSParserValueList&, RefPtr<CSSValue>&);
    121123
  • trunk/Source/WebCore/css/CSSValue.h

    r176798 r177223  
    164164        SVGColorClass,
    165165        SVGPaintClass,
     166        WebKitCSSResourceClass,
    166167
    167168        // List class types must appear after ValueListClass.
     
    175176        GridLineNamesClass,
    176177#endif
    177         WebKitCSSResourceClass
    178178
    179179        // Do not append non-list class types here.
  • trunk/Source/WebCore/css/DeprecatedStyleBuilder.cpp

    r177169 r177223  
    929929    setPropertyHandler(CSSPropertyWebkitMaskClip, ApplyPropertyFillLayer<EFillBox, CSSPropertyWebkitMaskClip, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isClipSet, &FillLayer::clip, &FillLayer::setClip, &FillLayer::clearClip, &FillLayer::initialFillClip, &CSSToStyleMap::mapFillClip>::createHandler());
    930930    setPropertyHandler(CSSPropertyWebkitMaskComposite, ApplyPropertyFillLayer<CompositeOperator, CSSPropertyWebkitMaskComposite, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isCompositeSet, &FillLayer::composite, &FillLayer::setComposite, &FillLayer::clearComposite, &FillLayer::initialFillComposite, &CSSToStyleMap::mapFillComposite>::createHandler());
    931     setPropertyHandler(CSSPropertyWebkitMaskImage, ApplyPropertyFillLayer<StyleImage*, CSSPropertyWebkitMaskImage, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isImageSet, &FillLayer::image, &FillLayer::setImage, &FillLayer::clearImage, &FillLayer::initialFillImage, &CSSToStyleMap::mapFillImage>::createHandler());
    932931    setPropertyHandler(CSSPropertyWebkitMaskOrigin, ApplyPropertyFillLayer<EFillBox, CSSPropertyWebkitMaskOrigin, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isOriginSet, &FillLayer::origin, &FillLayer::setOrigin, &FillLayer::clearOrigin, &FillLayer::initialFillOrigin, &CSSToStyleMap::mapFillOrigin>::createHandler());
    933932    setPropertyHandler(CSSPropertyWebkitMaskPositionX, ApplyPropertyFillLayer<Length, CSSPropertyWebkitMaskPositionX, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isXPositionSet, &FillLayer::xPosition, &FillLayer::setXPosition, &FillLayer::clearXPosition, &FillLayer::initialFillXPosition, &CSSToStyleMap::mapFillXPosition>::createHandler());
  • trunk/Source/WebCore/css/StyleResolver.cpp

    r177169 r177223  
    11581158}
    11591159
     1160void StyleResolver::adjustStyleForMaskImages()
     1161{
     1162    // If we already have the same mask image objects loaded on the old style,
     1163    // use the old ones instead of loading new ones.
     1164    RenderStyle* newStyle = m_state.style();
     1165    RenderStyle* oldStyle = (m_state.element() ? m_state.element()->renderStyle() : nullptr);
     1166
     1167    if (newStyle && oldStyle) {
     1168        Vector<RefPtr<MaskImageOperation>> removedExternalResources;
     1169       
     1170        // Get all mask objects from the old style in a vector
     1171        // so we can remove them as we match them, making the following steps faster.
     1172        Vector<RefPtr<MaskImageOperation>> oldStyleMaskImages;
     1173        const FillLayer* oldMaskLayer = oldStyle->maskLayers();
     1174        while (oldMaskLayer) {
     1175            RefPtr<MaskImageOperation> oldMaskImage = oldMaskLayer->maskImage();
     1176            if (oldMaskImage.get())
     1177                oldStyleMaskImages.append(oldMaskImage);
     1178
     1179            oldMaskLayer = oldMaskLayer->next();
     1180        }
     1181       
     1182        // Try to match the new mask objects through the list from the old style.
     1183        // This should work perfectly and optimal when the list of masks remained
     1184        // the same and also work correctly (but slower) when they were reordered.
     1185        FillLayer* newMaskLayer = newStyle->accessMaskLayers();
     1186        int countOldStyleMaskImages = oldStyleMaskImages.size();
     1187        while (newMaskLayer && countOldStyleMaskImages) {
     1188            RefPtr<MaskImageOperation> newMaskImage = newMaskLayer->maskImage();
     1189            if (newMaskImage.get()) {
     1190                for (int i = 0; i < countOldStyleMaskImages; i++) {
     1191                    RefPtr<MaskImageOperation> oldMaskImage = oldStyleMaskImages[i];
     1192                    if (*oldMaskImage == *newMaskImage) {
     1193                        newMaskLayer->setMaskImage(oldMaskImage);
     1194                        if (newMaskImage->isExternalDocument())
     1195                            removedExternalResources.append(newMaskImage);
     1196
     1197                        oldStyleMaskImages.remove(i);
     1198                        countOldStyleMaskImages--;
     1199                        break;
     1200                    }
     1201                }
     1202            }
     1203
     1204            newMaskLayer = newMaskLayer->next();
     1205        }
     1206
     1207        Vector<RefPtr<MaskImageOperation>>& pendingResources = m_state.maskImagesWithPendingSVGDocuments();
     1208        for (int i = pendingResources.size() - 1; i >= 0; i--) {
     1209            if (removedExternalResources.contains(pendingResources[i]))
     1210                pendingResources.remove(i);
     1211        }
     1212    }
     1213}
     1214
    11601215void StyleResolver::adjustRenderStyle(RenderStyle& style, const RenderStyle& parentStyle, Element *e)
    11611216{
     
    17641819    // so to preserve behavior, we queue them up during cascade and flush here.
    17651820    cascade.applyDeferredProperties(*this);
     1821   
     1822    adjustStyleForMaskImages();
    17661823
    17671824    // Start loading resources referenced by this style.
     
    25402597    }
    25412598#endif
     2599
     2600    case CSSPropertyWebkitMaskImage: {
     2601        Vector<RefPtr<MaskImageOperation>> operations;
     2602        if (createMaskImageOperations(value, operations))
     2603            state.style()->setMaskImage(operations);
     2604
     2605        return;
     2606    }
    25422607
    25432608#if ENABLE(CSS_GRID_LAYOUT)
     
    29673032    case CSSPropertyWebkitMaskClip:
    29683033    case CSSPropertyWebkitMaskComposite:
    2969     case CSSPropertyWebkitMaskImage:
    29703034    case CSSPropertyWebkitMaskOrigin:
    29713035    case CSSPropertyWebkitMaskPositionX:
     
    33183382    // reentering styleForElement().
    33193383    ASSERT(state.style());
    3320     if (!state.style() || !state.style()->hasFilter() || state.filtersWithPendingSVGDocuments().isEmpty())
     3384    if (!state.style())
     3385        return;
     3386   
     3387    bool hasFilters = (state.style()->hasFilter() && !state.filtersWithPendingSVGDocuments().isEmpty());
     3388    bool hasMasks = (state.style()->hasMask() && !state.maskImagesWithPendingSVGDocuments().isEmpty());
     3389   
     3390    if (!hasFilters && !hasMasks)
    33213391        return;
    33223392
    33233393    CachedResourceLoader* cachedResourceLoader = state.document().cachedResourceLoader();
    3324     for (auto& filterOperation : state.filtersWithPendingSVGDocuments())
    3325         filterOperation->getOrCreateCachedSVGDocumentReference()->load(cachedResourceLoader);
    3326 
    3327     state.filtersWithPendingSVGDocuments().clear();
     3394   
     3395    if (hasFilters) {
     3396        for (auto& filterOperation : state.filtersWithPendingSVGDocuments())
     3397            filterOperation->getOrCreateCachedSVGDocumentReference()->load(cachedResourceLoader);
     3398
     3399        state.filtersWithPendingSVGDocuments().clear();
     3400    }
     3401   
     3402    if (hasMasks) {
     3403        for (auto& maskImageOperation : state.maskImagesWithPendingSVGDocuments())
     3404            maskImageOperation->ensureCachedSVGDocumentReference()->load(cachedResourceLoader);
     3405
     3406        state.maskImagesWithPendingSVGDocuments().clear();
     3407    }
    33283408}
    33293409
     
    34733553        return false;
    34743554
    3475     ASSERT(is<CSSValueList>(*inValue));
    3476 
    3477     for (auto& currValue : downcast<CSSValueList>(*inValue)) {
    3478         if (!is<WebKitCSSResourceValue>(currValue.get()))
    3479             continue;
    3480        
    3481         WebKitCSSResourceValue& maskImageValue = downcast<WebKitCSSResourceValue>(currValue.get());
    3482         RefPtr<CSSValue> maskInnerValue = maskImageValue.innerValue();
     3555    RefPtr<WebKitCSSResourceValue> maskImageValue;
     3556    RefPtr<CSSValueList> maskImagesList;
     3557    CSSValueList::iterator listIterator;
     3558    if (is<WebKitCSSResourceValue>(*inValue))
     3559        maskImageValue = downcast<WebKitCSSResourceValue>(inValue);
     3560    else if (is<CSSValueList>(*inValue)) {
     3561        maskImagesList = downcast<CSSValueList>(inValue);
     3562        listIterator = maskImagesList->begin();
     3563        if (listIterator != maskImagesList->end())
     3564            maskImageValue = &downcast<WebKitCSSResourceValue>(listIterator->get());
     3565    }
     3566
     3567    while (maskImageValue.get()) {
     3568        RefPtr<CSSValue> maskInnerValue = maskImageValue->innerValue();
    34833569        RefPtr<MaskImageOperation> newMaskImage;
    3484        
     3570
    34853571        if (is<CSSPrimitiveValue>(maskInnerValue.get())) {
    34863572            RefPtr<CSSPrimitiveValue> primitiveValue = downcast<CSSPrimitiveValue>(maskInnerValue.get());
     
    34923578               
    34933579                bool isExternalDocument = (SVGURIReference::isExternalURIReference(cssUrl, m_state.document()));
    3494                 newMaskImage = MaskImageOperation::create(&maskImageValue, cssUrl, url.fragmentIdentifier(), isExternalDocument, m_state.document().cachedResourceLoader());
     3580                newMaskImage = MaskImageOperation::create(maskImageValue, cssUrl, url.fragmentIdentifier(), isExternalDocument, m_state.document().cachedResourceLoader());
    34953581                if (isExternalDocument)
    34963582                    m_state.maskImagesWithPendingSVGDocuments().append(newMaskImage);
     
    35073593
    35083594        outOperations.append(newMaskImage);
     3595
     3596        if (maskImagesList.get()) {
     3597            listIterator++;
     3598            maskImageValue = (listIterator != maskImagesList->end() ? &downcast<WebKitCSSResourceValue>(listIterator->get()) : nullptr);
     3599        } else
     3600            maskImageValue = nullptr;
    35093601    }
    35103602
     
    36303722        case CSSPropertyWebkitMaskImage: {
    36313723            for (FillLayer* maskLayer = m_state.style()->accessMaskLayers(); maskLayer; maskLayer = maskLayer->next()) {
    3632                 auto* styleImage = maskLayer->image();
     3724                RefPtr<MaskImageOperation> maskImage = maskLayer->maskImage();
     3725                auto* styleImage = maskImage.get() ? maskImage->image() : nullptr;
    36333726                if (is<StylePendingImage>(styleImage))
    3634                     maskLayer->setImage(loadPendingImage(downcast<StylePendingImage>(*styleImage)));
     3727                    maskImage->setImage(loadPendingImage(downcast<StylePendingImage>(*styleImage)));
    36353728            }
    36363729            break;
  • trunk/Source/WebCore/css/StyleResolver.h

    r177169 r177223  
    302302   
    303303    void adjustStyleForInterCharacterRuby();
     304    void adjustStyleForMaskImages();
    304305   
    305306    bool fastRejectSelector(const RuleData&) const;
  • trunk/Source/WebCore/page/FrameView.cpp

    r177169 r177223  
    43914391}
    43924392
    4393 bool FrameView::containsSVGDocument() const
    4394 {
    4395     if (frame().document())
    4396         return frame().document()->isSVGDocument();
    4397    
    4398     return false;
    4399 }
    4400 
    44014393void FrameView::notifyWidgetsInAllFrames(WidgetNotification notification)
    44024394{
  • trunk/Source/WebCore/page/FrameView.h

    r177169 r177223  
    528528    virtual bool isVerticalDocument() const override;
    529529    virtual bool isFlippedDocument() const override;
    530     virtual bool containsSVGDocument() const override;
    531530
    532531private:
  • trunk/Source/WebCore/page/animation/CSSPropertyAnimation.cpp

    r177169 r177223  
    4343#include "FloatConversion.h"
    4444#include "IdentityTransformOperation.h"
     45#include "MaskImageOperation.h"
    4546#include "Matrix3DTransformOperation.h"
    4647#include "MatrixTransformOperation.h"
     
    342343}
    343344
     345static inline PassRefPtr<MaskImageOperation> blendFunc(const AnimationBase* anim, const RefPtr<MaskImageOperation> from, const RefPtr<MaskImageOperation> to, double progress)
     346{
     347    if (!from.get() || !to.get())
     348        return to;
     349
     350    // Only animates between masks using images (PNG, entire SVG, generated image).
     351    // It does not animate between <mask> elements (file.svg#identifier).
     352    if (from->image() && to->image())
     353        return MaskImageOperation::create(blendFunc(anim, from->image(), to->image(), progress));
     354
     355    return to;
     356}
     357
    344358static inline NinePieceImage blendFunc(const AnimationBase* anim, const NinePieceImage& from, const NinePieceImage& to, double progress)
    345359{
     
    498512        StyleImage* imageB = (b->*m_getter)();
    499513        return StyleImage::imagesEquivalent(imageA, imageB);
     514    }
     515};
     516
     517class MaskImagePropertyWrapper : public PropertyWrapper<const RefPtr<MaskImageOperation>> {
     518public:
     519    MaskImagePropertyWrapper()
     520        : PropertyWrapper<const RefPtr<MaskImageOperation>>(CSSPropertyWebkitMaskImage, &RenderStyle::maskImage, &RenderStyle::setMaskImage)
     521    {
     522    }
     523   
     524    virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
     525    {
     526        // If the style pointers are the same, don't bother doing the test.
     527        // If either is null, return false. If both are null, return true.
     528        if (a == b)
     529            return true;
     530        if (!a || !b)
     531            return false;
     532       
     533        const RefPtr<MaskImageOperation> maskImageA = (a->*m_getter)();
     534        const RefPtr<MaskImageOperation> maskImageB = (b->*m_getter)();
     535        StyleImage* styleImageA = (maskImageA ? maskImageA->image() : nullptr);
     536        StyleImage* styleImageB = (maskImageB ? maskImageB->image() : nullptr);
     537        return StyleImage::imagesEquivalent(styleImageA, styleImageB);
    500538    }
    501539};
     
    11531191        new FillLayersPropertyWrapper(CSSPropertyBackgroundImage, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers),
    11541192        new StyleImagePropertyWrapper(CSSPropertyListStyleImage, &RenderStyle::listStyleImage, &RenderStyle::setListStyleImage),
    1155         new StyleImagePropertyWrapper(CSSPropertyWebkitMaskImage, &RenderStyle::maskImage, &RenderStyle::setMaskImage),
     1193        new MaskImagePropertyWrapper(),
    11561194
    11571195        new StyleImagePropertyWrapper(CSSPropertyBorderImageSource, &RenderStyle::borderImageSource, &RenderStyle::setBorderImageSource),
  • trunk/Source/WebCore/platform/ScrollView.h

    r177169 r177223  
    411411    virtual bool isVerticalDocument() const { return true; }
    412412    virtual bool isFlippedDocument() const { return false; }
    413     virtual bool containsSVGDocument() const { return false; }
    414413
    415414    // Called to update the scrollbars to accurately reflect the state of the view.
  • trunk/Source/WebCore/platform/graphics/MaskImageOperation.cpp

    r177169 r177223  
    8383MaskImageOperation::~MaskImageOperation()
    8484{
     85    setRenderLayerImageClient(nullptr);
     86}
     87
     88bool MaskImageOperation::operator==(const MaskImageOperation& other) const
     89{
     90    if (m_url.length())
     91        return (m_url == other.m_url && m_fragment == other.m_fragment && m_isExternalDocument == other.m_isExternalDocument);
     92
     93    return m_styleImage.get() == other.m_styleImage.get();
    8594}
    8695
  • trunk/Source/WebCore/platform/graphics/MaskImageOperation.h

    r177169 r177223  
    5858
    5959    virtual ~MaskImageOperation();
     60   
     61    bool operator==(const MaskImageOperation&) const;
     62    inline bool operator!=(const MaskImageOperation& other) const { return !operator==(other); }
    6063
    6164    const String& url() const { return m_url; }
    6265    const String& fragment() const { return m_fragment; }
     66    bool isExternalDocument() const { return m_isExternalDocument; }
    6367    StyleImage* image() const { return m_styleImage.get(); }
    6468    void setImage(PassRefPtr<StyleImage> image) { m_styleImage = image; }
  • trunk/Source/WebCore/rendering/RenderBox.cpp

    r177200 r177223  
    15311531    LayoutRect borderBox = borderBoxRect();
    15321532    for (const FillLayer* maskLayer = style().maskLayers(); maskLayer; maskLayer = maskLayer->next()) {
    1533         if (maskLayer->image()) {
     1533        if (maskLayer->maskImage()) {
    15341534            BackgroundImageGeometry geometry;
    15351535            // Masks should never have fixed attachment, so it's OK for paintContainer to be null.
  • trunk/Source/WebCore/rendering/RenderBox.h

    r177200 r177223  
    176176    virtual LayoutRect outlineBoundsForRepaint(const RenderLayerModelObject* /*repaintContainer*/, const RenderGeometryMap*) const override final;
    177177    virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) override;
     178   
     179    virtual FloatRect repaintRectInLocalCoordinates() const override { return borderBoxRect(); }
     180    virtual FloatRect objectBoundingBox() const override { return borderBoxRect(); }
    178181
    179182    // Use this with caution! No type checking is done!
  • trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp

    r177169 r177223  
    2828
    2929#include "BorderEdge.h"
     30#include "CachedImage.h"
     31#include "CachedSVGDocument.h"
    3032#include "FloatRoundedRect.h"
    3133#include "Frame.h"
     
    4850#include "RenderNamedFlowThread.h"
    4951#include "RenderRegion.h"
     52#include "RenderSVGResourceMasker.h"
    5053#include "RenderTable.h"
    5154#include "RenderTableRow.h"
     
    5356#include "RenderTextFragment.h"
    5457#include "RenderView.h"
     58#include "SVGImageForContainer.h"
     59#include "SVGSVGElement.h"
    5560#include "ScrollingConstraints.h"
    5661#include "Settings.h"
     62#include "StyleCachedImage.h"
    5763#include "TransformState.h"
    5864#include <wtf/NeverDestroyed.h>
     
    677683
    678684    // Fast path for drawing simple color backgrounds.
    679     if (!isRoot && !clippedWithLocalScrolling && !shouldPaintBackgroundImage && isBorderFill && !bgLayer->next()) {
     685    if (!isRoot && !clippedWithLocalScrolling && !shouldPaintBackgroundImage && isBorderFill && !bgLayer->hasMaskImage() && !bgLayer->next()) {
    680686        if (!colorVisible)
    681687            return;
     
    838844
    839845    // no progressive loading of the background image
    840     if (!baseBgColorOnly && shouldPaintBackgroundImage) {
     846    if (!baseBgColorOnly && (shouldPaintBackgroundImage || bgLayer->hasMaskImage())) {
    841847        BackgroundImageGeometry geometry;
    842848        calculateBackgroundImageGeometry(paintInfo.paintContainer, bgLayer, scrolledPaintRect, geometry, backgroundObject);
    843849        geometry.clip(LayoutRect(pixelSnappedRect));
     850
    844851        if (!geometry.destRect().isEmpty()) {
     852            bool didPaintCustomMask = false;
    845853            CompositeOperator compositeOp = op == CompositeSourceOver ? bgLayer->composite() : op;
    846854            auto clientForBackgroundImage = backgroundObject ? backgroundObject : this;
    847             RefPtr<Image> image = bgImage->image(clientForBackgroundImage, geometry.tileSize());
    848             context->setDrawLuminanceMask(bgLayer->maskSourceType() == MaskLuminance);
    849             bool useLowQualityScaling = shouldPaintAtLowQuality(context, image.get(), bgLayer, geometry.tileSize());
    850             if (image.get())
    851                 image->setSpaceSize(geometry.spaceSize());
    852             context->drawTiledImage(image.get(), style().colorSpace(), geometry.destRect(), geometry.relativePhase(), geometry.tileSize(), ImagePaintingOptions(compositeOp, bgLayer->blendMode(), ImageOrientationDescription(), useLowQualityScaling));
     855            RefPtr<Image> image = (bgImage ? bgImage->image(clientForBackgroundImage, geometry.tileSize()) : nullptr);
     856            if (!image.get() && bgLayer->hasMaskImage())
     857                didPaintCustomMask = bgLayer->maskImage()->drawMask(*this, geometry, context, compositeOp);
     858
     859            if (!didPaintCustomMask && shouldPaintBackgroundImage) {
     860                context->setDrawLuminanceMask(bgLayer->maskSourceType() == MaskLuminance);
     861                bool useLowQualityScaling = shouldPaintAtLowQuality(context, image.get(), bgLayer, geometry.tileSize());
     862                if (image.get())
     863                    image->setSpaceSize(geometry.spaceSize());
     864                context->drawTiledImage(image.get(), style().colorSpace(), geometry.destRect(), geometry.relativePhase(), geometry.tileSize(), ImagePaintingOptions(compositeOp, bgLayer->blendMode(), ImageOrientationDescription(), useLowQualityScaling));
     865            }
    853866        }
    854867    }
     
    955968    EFillSizeType type = fillLayer->size().type;
    956969
    957     LayoutSize imageIntrinsicSize = calculateImageIntrinsicDimensions(image, positioningAreaSize, ScaleByEffectiveZoom);
    958     imageIntrinsicSize.scale(1 / image->imageScaleFactor(), 1 / image->imageScaleFactor());
     970    LayoutSize imageIntrinsicSize;
     971    if (image) {
     972        imageIntrinsicSize = calculateImageIntrinsicDimensions(image, positioningAreaSize, ScaleByEffectiveZoom);
     973        imageIntrinsicSize.scale(1 / image->imageScaleFactor(), 1 / image->imageScaleFactor());
     974    } else
     975        imageIntrinsicSize = positioningAreaSize;
     976
    959977    switch (type) {
    960978        case SizeLength: {
     
    11521170    auto clientForBackgroundImage = backgroundObject ? backgroundObject : this;
    11531171    LayoutSize fillTileSize = calculateFillTileSize(fillLayer, positioningAreaSize);
    1154     fillLayer->image()->setContainerSizeForRenderer(clientForBackgroundImage, fillTileSize, style().effectiveZoom());
     1172    if (StyleImage* layerImage = fillLayer->image())
     1173        layerImage->setContainerSizeForRenderer(clientForBackgroundImage, fillTileSize, style().effectiveZoom());
     1174   
    11551175    geometry.setTileSize(fillTileSize);
    11561176
  • trunk/Source/WebCore/rendering/RenderElement.cpp

    r177200 r177223  
    119119            if (StyleImage* maskImage = maskLayer->image())
    120120                maskImage->removeClient(this);
     121            else if (maskLayer->maskImage().get())
     122                maskLayer->maskImage()->removeRendererImageClient(this);
    121123        }
    122124
     
    324326{
    325327    // Optimize the common case
    326     if (oldLayers && !oldLayers->next() && newLayers && !newLayers->next() && (oldLayers->image() == newLayers->image()))
     328    if (oldLayers && !oldLayers->next() && newLayers && !newLayers->next() && oldLayers->image() == newLayers->image() && oldLayers->maskImage() == newLayers->maskImage())
    327329        return;
    328330   
    329331    // Go through the new layers and addClients first, to avoid removing all clients of an image.
    330332    for (const FillLayer* currNew = newLayers; currNew; currNew = currNew->next()) {
    331         if (currNew->image())
    332             currNew->image()->addClient(this);
     333        if (StyleImage* image = currNew->image())
     334            image->addClient(this);
     335        else if (currNew->maskImage().get())
     336            currNew->maskImage()->addRendererImageClient(this);
    333337    }
    334338
    335339    for (const FillLayer* currOld = oldLayers; currOld; currOld = currOld->next()) {
    336         if (currOld->image())
    337             currOld->image()->removeClient(this);
     340        if (StyleImage* image = currOld->image())
     341            image->removeClient(this);
     342        else if (currOld->maskImage().get())
     343            currOld->maskImage()->removeRendererImageClient(this);
    338344    }
    339345}
  • trunk/Source/WebCore/rendering/RenderLayer.cpp

    r177200 r177223  
    65036503#endif
    65046504    updateOrRemoveFilterClients();
     6505    updateOrRemoveMaskImageClients(oldStyle);
    65056506
    65066507    updateNeedsCompositedScrolling();
     
    66576658}
    66586659
     6660void RenderLayer::updateOrRemoveMaskImageClients(const RenderStyle* oldStyle)
     6661{
     6662    if (oldStyle && oldStyle->maskImage().get()) {
     6663        if (MaskImageInfo* maskImageInfo = MaskImageInfo::getIfExists(*this))
     6664            maskImageInfo->removeMaskImageClients(*oldStyle);
     6665    }
     6666
     6667    if (renderer().style().maskImage().get())
     6668        MaskImageInfo::get(*this).updateMaskImageClients();
     6669    else if (MaskImageInfo* maskImageInfo = MaskImageInfo::getIfExists(*this))
     6670        maskImageInfo->removeMaskImageClients(renderer().style());
     6671}
     6672
    66596673void RenderLayer::updateOrRemoveFilterEffectRenderer()
    66606674{
  • trunk/Source/WebCore/rendering/RenderLayer.h

    r177200 r177223  
    11281128    void updateOrRemoveFilterEffectRenderer();
    11291129
     1130    void updateOrRemoveMaskImageClients(const RenderStyle* oldStyle);
     1131
    11301132#if ENABLE(CSS_COMPOSITING)
    11311133    void updateAncestorChainHasBlendingDescendants();
  • trunk/Source/WebCore/rendering/RenderLayerMaskImageInfo.cpp

    r177169 r177223  
    7878RenderLayer::MaskImageInfo::~MaskImageInfo()
    7979{
    80     removeMaskImageClients();
     80    removeMaskImageClients(m_layer.renderer().style());
    8181}
    8282
     
    9393void RenderLayer::MaskImageInfo::updateMaskImageClients()
    9494{
    95     removeMaskImageClients();
     95    removeMaskImageClients(m_layer.renderer().style());
    9696   
    9797    const FillLayer* maskLayer = m_layer.renderer().style().maskLayers();
     
    120120}
    121121
    122 void RenderLayer::MaskImageInfo::removeMaskImageClients()
     122void RenderLayer::MaskImageInfo::removeMaskImageClients(const RenderStyle& oldStyle)
    123123{
    124     const FillLayer* maskLayer = m_layer.renderer().style().maskLayers();
     124    const FillLayer* maskLayer = oldStyle.maskLayers();
    125125    while (maskLayer) {
    126126        if (maskLayer->maskImage())
  • trunk/Source/WebCore/rendering/RenderLayerMaskImageInfo.h

    r177169 r177223  
    8181
    8282    void updateMaskImageClients();
    83     void removeMaskImageClients();
     83    void removeMaskImageClients(const RenderStyle& oldStyle);
    8484
    8585private:
  • trunk/Source/WebCore/rendering/style/FillLayer.cpp

    r177169 r177223  
    379379{
    380380    for (auto* layer = this; layer; layer = layer->m_next.get()) {
    381         if (layer->m_image)
     381        if (layer->image())
    382382            return true;
    383383    }
  • trunk/Source/WebCore/rendering/style/FillLayer.h

    r177169 r177223  
    6969    ~FillLayer();
    7070
     71    StyleImage* image() const { return hasMaskImage() ? maskImage()->image() : m_image.get(); }
    7172    const RefPtr<MaskImageOperation>& maskImage() const { return m_maskImageOperation; }
    72     StyleImage* image() const { return m_image.get(); }
    73     StyleImage* imageOrMaskImage() const { return hasMaskImage() ? maskImage()->image() : image(); }
    7473    const Length& xPosition() const { return m_xPosition; }
    7574    const Length& yPosition() const { return m_yPosition; }
     
    183182    std::unique_ptr<FillLayer> m_next;
    184183
     184    // FIXME: A FillLayer will always have at least one of these pointers null.
     185    // Maybe we could group them together somehow and decrease the size of FillLayer.
    185186    RefPtr<MaskImageOperation> m_maskImageOperation;
    186187    RefPtr<StyleImage> m_image;
  • trunk/Source/WebCore/rendering/style/RenderStyle.cpp

    r177169 r177223  
    831831    return false;
    832832}
     833   
     834void RenderStyle::setMaskImage(const Vector<RefPtr<MaskImageOperation>>& ops)
     835{
     836    FillLayer* curLayer = &rareNonInheritedData.access()->m_mask;
     837    while (curLayer) {
     838        curLayer->setMaskImage(nullptr);
     839        curLayer = curLayer->next();
     840    }
     841
     842    curLayer = &rareNonInheritedData.access()->m_mask;
     843    FillLayer* prevLayer = nullptr;
     844    for (auto& maskImage : ops) {
     845        if (!curLayer) {
     846            prevLayer->setNext(std::make_unique<FillLayer>(MaskFillLayer));
     847            curLayer = prevLayer->next();
     848        }
     849
     850        curLayer->setMaskImage(maskImage);
     851        prevLayer = curLayer;
     852        curLayer = curLayer->next();
     853    }
     854}
    833855
    834856void RenderStyle::setClip(Length top, Length right, Length bottom, Length left)
  • trunk/Source/WebCore/rendering/style/RenderStyle.h

    r177169 r177223  
    109109class FontMetrics;
    110110class IntRect;
     111class MaskImageOperation;
    111112class Pair;
    112113class ShadowData;
     
    799800    const FillLayer* backgroundLayers() const { return &(m_background->background()); }
    800801
    801     StyleImage* maskImage() const { return rareNonInheritedData->m_mask.image(); }
    802802    EFillRepeat maskRepeatX() const { return static_cast<EFillRepeat>(rareNonInheritedData->m_mask.repeatX()); }
    803803    EFillRepeat maskRepeatY() const { return static_cast<EFillRepeat>(rareNonInheritedData->m_mask.repeatY()); }
     
    10261026    void setPageScaleTransform(float);
    10271027
    1028     bool hasMask() const { return rareNonInheritedData->m_mask.hasImage() || rareNonInheritedData->m_maskBoxImage.hasImage(); }
     1028    bool hasMask() const { return rareNonInheritedData->m_mask.hasNonEmptyMaskImage() || rareNonInheritedData->m_mask.hasImage() || rareNonInheritedData->m_maskBoxImage.hasImage(); }
    10291029
    10301030    TextCombine textCombine() const { return static_cast<TextCombine>(rareNonInheritedData->m_textCombine); }
     
    11271127    const FilterOperations& filter() const { return rareNonInheritedData->m_filter->m_operations; }
    11281128    bool hasFilter() const { return !rareNonInheritedData->m_filter->m_operations.operations().isEmpty(); }
     1129   
     1130    RefPtr<MaskImageOperation>& mutableMaskImage() { return rareNonInheritedData.access()->m_mask.m_maskImageOperation; }
     1131    const RefPtr<MaskImageOperation> maskImage() const { return rareNonInheritedData->m_mask.maskImage(); }
    11291132
    11301133#if ENABLE(FILTERS_LEVEL_2)
     
    13771380        }
    13781381    }
    1379 
    1380     void setMaskImage(PassRefPtr<StyleImage> v) { rareNonInheritedData.access()->m_mask.setImage(v); }
    13811382
    13821383    void setMaskBoxImage(const NinePieceImage& b) { SET_VAR(rareNonInheritedData, m_maskBoxImage, b); }
     
    15701571#endif
    15711572
     1573    void setMaskImage(const Vector<RefPtr<MaskImageOperation>>&);
     1574    void setMaskImage(const RefPtr<MaskImageOperation> maskImage) { Vector<RefPtr<MaskImageOperation>> vectMask; vectMask.append(maskImage); setMaskImage(vectMask); }
     1575
    15721576    void setTabSize(unsigned size) { SET_VAR(rareInheritedData, m_tabSize, size); }
    15731577
Note: See TracChangeset for help on using the changeset viewer.