Modified: trunk/Source/WebCore/display/css/DisplayCSSPainter.cpp (270199 => 270200)
--- trunk/Source/WebCore/display/css/DisplayCSSPainter.cpp 2020-11-27 18:49:07 UTC (rev 270199)
+++ trunk/Source/WebCore/display/css/DisplayCSSPainter.cpp 2020-11-27 18:50:25 UTC (rev 270200)
@@ -40,11 +40,11 @@
namespace Display {
// FIXME: Make this an iterator.
-void CSSPainter::recursivePaintDescendants(const ContainerBox& containerBox, PaintingContext& paintingContext, PaintPhase paintPhase)
+void CSSPainter::recursivePaintDescendantsForPhase(const ContainerBox& containerBox, PaintingContext& paintingContext, PaintPhase paintPhase)
{
for (const auto* child = containerBox.firstChild(); child; child = child->nextSibling()) {
auto& box = *child;
- if (isStackingContextPaintingBoundary(box))
+ if (participatesInZOrderSorting(box))
continue;
switch (paintPhase) {
@@ -61,57 +61,54 @@
BoxPainter::paintBoxContent(box, paintingContext);
};
if (is<ContainerBox>(box))
- recursivePaintDescendants(downcast<ContainerBox>(box), paintingContext, paintPhase);
+ recursivePaintDescendantsForPhase(downcast<ContainerBox>(box), paintingContext, paintPhase);
}
}
-void CSSPainter::paintStackingContext(const BoxModelBox& contextRoot, PaintingContext& paintingContext, const IntRect& dirtyRect)
+void CSSPainter::recursivePaintDescendants(const ContainerBox& containerBox, PaintingContext& paintingContext)
{
- UNUSED_PARAM(dirtyRect);
-
- BoxPainter::paintBoxDecorations(contextRoot, paintingContext);
+ // For all its in-flow, non-positioned, block-level descendants in tree order: If the element is a block, list-item, or other block equivalent:
+ // Box decorations.
+ // Table decorations.
+ recursivePaintDescendantsForPhase(containerBox, paintingContext, PaintPhase::BlockBackgrounds);
- auto paintDescendants = [&](const ContainerBox& containerBox) {
- // For all its in-flow, non-positioned, block-level descendants in tree order: If the element is a block, list-item, or other block equivalent:
- // Box decorations.
- // Table decorations.
- recursivePaintDescendants(containerBox, paintingContext, PaintPhase::BlockBackgrounds);
+ // All non-positioned floating descendants, in tree order. For each one of these, treat the element as if it created a new stacking context,
+ // but any positioned descendants and descendants which actually create a new stacking context should be considered part of the parent
+ // stacking context, not this new one.
+ recursivePaintDescendantsForPhase(containerBox, paintingContext, PaintPhase::Floats);
- // All non-positioned floating descendants, in tree order. For each one of these, treat the element as if it created a new stacking context,
- // but any positioned descendants and descendants which actually create a new stacking context should be considered part of the parent
- // stacking context, not this new one.
- recursivePaintDescendants(containerBox, paintingContext, PaintPhase::Floats);
+ // If the element is an inline element that generates a stacking context, then:
+ // FIXME: Handle this case.
+
+ // Otherwise: first for the element, then for all its in-flow, non-positioned, block-level descendants in tree order:
+ // 1. If the element is a block-level replaced element, then: the replaced content, atomically.
+ // 2. Otherwise, for each line box of that element...
+ recursivePaintDescendantsForPhase(containerBox, paintingContext, PaintPhase::BlockForegrounds);
+}
- // If the element is an inline element that generates a stacking context, then:
- // FIXME: Handle this case.
-
- // Otherwise: first for the element, then for all its in-flow, non-positioned, block-level descendants in tree order:
- // 1. If the element is a block-level replaced element, then: the replaced content, atomically.
- // 2. Otherwise, for each line box of that element...
- recursivePaintDescendants(containerBox, paintingContext, PaintPhase::BlockForegrounds);
- };
-
- if (is<ContainerBox>(contextRoot)) {
- auto& containerBox = downcast<ContainerBox>(contextRoot);
-
- Vector<const BoxModelBox*> negativeZOrderList;
- Vector<const BoxModelBox*> positiveZOrderList;
+void CSSPainter::paintAtomicallyPaintedBox(const Box& box, PaintingContext& paintingContext, const IntRect& dirtyRect, IncludeStackingContextDescendants includeStackingContextDescendants)
+{
+ UNUSED_PARAM(dirtyRect);
- recursiveCollectLayers(containerBox, negativeZOrderList, positiveZOrderList);
+ BoxPainter::paintBox(box, paintingContext, dirtyRect);
+ if (!is<ContainerBox>(box))
+ return;
- auto compareZIndex = [] (const BoxModelBox* a, const BoxModelBox* b) {
- return a->style().zIndex().valueOr(0) < b->style().zIndex().valueOr(0);
- };
+ auto& containerBox = downcast<ContainerBox>(box);
- std::stable_sort(positiveZOrderList.begin(), positiveZOrderList.end(), compareZIndex);
- std::stable_sort(negativeZOrderList.begin(), negativeZOrderList.end(), compareZIndex);
+ Vector<const BoxModelBox*> negativeZOrderList;
+ Vector<const BoxModelBox*> positiveZOrderList;
+ if (includeStackingContextDescendants == IncludeStackingContextDescendants::Yes) {
+ collectStackingContextDescendants(containerBox, negativeZOrderList, positiveZOrderList);
// Stacking contexts formed by positioned descendants with negative z-indices (excluding 0) in z-index order (most negative first) then tree order.
for (auto* box : negativeZOrderList)
paintStackingContext(*box, paintingContext, dirtyRect);
+ }
- paintDescendants(containerBox);
+ recursivePaintDescendants(containerBox, paintingContext);
+ if (includeStackingContextDescendants == IncludeStackingContextDescendants::Yes) {
// All positioned descendants with 'z-index: auto' or 'z-index: 0', in tree order. For those with 'z-index: auto', treat the element
// as if it created a new stacking context, but any positioned descendants and descendants which actually create a new stacking context
// should be considered part of the parent stacking context, not this new one. For those with 'z-index: 0', treat the stacking context
@@ -119,20 +116,39 @@
for (auto* box : positiveZOrderList) {
if (box->style().isStackingContext())
paintStackingContext(*box, paintingContext, dirtyRect);
- else if (is<ContainerBox>(*box)) {
- BoxPainter::paintBoxDecorations(*box, paintingContext);
- paintDescendants(downcast<ContainerBox>(*box));
- } else
- BoxPainter::paintBox(*box, paintingContext, dirtyRect);
+ else
+ paintAtomicallyPaintedBox(*box, paintingContext, dirtyRect);
}
}
}
+void CSSPainter::paintStackingContext(const BoxModelBox& contextRoot, PaintingContext& paintingContext, const IntRect& dirtyRect)
+{
+ paintAtomicallyPaintedBox(contextRoot, paintingContext, dirtyRect, IncludeStackingContextDescendants::Yes);
+}
+
bool CSSPainter::isStackingContextPaintingBoundary(const Box& box)
{
return box.style().isStackingContext();
}
+bool CSSPainter::participatesInZOrderSorting(const Box& box)
+{
+ return box.style().participatesInZOrderSorting();
+}
+
+void CSSPainter::collectStackingContextDescendants(const ContainerBox& containerBox, Vector<const BoxModelBox*>& negativeZOrderList, Vector<const BoxModelBox*>& positiveZOrderList)
+{
+ recursiveCollectLayers(containerBox, negativeZOrderList, positiveZOrderList);
+
+ auto compareZIndex = [] (const BoxModelBox* a, const BoxModelBox* b) {
+ return a->style().zIndex().valueOr(0) < b->style().zIndex().valueOr(0);
+ };
+
+ std::stable_sort(positiveZOrderList.begin(), positiveZOrderList.end(), compareZIndex);
+ std::stable_sort(negativeZOrderList.begin(), negativeZOrderList.end(), compareZIndex);
+}
+
void CSSPainter::recursiveCollectLayers(const ContainerBox& containerBox, Vector<const BoxModelBox*>& negativeZOrderList, Vector<const BoxModelBox*>& positiveZOrderList)
{
for (const auto* child = containerBox.firstChild(); child; child = child->nextSibling()) {
@@ -140,7 +156,6 @@
auto& childBox = downcast<BoxModelBox>(*child);
auto zIndex = childBox.style().zIndex().valueOr(0);
-
if (zIndex < 0)
negativeZOrderList.append(&childBox);
else
Modified: trunk/Source/WebCore/display/css/DisplayCSSPainter.h (270199 => 270200)
--- trunk/Source/WebCore/display/css/DisplayCSSPainter.h 2020-11-27 18:49:07 UTC (rev 270199)
+++ trunk/Source/WebCore/display/css/DisplayCSSPainter.h 2020-11-27 18:50:25 UTC (rev 270200)
@@ -48,7 +48,6 @@
class CSSPainter {
public:
- static void paintStackingContext(const BoxModelBox&, PaintingContext&, const IntRect& dirtyRect);
static void paintTree(const Tree&, PaintingContext&, const IntRect& dirtyRect);
private:
@@ -57,9 +56,18 @@
Floats,
BlockForegrounds
};
- static void recursivePaintDescendants(const ContainerBox&, PaintingContext&, PaintPhase);
+ static void recursivePaintDescendants(const ContainerBox&, PaintingContext&);
+ static void recursivePaintDescendantsForPhase(const ContainerBox&, PaintingContext&, PaintPhase);
+ enum class IncludeStackingContextDescendants { Yes, No };
+ static void paintAtomicallyPaintedBox(const Box&, PaintingContext&, const IntRect& dirtyRect, IncludeStackingContextDescendants = IncludeStackingContextDescendants::No);
+
+ static void paintStackingContext(const BoxModelBox&, PaintingContext&, const IntRect& dirtyRect);
+
static bool isStackingContextPaintingBoundary(const Box&);
+ static bool participatesInZOrderSorting(const Box&);
+
+ static void collectStackingContextDescendants(const ContainerBox&, Vector<const BoxModelBox*>& negativeZOrderList, Vector<const BoxModelBox*>& positiveZOrderList);
static void recursiveCollectLayers(const ContainerBox&, Vector<const BoxModelBox*>& negativeZOrderList, Vector<const BoxModelBox*>& positiveZOrderList);
};