Diff
Modified: trunk/LayoutTests/ChangeLog (284379 => 284380)
--- trunk/LayoutTests/ChangeLog 2021-10-18 17:16:46 UTC (rev 284379)
+++ trunk/LayoutTests/ChangeLog 2021-10-18 17:17:56 UTC (rev 284380)
@@ -1,3 +1,13 @@
+2021-10-18 Antti Koivisto <an...@apple.com>
+
+ background-clip:text doesn't paint correctly for inline box spanning multiple lines
+ https://bugs.webkit.org/show_bug.cgi?id=231891
+
+ Reviewed by Alan Bujtas.
+
+ * fast/inline/inline-background-clip-text-multiline-expected.html: Added.
+ * fast/inline/inline-background-clip-text-multiline.html: Added.
+
2021-10-18 Ayumi Kojima <ayumi_koj...@apple.com>
[ iOS 15 ] Rebaselining 4 fast tests.
Added: trunk/LayoutTests/fast/inline/inline-background-clip-text-multiline-expected.html (0 => 284380)
--- trunk/LayoutTests/fast/inline/inline-background-clip-text-multiline-expected.html (rev 0)
+++ trunk/LayoutTests/fast/inline/inline-background-clip-text-multiline-expected.html 2021-10-18 17:17:56 UTC (rev 284380)
@@ -0,0 +1,17 @@
+<style>
+div {
+ font-family: 'Ahem';
+}
+.clip {
+ color: transparent;
+ background-image: linear-gradient(60deg, blue, yellow, blue, yellow, blue);
+}
+.space {
+ color: white;
+}
+</style>
+<div>a <span class="clip">b<br>
+c<span class="space">w</span>d<br>
+<span>e<span class="space">w</span></span>f</span>
+</div>
+
Added: trunk/LayoutTests/fast/inline/inline-background-clip-text-multiline.html (0 => 284380)
--- trunk/LayoutTests/fast/inline/inline-background-clip-text-multiline.html (rev 0)
+++ trunk/LayoutTests/fast/inline/inline-background-clip-text-multiline.html 2021-10-18 17:17:56 UTC (rev 284380)
@@ -0,0 +1,14 @@
+<style>
+div {
+ font-family: 'Ahem';
+}
+.clip {
+ color: transparent;
+ background-image: linear-gradient(60deg, blue, yellow, blue, yellow, blue);
+ background-clip: text;
+}
+</style>
+<div>a <span class="clip">b<br>
+c d<br>
+<span>e </span>f</span>
+</div>
Modified: trunk/LayoutTests/platform/win/TestExpectations (284379 => 284380)
--- trunk/LayoutTests/platform/win/TestExpectations 2021-10-18 17:16:46 UTC (rev 284379)
+++ trunk/LayoutTests/platform/win/TestExpectations 2021-10-18 17:17:56 UTC (rev 284380)
@@ -2912,6 +2912,7 @@
fast/inline/padding-ellipsis-right.html [ ImageOnlyFailure ]
fast/inline/inline-background-clip-text.html [ ImageOnlyFailure ]
+fast/inline/inline-background-clip-text-multiline.html [ ImageOnlyFailure ]
# This test hardcodes the result of a platform-dependent font lookup algorithm.
fast/text/fallback-language-han.html [ Skip ]
Modified: trunk/Source/WebCore/ChangeLog (284379 => 284380)
--- trunk/Source/WebCore/ChangeLog 2021-10-18 17:16:46 UTC (rev 284379)
+++ trunk/Source/WebCore/ChangeLog 2021-10-18 17:17:56 UTC (rev 284380)
@@ -1,3 +1,37 @@
+2021-10-18 Antti Koivisto <an...@apple.com>
+
+ background-clip:text doesn't paint correctly for inline box spanning multiple lines
+ https://bugs.webkit.org/show_bug.cgi?id=231891
+
+ Reviewed by Alan Bujtas.
+
+ 'background-clip: text' paints to a wrong position if the inline box spans multiple lines.
+
+ Test: fast/inline/inline-background-clip-text-multiline.html
+
+ * rendering/InlineBoxPainter.cpp:
+ (WebCore::InlineBoxPainter::paintFillLayer):
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::paintFillLayer):
+ * rendering/RenderBoxModelObject.cpp:
+ (WebCore::RenderBoxModelObject::getBackgroundRoundedRect const):
+ (WebCore::RenderBoxModelObject::backgroundRoundedRectAdjustedForBleedAvoidance const):
+
+ No need to pass box size separately as it now always matches the passed in border rect.
+
+ (WebCore::RenderBoxModelObject::paintFillLayerExtended):
+
+ The 'rect' parameter used to be either the border box rect of the box being painted or,
+ in the case of multiline inline box background image, the image strip being painted.
+
+ Make the 'rect' parameter to always be the border box and pass the background image strip
+ separately.
+
+ Use the background image strip only during background image painting.
+
+ * rendering/RenderBoxModelObject.h:
+ (WebCore::RenderBoxModelObject::paintFillLayerExtended):
+
2021-10-18 Kimmo Kinnunen <kkinnu...@apple.com>
Cocoa GraphicsContextGLOpenGL should not use WebGLLayer
Modified: trunk/Source/WebCore/rendering/InlineBoxPainter.cpp (284379 => 284380)
--- trunk/Source/WebCore/rendering/InlineBoxPainter.cpp 2021-10-18 17:16:46 UTC (rev 284379)
+++ trunk/Source/WebCore/rendering/InlineBoxPainter.cpp 2021-10-18 17:17:56 UTC (rev 284380)
@@ -298,7 +298,7 @@
bool hasSingleLine = !m_inlineBox.previousInlineBox() && !m_inlineBox.nextInlineBox();
if (!hasFillImageOrBorderRadious || hasSingleLine || m_isRootInlineBox) {
- renderer().paintFillLayerExtended(m_paintInfo, color, fillLayer, rect, BackgroundBleedNone, m_inlineBox, rect.size(), op);
+ renderer().paintFillLayerExtended(m_paintInfo, color, fillLayer, rect, BackgroundBleedNone, m_inlineBox, { }, op);
return;
}
@@ -306,7 +306,7 @@
if (renderer().style().boxDecorationBreak() == BoxDecorationBreak::Clone) {
GraphicsContextStateSaver stateSaver(m_paintInfo.context());
m_paintInfo.context().clip({ rect.x(), rect.y(), LayoutUnit(m_inlineBox.rect().width()), LayoutUnit(m_inlineBox.rect().height()) });
- renderer().paintFillLayerExtended(m_paintInfo, color, fillLayer, rect, BackgroundBleedNone, m_inlineBox, rect.size(), op);
+ renderer().paintFillLayerExtended(m_paintInfo, color, fillLayer, rect, BackgroundBleedNone, m_inlineBox, { }, op);
return;
}
#endif
@@ -332,14 +332,16 @@
for (auto box = m_inlineBox.iterator(); box; box.traversePreviousInlineBox())
totalLogicalWidth += box->logicalWidth();
}
- LayoutUnit stripX = rect.x() - (isHorizontal() ? logicalOffsetOnLine : 0_lu);
- LayoutUnit stripY = rect.y() - (isHorizontal() ? 0_lu : logicalOffsetOnLine);
- LayoutUnit stripWidth = isHorizontal() ? totalLogicalWidth : LayoutUnit(m_inlineBox.rect().width());
- LayoutUnit stripHeight = isHorizontal() ? LayoutUnit(m_inlineBox.rect().height()) : totalLogicalWidth;
+ LayoutRect backgroundImageStrip {
+ rect.x() - (isHorizontal() ? logicalOffsetOnLine : 0_lu),
+ rect.y() - (isHorizontal() ? 0_lu : logicalOffsetOnLine),
+ isHorizontal() ? totalLogicalWidth : LayoutUnit(m_inlineBox.rect().width()),
+ isHorizontal() ? LayoutUnit(m_inlineBox.rect().height()) : totalLogicalWidth
+ };
GraphicsContextStateSaver stateSaver(m_paintInfo.context());
- m_paintInfo.context().clip({ rect.x(), rect.y(), LayoutUnit(m_inlineBox.rect().width()), LayoutUnit(m_inlineBox.rect().height()) });
- renderer().paintFillLayerExtended(m_paintInfo, color, fillLayer, LayoutRect(stripX, stripY, stripWidth, stripHeight), BackgroundBleedNone, m_inlineBox, rect.size(), op);
+ m_paintInfo.context().clip(FloatRect { rect });
+ renderer().paintFillLayerExtended(m_paintInfo, color, fillLayer, rect, BackgroundBleedNone, m_inlineBox, backgroundImageStrip, op);
}
void InlineBoxPainter::paintBoxShadow(ShadowStyle shadowStyle, const LayoutRect& paintRect)
Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (284379 => 284380)
--- trunk/Source/WebCore/rendering/RenderBox.cpp 2021-10-18 17:16:46 UTC (rev 284379)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp 2021-10-18 17:17:56 UTC (rev 284380)
@@ -1883,7 +1883,7 @@
void RenderBox::paintFillLayer(const PaintInfo& paintInfo, const Color& c, const FillLayer& fillLayer, const LayoutRect& rect,
BackgroundBleedAvoidance bleedAvoidance, CompositeOperator op, RenderElement* backgroundObject, BaseBackgroundColorUsage baseBgColorUsage)
{
- paintFillLayerExtended(paintInfo, c, fillLayer, rect, bleedAvoidance, { }, LayoutSize(), op, backgroundObject, baseBgColorUsage);
+ paintFillLayerExtended(paintInfo, c, fillLayer, rect, bleedAvoidance, { }, { }, op, backgroundObject, baseBgColorUsage);
}
static StyleImage* findLayerUsedImage(WrappedImagePtr image, const FillLayer& layers)
Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp (284379 => 284380)
--- trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp 2021-10-18 17:16:46 UTC (rev 284379)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp 2021-10-18 17:17:56 UTC (rev 284380)
@@ -623,12 +623,12 @@
return minimumValueForLength(padding, w);
}
-RoundedRect RenderBoxModelObject::getBackgroundRoundedRect(const LayoutRect& borderRect, const InlineIterator::InlineBoxIterator& box, LayoutUnit inlineBoxWidth, LayoutUnit inlineBoxHeight,
+RoundedRect RenderBoxModelObject::getBackgroundRoundedRect(const LayoutRect& borderRect, const InlineIterator::InlineBoxIterator& box,
bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const
{
RoundedRect border = style().getRoundedBorderFor(borderRect, includeLogicalLeftEdge, includeLogicalRightEdge);
if (box && (box->nextInlineBox() || box->previousInlineBox())) {
- RoundedRect segmentBorder = style().getRoundedBorderFor(LayoutRect(0_lu, 0_lu, inlineBoxWidth, inlineBoxHeight), includeLogicalLeftEdge, includeLogicalRightEdge);
+ RoundedRect segmentBorder = style().getRoundedBorderFor(LayoutRect(0_lu, 0_lu, borderRect.width(), borderRect.height()), includeLogicalLeftEdge, includeLogicalRightEdge);
border.setRadii(segmentBorder.radii());
}
return border;
@@ -684,17 +684,17 @@
return shrinkRectByOneDevicePixel(context, rect, document().deviceScaleFactor());
}
-RoundedRect RenderBoxModelObject::backgroundRoundedRectAdjustedForBleedAvoidance(const GraphicsContext& context, const LayoutRect& borderRect, BackgroundBleedAvoidance bleedAvoidance, const InlineIterator::InlineBoxIterator& box, const LayoutSize& boxSize, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const
+RoundedRect RenderBoxModelObject::backgroundRoundedRectAdjustedForBleedAvoidance(const GraphicsContext& context, const LayoutRect& borderRect, BackgroundBleedAvoidance bleedAvoidance, const InlineIterator::InlineBoxIterator& box, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const
{
if (bleedAvoidance == BackgroundBleedShrinkBackground) {
// We shrink the rectangle by one device pixel on each side because the bleed is one pixel maximum.
- return getBackgroundRoundedRect(shrinkRectByOneDevicePixel(context, borderRect, document().deviceScaleFactor()), box, boxSize.width(), boxSize.height(),
+ return getBackgroundRoundedRect(shrinkRectByOneDevicePixel(context, borderRect, document().deviceScaleFactor()), box,
includeLogicalLeftEdge, includeLogicalRightEdge);
}
if (bleedAvoidance == BackgroundBleedBackgroundOverBorder)
return style().getRoundedInnerBorderFor(borderRect, includeLogicalLeftEdge, includeLogicalRightEdge);
- return getBackgroundRoundedRect(borderRect, box, boxSize.width(), boxSize.height(), includeLogicalLeftEdge, includeLogicalRightEdge);
+ return getBackgroundRoundedRect(borderRect, box, includeLogicalLeftEdge, includeLogicalRightEdge);
}
static void applyBoxShadowForBackground(GraphicsContext& context, const RenderStyle& style)
@@ -737,7 +737,7 @@
}
void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, const Color& color, const FillLayer& bgLayer, const LayoutRect& rect,
- BackgroundBleedAvoidance bleedAvoidance, const InlineIterator::InlineBoxIterator& box, const LayoutSize& boxSize, CompositeOperator op, RenderElement* backgroundObject, BaseBackgroundColorUsage baseBgColorUsage)
+ BackgroundBleedAvoidance bleedAvoidance, const InlineIterator::InlineBoxIterator& box, const LayoutRect& backgroundImageStrip, CompositeOperator op, RenderElement* backgroundObject, BaseBackgroundColorUsage baseBgColorUsage)
{
GraphicsContext& context = paintInfo.context();
@@ -812,7 +812,7 @@
applyBoxShadowForBackground(context, style());
if (hasRoundedBorder && bleedAvoidance != BackgroundBleedUseTransparencyLayer) {
- FloatRoundedRect pixelSnappedBorder = backgroundRoundedRectAdjustedForBleedAvoidance(context, rect, bleedAvoidance, box, boxSize,
+ FloatRoundedRect pixelSnappedBorder = backgroundRoundedRectAdjustedForBleedAvoidance(context, rect, bleedAvoidance, box,
includeLeftEdge, includeRightEdge).pixelSnappedRoundedRectForPainting(deviceScaleFactor);
if (pixelSnappedBorder.isRenderable()) {
CompositeOperator previousOperator = context.compositeOperation();
@@ -840,7 +840,7 @@
bool clipToBorderRadius = hasRoundedBorder && !(isBorderFill && bleedAvoidance == BackgroundBleedUseTransparencyLayer);
GraphicsContextStateSaver clipToBorderStateSaver(context, clipToBorderRadius);
if (clipToBorderRadius) {
- RoundedRect border = isBorderFill ? backgroundRoundedRectAdjustedForBleedAvoidance(context, rect, bleedAvoidance, box, boxSize, includeLeftEdge, includeRightEdge) : getBackgroundRoundedRect(rect, box, boxSize.width(), boxSize.height(), includeLeftEdge, includeRightEdge);
+ RoundedRect border = isBorderFill ? backgroundRoundedRectAdjustedForBleedAvoidance(context, rect, bleedAvoidance, box, includeLeftEdge, includeRightEdge) : getBackgroundRoundedRect(rect, box, includeLeftEdge, includeRightEdge);
// Clip to the padding or content boxes as necessary.
if (bgLayer.clip() == FillBox::Content) {
@@ -954,7 +954,10 @@
// no progressive loading of the background image
if (!baseBgColorOnly && shouldPaintBackgroundImage) {
- auto geometry = calculateBackgroundImageGeometry(paintInfo.paintContainer, bgLayer, rect.location(), scrolledPaintRect, backgroundObject);
+ // Multiline inline boxes paint like the image was one long strip spanning lines. The backgroundImageStrip is this fictional rectangle.
+ auto imageRect = backgroundImageStrip.isEmpty() ? scrolledPaintRect : backgroundImageStrip;
+ auto paintOffset = backgroundImageStrip.isEmpty() ? rect.location() : backgroundImageStrip.location();
+ auto geometry = calculateBackgroundImageGeometry(paintInfo.paintContainer, bgLayer, paintOffset, imageRect, backgroundObject);
geometry.clip(LayoutRect(pixelSnappedRect));
RefPtr<Image> image;
if (!geometry.destRect().isEmpty() && (image = bgImage->image(backgroundObject ? backgroundObject : this, geometry.tileSize()))) {
Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.h (284379 => 284380)
--- trunk/Source/WebCore/rendering/RenderBoxModelObject.h 2021-10-18 17:16:46 UTC (rev 284379)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.h 2021-10-18 17:17:56 UTC (rev 284380)
@@ -213,7 +213,7 @@
void paintBorder(const PaintInfo&, const LayoutRect&, const RenderStyle&, BackgroundBleedAvoidance = BackgroundBleedNone, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true);
bool paintNinePieceImage(GraphicsContext&, const LayoutRect&, const RenderStyle&, const NinePieceImage&, CompositeOperator = CompositeOperator::SourceOver);
void paintBoxShadow(const PaintInfo&, const LayoutRect&, const RenderStyle&, ShadowStyle, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true);
- void paintFillLayerExtended(const PaintInfo&, const Color&, const FillLayer&, const LayoutRect&, BackgroundBleedAvoidance, const InlineIterator::InlineBoxIterator&, const LayoutSize& = LayoutSize(), CompositeOperator = CompositeOperator::SourceOver, RenderElement* backgroundObject = nullptr, BaseBackgroundColorUsage = BaseBackgroundColorUse);
+ void paintFillLayerExtended(const PaintInfo&, const Color&, const FillLayer&, const LayoutRect&, BackgroundBleedAvoidance, const InlineIterator::InlineBoxIterator&, const LayoutRect& backgroundImageStrip = { }, CompositeOperator = CompositeOperator::SourceOver, RenderElement* backgroundObject = nullptr, BaseBackgroundColorUsage = BaseBackgroundColorUse);
virtual bool boxShadowShouldBeAppliedToBackground(const LayoutPoint& absolutePaintPostion, BackgroundBleedAvoidance, const InlineIterator::InlineBoxIterator&) const;
@@ -259,7 +259,7 @@
const LayoutRect& paintRect, RenderElement* = nullptr) const;
bool borderObscuresBackgroundEdge(const FloatSize& contextScale) const;
bool borderObscuresBackground() const;
- RoundedRect backgroundRoundedRectAdjustedForBleedAvoidance(const GraphicsContext&, const LayoutRect&, BackgroundBleedAvoidance, const InlineIterator::InlineBoxIterator&, const LayoutSize&, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const;
+ RoundedRect backgroundRoundedRectAdjustedForBleedAvoidance(const GraphicsContext&, const LayoutRect&, BackgroundBleedAvoidance, const InlineIterator::InlineBoxIterator&, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const;
LayoutRect borderInnerRectAdjustedForBleedAvoidance(const GraphicsContext&, const LayoutRect&, BackgroundBleedAvoidance) const;
InterpolationQuality chooseInterpolationQuality(GraphicsContext&, Image&, const void*, const LayoutSize&);
@@ -310,8 +310,7 @@
LayoutSize calculateFillTileSize(const FillLayer&, const LayoutSize& scaledPositioningAreaSize) const;
- RoundedRect getBackgroundRoundedRect(const LayoutRect&, const InlineIterator::InlineBoxIterator&, LayoutUnit inlineBoxWidth, LayoutUnit inlineBoxHeight,
- bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const;
+ RoundedRect getBackgroundRoundedRect(const LayoutRect&, const InlineIterator::InlineBoxIterator&, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const;
bool fixedBackgroundPaintsInLocalCoordinates() const;