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