Diff
Modified: trunk/Source/WebCore/ChangeLog (282958 => 282959)
--- trunk/Source/WebCore/ChangeLog 2021-09-23 13:08:26 UTC (rev 282958)
+++ trunk/Source/WebCore/ChangeLog 2021-09-23 14:11:56 UTC (rev 282959)
@@ -1,3 +1,52 @@
+2021-09-23 Antti Koivisto <[email protected]>
+
+ Factor LegacyInlineFlowBox painting into a class
+ https://bugs.webkit.org/show_bug.cgi?id=230683
+
+ Reviewed by Alan Bujtas.
+
+ Introduce InlineBoxPainter, similar to TextBoxPainter.
+
+ * Sources.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * rendering/InlineBoxPainter.cpp: Added.
+ (WebCore::InlineBoxPainter::InlineBoxPainter):
+ (WebCore::InlineBoxPainter::paint):
+ (WebCore::clipRectForNinePieceImageStrip):
+ (WebCore::InlineBoxPainter::paintMask):
+ (WebCore::InlineBoxPainter::paintDecorations):
+ (WebCore::InlineBoxPainter::style const):
+ (WebCore::InlineBoxPainter::constrainToLineTopAndBottomIfNeeded const):
+ (WebCore::InlineBoxPainter::paintFillLayers):
+ (WebCore::InlineBoxPainter::paintFillLayer):
+ (WebCore::InlineBoxPainter::paintBoxShadow):
+ * rendering/InlineBoxPainter.h: Added.
+ (WebCore::InlineBoxPainter::renderer const):
+ (WebCore::InlineBoxPainter::isHorizontal const):
+ * rendering/LegacyInlineFlowBox.cpp:
+ (WebCore::LegacyInlineFlowBox::paint):
+ (WebCore::LegacyInlineFlowBox::paintFillLayers): Deleted.
+ (WebCore::LegacyInlineFlowBox::paintFillLayer): Deleted.
+ (WebCore::LegacyInlineFlowBox::paintBoxShadow): Deleted.
+ (WebCore::LegacyInlineFlowBox::constrainToLineTopAndBottomIfNeeded const): Deleted.
+ (WebCore::clipRectForNinePieceImageStrip): Deleted.
+ (WebCore::LegacyInlineFlowBox::paintBoxDecorations): Deleted.
+ (WebCore::LegacyInlineFlowBox::paintMask): Deleted.
+ * rendering/LegacyInlineFlowBox.h:
+ * rendering/RenderBoxModelObject.cpp:
+ (WebCore::RenderBoxModelObject::getBackgroundRoundedRect const):
+ (WebCore::RenderBoxModelObject::backgroundRoundedRectAdjustedForBleedAvoidance const):
+ (WebCore::RenderBoxModelObject::paintMaskForTextFillBox):
+ (WebCore::RenderBoxModelObject::paintFillLayerExtended):
+ (WebCore::RenderBoxModelObject::boxShadowShouldBeAppliedToBackground const):
+ * rendering/RenderBoxModelObject.h:
+ * rendering/RenderImage.cpp:
+ (WebCore::RenderImage::boxShadowShouldBeAppliedToBackground const):
+ * rendering/RenderImage.h:
+ * rendering/RenderTableCell.cpp:
+ (WebCore::RenderTableCell::boxShadowShouldBeAppliedToBackground const):
+ * rendering/RenderTableCell.h:
+
2021-09-23 Andres Gonzalez <[email protected]>
Remove AXDRTElementIdAttribute from the AX object platform wrapper interface.
Modified: trunk/Source/WebCore/Sources.txt (282958 => 282959)
--- trunk/Source/WebCore/Sources.txt 2021-09-23 13:08:26 UTC (rev 282958)
+++ trunk/Source/WebCore/Sources.txt 2021-09-23 14:11:56 UTC (rev 282959)
@@ -2207,6 +2207,7 @@
rendering/HitTestResult.cpp
rendering/HitTestingTransformState.cpp
rendering/ImageQualityController.cpp
+rendering/InlineBoxPainter.cpp
rendering/InlineIterator.cpp
rendering/LayerAncestorClippingStack.cpp
rendering/LayerOverlapMap.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (282958 => 282959)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-09-23 13:08:26 UTC (rev 282958)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-09-23 14:11:56 UTC (rev 282959)
@@ -5339,6 +5339,7 @@
E4E94D6122FF158A00DD191F /* LegacyLineLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = E4A1AC7822FAFD500017B75B /* LegacyLineLayout.h */; settings = {ATTRIBUTES = (Private, ); }; };
E4F0BE3125712F6E009E7431 /* CaretRectComputation.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F0BE2E25710A75009E7431 /* CaretRectComputation.h */; };
E4F38D1B2626F13B007B1064 /* DefaultResourceLoadPriority.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F38D192626F13B007B1064 /* DefaultResourceLoadPriority.h */; };
+ E4F819C626FB4EBF0094E162 /* InlineBoxPainter.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F819C526FB4EBF0094E162 /* InlineBoxPainter.h */; };
E4F9EEF3156DA00700D23E7E /* StyleSheetContents.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F9EEF1156D84C400D23E7E /* StyleSheetContents.h */; settings = {ATTRIBUTES = (Private, ); }; };
E50620842540919C00C43091 /* ContactsRequestData.h in Headers */ = {isa = PBXBuildFile; fileRef = E50620832540919B00C43091 /* ContactsRequestData.h */; settings = {ATTRIBUTES = (Private, ); }; };
E516699120FF9918009D2C27 /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = E516698F20FF9916009D2C27 /* [email protected] */; };
@@ -16607,6 +16608,8 @@
E4F0BE3025710A76009E7431 /* CaretRectComputation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CaretRectComputation.cpp; sourceTree = "<group>"; };
E4F38D192626F13B007B1064 /* DefaultResourceLoadPriority.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DefaultResourceLoadPriority.h; sourceTree = "<group>"; };
E4F38D1C2626F144007B1064 /* DefaultResourceLoadPriority.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DefaultResourceLoadPriority.cpp; sourceTree = "<group>"; };
+ E4F819C226FB4EAF0094E162 /* InlineBoxPainter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InlineBoxPainter.cpp; sourceTree = "<group>"; };
+ E4F819C526FB4EBF0094E162 /* InlineBoxPainter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InlineBoxPainter.h; sourceTree = "<group>"; };
E4F9EEF0156D84C400D23E7E /* StyleSheetContents.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleSheetContents.cpp; sourceTree = "<group>"; };
E4F9EEF1156D84C400D23E7E /* StyleSheetContents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleSheetContents.h; sourceTree = "<group>"; };
E4FB4B35239BEB10003C336A /* LayoutIntegrationInlineContent.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutIntegrationInlineContent.cpp; sourceTree = "<group>"; };
@@ -29905,6 +29908,8 @@
9307F1D60AF2D59000DBA31A /* HitTestResult.h */,
B51A2F4017D7D5DA0072517A /* ImageQualityController.cpp */,
B51A2F3E17D7D3A40072517A /* ImageQualityController.h */,
+ E4F819C226FB4EAF0094E162 /* InlineBoxPainter.cpp */,
+ E4F819C526FB4EBF0094E162 /* InlineBoxPainter.h */,
930C90DC19CF965300D6C21A /* InlineIterator.cpp */,
BCE789151120D6080060ECE5 /* InlineIterator.h */,
0FEC120B22BF2CC7004E9D35 /* LayerAncestorClippingStack.cpp */,
@@ -32899,10 +32904,12 @@
51EEAA741BEFFAB100218008 /* IndexValueEntry.h in Headers */,
517138F81BF128BB000D5F01 /* IndexValueStore.h in Headers */,
CD063F831E23FA8900812BE3 /* InitDataRegistry.h in Headers */,
+ E4F819C626FB4EBF0094E162 /* InlineBoxPainter.h in Headers */,
E30592641E27A3AD00D57C98 /* InlineClassicScript.h in Headers */,
6FE198172178397C00446F08 /* InlineContentBreaker.h in Headers */,
111FA1C826F0F30F003B8F16 /* InlineDamage.h in Headers */,
11513D0326D981E8004D3FAA /* InlineDisplayContentBuilder.h in Headers */,
+ 6F91421125152138004E4FEA /* InlineDisplayLine.h in Headers */,
6F7CA3CA208C2B2E002F29AB /* InlineFormattingContext.h in Headers */,
47C4D57D26508BCB00C7AB1F /* InlineFormattingGeometry.h in Headers */,
6FE636E82647962900F0951E /* InlineFormattingQuirks.h in Headers */,
@@ -32916,7 +32923,6 @@
11C3227D26D958CE00328F4D /* InlineLineBoxBuilder.h in Headers */,
6F6EE74326D44EE300374CDA /* InlineLineBoxVerticalAligner.h in Headers */,
6F26EB48234004A5006906E2 /* InlineLineBuilder.h in Headers */,
- 6F91421125152138004E4FEA /* InlineDisplayLine.h in Headers */,
6FC3F9472516756700A49BEA /* InlineLineRun.h in Headers */,
F45775CE241437D5002DF1A0 /* InlinePathData.h in Headers */,
6F40DA822513033A00EC04B7 /* InlineRect.h in Headers */,
Added: trunk/Source/WebCore/rendering/InlineBoxPainter.cpp (0 => 282959)
--- trunk/Source/WebCore/rendering/InlineBoxPainter.cpp (rev 0)
+++ trunk/Source/WebCore/rendering/InlineBoxPainter.cpp 2021-09-23 14:11:56 UTC (rev 282959)
@@ -0,0 +1,378 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "InlineBoxPainter.h"
+
+#include "GraphicsContext.h"
+#include "LegacyInlineFlowBox.h"
+#include "PaintInfo.h"
+#include "RenderBlockFlow.h"
+#include "RenderInline.h"
+#include "RenderLayer.h"
+#include "RenderView.h"
+
+namespace WebCore {
+
+InlineBoxPainter::InlineBoxPainter(const LegacyInlineFlowBox& inlineBox, PaintInfo& paintInfo, const LayoutPoint& paintOffset)
+ : m_inlineBox(inlineBox)
+ , m_paintInfo(paintInfo)
+ , m_paintOffset(paintOffset)
+ , m_renderer(m_inlineBox.renderer())
+ , m_isFirstLine(m_inlineBox.isFirstLine())
+ , m_isRootInlineBox(is<RenderBlockFlow>(m_renderer))
+ , m_isHorizontal(m_inlineBox.isHorizontal())
+{
+}
+
+InlineBoxPainter::~InlineBoxPainter() = default;
+
+void InlineBoxPainter::paint()
+{
+ if (m_paintInfo.phase == PaintPhase::Outline || m_paintInfo.phase == PaintPhase::SelfOutline) {
+ if (renderer().style().visibility() != Visibility::Visible || !renderer().hasOutline() || m_isRootInlineBox)
+ return;
+
+ auto& inlineFlow = downcast<RenderInline>(renderer());
+ RenderBlock* containingBlock = nullptr;
+
+ bool containingBlockPaintsContinuationOutline = inlineFlow.continuation() || inlineFlow.isContinuation();
+ if (containingBlockPaintsContinuationOutline) {
+ // FIXME: See https://bugs.webkit.org/show_bug.cgi?id=54690. We currently don't reconnect inline continuations
+ // after a child removal. As a result, those merged inlines do not get seperated and hence not get enclosed by
+ // anonymous blocks. In this case, it is better to bail out and paint it ourself.
+ RenderBlock* enclosingAnonymousBlock = renderer().containingBlock();
+ if (!enclosingAnonymousBlock->isAnonymousBlock())
+ containingBlockPaintsContinuationOutline = false;
+ else {
+ containingBlock = enclosingAnonymousBlock->containingBlock();
+ for (auto* box = &renderer(); box != containingBlock; box = &box->parent()->enclosingBoxModelObject()) {
+ if (box->hasSelfPaintingLayer()) {
+ containingBlockPaintsContinuationOutline = false;
+ break;
+ }
+ }
+ }
+ }
+
+ if (containingBlockPaintsContinuationOutline) {
+ // Add ourselves to the containing block of the entire continuation so that it can
+ // paint us atomically.
+ containingBlock->addContinuationWithOutline(downcast<RenderInline>(renderer().element()->renderer()));
+ } else if (!inlineFlow.isContinuation())
+ m_paintInfo.outlineObjects->add(&inlineFlow);
+
+ return;
+ }
+
+ if (m_paintInfo.phase == PaintPhase::Mask) {
+ paintMask();
+ return;
+ }
+
+ paintDecorations();
+}
+
+static LayoutRect clipRectForNinePieceImageStrip(const LegacyInlineFlowBox* box, const NinePieceImage& image, const LayoutRect& paintRect)
+{
+ LayoutRect clipRect(paintRect);
+ auto& style = box->renderer().style();
+ LayoutBoxExtent outsets = style.imageOutsets(image);
+ if (box->isHorizontal()) {
+ clipRect.setY(paintRect.y() - outsets.top());
+ clipRect.setHeight(paintRect.height() + outsets.top() + outsets.bottom());
+ if (box->includeLogicalLeftEdge()) {
+ clipRect.setX(paintRect.x() - outsets.left());
+ clipRect.setWidth(paintRect.width() + outsets.left());
+ }
+ if (box->includeLogicalRightEdge())
+ clipRect.setWidth(clipRect.width() + outsets.right());
+ } else {
+ clipRect.setX(paintRect.x() - outsets.left());
+ clipRect.setWidth(paintRect.width() + outsets.left() + outsets.right());
+ if (box->includeLogicalLeftEdge()) {
+ clipRect.setY(paintRect.y() - outsets.top());
+ clipRect.setHeight(paintRect.height() + outsets.top());
+ }
+ if (box->includeLogicalRightEdge())
+ clipRect.setHeight(clipRect.height() + outsets.bottom());
+ }
+ return clipRect;
+}
+
+void InlineBoxPainter::paintMask()
+{
+ if (!m_paintInfo.shouldPaintWithinRoot(renderer()) || renderer().style().visibility() != Visibility::Visible || m_paintInfo.phase != PaintPhase::Mask)
+ return;
+
+ LayoutRect frameRect(m_inlineBox.frameRect());
+ constrainToLineTopAndBottomIfNeeded(frameRect);
+
+ // Move x/y to our coordinates.
+ LayoutRect localRect(frameRect);
+ m_inlineBox.root().blockFlow().flipForWritingMode(localRect);
+ LayoutPoint adjustedPaintOffset = m_paintOffset + localRect.location();
+
+ const NinePieceImage& maskNinePieceImage = renderer().style().maskBoxImage();
+ StyleImage* maskBoxImage = renderer().style().maskBoxImage().image();
+
+ // Figure out if we need to push a transparency layer to render our mask.
+ bool pushTransparencyLayer = false;
+ bool compositedMask = renderer().hasLayer() && renderer().layer()->hasCompositedMask();
+ bool flattenCompositingLayers = renderer().view().frameView().paintBehavior().contains(PaintBehavior::FlattenCompositingLayers);
+ CompositeOperator compositeOp = CompositeOperator::SourceOver;
+ if (!compositedMask || flattenCompositingLayers) {
+ if ((maskBoxImage && renderer().style().maskLayers().hasImage()) || renderer().style().maskLayers().next())
+ pushTransparencyLayer = true;
+
+ compositeOp = CompositeOperator::DestinationIn;
+ if (pushTransparencyLayer) {
+ m_paintInfo.context().setCompositeOperation(CompositeOperator::DestinationIn);
+ m_paintInfo.context().beginTransparencyLayer(1.0f);
+ compositeOp = CompositeOperator::SourceOver;
+ }
+ }
+
+ LayoutRect paintRect = LayoutRect(adjustedPaintOffset, frameRect.size());
+
+ paintFillLayers(Color(), renderer().style().maskLayers(), paintRect, compositeOp);
+
+ bool hasBoxImage = maskBoxImage && maskBoxImage->canRender(&renderer(), renderer().style().effectiveZoom());
+ if (!hasBoxImage || !maskBoxImage->isLoaded()) {
+ if (pushTransparencyLayer)
+ m_paintInfo.context().endTransparencyLayer();
+ return; // Don't paint anything while we wait for the image to load.
+ }
+
+ bool hasSingleLine = !m_inlineBox.prevLineBox() && !m_inlineBox.nextLineBox();
+ if (hasSingleLine)
+ renderer().paintNinePieceImage(m_paintInfo.context(), LayoutRect(adjustedPaintOffset, frameRect.size()), renderer().style(), maskNinePieceImage, compositeOp);
+ else {
+ // We have a mask image that spans multiple lines.
+ // We need to adjust _tx and _ty by the width of all previous lines.
+ LayoutUnit logicalOffsetOnLine;
+ for (auto* curr = m_inlineBox.prevLineBox(); curr; curr = curr->prevLineBox())
+ logicalOffsetOnLine += curr->logicalWidth();
+ LayoutUnit totalLogicalWidth = logicalOffsetOnLine;
+ for (auto* curr = &m_inlineBox; curr; curr = curr->nextLineBox())
+ totalLogicalWidth += curr->logicalWidth();
+ LayoutUnit stripX = adjustedPaintOffset.x() - (isHorizontal() ? logicalOffsetOnLine : 0_lu);
+ LayoutUnit stripY = adjustedPaintOffset.y() - (isHorizontal() ? 0_lu : logicalOffsetOnLine);
+ LayoutUnit stripWidth = isHorizontal() ? totalLogicalWidth : frameRect.width();
+ LayoutUnit stripHeight = isHorizontal() ? frameRect.height() : totalLogicalWidth;
+
+ LayoutRect clipRect = clipRectForNinePieceImageStrip(&m_inlineBox, maskNinePieceImage, paintRect);
+ GraphicsContextStateSaver stateSaver(m_paintInfo.context());
+ m_paintInfo.context().clip(clipRect);
+ renderer().paintNinePieceImage(m_paintInfo.context(), LayoutRect(stripX, stripY, stripWidth, stripHeight), renderer().style(), maskNinePieceImage, compositeOp);
+ }
+
+ if (pushTransparencyLayer)
+ m_paintInfo.context().endTransparencyLayer();
+}
+
+void InlineBoxPainter::paintDecorations()
+{
+ if (!m_paintInfo.shouldPaintWithinRoot(renderer()) || renderer().style().visibility() != Visibility::Visible || m_paintInfo.phase != PaintPhase::Foreground)
+ return;
+
+ if (!m_isRootInlineBox && !renderer().hasVisibleBoxDecorations())
+ return;
+
+ auto& style = this->style();
+ // You can use p::first-line to specify a background. If so, the root inline boxes for
+ // a line may actually have to paint a background.
+ if (m_isRootInlineBox && (!m_isFirstLine || &style == &renderer().style()))
+ return;
+
+ LayoutRect frameRect(m_inlineBox.frameRect());
+ constrainToLineTopAndBottomIfNeeded(frameRect);
+
+ // Move x/y to our coordinates.
+ LayoutRect localRect(frameRect);
+ m_inlineBox.root().blockFlow().flipForWritingMode(localRect);
+
+ LayoutPoint adjustedPaintoffset = m_paintOffset + localRect.location();
+ GraphicsContext& context = m_paintInfo.context();
+ LayoutRect paintRect = LayoutRect(adjustedPaintoffset, frameRect.size());
+ // Shadow comes first and is behind the background and border.
+ if (!renderer().boxShadowShouldBeAppliedToBackground(adjustedPaintoffset, BackgroundBleedNone, &m_inlineBox))
+ paintBoxShadow(ShadowStyle::Normal, paintRect);
+
+ auto color = style.visitedDependentColor(CSSPropertyBackgroundColor);
+ auto compositeOp = renderer().document().compositeOperatorForBackgroundColor(color, renderer());
+
+ color = style.colorByApplyingColorFilter(color);
+
+ paintFillLayers(color, style.backgroundLayers(), paintRect, compositeOp);
+ paintBoxShadow(ShadowStyle::Inset, paintRect);
+
+ // :first-line cannot be used to put borders on a line. Always paint borders with our
+ // non-first-line style.
+ if (m_isRootInlineBox || !renderer().style().hasVisibleBorderDecoration())
+ return;
+
+ const NinePieceImage& borderImage = renderer().style().borderImage();
+ StyleImage* borderImageSource = borderImage.image();
+ bool hasBorderImage = borderImageSource && borderImageSource->canRender(&renderer(), style.effectiveZoom());
+ if (hasBorderImage && !borderImageSource->isLoaded())
+ return; // Don't paint anything while we wait for the image to load.
+
+ bool hasSingleLine = !m_inlineBox.prevLineBox() && !m_inlineBox.nextLineBox();
+ if (!hasBorderImage || hasSingleLine) {
+ renderer().paintBorder(m_paintInfo, paintRect, style, BackgroundBleedNone, m_inlineBox.includeLogicalLeftEdge(), m_inlineBox.includeLogicalRightEdge());
+ return;
+ }
+
+ // We have a border image that spans multiple lines.
+ // We need to adjust tx and ty by the width of all previous lines.
+ // Think of border image painting on inlines as though you had one long line, a single continuous
+ // strip. Even though that strip has been broken up across multiple lines, you still paint it
+ // as though you had one single line. This means each line has to pick up the image where
+ // the previous line left off.
+ // FIXME: What the heck do we do with RTL here? The math we're using is obviously not right,
+ // but it isn't even clear how this should work at all.
+ LayoutUnit logicalOffsetOnLine;
+ for (auto* curr = m_inlineBox.prevLineBox(); curr; curr = curr->prevLineBox())
+ logicalOffsetOnLine += curr->logicalWidth();
+ LayoutUnit totalLogicalWidth = logicalOffsetOnLine;
+ for (auto* curr = &m_inlineBox; curr; curr = curr->nextLineBox())
+ totalLogicalWidth += curr->logicalWidth();
+
+ LayoutUnit stripX = adjustedPaintoffset.x() - (isHorizontal() ? logicalOffsetOnLine : 0_lu);
+ LayoutUnit stripY = adjustedPaintoffset.y() - (isHorizontal() ? 0_lu : logicalOffsetOnLine);
+ LayoutUnit stripWidth = isHorizontal() ? totalLogicalWidth : frameRect.width();
+ LayoutUnit stripHeight = isHorizontal() ? frameRect.height() : totalLogicalWidth;
+
+ LayoutRect clipRect = clipRectForNinePieceImageStrip(&m_inlineBox, borderImage, paintRect);
+ GraphicsContextStateSaver stateSaver(context);
+ context.clip(clipRect);
+ renderer().paintBorder(m_paintInfo, LayoutRect(stripX, stripY, stripWidth, stripHeight), style);
+}
+
+void InlineBoxPainter::paintFillLayers(const Color& color, const FillLayer& fillLayer, const LayoutRect& rect, CompositeOperator op)
+{
+ Vector<const FillLayer*, 8> layers;
+ for (auto* layer = &fillLayer; layer; layer = layer->next())
+ layers.append(layer);
+ layers.reverse();
+ for (auto* layer : layers)
+ paintFillLayer(color, *layer, rect, op);
+}
+
+void InlineBoxPainter::paintFillLayer(const Color& color, const FillLayer& fillLayer, const LayoutRect& rect, CompositeOperator op)
+{
+ auto* image = fillLayer.image();
+ bool hasFillImage = image && image->canRender(&renderer(), renderer().style().effectiveZoom());
+ bool hasFillImageOrBorderRadious = hasFillImage || renderer().style().hasBorderRadius();
+ bool hasSingleLine = !m_inlineBox.prevLineBox() && !m_inlineBox.nextLineBox();
+
+ if (!hasFillImageOrBorderRadious || hasSingleLine || m_isRootInlineBox) {
+ renderer().paintFillLayerExtended(m_paintInfo, color, fillLayer, rect, BackgroundBleedNone, &m_inlineBox, rect.size(), op);
+ return;
+ }
+
+#if ENABLE(CSS_BOX_DECORATION_BREAK)
+ if (renderer().style().boxDecorationBreak() == BoxDecorationBreak::Clone) {
+ GraphicsContextStateSaver stateSaver(m_paintInfo.context());
+ m_paintInfo.context().clip({ rect.x(), rect.y(), LayoutUnit(m_inlineBox.width()), LayoutUnit(m_inlineBox.height()) });
+ renderer().paintFillLayerExtended(m_paintInfo, color, fillLayer, rect, BackgroundBleedNone, &m_inlineBox, rect.size(), op);
+ return;
+ }
+#endif
+
+ // We have a fill image that spans multiple lines.
+ // We need to adjust tx and ty by the width of all previous lines.
+ // Think of background painting on inlines as though you had one long line, a single continuous
+ // strip. Even though that strip has been broken up across multiple lines, you still paint it
+ // as though you had one single line. This means each line has to pick up the background where
+ // the previous line left off.
+ LayoutUnit logicalOffsetOnLine;
+ LayoutUnit totalLogicalWidth;
+ if (renderer().style().direction() == TextDirection::LTR) {
+ for (auto* curr = m_inlineBox.prevLineBox(); curr; curr = curr->prevLineBox())
+ logicalOffsetOnLine += curr->logicalWidth();
+ totalLogicalWidth = logicalOffsetOnLine;
+ for (auto* curr = &m_inlineBox; curr; curr = curr->nextLineBox())
+ totalLogicalWidth += curr->logicalWidth();
+ } else {
+ for (auto* curr = m_inlineBox.nextLineBox(); curr; curr = curr->nextLineBox())
+ logicalOffsetOnLine += curr->logicalWidth();
+ totalLogicalWidth = logicalOffsetOnLine;
+ for (auto* curr = &m_inlineBox; curr; curr = curr->prevLineBox())
+ totalLogicalWidth += curr->logicalWidth();
+ }
+ LayoutUnit stripX = rect.x() - (isHorizontal() ? logicalOffsetOnLine : 0_lu);
+ LayoutUnit stripY = rect.y() - (isHorizontal() ? 0_lu : logicalOffsetOnLine);
+ LayoutUnit stripWidth = isHorizontal() ? totalLogicalWidth : LayoutUnit(m_inlineBox.width());
+ LayoutUnit stripHeight = isHorizontal() ? LayoutUnit(m_inlineBox.height()) : totalLogicalWidth;
+
+ GraphicsContextStateSaver stateSaver(m_paintInfo.context());
+ m_paintInfo.context().clip({ rect.x(), rect.y(), LayoutUnit(m_inlineBox.width()), LayoutUnit(m_inlineBox.height()) });
+ renderer().paintFillLayerExtended(m_paintInfo, color, fillLayer, LayoutRect(stripX, stripY, stripWidth, stripHeight), BackgroundBleedNone, &m_inlineBox, rect.size(), op);
+}
+
+void InlineBoxPainter::paintBoxShadow(ShadowStyle shadowStyle, const LayoutRect& paintRect)
+{
+ bool hasSingleLine = !m_inlineBox.prevLineBox() && !m_inlineBox.nextLineBox();
+ if (hasSingleLine || m_isRootInlineBox) {
+ renderer().paintBoxShadow(m_paintInfo, paintRect, style(), shadowStyle);
+ return;
+ }
+
+ // FIXME: We can do better here in the multi-line case. We want to push a clip so that the shadow doesn't
+ // protrude incorrectly at the edges, and we want to possibly include shadows cast from the previous/following lines
+ renderer().paintBoxShadow(m_paintInfo, paintRect, style(), shadowStyle, m_inlineBox.includeLogicalLeftEdge(), m_inlineBox.includeLogicalRightEdge());
+}
+
+void InlineBoxPainter::constrainToLineTopAndBottomIfNeeded(LayoutRect& rect) const
+{
+ if (renderer().document().inNoQuirksMode())
+ return;
+ if (m_inlineBox.hasTextChildren())
+ return;
+ if (m_inlineBox.descendantsHaveSameLineHeightAndBaseline() && m_inlineBox.hasTextDescendants())
+ return;
+
+ LayoutUnit logicalTop = isHorizontal() ? rect.y() : rect.x();
+ LayoutUnit logicalHeight = isHorizontal() ? rect.height() : rect.width();
+
+ LayoutUnit bottom = std::min(m_inlineBox.root().lineBottom(), logicalTop + logicalHeight);
+ logicalTop = std::max(m_inlineBox.root().lineTop(), logicalTop);
+ logicalHeight = bottom - logicalTop;
+ if (isHorizontal()) {
+ rect.setY(logicalTop);
+ rect.setHeight(logicalHeight);
+ } else {
+ rect.setX(logicalTop);
+ rect.setWidth(logicalHeight);
+ }
+}
+
+const RenderStyle& InlineBoxPainter::style() const
+{
+ return m_isFirstLine ? renderer().firstLineStyle() : renderer().style();
+}
+
+}
Added: trunk/Source/WebCore/rendering/InlineBoxPainter.h (0 => 282959)
--- trunk/Source/WebCore/rendering/InlineBoxPainter.h (rev 0)
+++ trunk/Source/WebCore/rendering/InlineBoxPainter.h 2021-09-23 14:11:56 UTC (rev 282959)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "FloatRect.h"
+#include "GraphicsTypes.h"
+#include "LayoutRect.h"
+#include "ShadowData.h"
+
+namespace WebCore {
+
+class Color;
+class FillLayer;
+class LegacyInlineFlowBox;
+class RenderBoxModelObject;
+class RenderStyle;
+struct PaintInfo;
+
+class InlineBoxPainter {
+public:
+ InlineBoxPainter(const LegacyInlineFlowBox&, PaintInfo&, const LayoutPoint& paintOffset);
+ ~InlineBoxPainter();
+
+ void paint();
+
+private:
+ void paintMask();
+ void paintDecorations();
+ void paintFillLayers(const Color&, const FillLayer&, const LayoutRect& paintRect, CompositeOperator);
+ void paintFillLayer(const Color&, const FillLayer&, const LayoutRect& paintRect, CompositeOperator);
+ void paintBoxShadow(ShadowStyle, const LayoutRect& paintRect);
+
+ void constrainToLineTopAndBottomIfNeeded(LayoutRect&) const;
+
+ const RenderStyle& style() const;
+ // FIXME: Make RenderBoxModelObject functions const.
+ RenderBoxModelObject& renderer() const { return const_cast<RenderBoxModelObject&>(m_renderer); }
+ bool isHorizontal() const { return m_isHorizontal; }
+
+ const LegacyInlineFlowBox& m_inlineBox;
+ PaintInfo& m_paintInfo;
+ const LayoutPoint m_paintOffset;
+ const RenderBoxModelObject& m_renderer;
+ const bool m_isFirstLine;
+ const bool m_isRootInlineBox;
+ const bool m_isHorizontal;
+};
+
+}
Modified: trunk/Source/WebCore/rendering/LegacyInlineFlowBox.cpp (282958 => 282959)
--- trunk/Source/WebCore/rendering/LegacyInlineFlowBox.cpp 2021-09-23 13:08:26 UTC (rev 282958)
+++ trunk/Source/WebCore/rendering/LegacyInlineFlowBox.cpp 2021-09-23 14:11:56 UTC (rev 282959)
@@ -25,6 +25,7 @@
#include "FontCascade.h"
#include "GraphicsContext.h"
#include "HitTestResult.h"
+#include "InlineBoxPainter.h"
#include "LegacyEllipsisBox.h"
#include "LegacyInlineTextBox.h"
#include "LegacyRootInlineBox.h"
@@ -1112,45 +1113,8 @@
return;
if (paintInfo.phase != PaintPhase::ChildOutlines) {
- if (paintInfo.phase == PaintPhase::Outline || paintInfo.phase == PaintPhase::SelfOutline) {
- // Add ourselves to the paint info struct's list of inlines that need to paint their
- // outlines.
- if (renderer().style().visibility() == Visibility::Visible && renderer().hasOutline() && !isRootInlineBox()) {
- RenderInline& inlineFlow = downcast<RenderInline>(renderer());
-
- RenderBlock* containingBlock = nullptr;
- bool containingBlockPaintsContinuationOutline = inlineFlow.continuation() || inlineFlow.isContinuation();
- if (containingBlockPaintsContinuationOutline) {
- // FIXME: See https://bugs.webkit.org/show_bug.cgi?id=54690. We currently don't reconnect inline continuations
- // after a child removal. As a result, those merged inlines do not get seperated and hence not get enclosed by
- // anonymous blocks. In this case, it is better to bail out and paint it ourself.
- RenderBlock* enclosingAnonymousBlock = renderer().containingBlock();
- if (!enclosingAnonymousBlock->isAnonymousBlock())
- containingBlockPaintsContinuationOutline = false;
- else {
- containingBlock = enclosingAnonymousBlock->containingBlock();
- for (auto* box = &renderer(); box != containingBlock; box = &box->parent()->enclosingBoxModelObject()) {
- if (box->hasSelfPaintingLayer()) {
- containingBlockPaintsContinuationOutline = false;
- break;
- }
- }
- }
- }
-
- if (containingBlockPaintsContinuationOutline) {
- // Add ourselves to the containing block of the entire continuation so that it can
- // paint us atomically.
- containingBlock->addContinuationWithOutline(downcast<RenderInline>(renderer().element()->renderer()));
- } else if (!inlineFlow.isContinuation())
- paintInfo.outlineObjects->add(&inlineFlow);
- }
- } else if (paintInfo.phase == PaintPhase::Mask)
- paintMask(paintInfo, paintOffset);
- else {
- // Paint our background, border and box-shadow.
- paintBoxDecorations(paintInfo, paintOffset);
- }
+ InlineBoxPainter painter(*this, paintInfo, paintOffset);
+ painter.paint();
}
if (paintInfo.phase == PaintPhase::Mask)
@@ -1170,16 +1134,6 @@
}
}
-void LegacyInlineFlowBox::paintFillLayers(const PaintInfo& paintInfo, const Color& color, const FillLayer& fillLayer, const LayoutRect& rect, CompositeOperator op)
-{
- Vector<const FillLayer*, 8> layers;
- for (auto* layer = &fillLayer; layer; layer = layer->next())
- layers.append(layer);
- layers.reverse();
- for (auto* layer : layers)
- paintFillLayer(paintInfo, color, *layer, rect, op);
-}
-
bool LegacyInlineFlowBox::boxShadowCanBeAppliedToBackground(const FillLayer& lastBackgroundLayer) const
{
// The checks here match how paintFillLayer() decides whether to clip (if it does, the shadow
@@ -1189,257 +1143,6 @@
return (!hasFillImage && !renderer().style().hasBorderRadius()) || (!prevLineBox() && !nextLineBox()) || !parent();
}
-void LegacyInlineFlowBox::paintFillLayer(const PaintInfo& paintInfo, const Color& color, const FillLayer& fillLayer, const LayoutRect& rect, CompositeOperator op)
-{
- auto* image = fillLayer.image();
- bool hasFillImage = image && image->canRender(&renderer(), renderer().style().effectiveZoom());
- if ((!hasFillImage && !renderer().style().hasBorderRadius()) || (!prevLineBox() && !nextLineBox()) || !parent())
- renderer().paintFillLayerExtended(paintInfo, color, fillLayer, rect, BackgroundBleedNone, this, rect.size(), op);
-#if ENABLE(CSS_BOX_DECORATION_BREAK)
- else if (renderer().style().boxDecorationBreak() == BoxDecorationBreak::Clone) {
- GraphicsContextStateSaver stateSaver(paintInfo.context());
- paintInfo.context().clip({ rect.x(), rect.y(), LayoutUnit(width()), LayoutUnit(height()) });
- renderer().paintFillLayerExtended(paintInfo, color, fillLayer, rect, BackgroundBleedNone, this, rect.size(), op);
- }
-#endif
- else {
- // We have a fill image that spans multiple lines.
- // We need to adjust tx and ty by the width of all previous lines.
- // Think of background painting on inlines as though you had one long line, a single continuous
- // strip. Even though that strip has been broken up across multiple lines, you still paint it
- // as though you had one single line. This means each line has to pick up the background where
- // the previous line left off.
- LayoutUnit logicalOffsetOnLine;
- LayoutUnit totalLogicalWidth;
- if (renderer().style().direction() == TextDirection::LTR) {
- for (auto* curr = prevLineBox(); curr; curr = curr->prevLineBox())
- logicalOffsetOnLine += curr->logicalWidth();
- totalLogicalWidth = logicalOffsetOnLine;
- for (auto* curr = this; curr; curr = curr->nextLineBox())
- totalLogicalWidth += curr->logicalWidth();
- } else {
- for (auto* curr = nextLineBox(); curr; curr = curr->nextLineBox())
- logicalOffsetOnLine += curr->logicalWidth();
- totalLogicalWidth = logicalOffsetOnLine;
- for (auto* curr = this; curr; curr = curr->prevLineBox())
- totalLogicalWidth += curr->logicalWidth();
- }
- LayoutUnit stripX = rect.x() - (isHorizontal() ? logicalOffsetOnLine : 0_lu);
- LayoutUnit stripY = rect.y() - (isHorizontal() ? 0_lu : logicalOffsetOnLine);
- LayoutUnit stripWidth = isHorizontal() ? totalLogicalWidth : LayoutUnit(width());
- LayoutUnit stripHeight = isHorizontal() ? LayoutUnit(height()) : totalLogicalWidth;
-
- GraphicsContextStateSaver stateSaver(paintInfo.context());
- paintInfo.context().clip({ rect.x(), rect.y(), LayoutUnit(width()), LayoutUnit(height()) });
- renderer().paintFillLayerExtended(paintInfo, color, fillLayer, LayoutRect(stripX, stripY, stripWidth, stripHeight), BackgroundBleedNone, this, rect.size(), op);
- }
-}
-
-void LegacyInlineFlowBox::paintBoxShadow(const PaintInfo& info, const RenderStyle& style, ShadowStyle shadowStyle, const LayoutRect& paintRect)
-{
- if ((!prevLineBox() && !nextLineBox()) || !parent())
- renderer().paintBoxShadow(info, paintRect, style, shadowStyle);
- else {
- // FIXME: We can do better here in the multi-line case. We want to push a clip so that the shadow doesn't
- // protrude incorrectly at the edges, and we want to possibly include shadows cast from the previous/following lines
- renderer().paintBoxShadow(info, paintRect, style, shadowStyle, includeLogicalLeftEdge(), includeLogicalRightEdge());
- }
-}
-
-void LegacyInlineFlowBox::constrainToLineTopAndBottomIfNeeded(LayoutRect& rect) const
-{
- bool noQuirksMode = renderer().document().inNoQuirksMode();
- if (!noQuirksMode && !hasTextChildren() && !(descendantsHaveSameLineHeightAndBaseline() && hasTextDescendants())) {
- const LegacyRootInlineBox& rootBox = root();
- LayoutUnit logicalTop = isHorizontal() ? rect.y() : rect.x();
- LayoutUnit logicalHeight = isHorizontal() ? rect.height() : rect.width();
- LayoutUnit bottom = std::min(rootBox.lineBottom(), logicalTop + logicalHeight);
- logicalTop = std::max(rootBox.lineTop(), logicalTop);
- logicalHeight = bottom - logicalTop;
- if (isHorizontal()) {
- rect.setY(logicalTop);
- rect.setHeight(logicalHeight);
- } else {
- rect.setX(logicalTop);
- rect.setWidth(logicalHeight);
- }
- }
-}
-
-static LayoutRect clipRectForNinePieceImageStrip(LegacyInlineFlowBox* box, const NinePieceImage& image, const LayoutRect& paintRect)
-{
- LayoutRect clipRect(paintRect);
- auto& style = box->renderer().style();
- LayoutBoxExtent outsets = style.imageOutsets(image);
- if (box->isHorizontal()) {
- clipRect.setY(paintRect.y() - outsets.top());
- clipRect.setHeight(paintRect.height() + outsets.top() + outsets.bottom());
- if (box->includeLogicalLeftEdge()) {
- clipRect.setX(paintRect.x() - outsets.left());
- clipRect.setWidth(paintRect.width() + outsets.left());
- }
- if (box->includeLogicalRightEdge())
- clipRect.setWidth(clipRect.width() + outsets.right());
- } else {
- clipRect.setX(paintRect.x() - outsets.left());
- clipRect.setWidth(paintRect.width() + outsets.left() + outsets.right());
- if (box->includeLogicalLeftEdge()) {
- clipRect.setY(paintRect.y() - outsets.top());
- clipRect.setHeight(paintRect.height() + outsets.top());
- }
- if (box->includeLogicalRightEdge())
- clipRect.setHeight(clipRect.height() + outsets.bottom());
- }
- return clipRect;
-}
-
-void LegacyInlineFlowBox::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
-{
- if (!paintInfo.shouldPaintWithinRoot(renderer()) || renderer().style().visibility() != Visibility::Visible || paintInfo.phase != PaintPhase::Foreground)
- return;
-
- // You can use p::first-line to specify a background. If so, the root line boxes for
- // a line may actually have to paint a background.
- if (parent() && !renderer().hasVisibleBoxDecorations())
- return;
- const RenderStyle& lineStyle = this->lineStyle();
- if (!parent() && (!isFirstLine() || &lineStyle == &renderer().style()))
- return;
-
- LayoutRect frameRect(this->frameRect());
- constrainToLineTopAndBottomIfNeeded(frameRect);
-
- // Move x/y to our coordinates.
- LayoutRect localRect(frameRect);
- flipForWritingMode(localRect);
-
- LayoutPoint adjustedPaintoffset = paintOffset + localRect.location();
- GraphicsContext& context = paintInfo.context();
- LayoutRect paintRect = LayoutRect(adjustedPaintoffset, frameRect.size());
- // Shadow comes first and is behind the background and border.
- if (!renderer().boxShadowShouldBeAppliedToBackground(adjustedPaintoffset, BackgroundBleedNone, this))
- paintBoxShadow(paintInfo, lineStyle, ShadowStyle::Normal, paintRect);
-
- auto color = lineStyle.visitedDependentColor(CSSPropertyBackgroundColor);
- auto compositeOp = renderer().document().compositeOperatorForBackgroundColor(color, renderer());
-
- color = lineStyle.colorByApplyingColorFilter(color);
-
- paintFillLayers(paintInfo, color, lineStyle.backgroundLayers(), paintRect, compositeOp);
- paintBoxShadow(paintInfo, lineStyle, ShadowStyle::Inset, paintRect);
-
- // :first-line cannot be used to put borders on a line. Always paint borders with our
- // non-first-line style.
- if (!parent() || !renderer().style().hasVisibleBorderDecoration())
- return;
- const NinePieceImage& borderImage = renderer().style().borderImage();
- StyleImage* borderImageSource = borderImage.image();
- bool hasBorderImage = borderImageSource && borderImageSource->canRender(&renderer(), lineStyle.effectiveZoom());
- if (hasBorderImage && !borderImageSource->isLoaded())
- return; // Don't paint anything while we wait for the image to load.
-
- // The simple case is where we either have no border image or we are the only box for this object. In those
- // cases only a single call to draw is required.
- if (!hasBorderImage || (!prevLineBox() && !nextLineBox()))
- renderer().paintBorder(paintInfo, paintRect, lineStyle, BackgroundBleedNone, includeLogicalLeftEdge(), includeLogicalRightEdge());
- else {
- // We have a border image that spans multiple lines.
- // We need to adjust tx and ty by the width of all previous lines.
- // Think of border image painting on inlines as though you had one long line, a single continuous
- // strip. Even though that strip has been broken up across multiple lines, you still paint it
- // as though you had one single line. This means each line has to pick up the image where
- // the previous line left off.
- // FIXME: What the heck do we do with RTL here? The math we're using is obviously not right,
- // but it isn't even clear how this should work at all.
- LayoutUnit logicalOffsetOnLine;
- for (auto* curr = prevLineBox(); curr; curr = curr->prevLineBox())
- logicalOffsetOnLine += curr->logicalWidth();
- LayoutUnit totalLogicalWidth = logicalOffsetOnLine;
- for (auto* curr = this; curr; curr = curr->nextLineBox())
- totalLogicalWidth += curr->logicalWidth();
- LayoutUnit stripX = adjustedPaintoffset.x() - (isHorizontal() ? logicalOffsetOnLine : 0_lu);
- LayoutUnit stripY = adjustedPaintoffset.y() - (isHorizontal() ? 0_lu : logicalOffsetOnLine);
- LayoutUnit stripWidth = isHorizontal() ? totalLogicalWidth : frameRect.width();
- LayoutUnit stripHeight = isHorizontal() ? frameRect.height() : totalLogicalWidth;
-
- LayoutRect clipRect = clipRectForNinePieceImageStrip(this, borderImage, paintRect);
- GraphicsContextStateSaver stateSaver(context);
- context.clip(clipRect);
- renderer().paintBorder(paintInfo, LayoutRect(stripX, stripY, stripWidth, stripHeight), lineStyle);
- }
-}
-
-void LegacyInlineFlowBox::paintMask(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
-{
- if (!paintInfo.shouldPaintWithinRoot(renderer()) || renderer().style().visibility() != Visibility::Visible || paintInfo.phase != PaintPhase::Mask)
- return;
-
- LayoutRect frameRect(this->frameRect());
- constrainToLineTopAndBottomIfNeeded(frameRect);
-
- // Move x/y to our coordinates.
- LayoutRect localRect(frameRect);
- flipForWritingMode(localRect);
- LayoutPoint adjustedPaintOffset = paintOffset + localRect.location();
-
- const NinePieceImage& maskNinePieceImage = renderer().style().maskBoxImage();
- StyleImage* maskBoxImage = renderer().style().maskBoxImage().image();
-
- // Figure out if we need to push a transparency layer to render our mask.
- bool pushTransparencyLayer = false;
- bool compositedMask = renderer().hasLayer() && renderer().layer()->hasCompositedMask();
- bool flattenCompositingLayers = renderer().view().frameView().paintBehavior().contains(PaintBehavior::FlattenCompositingLayers);
- CompositeOperator compositeOp = CompositeOperator::SourceOver;
- if (!compositedMask || flattenCompositingLayers) {
- if ((maskBoxImage && renderer().style().maskLayers().hasImage()) || renderer().style().maskLayers().next())
- pushTransparencyLayer = true;
-
- compositeOp = CompositeOperator::DestinationIn;
- if (pushTransparencyLayer) {
- paintInfo.context().setCompositeOperation(CompositeOperator::DestinationIn);
- paintInfo.context().beginTransparencyLayer(1.0f);
- compositeOp = CompositeOperator::SourceOver;
- }
- }
-
- LayoutRect paintRect = LayoutRect(adjustedPaintOffset, frameRect.size());
- paintFillLayers(paintInfo, Color(), renderer().style().maskLayers(), paintRect, compositeOp);
-
- bool hasBoxImage = maskBoxImage && maskBoxImage->canRender(&renderer(), renderer().style().effectiveZoom());
- if (!hasBoxImage || !maskBoxImage->isLoaded()) {
- if (pushTransparencyLayer)
- paintInfo.context().endTransparencyLayer();
- return; // Don't paint anything while we wait for the image to load.
- }
-
- // The simple case is where we are the only box for this object. In those
- // cases only a single call to draw is required.
- if (!prevLineBox() && !nextLineBox())
- renderer().paintNinePieceImage(paintInfo.context(), LayoutRect(adjustedPaintOffset, frameRect.size()), renderer().style(), maskNinePieceImage, compositeOp);
- else {
- // We have a mask image that spans multiple lines.
- // We need to adjust _tx and _ty by the width of all previous lines.
- LayoutUnit logicalOffsetOnLine;
- for (auto* curr = prevLineBox(); curr; curr = curr->prevLineBox())
- logicalOffsetOnLine += curr->logicalWidth();
- LayoutUnit totalLogicalWidth = logicalOffsetOnLine;
- for (auto* curr = this; curr; curr = curr->nextLineBox())
- totalLogicalWidth += curr->logicalWidth();
- LayoutUnit stripX = adjustedPaintOffset.x() - (isHorizontal() ? logicalOffsetOnLine : 0_lu);
- LayoutUnit stripY = adjustedPaintOffset.y() - (isHorizontal() ? 0_lu : logicalOffsetOnLine);
- LayoutUnit stripWidth = isHorizontal() ? totalLogicalWidth : frameRect.width();
- LayoutUnit stripHeight = isHorizontal() ? frameRect.height() : totalLogicalWidth;
-
- LayoutRect clipRect = clipRectForNinePieceImageStrip(this, maskNinePieceImage, paintRect);
- GraphicsContextStateSaver stateSaver(paintInfo.context());
- paintInfo.context().clip(clipRect);
- renderer().paintNinePieceImage(paintInfo.context(), LayoutRect(stripX, stripY, stripWidth, stripHeight), renderer().style(), maskNinePieceImage, compositeOp);
- }
-
- if (pushTransparencyLayer)
- paintInfo.context().endTransparencyLayer();
-}
-
LegacyInlineBox* LegacyInlineFlowBox::firstLeafDescendant() const
{
LegacyInlineBox* leaf = nullptr;
Modified: trunk/Source/WebCore/rendering/LegacyInlineFlowBox.h (282958 => 282959)
--- trunk/Source/WebCore/rendering/LegacyInlineFlowBox.h 2021-09-23 13:08:26 UTC (rev 282958)
+++ trunk/Source/WebCore/rendering/LegacyInlineFlowBox.h 2021-09-23 14:11:56 UTC (rev 282959)
@@ -115,11 +115,6 @@
void clearTruncation() override;
- void paintBoxDecorations(PaintInfo&, const LayoutPoint&);
- void paintMask(PaintInfo&, const LayoutPoint&);
- void paintFillLayers(const PaintInfo&, const Color&, const FillLayer&, const LayoutRect&, CompositeOperator = CompositeOperator::SourceOver);
- void paintFillLayer(const PaintInfo&, const Color&, const FillLayer&, const LayoutRect&, CompositeOperator = CompositeOperator::SourceOver);
- void paintBoxShadow(const PaintInfo&, const RenderStyle&, ShadowStyle, const LayoutRect&);
void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom) override;
bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom, HitTestAction) override;
@@ -305,7 +300,6 @@
void addTextBoxVisualOverflow(LegacyInlineTextBox&, GlyphOverflowAndFallbackFontsMap&, LayoutRect& logicalVisualOverflow);
void addOutlineVisualOverflow(LayoutRect& logicalVisualOverflow);
void addReplacedChildOverflow(const LegacyInlineBox*, LayoutRect& logicalLayoutOverflow, LayoutRect& logicalVisualOverflow);
- void constrainToLineTopAndBottomIfNeeded(LayoutRect&) const;
private:
unsigned m_includeLogicalLeftEdge : 1;
Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp (282958 => 282959)
--- trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp 2021-09-23 13:08:26 UTC (rev 282958)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp 2021-09-23 14:11:56 UTC (rev 282959)
@@ -621,7 +621,7 @@
return minimumValueForLength(padding, w);
}
-RoundedRect RenderBoxModelObject::getBackgroundRoundedRect(const LayoutRect& borderRect, LegacyInlineFlowBox* box, LayoutUnit inlineBoxWidth, LayoutUnit inlineBoxHeight,
+RoundedRect RenderBoxModelObject::getBackgroundRoundedRect(const LayoutRect& borderRect, const LegacyInlineFlowBox* box, LayoutUnit inlineBoxWidth, LayoutUnit inlineBoxHeight,
bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const
{
RoundedRect border = style().getRoundedBorderFor(borderRect, includeLogicalLeftEdge, includeLogicalRightEdge);
@@ -682,7 +682,7 @@
return shrinkRectByOneDevicePixel(context, rect, document().deviceScaleFactor());
}
-RoundedRect RenderBoxModelObject::backgroundRoundedRectAdjustedForBleedAvoidance(const GraphicsContext& context, const LayoutRect& borderRect, BackgroundBleedAvoidance bleedAvoidance, LegacyInlineFlowBox* box, const LayoutSize& boxSize, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const
+RoundedRect RenderBoxModelObject::backgroundRoundedRectAdjustedForBleedAvoidance(const GraphicsContext& context, const LayoutRect& borderRect, BackgroundBleedAvoidance bleedAvoidance, const LegacyInlineFlowBox* box, const LayoutSize& boxSize, 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.
@@ -710,7 +710,7 @@
return view().imageQualityController().chooseInterpolationQuality(context, this, image, layer, size);
}
-void RenderBoxModelObject::paintMaskForTextFillBox(ImageBuffer* maskImage, const FloatRect& maskRect, LegacyInlineFlowBox* box, const LayoutRect& scrolledPaintRect)
+void RenderBoxModelObject::paintMaskForTextFillBox(ImageBuffer* maskImage, const FloatRect& maskRect, const LegacyInlineFlowBox* box, const LayoutRect& scrolledPaintRect)
{
GraphicsContext& maskImageContext = maskImage->context();
maskImageContext.translate(-maskRect.location());
@@ -720,7 +720,7 @@
PaintInfo info(maskImageContext, LayoutRect { maskRect }, PaintPhase::TextClip, PaintBehavior::ForceBlackText);
if (box) {
const LegacyRootInlineBox& rootBox = box->root();
- box->paint(info, LayoutPoint(scrolledPaintRect.x() - box->x(), scrolledPaintRect.y() - box->y()), rootBox.lineTop(), rootBox.lineBottom());
+ const_cast<LegacyInlineFlowBox*>(box)->paint(info, LayoutPoint(scrolledPaintRect.x() - box->x(), scrolledPaintRect.y() - box->y()), rootBox.lineTop(), rootBox.lineBottom());
} else {
LayoutSize localOffset = is<RenderBox>(*this) ? downcast<RenderBox>(*this).locationOffset() : LayoutSize();
paint(info, scrolledPaintRect.location() - localOffset);
@@ -728,7 +728,7 @@
}
void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, const Color& color, const FillLayer& bgLayer, const LayoutRect& rect,
- BackgroundBleedAvoidance bleedAvoidance, LegacyInlineFlowBox* box, const LayoutSize& boxSize, CompositeOperator op, RenderElement* backgroundObject, BaseBackgroundColorUsage baseBgColorUsage)
+ BackgroundBleedAvoidance bleedAvoidance, const LegacyInlineFlowBox* box, const LayoutSize& boxSize, CompositeOperator op, RenderElement* backgroundObject, BaseBackgroundColorUsage baseBgColorUsage)
{
GraphicsContext& context = paintInfo.context();
@@ -2326,7 +2326,7 @@
return true;
}
-bool RenderBoxModelObject::boxShadowShouldBeAppliedToBackground(const LayoutPoint&, BackgroundBleedAvoidance bleedAvoidance, LegacyInlineFlowBox* inlineFlowBox) const
+bool RenderBoxModelObject::boxShadowShouldBeAppliedToBackground(const LayoutPoint&, BackgroundBleedAvoidance bleedAvoidance, const LegacyInlineFlowBox* inlineFlowBox) const
{
if (bleedAvoidance != BackgroundBleedNone)
return false;
Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.h (282958 => 282959)
--- trunk/Source/WebCore/rendering/RenderBoxModelObject.h 2021-09-23 13:08:26 UTC (rev 282958)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.h 2021-09-23 14:11:56 UTC (rev 282959)
@@ -210,9 +210,9 @@
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, LegacyInlineFlowBox* = nullptr, const LayoutSize& = LayoutSize(), CompositeOperator = CompositeOperator::SourceOver, RenderElement* backgroundObject = nullptr, BaseBackgroundColorUsage = BaseBackgroundColorUse);
+ void paintFillLayerExtended(const PaintInfo&, const Color&, const FillLayer&, const LayoutRect&, BackgroundBleedAvoidance, const LegacyInlineFlowBox* = nullptr, const LayoutSize& = LayoutSize(), CompositeOperator = CompositeOperator::SourceOver, RenderElement* backgroundObject = nullptr, BaseBackgroundColorUsage = BaseBackgroundColorUse);
- virtual bool boxShadowShouldBeAppliedToBackground(const LayoutPoint& absolutePaintPostion, BackgroundBleedAvoidance, LegacyInlineFlowBox* = nullptr) const;
+ virtual bool boxShadowShouldBeAppliedToBackground(const LayoutPoint& absolutePaintPostion, BackgroundBleedAvoidance, const LegacyInlineFlowBox* = nullptr) const;
// Overridden by subclasses to determine line height and baseline position.
virtual LayoutUnit lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const = 0;
@@ -256,7 +256,7 @@
const LayoutRect& paintRect, RenderElement* = nullptr) const;
bool borderObscuresBackgroundEdge(const FloatSize& contextScale) const;
bool borderObscuresBackground() const;
- RoundedRect backgroundRoundedRectAdjustedForBleedAvoidance(const GraphicsContext&, const LayoutRect&, BackgroundBleedAvoidance, LegacyInlineFlowBox*, const LayoutSize&, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const;
+ RoundedRect backgroundRoundedRectAdjustedForBleedAvoidance(const GraphicsContext&, const LayoutRect&, BackgroundBleedAvoidance, const LegacyInlineFlowBox* , const LayoutSize&, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const;
LayoutRect borderInnerRectAdjustedForBleedAvoidance(const GraphicsContext&, const LayoutRect&, BackgroundBleedAvoidance) const;
InterpolationQuality chooseInterpolationQuality(GraphicsContext&, Image&, const void*, const LayoutSize&);
@@ -307,7 +307,7 @@
LayoutSize calculateFillTileSize(const FillLayer&, const LayoutSize& scaledPositioningAreaSize) const;
- RoundedRect getBackgroundRoundedRect(const LayoutRect&, LegacyInlineFlowBox*, LayoutUnit inlineBoxWidth, LayoutUnit inlineBoxHeight,
+ RoundedRect getBackgroundRoundedRect(const LayoutRect&, const LegacyInlineFlowBox* , LayoutUnit inlineBoxWidth, LayoutUnit inlineBoxHeight,
bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const;
bool fixedBackgroundPaintsInLocalCoordinates() const;
@@ -326,7 +326,7 @@
void drawBoxSideFromPath(GraphicsContext&, const LayoutRect&, const Path&, const BorderEdges&,
float thickness, float drawThickness, BoxSide, const RenderStyle&,
Color, BorderStyle, BackgroundBleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge);
- void paintMaskForTextFillBox(ImageBuffer*, const FloatRect&, LegacyInlineFlowBox*, const LayoutRect&);
+ void paintMaskForTextFillBox(ImageBuffer*, const FloatRect&, const LegacyInlineFlowBox* , const LayoutRect&);
};
} // namespace WebCore
Modified: trunk/Source/WebCore/rendering/RenderImage.cpp (282958 => 282959)
--- trunk/Source/WebCore/rendering/RenderImage.cpp 2021-09-23 13:08:26 UTC (rev 282958)
+++ trunk/Source/WebCore/rendering/RenderImage.cpp 2021-09-23 14:11:56 UTC (rev 282959)
@@ -691,7 +691,7 @@
return drawResult;
}
-bool RenderImage::boxShadowShouldBeAppliedToBackground(const LayoutPoint& paintOffset, BackgroundBleedAvoidance bleedAvoidance, LegacyInlineFlowBox*) const
+bool RenderImage::boxShadowShouldBeAppliedToBackground(const LayoutPoint& paintOffset, BackgroundBleedAvoidance bleedAvoidance, const LegacyInlineFlowBox*) const
{
if (!RenderBoxModelObject::boxShadowShouldBeAppliedToBackground(paintOffset, bleedAvoidance))
return false;
Modified: trunk/Source/WebCore/rendering/RenderImage.h (282958 => 282959)
--- trunk/Source/WebCore/rendering/RenderImage.h 2021-09-23 13:08:26 UTC (rev 282958)
+++ trunk/Source/WebCore/rendering/RenderImage.h 2021-09-23 14:11:56 UTC (rev 282959)
@@ -121,7 +121,7 @@
void notifyFinished(CachedResource&, const NetworkLoadMetrics&) final;
bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) final;
- bool boxShadowShouldBeAppliedToBackground(const LayoutPoint& paintOffset, BackgroundBleedAvoidance, LegacyInlineFlowBox*) const final;
+ bool boxShadowShouldBeAppliedToBackground(const LayoutPoint& paintOffset, BackgroundBleedAvoidance, const LegacyInlineFlowBox*) const final;
IntSize imageSizeForError(CachedImage*) const;
void repaintOrMarkForLayout(ImageSizeChangeType, const IntRect* = nullptr);
Modified: trunk/Source/WebCore/rendering/RenderTableCell.cpp (282958 => 282959)
--- trunk/Source/WebCore/rendering/RenderTableCell.cpp 2021-09-23 13:08:26 UTC (rev 282958)
+++ trunk/Source/WebCore/rendering/RenderTableCell.cpp 2021-09-23 14:11:56 UTC (rev 282959)
@@ -1347,7 +1347,7 @@
paintMaskImages(paintInfo, paintRect);
}
-bool RenderTableCell::boxShadowShouldBeAppliedToBackground(const LayoutPoint&, BackgroundBleedAvoidance, LegacyInlineFlowBox*) const
+bool RenderTableCell::boxShadowShouldBeAppliedToBackground(const LayoutPoint&, BackgroundBleedAvoidance, const LegacyInlineFlowBox*) const
{
return false;
}
Modified: trunk/Source/WebCore/rendering/RenderTableCell.h (282958 => 282959)
--- trunk/Source/WebCore/rendering/RenderTableCell.h 2021-09-23 13:08:26 UTC (rev 282958)
+++ trunk/Source/WebCore/rendering/RenderTableCell.h 2021-09-23 14:11:56 UTC (rev 282959)
@@ -151,7 +151,7 @@
void paintBoxDecorations(PaintInfo&, const LayoutPoint&) override;
void paintMask(PaintInfo&, const LayoutPoint&) override;
- bool boxShadowShouldBeAppliedToBackground(const LayoutPoint& paintOffset, BackgroundBleedAvoidance, LegacyInlineFlowBox*) const override;
+ bool boxShadowShouldBeAppliedToBackground(const LayoutPoint& paintOffset, BackgroundBleedAvoidance, const LegacyInlineFlowBox*) const override;
LayoutSize offsetFromContainer(RenderElement&, const LayoutPoint&, bool* offsetDependsOnPoint = 0) const override;
std::optional<LayoutRect> computeVisibleRectInContainer(const LayoutRect&, const RenderLayerModelObject* container, VisibleRectContext) const override;