1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_BOX_DECORATION_DATA_H_
6 #define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_BOX_DECORATION_DATA_H_
7 
8 #include "third_party/blink/renderer/core/layout/background_bleed_avoidance.h"
9 #include "third_party/blink/renderer/core/layout/layout_box.h"
10 #include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
11 #include "third_party/blink/renderer/core/paint/paint_info.h"
12 #include "third_party/blink/renderer/core/style/computed_style.h"
13 #include "third_party/blink/renderer/platform/graphics/color.h"
14 
15 namespace blink {
16 
17 // Data for box decoration painting.
18 class BoxDecorationData {
19   STACK_ALLOCATED();
20 
21  public:
BoxDecorationData(const PaintInfo & paint_info,const LayoutBox & layout_box)22   BoxDecorationData(const PaintInfo& paint_info, const LayoutBox& layout_box)
23       : BoxDecorationData(paint_info,
24                           layout_box,
25                           layout_box.StyleRef(),
26                           layout_box.HasNonCollapsedBorderDecoration()) {}
27 
BoxDecorationData(const PaintInfo & paint_info,const NGPhysicalFragment & fragment,const ComputedStyle & style)28   BoxDecorationData(const PaintInfo& paint_info,
29                     const NGPhysicalFragment& fragment,
30                     const ComputedStyle& style)
31       : BoxDecorationData(
32             paint_info,
33             To<LayoutBox>(*fragment.GetLayoutObject()),
34             style,
35             !fragment.HasCollapsedBorders() && style.HasBorderDecoration()) {}
36 
BoxDecorationData(const PaintInfo & paint_info,const NGPhysicalFragment & fragment)37   BoxDecorationData(const PaintInfo& paint_info,
38                     const NGPhysicalFragment& fragment)
39       : BoxDecorationData(paint_info, fragment, fragment.Style()) {}
40 
IsPaintingScrollingBackground()41   bool IsPaintingScrollingBackground() const {
42     return is_painting_scrolling_background_;
43   }
HasAppearance()44   bool HasAppearance() const { return has_appearance_; }
ShouldPaintBackground()45   bool ShouldPaintBackground() const { return should_paint_background_; }
ShouldPaintBorder()46   bool ShouldPaintBorder() const { return should_paint_border_; }
ShouldPaintShadow()47   bool ShouldPaintShadow() const { return should_paint_shadow_; }
48 
GetBackgroundBleedAvoidance()49   BackgroundBleedAvoidance GetBackgroundBleedAvoidance() const {
50     if (!bleed_avoidance_)
51       bleed_avoidance_ = ComputeBleedAvoidance();
52     return *bleed_avoidance_;
53   }
54 
ShouldPaint()55   bool ShouldPaint() const {
56     return HasAppearance() || ShouldPaintBackground() || ShouldPaintBorder() ||
57            ShouldPaintShadow();
58   }
59 
60   // This is not cached because the caller is unlikely to call this repeatedly.
BackgroundColor()61   Color BackgroundColor() const {
62     return style_.VisitedDependentColor(GetCSSPropertyBackgroundColor());
63   }
64 
IsPaintingScrollingBackground(const PaintInfo & paint_info,const LayoutBox & layout_box)65   static bool IsPaintingScrollingBackground(const PaintInfo& paint_info,
66                                             const LayoutBox& layout_box) {
67     if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
68       return paint_info.IsPaintingScrollingBackground();
69     return (paint_info.PaintFlags() & kPaintLayerPaintingOverflowContents) &&
70            !(paint_info.PaintFlags() &
71              kPaintLayerPaintingCompositingBackgroundPhase) &&
72            layout_box == paint_info.PaintContainer();
73   }
74 
75  private:
BoxDecorationData(const PaintInfo & paint_info,const LayoutBox & layout_box,const ComputedStyle & style,const bool has_non_collapsed_border_decoration)76   BoxDecorationData(const PaintInfo& paint_info,
77                     const LayoutBox& layout_box,
78                     const ComputedStyle& style,
79                     const bool has_non_collapsed_border_decoration)
80       : paint_info_(paint_info),
81         layout_box_(layout_box),
82         style_(style),
83         is_painting_scrolling_background_(
84             IsPaintingScrollingBackground(paint_info, layout_box)),
85         has_appearance_(style.HasEffectiveAppearance()),
86         should_paint_background_(ComputeShouldPaintBackground()),
87         should_paint_border_(
88             ComputeShouldPaintBorder(has_non_collapsed_border_decoration)),
89         should_paint_shadow_(ComputeShouldPaintShadow()) {}
90 
ComputeShouldPaintBackground()91   bool ComputeShouldPaintBackground() const {
92     if (!style_.HasBackground())
93       return false;
94     if (layout_box_.BackgroundTransfersToView())
95       return false;
96     if (paint_info_.SkipRootBackground() &&
97         paint_info_.PaintContainer() == &layout_box_)
98       return false;
99     return true;
100   }
101 
ComputeShouldPaintBorder(bool has_non_collapsed_border_decoration)102   bool ComputeShouldPaintBorder(
103       bool has_non_collapsed_border_decoration) const {
104     if (is_painting_scrolling_background_)
105       return false;
106     return has_non_collapsed_border_decoration;
107   }
108 
ComputeShouldPaintShadow()109   bool ComputeShouldPaintShadow() const {
110     return !is_painting_scrolling_background_ && style_.BoxShadow();
111   }
112 
113   bool BorderObscuresBackgroundEdge() const;
114   BackgroundBleedAvoidance ComputeBleedAvoidance() const;
115 
116   // Inputs.
117   const PaintInfo& paint_info_;
118   const LayoutBox& layout_box_;
119   const ComputedStyle& style_;
120   // Outputs that are initialized in the constructor.
121   const bool is_painting_scrolling_background_;
122   const bool has_appearance_;
123   const bool should_paint_background_;
124   const bool should_paint_border_;
125   const bool should_paint_shadow_;
126   // This is lazily initialized.
127   mutable base::Optional<BackgroundBleedAvoidance> bleed_avoidance_;
128 };
129 
130 }  // namespace blink
131 
132 #endif
133