virtual void applyValue(CSSStyleSelector* selector, CSSValue* value) const
 {
     FillLayer* currChild = (selector->style()->*m_accessLayers)();
     FillLayer* prevChild = 0;
     if (value->isValueList()) {
         /* Walk each value and put it into a layer, creating new layers as needed. */
         CSSValueList* valueList = static_cast<CSSValueList*>(value);
         for (unsigned int i = 0; i < valueList->length(); i++) {
             if (!currChild) {
                 /* Need to make a new layer to hold this value */
                 currChild = new FillLayer(m_fillLayerType);
                 prevChild->setNext(currChild);
             }
             (selector->*m_mapFill)(m_propertyId, currChild, valueList->itemWithoutBoundsCheck(i));
             prevChild = currChild;
             currChild = currChild->next();
         }
     } else {
         (selector->*m_mapFill)(m_propertyId, currChild, value);
         currChild = currChild->next();
     }
     while (currChild) {
         /* Reset all remaining layers to not have the property set. */
         (currChild->*m_clear)();
         currChild = currChild->next();
     }
 }
 virtual void applyInitialValue(CSSStyleSelector* selector) const
 {
     FillLayer* currChild = (selector->style()->*m_accessLayers)();
     (currChild->*m_set)((*m_initial)(m_fillLayerType));
     for (currChild = currChild->next(); currChild; currChild = currChild->next())
         (currChild->*m_clear)();
 }
Exemplo n.º 3
0
void InlineFlowBoxPainter::paintFillLayers(const PaintInfo& paintInfo, const Color& c, const FillLayer& fillLayer, const LayoutRect& rect, SkXfermode::Mode op)
{
    // FIXME: This should be a for loop or similar. It's a little non-trivial to do so, however, since the layers need to be
    // painted in reverse order.
    if (fillLayer.next())
        paintFillLayers(paintInfo, c, *fillLayer.next(), rect, op);
    paintFillLayer(paintInfo, c, fillLayer, rect, op);
}
Exemplo n.º 4
0
void SizeListPropertyFunctions::setSizeList(CSSPropertyID property,
                                            ComputedStyle& style,
                                            const SizeList& sizeList) {
  FillLayer* fillLayer = accessFillLayer(property, style);
  FillLayer* prev = nullptr;
  for (const FillSize& size : sizeList) {
    if (!fillLayer)
      fillLayer = prev->ensureNext();
    fillLayer->setSize(size);
    prev = fillLayer;
    fillLayer = fillLayer->next();
  }
  while (fillLayer) {
    fillLayer->clearSize();
    fillLayer = fillLayer->next();
  }
}
    virtual void applyInheritValue(CSSStyleSelector* selector) const
    {
        FillLayer* currChild = (selector->style()->*m_accessLayers)();
        FillLayer* prevChild = 0;
        const FillLayer* currParent = (selector->parentStyle()->*m_layers)();
        while (currParent && (currParent->*m_test)()) {
            if (!currChild) {
                /* Need to make a new layer.*/
                currChild = new FillLayer(m_fillLayerType);
                prevChild->setNext(currChild);
            }
            (currChild->*m_set)((currParent->*m_get)());
            prevChild = currChild;
            currChild = prevChild->next();
            currParent = currParent->next();
        }

        while (currChild) {
            /* Reset any remaining layers to not have the property set. */
            (currChild->*m_clear)();
            currChild = currChild->next();
        }
    }
void StyleResourceLoader::loadPendingImages(RenderStyle* style, const ElementStyleResources& elementStyleResources)
{
    if (elementStyleResources.pendingImageProperties().isEmpty())
        return;

    PendingImagePropertyMap::const_iterator::Keys end = elementStyleResources.pendingImageProperties().end().keys();
    for (PendingImagePropertyMap::const_iterator::Keys it = elementStyleResources.pendingImageProperties().begin().keys(); it != end; ++it) {
        CSSPropertyID currentProperty = *it;

        switch (currentProperty) {
        case CSSPropertyBackgroundImage: {
            for (FillLayer* backgroundLayer = style->accessBackgroundLayers(); backgroundLayer; backgroundLayer = backgroundLayer->next()) {
                if (backgroundLayer->image() && backgroundLayer->image()->isPendingImage())
                    backgroundLayer->setImage(loadPendingImage(static_cast<StylePendingImage*>(backgroundLayer->image()), elementStyleResources.deviceScaleFactor()));
            }
            break;
        }
        case CSSPropertyContent: {
            for (ContentData* contentData = const_cast<ContentData*>(style->contentData()); contentData; contentData = contentData->next()) {
                if (contentData->isImage()) {
                    StyleImage* image = static_cast<ImageContentData*>(contentData)->image();
                    if (image->isPendingImage()) {
                        RefPtr<StyleImage> loadedImage = loadPendingImage(static_cast<StylePendingImage*>(image), elementStyleResources.deviceScaleFactor());
                        if (loadedImage)
                            static_cast<ImageContentData*>(contentData)->setImage(loadedImage.release());
                    }
                }
            }
            break;
        }
        case CSSPropertyCursor: {
            if (CursorList* cursorList = style->cursors()) {
                for (size_t i = 0; i < cursorList->size(); ++i) {
                    CursorData& currentCursor = cursorList->at(i);
                    if (StyleImage* image = currentCursor.image()) {
                        if (image->isPendingImage())
                            currentCursor.setImage(loadPendingImage(static_cast<StylePendingImage*>(image), elementStyleResources.deviceScaleFactor()));
                    }
                }
            }
            break;
        }
        case CSSPropertyListStyleImage: {
            if (style->listStyleImage() && style->listStyleImage()->isPendingImage())
                style->setListStyleImage(loadPendingImage(static_cast<StylePendingImage*>(style->listStyleImage()), elementStyleResources.deviceScaleFactor()));
            break;
        }
        case CSSPropertyBorderImageSource: {
            if (style->borderImageSource() && style->borderImageSource()->isPendingImage())
                style->setBorderImageSource(loadPendingImage(static_cast<StylePendingImage*>(style->borderImageSource()), elementStyleResources.deviceScaleFactor()));
            break;
        }
        case CSSPropertyWebkitBoxReflect: {
            if (StyleReflection* reflection = style->boxReflect()) {
                const NinePieceImage& maskImage = reflection->mask();
                if (maskImage.image() && maskImage.image()->isPendingImage()) {
                    RefPtr<StyleImage> loadedImage = loadPendingImage(static_cast<StylePendingImage*>(maskImage.image()), elementStyleResources.deviceScaleFactor());
                    reflection->setMask(NinePieceImage(loadedImage.release(), maskImage.imageSlices(), maskImage.fill(), maskImage.borderSlices(), maskImage.outset(), maskImage.horizontalRule(), maskImage.verticalRule()));
                }
            }
            break;
        }
        case CSSPropertyWebkitMaskBoxImageSource: {
            if (style->maskBoxImageSource() && style->maskBoxImageSource()->isPendingImage())
                style->setMaskBoxImageSource(loadPendingImage(static_cast<StylePendingImage*>(style->maskBoxImageSource()), elementStyleResources.deviceScaleFactor()));
            break;
        }
        case CSSPropertyWebkitMaskImage: {
            for (FillLayer* maskLayer = style->accessMaskLayers(); maskLayer; maskLayer = maskLayer->next()) {
                if (maskLayer->image() && maskLayer->image()->isPendingImage())
                    maskLayer->setImage(loadPendingImage(static_cast<StylePendingImage*>(maskLayer->image()), elementStyleResources.deviceScaleFactor()));
            }
            break;
        }
        case CSSPropertyWebkitShapeInside:
            loadPendingShapeImage(style, style->shapeInside());
            break;
        case CSSPropertyWebkitShapeOutside:
            loadPendingShapeImage(style, style->shapeOutside());
            break;
        default:
            ASSERT_NOT_REACHED();
        }
    }
}
Exemplo n.º 7
0
void FillLayer::fillUnsetProperties()
{
    FillLayer* curr;
    for (curr = this; curr && curr->isXPositionSet(); curr = curr->next()) { }
    if (curr && curr != this) {
        // We need to fill in the remaining values with the pattern specified.
        for (FillLayer* pattern = this; curr; curr = curr->next()) {
            curr->m_xPosition = pattern->m_xPosition;
            if (pattern->isBackgroundOriginSet()) {
                curr->m_backgroundXOrigin = pattern->m_backgroundXOrigin;
                curr->m_backgroundYOrigin = pattern->m_backgroundYOrigin;
            }
            pattern = pattern->next();
            if (pattern == curr || !pattern)
                pattern = this;
        }
    }
    
    for (curr = this; curr && curr->isYPositionSet(); curr = curr->next()) { }
    if (curr && curr != this) {
        // We need to fill in the remaining values with the pattern specified.
        for (FillLayer* pattern = this; curr; curr = curr->next()) {
            curr->m_yPosition = pattern->m_yPosition;
            if (pattern->isBackgroundOriginSet()) {
                curr->m_backgroundXOrigin = pattern->m_backgroundXOrigin;
                curr->m_backgroundYOrigin = pattern->m_backgroundYOrigin;
            }
            pattern = pattern->next();
            if (pattern == curr || !pattern)
                pattern = this;
        }
    }

    for (curr = this; curr && curr->isAttachmentSet(); curr = curr->next()) { }
    if (curr && curr != this) {
        // We need to fill in the remaining values with the pattern specified.
        for (FillLayer* pattern = this; curr; curr = curr->next()) {
            curr->m_attachment = pattern->m_attachment;
            pattern = pattern->next();
            if (pattern == curr || !pattern)
                pattern = this;
        }
    }
    
    for (curr = this; curr && curr->isClipSet(); curr = curr->next()) { }
    if (curr && curr != this) {
        // We need to fill in the remaining values with the pattern specified.
        for (FillLayer* pattern = this; curr; curr = curr->next()) {
            curr->m_clip = pattern->m_clip;
            pattern = pattern->next();
            if (pattern == curr || !pattern)
                pattern = this;
        }
    }

    for (curr = this; curr && curr->isCompositeSet(); curr = curr->next()) { }
    if (curr && curr != this) {
        // We need to fill in the remaining values with the pattern specified.
        for (FillLayer* pattern = this; curr; curr = curr->next()) {
            curr->m_composite = pattern->m_composite;
            pattern = pattern->next();
            if (pattern == curr || !pattern)
                pattern = this;
        }
    }

    for (curr = this; curr && curr->isBlendModeSet(); curr = curr->next()) { }
    if (curr && curr != this) {
        // We need to fill in the remaining values with the pattern specified.
        for (FillLayer* pattern = this; curr; curr = curr->next()) {
            curr->m_blendMode = pattern->m_blendMode;
            pattern = pattern->next();
            if (pattern == curr || !pattern)
                pattern = this;
        }
    }

    for (curr = this; curr && curr->isOriginSet(); curr = curr->next()) { }
    if (curr && curr != this) {
        // We need to fill in the remaining values with the pattern specified.
        for (FillLayer* pattern = this; curr; curr = curr->next()) {
            curr->m_origin = pattern->m_origin;
            pattern = pattern->next();
            if (pattern == curr || !pattern)
                pattern = this;
        }
    }

    for (curr = this; curr && curr->isRepeatXSet(); curr = curr->next()) { }
    if (curr && curr != this) {
        // We need to fill in the remaining values with the pattern specified.
        for (FillLayer* pattern = this; curr; curr = curr->next()) {
            curr->m_repeatX = pattern->m_repeatX;
            pattern = pattern->next();
            if (pattern == curr || !pattern)
                pattern = this;
        }
    }

    for (curr = this; curr && curr->isRepeatYSet(); curr = curr->next()) { }
    if (curr && curr != this) {
        // We need to fill in the remaining values with the pattern specified.
        for (FillLayer* pattern = this; curr; curr = curr->next()) {
            curr->m_repeatY = pattern->m_repeatY;
            pattern = pattern->next();
            if (pattern == curr || !pattern)
                pattern = this;
        }
    }
    
    for (curr = this; curr && curr->isSizeSet(); curr = curr->next()) { }
    if (curr && curr != this) {
        // We need to fill in the remaining values with the pattern specified.
        for (FillLayer* pattern = this; curr; curr = curr->next()) {
            curr->m_sizeType = pattern->m_sizeType;
            curr->m_sizeLength = pattern->m_sizeLength;
            pattern = pattern->next();
            if (pattern == curr || !pattern)
                pattern = this;
        }
    }
}
Exemplo n.º 8
0
void StyleResourceLoader::loadPendingImages(RenderStyle* style, ElementStyleResources& elementStyleResources)
{
    if (elementStyleResources.pendingImageProperties().isEmpty())
        return;

    PendingImagePropertyMap::const_iterator::Keys end = elementStyleResources.pendingImageProperties().end().keys();
    for (PendingImagePropertyMap::const_iterator::Keys it = elementStyleResources.pendingImageProperties().begin().keys(); it != end; ++it) {
        CSSPropertyID currentProperty = *it;

        switch (currentProperty) {
        case CSSPropertyBackgroundImage: {
            for (FillLayer* backgroundLayer = &style->accessBackgroundLayers(); backgroundLayer; backgroundLayer = backgroundLayer->next()) {
                if (backgroundLayer->image() && backgroundLayer->image()->isPendingImage())
                    backgroundLayer->setImage(loadPendingImage(toStylePendingImage(backgroundLayer->image()), elementStyleResources.deviceScaleFactor()));
            }
            break;
        }
        case CSSPropertyCursor: {
            if (CursorList* cursorList = style->cursors()) {
                for (size_t i = 0; i < cursorList->size(); ++i) {
                    CursorData& currentCursor = cursorList->at(i);
                    if (StyleImage* image = currentCursor.image()) {
                        if (image->isPendingImage())
                            currentCursor.setImage(loadPendingImage(toStylePendingImage(image), elementStyleResources.deviceScaleFactor()));
                    }
                }
            }
            break;
        }
        case CSSPropertyListStyleImage: {
            if (style->listStyleImage() && style->listStyleImage()->isPendingImage())
                style->setListStyleImage(loadPendingImage(toStylePendingImage(style->listStyleImage()), elementStyleResources.deviceScaleFactor()));
            break;
        }
        case CSSPropertyBorderImageSource: {
            if (style->borderImageSource() && style->borderImageSource()->isPendingImage())
                style->setBorderImageSource(loadPendingImage(toStylePendingImage(style->borderImageSource()), elementStyleResources.deviceScaleFactor()));
            break;
        }
        case CSSPropertyWebkitMaskBoxImageSource: {
            if (style->maskBoxImageSource() && style->maskBoxImageSource()->isPendingImage())
                style->setMaskBoxImageSource(loadPendingImage(toStylePendingImage(style->maskBoxImageSource()), elementStyleResources.deviceScaleFactor()));
            break;
        }
        case CSSPropertyWebkitMaskImage: {
            for (FillLayer* maskLayer = &style->accessMaskLayers(); maskLayer; maskLayer = maskLayer->next()) {
                if (maskLayer->image() && maskLayer->image()->isPendingImage())
                    maskLayer->setImage(loadPendingImage(toStylePendingImage(maskLayer->image()), elementStyleResources.deviceScaleFactor()));
            }
            break;
        }
        default:
            ASSERT_NOT_REACHED();
        }
    }

    elementStyleResources.clearPendingImageProperties();
}
Exemplo n.º 9
0
static void loadPendingImages(const PendingResources& pendingResources, Document& document, RenderStyle& style, const Element* element)
{
    for (auto currentProperty : pendingResources.pendingImages.keys()) {
        switch (currentProperty) {
        case CSSPropertyBackgroundImage: {
            for (FillLayer* backgroundLayer = &style.ensureBackgroundLayers(); backgroundLayer; backgroundLayer = backgroundLayer->next()) {
                auto* styleImage = backgroundLayer->image();
                if (is<StylePendingImage>(styleImage))
                    backgroundLayer->setImage(loadPendingImage(document, *styleImage, element));
            }
            break;
        }
        case CSSPropertyContent: {
            for (ContentData* contentData = const_cast<ContentData*>(style.contentData()); contentData; contentData = contentData->next()) {
                if (is<ImageContentData>(*contentData)) {
                    auto& styleImage = downcast<ImageContentData>(*contentData).image();
                    if (is<StylePendingImage>(styleImage)) {
                        if (auto loadedImage = loadPendingImage(document, styleImage, element))
                            downcast<ImageContentData>(*contentData).setImage(WTFMove(loadedImage));
                    }
                }
            }
            break;
        }
        case CSSPropertyCursor: {
            if (CursorList* cursorList = style.cursors()) {
                for (size_t i = 0; i < cursorList->size(); ++i) {
                    CursorData& currentCursor = cursorList->at(i);
                    auto* styleImage = currentCursor.image();
                    if (is<StylePendingImage>(styleImage))
                        currentCursor.setImage(loadPendingImage(document, *styleImage, element));
                }
            }
            break;
        }
        case CSSPropertyListStyleImage: {
            auto* styleImage = style.listStyleImage();
            if (is<StylePendingImage>(styleImage))
                style.setListStyleImage(loadPendingImage(document, *styleImage, element));
            break;
        }
        case CSSPropertyBorderImageSource: {
            auto* styleImage = style.borderImageSource();
            if (is<StylePendingImage>(styleImage))
                style.setBorderImageSource(loadPendingImage(document, *styleImage, element));
            break;
        }
        case CSSPropertyWebkitBoxReflect: {
            if (StyleReflection* reflection = style.boxReflect()) {
                const NinePieceImage& maskImage = reflection->mask();
                auto* styleImage = maskImage.image();
                if (is<StylePendingImage>(styleImage)) {
                    auto loadedImage = loadPendingImage(document, *styleImage, element);
                    reflection->setMask(NinePieceImage(WTFMove(loadedImage), maskImage.imageSlices(), maskImage.fill(), maskImage.borderSlices(), maskImage.outset(), maskImage.horizontalRule(), maskImage.verticalRule()));
                }
            }
            break;
        }
        case CSSPropertyWebkitMaskBoxImageSource: {
            auto* styleImage = style.maskBoxImageSource();
            if (is<StylePendingImage>(styleImage))
                style.setMaskBoxImageSource(loadPendingImage(document, *styleImage, element));
            break;
        }
        case CSSPropertyWebkitMaskImage: {
            for (FillLayer* maskLayer = &style.ensureMaskLayers(); maskLayer; maskLayer = maskLayer->next()) {
                auto* styleImage = maskLayer->image();
                if (is<StylePendingImage>(styleImage))
                    maskLayer->setImage(loadPendingImage(document, *styleImage, element));
            }
            break;
        }
#if ENABLE(CSS_SHAPES)
        case CSSPropertyWebkitShapeOutside: {
            if (!style.shapeOutside())
                return;

            StyleImage* image = style.shapeOutside()->image();
            if (is<StylePendingImage>(image))
                style.shapeOutside()->setImage(loadPendingImage(document, *image, element, LoadPolicy::ShapeOutside));

            break;
        }
#endif
        default:
            ASSERT_NOT_REACHED();
        }
    }
}
void ElementStyleResources::loadPendingImages(ComputedStyle* style)
{
    // We must loop over the properties and then look at the style to see if
    // a pending image exists, and only load that image. For example:
    //
    // <style>
    //    div { background-image: url(a.png); }
    //    div { background-image: url(b.png); }
    //    div { background-image: none; }
    // </style>
    // <div></div>
    //
    // We call styleImage() for both a.png and b.png adding the
    // CSSPropertyBackgroundImage property to the m_pendingImageProperties set,
    // then we null out the background image because of the "none".
    //
    // If we eagerly loaded the images we'd fetch a.png, even though it's not
    // used. If we didn't null check below we'd crash since the none actually
    // removed all background images.

    for (CSSPropertyID property : m_pendingImageProperties) {
        switch (property) {
        case CSSPropertyBackgroundImage: {
            for (FillLayer* backgroundLayer = &style->accessBackgroundLayers(); backgroundLayer; backgroundLayer = backgroundLayer->next()) {
                if (backgroundLayer->image() && backgroundLayer->image()->isPendingImage())
                    backgroundLayer->setImage(loadPendingImage(toStylePendingImage(backgroundLayer->image())));
            }
            break;
        }
        case CSSPropertyContent: {
            for (ContentData* contentData = const_cast<ContentData*>(style->contentData()); contentData; contentData = contentData->next()) {
                if (contentData->isImage()) {
                    StyleImage* image = toImageContentData(contentData)->image();
                    if (image->isPendingImage())
                        toImageContentData(contentData)->setImage(loadPendingImage(toStylePendingImage(image)));
                }
            }
            break;
        }
        case CSSPropertyCursor: {
            if (CursorList* cursorList = style->cursors()) {
                for (size_t i = 0; i < cursorList->size(); ++i) {
                    CursorData& currentCursor = cursorList->at(i);
                    if (StyleImage* image = currentCursor.image()) {
                        if (image->isPendingImage())
                            currentCursor.setImage(loadPendingImage(toStylePendingImage(image)));
                    }
                }
            }
            break;
        }
        case CSSPropertyListStyleImage: {
            if (style->listStyleImage() && style->listStyleImage()->isPendingImage())
                style->setListStyleImage(loadPendingImage(toStylePendingImage(style->listStyleImage())));
            break;
        }
        case CSSPropertyBorderImageSource: {
            if (style->borderImageSource() && style->borderImageSource()->isPendingImage())
                style->setBorderImageSource(loadPendingImage(toStylePendingImage(style->borderImageSource())));
            break;
        }
        case CSSPropertyWebkitBoxReflect: {
            if (StyleReflection* reflection = style->boxReflect()) {
                const NinePieceImage& maskImage = reflection->mask();
                if (maskImage.image() && maskImage.image()->isPendingImage()) {
                    RefPtrWillBeRawPtr<StyleImage> loadedImage = loadPendingImage(toStylePendingImage(maskImage.image()));
                    reflection->setMask(NinePieceImage(loadedImage.release(), maskImage.imageSlices(), maskImage.fill(), maskImage.borderSlices(), maskImage.outset(), maskImage.horizontalRule(), maskImage.verticalRule()));
                }
            }
            break;
        }
        case CSSPropertyWebkitMaskBoxImageSource: {
            if (style->maskBoxImageSource() && style->maskBoxImageSource()->isPendingImage())
                style->setMaskBoxImageSource(loadPendingImage(toStylePendingImage(style->maskBoxImageSource())));
            break;
        }
        case CSSPropertyWebkitMaskImage: {
            for (FillLayer* maskLayer = &style->accessMaskLayers(); maskLayer; maskLayer = maskLayer->next()) {
                if (maskLayer->image() && maskLayer->image()->isPendingImage())
                    maskLayer->setImage(loadPendingImage(toStylePendingImage(maskLayer->image())));
            }
            break;
        }
        case CSSPropertyShapeOutside:
            if (style->shapeOutside() && style->shapeOutside()->image() && style->shapeOutside()->image()->isPendingImage())
                style->shapeOutside()->setImage(loadPendingImage(toStylePendingImage(style->shapeOutside()->image()), CrossOriginAttributeAnonymous));
            break;
        default:
            ASSERT_NOT_REACHED();
        }
    }
}