Skip to content
Permalink
Browse files
Support background images on ::first-line
https://bugs.webkit.org/show_bug.cgi?id=244039
<rdar://98157640>

Reviewed by Simon Fraser.

This sort-of-worked (no paint invalidation) and got completely broken in 248098@main refactoring
because we don't even trigger the resource load.

This patch fixes the regression and also adds paint invalidation.

* LayoutTests/TestExpectations:
* Source/WebCore/rendering/RenderBox.cpp:

Issue a repaint for ::first-line style if needed.

(WebCore::RenderBox::imageChanged):
* Source/WebCore/rendering/RenderElement.cpp:
(WebCore::RenderElement::styleDidChange):

Register renderer as client for resources in ::first-line style.

(WebCore::RenderElement::willBeDestroyed):

Unregister.

* Source/WebCore/style/StylePendingResources.cpp:
(WebCore::Style::loadPendingResources):

Trigger the load for resources in ::first-line style.

Canonical link: https://commits.webkit.org/253553@main
  • Loading branch information
anttijk committed Aug 18, 2022
1 parent 3fe4b72 commit 4385a00da760f9db033925547caa238d3a9f0885
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 25 deletions.
@@ -1799,7 +1799,6 @@ webkit.org/b/186045 imported/w3c/web-platform-tests/css/css-backgrounds/backgrou
webkit.org/b/186045 imported/w3c/web-platform-tests/css/css-backgrounds/background-clip-color-repaint.html [ Skip ]
webkit.org/b/186045 imported/w3c/web-platform-tests/css/css-backgrounds/background-color-body-propagation-006.html [ Skip ]
webkit.org/b/186045 imported/w3c/web-platform-tests/css/css-backgrounds/background-color-root-propagation-002.html [ Skip ]
webkit.org/b/186045 imported/w3c/web-platform-tests/css/css-backgrounds/background-image-first-line.html [ Skip ]
webkit.org/b/186045 imported/w3c/web-platform-tests/css/css-backgrounds/background-image-none-gradient-repaint.html [ Skip ]
webkit.org/b/186045 imported/w3c/web-platform-tests/css/css-backgrounds/border-radius-dynamic-from-no-radius.html [ Skip ]
webkit.org/b/186045 imported/w3c/web-platform-tests/css/css-backgrounds/child-move-reveals-parent-background.html [ Skip ]
@@ -2049,9 +2049,19 @@ void RenderBox::imageChanged(WrappedImagePtr image, const IntRect*)
markShapeOutsideDependentsForLayout();
}

bool didFullRepaint = repaintLayerRectsForImage(image, style().backgroundLayers(), true);
if (!didFullRepaint)
repaintLayerRectsForImage(image, style().maskLayers(), false);
bool didFullRepaint = false;

auto repaintForBackgroundAndMask = [&](auto& style) {
if (!didFullRepaint)
didFullRepaint = repaintLayerRectsForImage(image, style.backgroundLayers(), true);
if (!didFullRepaint)
didFullRepaint = repaintLayerRectsForImage(image, style.maskLayers(), false);
};

repaintForBackgroundAndMask(style());

if (auto* firstLineStyle = style().getCachedPseudoStyle(PseudoId::FirstLine))
repaintForBackgroundAndMask(*firstLineStyle);

if (!isComposited())
return;
@@ -882,11 +882,19 @@ static inline bool areCursorsEqual(const RenderStyle* a, const RenderStyle* b)

void RenderElement::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
updateFillImages(oldStyle ? &oldStyle->backgroundLayers() : nullptr, m_style.backgroundLayers());
updateFillImages(oldStyle ? &oldStyle->maskLayers() : nullptr, m_style.maskLayers());
updateImage(oldStyle ? oldStyle->borderImage().image() : nullptr, m_style.borderImage().image());
updateImage(oldStyle ? oldStyle->maskBoxImage().image() : nullptr, m_style.maskBoxImage().image());
updateShapeImage(oldStyle ? oldStyle->shapeOutside() : nullptr, m_style.shapeOutside());
auto registerImages = [this](auto& style, auto* oldStyle) {
updateFillImages(oldStyle ? &oldStyle->backgroundLayers() : nullptr, style.backgroundLayers());
updateFillImages(oldStyle ? &oldStyle->maskLayers() : nullptr, style.maskLayers());
updateImage(oldStyle ? oldStyle->borderImage().image() : nullptr, style.borderImage().image());
updateImage(oldStyle ? oldStyle->maskBoxImage().image() : nullptr, style.maskBoxImage().image());
updateShapeImage(oldStyle ? oldStyle->shapeOutside() : nullptr, style.shapeOutside());
};

registerImages(style(), oldStyle);

// Are there other pseudo-elements that need the resources to be registered?
if (auto* firstLineStyle = style().getCachedPseudoStyle(PseudoId::FirstLine))
registerImages(*firstLineStyle, oldStyle ? oldStyle->getCachedPseudoStyle(PseudoId::FirstLine) : nullptr);

SVGRenderSupport::styleChanged(*this, oldStyle);

@@ -1012,24 +1020,29 @@ void RenderElement::willBeDestroyed()

clearSubtreeLayoutRootIfNeeded();

auto unregisterImage = [this](auto* image) {
if (image)
image->removeClient(*this);
};

auto unregisterImages = [&](auto& style) {
for (auto* backgroundLayer = &style.backgroundLayers(); backgroundLayer; backgroundLayer = backgroundLayer->next())
unregisterImage(backgroundLayer->image());
for (auto* maskLayer = &style.maskLayers(); maskLayer; maskLayer = maskLayer->next())
unregisterImage(maskLayer->image());
unregisterImage(style.borderImage().image());
unregisterImage(style.maskBoxImage().image());
if (auto shapeValue = style.shapeOutside())
unregisterImage(shapeValue->image());
};

if (hasInitializedStyle()) {
for (auto* bgLayer = &m_style.backgroundLayers(); bgLayer; bgLayer = bgLayer->next()) {
if (auto* backgroundImage = bgLayer->image())
backgroundImage->removeClient(*this);
}
for (auto* maskLayer = &m_style.maskLayers(); maskLayer; maskLayer = maskLayer->next()) {
if (auto* maskImage = maskLayer->image())
maskImage->removeClient(*this);
}
if (auto* borderImage = m_style.borderImage().image())
borderImage->removeClient(*this);
if (auto* maskBoxImage = m_style.maskBoxImage().image())
maskBoxImage->removeClient(*this);
if (auto shapeValue = m_style.shapeOutside()) {
if (auto shapeImage = shapeValue->image())
shapeImage->removeClient(*this);
}
unregisterImages(m_style);

if (auto* firstLineStyle = style().getCachedPseudoStyle(PseudoId::FirstLine))
unregisterImages(*firstLineStyle);
}

if (m_hasPausedImageAnimations)
view().removeRendererWithPausedImageAnimations(*this);
}
@@ -103,6 +103,10 @@ void loadPendingResources(RenderStyle& style, Document& document, const Element*

if (style.shapeOutside())
loadPendingImage(document, style.shapeOutside()->image(), element, LoadPolicy::Anonymous);

// Are there other pseudo-elements that need resource loading?
if (auto* firstLineStyle = style.getCachedPseudoStyle(PseudoId::FirstLine))
loadPendingResources(*firstLineStyle, document, element);
}

}

0 comments on commit 4385a00

Please sign in to comment.