Changeset 269822 in webkit


Ignore:
Timestamp:
Nov 14, 2020 5:38:12 PM (3 years ago)
Author:
Simon Fraser
Message:

[LFC Display] Implement propagation background style from body to root
https://bugs.webkit.org/show_bug.cgi?id=218947

Reviewed by Zalan Bujtas.

The root display box needs to get its background style from the document element box,
if it has one, otherwise the body box. If the body background style is propagated
to the root, then the body box needs to not paint its background.

Implement by adding BoxFactory::determineRootBackgroundPropagation(), and consulting
the result when creating the display boxes for the root and body. This is complicated
slightly by the need to pass the correct style to constructBoxDecorationData(),
which deals with both backgrounds and other (non-propagating) properties.

  • display/DisplayTreeBuilder.cpp:

(WebCore::Display::TreeBuilder::build):
(WebCore::Display::TreeBuilder::recursiveBuildDisplayTree const):
(WebCore::Display::TreeBuilder::build const): Deleted.

  • display/DisplayTreeBuilder.h:
  • display/css/DisplayBoxFactory.cpp:

(WebCore::Display::BoxFactory::determineRootBackgroundPropagation):
(WebCore::Display::BoxFactory::displayBoxForRootBox const):
(WebCore::Display::BoxFactory::displayBoxForBodyBox const):
(WebCore::Display::BoxFactory::displayBoxForLayoutBox const):
(WebCore::Display::BoxFactory::constructBoxDecorationData const):
(WebCore::Display::BoxFactory::setupBoxModelBox const):
(WebCore::Display::BoxFactory::documentElementBoxFromRootBox):
(WebCore::Display::BoxFactory::bodyBoxFromRootBox):

  • display/css/DisplayBoxFactory.h:
  • display/css/DisplayFillLayerImageGeometry.cpp:

(WebCore::Display::calculateFillLayerImageGeometry):

  • display/css/DisplayFillLayerImageGeometry.h:
  • display/css/DisplayStyle.cpp:

(WebCore::Display::Style::Style):
(WebCore::Display::Style::setupBackground):

  • display/css/DisplayStyle.h:
Location:
trunk/Source/WebCore
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r269821 r269822  
     12020-11-14  Simon Fraser  <simon.fraser@apple.com>
     2
     3        [LFC Display] Implement propagation background style from body to root
     4        https://bugs.webkit.org/show_bug.cgi?id=218947
     5
     6        Reviewed by Zalan Bujtas.
     7
     8        The root display box needs to get its background style from the document element box,
     9        if it has one, otherwise the body box. If the body background style is propagated
     10        to the root, then the body box needs to not paint its background.
     11
     12        Implement by adding BoxFactory::determineRootBackgroundPropagation(), and consulting
     13        the result when creating the display boxes for the root and body. This is complicated
     14        slightly by the need to pass the correct style to constructBoxDecorationData(),
     15        which deals with both backgrounds and other (non-propagating) properties.
     16
     17        * display/DisplayTreeBuilder.cpp:
     18        (WebCore::Display::TreeBuilder::build):
     19        (WebCore::Display::TreeBuilder::recursiveBuildDisplayTree const):
     20        (WebCore::Display::TreeBuilder::build const): Deleted.
     21        * display/DisplayTreeBuilder.h:
     22        * display/css/DisplayBoxFactory.cpp:
     23        (WebCore::Display::BoxFactory::determineRootBackgroundPropagation):
     24        (WebCore::Display::BoxFactory::displayBoxForRootBox const):
     25        (WebCore::Display::BoxFactory::displayBoxForBodyBox const):
     26        (WebCore::Display::BoxFactory::displayBoxForLayoutBox const):
     27        (WebCore::Display::BoxFactory::constructBoxDecorationData const):
     28        (WebCore::Display::BoxFactory::setupBoxModelBox const):
     29        (WebCore::Display::BoxFactory::documentElementBoxFromRootBox):
     30        (WebCore::Display::BoxFactory::bodyBoxFromRootBox):
     31        * display/css/DisplayBoxFactory.h:
     32        * display/css/DisplayFillLayerImageGeometry.cpp:
     33        (WebCore::Display::calculateFillLayerImageGeometry):
     34        * display/css/DisplayFillLayerImageGeometry.h:
     35        * display/css/DisplayStyle.cpp:
     36        (WebCore::Display::Style::Style):
     37        (WebCore::Display::Style::setupBackground):
     38        * display/css/DisplayStyle.h:
     39
    1402020-11-14  Zalan Bujtas  <zalan@apple.com>
    241
  • trunk/Source/WebCore/display/DisplayTreeBuilder.cpp

    r269181 r269822  
    5252}
    5353
    54 std::unique_ptr<Tree> TreeBuilder::build(const Layout::LayoutState& layoutState) const
     54std::unique_ptr<Tree> TreeBuilder::build(const Layout::LayoutState& layoutState)
    5555{
    5656    ASSERT(layoutState.hasRoot());
     
    6262#endif
    6363
     64    m_rootBackgroundPropgation = BoxFactory::determineRootBackgroundPropagation(rootLayoutBox);
     65
    6466    auto geometry = layoutState.geometryForBox(rootLayoutBox);
    65     auto rootDisplayBox = m_boxFactory.displayBoxForRootBox(rootLayoutBox, geometry);
     67    auto rootDisplayBox = m_boxFactory.displayBoxForRootBox(rootLayoutBox, geometry, m_rootBackgroundPropgation);
    6668    auto rootDisplayContainerBox = std::unique_ptr<ContainerBox> { downcast<ContainerBox>(rootDisplayBox.release()) };
    6769
     
    120122{
    121123    auto geometry = layoutState.geometryForBox(layoutBox);
    122     auto displayBox = m_boxFactory.displayBoxForLayoutBox(layoutBox, geometry, offsetFromRoot);
     124    std::unique_ptr<Box> displayBox;
     125   
     126    if (layoutBox.isBodyBox())
     127        displayBox = m_boxFactory.displayBoxForBodyBox(layoutBox, geometry, m_rootBackgroundPropgation, offsetFromRoot);
     128    else
     129        displayBox = m_boxFactory.displayBoxForLayoutBox(layoutBox, geometry, offsetFromRoot);
    123130   
    124131    insert(WTFMove(displayBox), insertionPosition);
  • trunk/Source/WebCore/display/DisplayTreeBuilder.h

    r268959 r269822  
    5656    explicit TreeBuilder(float pixelSnappingFactor);
    5757
    58     std::unique_ptr<Tree> build(const Layout::LayoutState&) const;
     58    std::unique_ptr<Tree> build(const Layout::LayoutState&);
    5959
    6060private:
     
    7171
    7272    BoxFactory m_boxFactory;
     73    RootBackgroundPropagation m_rootBackgroundPropgation { RootBackgroundPropagation::None };
    7374};
    7475
  • trunk/Source/WebCore/display/css/DisplayBoxFactory.cpp

    r269563 r269822  
    3737#include "LayoutBoxGeometry.h"
    3838#include "LayoutContainerBox.h"
     39#include "LayoutInitialContainingBlock.h"
    3940#include "LayoutReplacedBox.h"
     41#include "Logging.h"
    4042
    4143namespace WebCore {
     
    4749}
    4850
    49 std::unique_ptr<Box> BoxFactory::displayBoxForRootBox(const Layout::ContainerBox& rootLayoutBox, const Layout::BoxGeometry& geometry) const
    50 {
     51RootBackgroundPropagation BoxFactory::determineRootBackgroundPropagation(const Layout::ContainerBox& rootLayoutBox)
     52{
     53    auto* documentElementBox = documentElementBoxFromRootBox(rootLayoutBox);
     54    auto* bodyBox = bodyBoxFromRootBox(rootLayoutBox);
     55
     56    if (documentElementBox && documentElementBox->style().hasBackground())
     57        return RootBackgroundPropagation::None;
     58
     59    if (bodyBox && bodyBox->style().hasBackground())
     60        return RootBackgroundPropagation::BodyToRoot;
     61   
     62    return RootBackgroundPropagation::None;
     63}
     64
     65std::unique_ptr<Box> BoxFactory::displayBoxForRootBox(const Layout::ContainerBox& rootLayoutBox, const Layout::BoxGeometry& geometry, RootBackgroundPropagation rootBackgroundPropagation) const
     66{
     67    ASSERT(is<Layout::InitialContainingBlock>(rootLayoutBox));
     68
    5169    // FIXME: Need to do logical -> physical coordinate mapping here.
    5270    auto borderBoxRect = LayoutRect { Layout::BoxGeometry::borderBoxRect(geometry) };
    5371
    54     auto style = Style { rootLayoutBox.style() };
     72    auto* documentElementBox = documentElementBoxFromRootBox(rootLayoutBox);
     73
     74    const RenderStyle* styleForBackground = documentElementBox ? &documentElementBox->style() : nullptr;
     75
     76    if (rootBackgroundPropagation == RootBackgroundPropagation::BodyToRoot) {
     77        if (auto* bodyBox = bodyBoxFromRootBox(rootLayoutBox))
     78            styleForBackground = &bodyBox->style();
     79    }
     80
     81    auto style = Style { rootLayoutBox.style(), styleForBackground };
     82
    5583    auto rootBox = makeUnique<ContainerBox>(snapRectToDevicePixels(borderBoxRect, m_pixelSnappingFactor), WTFMove(style));
    56     setupBoxModelBox(*rootBox, rootLayoutBox, geometry, { });
     84    setupBoxModelBox(*rootBox, rootLayoutBox, styleForBackground, geometry, { });
    5785    return rootBox;
    5886}
    5987
     88std::unique_ptr<Box> BoxFactory::displayBoxForBodyBox(const Layout::Box& layoutBox, const Layout::BoxGeometry& geometry, RootBackgroundPropagation rootBackgroundPropagation, LayoutSize offsetFromRoot) const
     89{
     90    const RenderStyle* styleForBackground = &layoutBox.style();
     91   
     92    if (rootBackgroundPropagation == RootBackgroundPropagation::BodyToRoot)
     93        styleForBackground = nullptr;
     94   
     95    auto style = Style { layoutBox.style(), styleForBackground };
     96    return displayBoxForLayoutBox(layoutBox, styleForBackground, geometry, offsetFromRoot, WTFMove(style));
     97}
     98
    6099std::unique_ptr<Box> BoxFactory::displayBoxForLayoutBox(const Layout::Box& layoutBox, const Layout::BoxGeometry& geometry, LayoutSize offsetFromRoot) const
     100{
     101    auto style = Style { layoutBox.style() };
     102    return displayBoxForLayoutBox(layoutBox, &layoutBox.style(), geometry, offsetFromRoot, WTFMove(style));
     103}
     104
     105std::unique_ptr<Box> BoxFactory::displayBoxForLayoutBox(const Layout::Box& layoutBox, const RenderStyle* styleForBackground, const Layout::BoxGeometry& geometry, LayoutSize offsetFromRoot, Style&& style) const
    61106{
    62107    // FIXME: Need to map logical to physical rects.
     
    66111
    67112    // FIXME: Handle isAnonymous()
    68     // FIXME: Do hoisting of <body> styles to the root where appropriate.
    69 
    70     // FIXME: Need to do logical -> physical coordinate mapping here.
    71     auto style = Style { layoutBox.style() };
    72113   
    73114    if (is<Layout::ReplacedBox>(layoutBox)) {
     
    78119
    79120        auto imageBox = makeUnique<ImageBox>(pixelSnappedBorderBoxRect, WTFMove(style), WTFMove(image));
    80         setupBoxModelBox(*imageBox, layoutBox, geometry, offsetFromRoot);
     121        setupBoxModelBox(*imageBox, layoutBox, styleForBackground, geometry, offsetFromRoot);
    81122        return imageBox;
    82123    }
     
    85126        // FIXME: The decision to make a ContainerBox should be made based on whether this Display::Box will have children.
    86127        auto containerBox = makeUnique<ContainerBox>(pixelSnappedBorderBoxRect, WTFMove(style));
    87         setupBoxModelBox(*containerBox, layoutBox, geometry, offsetFromRoot);
     128        setupBoxModelBox(*containerBox, layoutBox, styleForBackground, geometry, offsetFromRoot);
    88129        return containerBox;
    89130    }
     
    129170}
    130171
    131 std::unique_ptr<BoxDecorationData> BoxFactory::constructBoxDecorationData(const Layout::Box& layoutBox, const Layout::BoxGeometry& layoutGeometry, LayoutSize offsetFromRoot) const
     172std::unique_ptr<BoxDecorationData> BoxFactory::constructBoxDecorationData(const Layout::Box& layoutBox, const RenderStyle* styleForBackground, const Layout::BoxGeometry& layoutGeometry, LayoutSize offsetFromRoot) const
    132173{
    133174    auto boxDecorationData = makeUnique<BoxDecorationData>();
    134175
    135     auto backgroundImageGeometry = calculateFillLayerImageGeometry(layoutBox, layoutGeometry, offsetFromRoot, m_pixelSnappingFactor);
    136     boxDecorationData->setBackgroundImageGeometry(WTFMove(backgroundImageGeometry));
     176    if (styleForBackground) {
     177        auto backgroundImageGeometry = calculateFillLayerImageGeometry(*styleForBackground, layoutGeometry, offsetFromRoot, m_pixelSnappingFactor);
     178        boxDecorationData->setBackgroundImageGeometry(WTFMove(backgroundImageGeometry));
     179    }
    137180
    138181    bool includeLogicalLeftEdge = true; // FIXME.
     
    155198}
    156199
    157 void BoxFactory::setupBoxModelBox(BoxModelBox& box, const Layout::Box& layoutBox, const Layout::BoxGeometry& layoutGeometry, LayoutSize offsetFromRoot) const
     200void BoxFactory::setupBoxModelBox(BoxModelBox& box, const Layout::Box& layoutBox, const RenderStyle* styleForBackground, const Layout::BoxGeometry& layoutGeometry, LayoutSize offsetFromRoot) const
    158201{
    159202    setupBoxGeometry(box, layoutBox, layoutGeometry, offsetFromRoot);
    160203
    161204    auto& renderStyle = layoutBox.style();
    162     if (!renderStyle.hasBackground() && !renderStyle.hasBorder())
     205    if (!(styleForBackground && styleForBackground->hasBackground()) && !renderStyle.hasBorder())
    163206        return;
    164207
    165     auto boxDecorationData = constructBoxDecorationData(layoutBox, layoutGeometry, offsetFromRoot);
     208    auto boxDecorationData = constructBoxDecorationData(layoutBox, styleForBackground, layoutGeometry, offsetFromRoot);
    166209    box.setBoxDecorationData(WTFMove(boxDecorationData));
    167210}
    168211
     212const Layout::ContainerBox* BoxFactory::documentElementBoxFromRootBox(const Layout::ContainerBox& rootLayoutBox)
     213{
     214    auto* documentBox = rootLayoutBox.firstChild();
     215    if (!documentBox || !documentBox->isDocumentBox() || !is<Layout::ContainerBox>(documentBox))
     216        return nullptr;
     217
     218    return downcast<Layout::ContainerBox>(documentBox);
     219}
     220
     221const Layout::Box* BoxFactory::bodyBoxFromRootBox(const Layout::ContainerBox& rootLayoutBox)
     222{
     223    auto* documentBox = rootLayoutBox.firstChild();
     224    if (!documentBox || !documentBox->isDocumentBox() || !is<Layout::ContainerBox>(documentBox))
     225        return nullptr;
     226
     227    auto* bodyBox = downcast<Layout::ContainerBox>(documentBox)->firstChild();
     228    if (!bodyBox || !bodyBox->isBodyBox())
     229        return nullptr;
     230
     231    return bodyBox;
     232}
    169233
    170234} // namespace Display
  • trunk/Source/WebCore/display/css/DisplayBoxFactory.h

    r269468 r269822  
    4848class BoxModelBox;
    4949
     50enum class RootBackgroundPropagation : uint8_t {
     51    None,
     52    BodyToRoot,
     53};
     54
    5055class BoxFactory {
    5156public:
    5257    explicit BoxFactory(float pixelSnappingFactor);
    5358
    54     std::unique_ptr<Box> displayBoxForRootBox(const Layout::ContainerBox&, const Layout::BoxGeometry&) const;
     59    static RootBackgroundPropagation determineRootBackgroundPropagation(const Layout::ContainerBox& rootLayoutBox);
     60
     61    std::unique_ptr<Box> displayBoxForRootBox(const Layout::ContainerBox&, const Layout::BoxGeometry&, RootBackgroundPropagation) const;
     62    std::unique_ptr<Box> displayBoxForBodyBox(const Layout::Box&, const Layout::BoxGeometry&, RootBackgroundPropagation, LayoutSize offsetFromRoot) const;
    5563    std::unique_ptr<Box> displayBoxForLayoutBox(const Layout::Box&, const Layout::BoxGeometry&, LayoutSize offsetFromRoot) const;
    5664
    5765    std::unique_ptr<Box> displayBoxForTextRun(const Layout::LineRun&, const Layout::InlineLineGeometry&, LayoutSize offsetFromRoot) const;
     66
    5867private:
     68    std::unique_ptr<Box> displayBoxForLayoutBox(const Layout::Box&, const RenderStyle* styleForBackground, const Layout::BoxGeometry&, LayoutSize offsetFromRoot, Style&&) const;
    5969
    6070    void setupBoxGeometry(BoxModelBox&, const Layout::Box&, const Layout::BoxGeometry&, LayoutSize offsetFromRoot) const;
    61     void setupBoxModelBox(BoxModelBox&, const Layout::Box&, const Layout::BoxGeometry&, LayoutSize offsetFromRoot) const;
     71    void setupBoxModelBox(BoxModelBox&, const Layout::Box&, const RenderStyle* styleForBackground, const Layout::BoxGeometry&, LayoutSize offsetFromRoot) const;
    6272
    63     std::unique_ptr<BoxDecorationData> constructBoxDecorationData(const Layout::Box&, const Layout::BoxGeometry&, LayoutSize offsetFromRoot) const;
     73    std::unique_ptr<BoxDecorationData> constructBoxDecorationData(const Layout::Box&, const RenderStyle* styleForBackground, const Layout::BoxGeometry&, LayoutSize offsetFromRoot) const;
     74
     75    static const Layout::ContainerBox* documentElementBoxFromRootBox(const Layout::ContainerBox& rootLayoutBox);
     76    static const Layout::Box* bodyBoxFromRootBox(const Layout::ContainerBox& rootLayoutBox);
    6477
    6578    float m_pixelSnappingFactor { 1 };
  • trunk/Source/WebCore/display/css/DisplayFillLayerImageGeometry.cpp

    r268959 r269822  
    375375}
    376376
    377 Vector<FillLayerImageGeometry, 1> calculateFillLayerImageGeometry(const Layout::Box& layoutBox, const Layout::BoxGeometry& boxGeometry, LayoutSize offsetFromRoot, float pixelSnappingFactor)
    378 {
    379     auto& renderStyle = layoutBox.style();
    380 
     377Vector<FillLayerImageGeometry, 1> calculateFillLayerImageGeometry(const RenderStyle& renderStyle, const Layout::BoxGeometry& boxGeometry, LayoutSize offsetFromRoot, float pixelSnappingFactor)
     378{
    381379    // FIXME: Need to map logical to physical rects.
    382380    auto borderBoxRect = LayoutRect { Layout::BoxGeometry::borderBoxRect(boxGeometry) };
  • trunk/Source/WebCore/display/css/DisplayFillLayerImageGeometry.h

    r268959 r269822  
    3434namespace WebCore {
    3535class FillLayer;
     36class RenderStyle;
    3637class StyleImage;
    3738
     
    8182};
    8283
    83 Vector<FillLayerImageGeometry, 1> calculateFillLayerImageGeometry(const Layout::Box&, const Layout::BoxGeometry&, LayoutSize offsetFromRoot, float pixelSnappingFactor);
     84Vector<FillLayerImageGeometry, 1> calculateFillLayerImageGeometry(const RenderStyle&, const Layout::BoxGeometry&, LayoutSize offsetFromRoot, float pixelSnappingFactor);
    8485
    8586} // namespace Display
  • trunk/Source/WebCore/display/css/DisplayStyle.cpp

    r269601 r269822  
    5858
    5959Style::Style(const RenderStyle& style)
     60    : Style(style, &style)
     61{
     62}
     63
     64Style::Style(const RenderStyle& style, const RenderStyle* styleForBackground)
    6065    : m_fontCascade(style.fontCascade())
    6166    , m_whiteSpace(style.whiteSpace())
     
    6570    m_color = style.visitedDependentColorWithColorFilter(CSSPropertyColor);
    6671
    67     m_backgroundColor = style.visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor);
    68     m_backgroundLayers = deepCopy(style.backgroundLayers());
     72    if (styleForBackground)
     73        setupBackground(*styleForBackground);
    6974
    7075    if (!style.hasAutoUsedZIndex())
     
    7378    setIsPositioned(style.position() != PositionType::Static);
    7479    setIsFloating(style.floating() != Float::No);
     80}
     81
     82void Style::setupBackground(const RenderStyle& style)
     83{
     84    m_backgroundColor = style.visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor);
     85    m_backgroundLayers = deepCopy(style.backgroundLayers());
    7586}
    7687
  • trunk/Source/WebCore/display/css/DisplayStyle.h

    r269601 r269822  
    5959
    6060    explicit Style(const RenderStyle&);
     61    explicit Style(const RenderStyle&, const RenderStyle* styleForBackground);
    6162
    6263    const Color& color() const { return m_color; }
     
    8889
    8990private:
     91    void setupBackground(const RenderStyle&);
     92
    9093    void setIsPositioned(bool value) { m_flags.set({ Flags::Positioned }, value); }
    9194    void setIsFloating(bool value) { m_flags.set({ Flags::Floating }, value); }
Note: See TracChangeset for help on using the changeset viewer.