1 // Copyright 2017 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 #include "third_party/blink/renderer/core/paint/fragment_data.h" 6 #include "third_party/blink/renderer/core/paint/paint_layer.h" 7 #include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h" 8 9 namespace blink { 10 11 // These are defined here because of PaintLayer dependency. 12 RareData()13FragmentData::RareData::RareData() : unique_id(NewUniqueObjectId()) {} 14 15 FragmentData::RareData::~RareData() = default; 16 DestroyTail()17void FragmentData::DestroyTail() { 18 if (!rare_data_) 19 return; 20 // Take next_fragment_ which clears it in this fragment. 21 std::unique_ptr<FragmentData> next = std::move(rare_data_->next_fragment_); 22 while (next && next->rare_data_) { 23 // Take next_fragment_ which clears it in that fragment, and the assignment 24 // deletes the previous |next|. 25 next = std::move(next->rare_data_->next_fragment_); 26 } 27 // The last |next| will be deleted on return. 28 } 29 EnsureNextFragment()30FragmentData& FragmentData::EnsureNextFragment() { 31 if (!NextFragment()) 32 EnsureRareData().next_fragment_ = std::make_unique<FragmentData>(); 33 return *rare_data_->next_fragment_; 34 } 35 EnsureRareData()36FragmentData::RareData& FragmentData::EnsureRareData() { 37 if (!rare_data_) 38 rare_data_ = std::make_unique<RareData>(); 39 return *rare_data_; 40 } 41 SetLayer(std::unique_ptr<PaintLayer> layer)42void FragmentData::SetLayer(std::unique_ptr<PaintLayer> layer) { 43 if (rare_data_ || layer) 44 EnsureRareData().layer = std::move(layer); 45 } 46 PreTransform() const47const TransformPaintPropertyNode& FragmentData::PreTransform() const { 48 if (const auto* properties = PaintProperties()) { 49 if (const auto* transform = properties->Transform()) { 50 DCHECK(transform->Parent()); 51 return *transform->Parent(); 52 } 53 } 54 return LocalBorderBoxProperties().Transform(); 55 } 56 PostScrollTranslation() const57const TransformPaintPropertyNode& FragmentData::PostScrollTranslation() const { 58 if (const auto* properties = PaintProperties()) { 59 if (properties->TransformIsolationNode()) 60 return *properties->TransformIsolationNode(); 61 if (properties->ScrollTranslation()) 62 return *properties->ScrollTranslation(); 63 if (properties->ReplacedContentTransform()) 64 return *properties->ReplacedContentTransform(); 65 if (properties->Perspective()) 66 return *properties->Perspective(); 67 } 68 return LocalBorderBoxProperties().Transform(); 69 } 70 PreClip() const71const ClipPaintPropertyNode& FragmentData::PreClip() const { 72 if (const auto* properties = PaintProperties()) { 73 if (const auto* clip = properties->ClipPathClip()) { 74 // SPv1 composited clip-path has an alternative clip tree structure. 75 // If the clip-path is parented by the mask clip, it is only used 76 // to clip mask layer chunks, and not in the clip inheritance chain. 77 DCHECK(clip->Parent()); 78 if (clip->Parent() != properties->MaskClip()) 79 return *clip->Parent(); 80 } 81 if (const auto* mask_clip = properties->MaskClip()) { 82 DCHECK(mask_clip->Parent()); 83 return *mask_clip->Parent(); 84 } 85 if (const auto* css_clip = properties->CssClip()) { 86 DCHECK(css_clip->Parent()); 87 return *css_clip->Parent(); 88 } 89 } 90 return LocalBorderBoxProperties().Clip(); 91 } 92 PostOverflowClip() const93const ClipPaintPropertyNode& FragmentData::PostOverflowClip() const { 94 if (const auto* properties = PaintProperties()) { 95 if (properties->ClipIsolationNode()) 96 return *properties->ClipIsolationNode(); 97 if (properties->OverflowClip()) 98 return *properties->OverflowClip(); 99 if (properties->InnerBorderRadiusClip()) 100 return *properties->InnerBorderRadiusClip(); 101 } 102 return LocalBorderBoxProperties().Clip(); 103 } 104 PreEffect() const105const EffectPaintPropertyNode& FragmentData::PreEffect() const { 106 if (const auto* properties = PaintProperties()) { 107 if (const auto* effect = properties->Effect()) { 108 DCHECK(effect->Parent()); 109 return *effect->Parent(); 110 } 111 if (const auto* filter = properties->Filter()) { 112 DCHECK(filter->Parent()); 113 return *filter->Parent(); 114 } 115 } 116 return LocalBorderBoxProperties().Effect(); 117 } 118 PreFilter() const119const EffectPaintPropertyNode& FragmentData::PreFilter() const { 120 if (const auto* properties = PaintProperties()) { 121 if (const auto* filter = properties->Filter()) { 122 DCHECK(filter->Parent()); 123 return *filter->Parent(); 124 } 125 } 126 return LocalBorderBoxProperties().Effect(); 127 } 128 PostIsolationEffect() const129const EffectPaintPropertyNode& FragmentData::PostIsolationEffect() const { 130 if (const auto* properties = PaintProperties()) { 131 if (properties->EffectIsolationNode()) 132 return *properties->EffectIsolationNode(); 133 } 134 return LocalBorderBoxProperties().Effect(); 135 } 136 InvalidateClipPathCache()137void FragmentData::InvalidateClipPathCache() { 138 if (!rare_data_) 139 return; 140 141 rare_data_->is_clip_path_cache_valid = false; 142 rare_data_->clip_path_bounding_box = base::nullopt; 143 rare_data_->clip_path_path = nullptr; 144 } 145 SetClipPathCache(const IntRect & bounding_box,scoped_refptr<const RefCountedPath> path)146void FragmentData::SetClipPathCache(const IntRect& bounding_box, 147 scoped_refptr<const RefCountedPath> path) { 148 EnsureRareData().is_clip_path_cache_valid = true; 149 rare_data_->clip_path_bounding_box = bounding_box; 150 rare_data_->clip_path_path = std::move(path); 151 } 152 MapRectToFragment(const FragmentData & fragment,IntRect & rect) const153void FragmentData::MapRectToFragment(const FragmentData& fragment, 154 IntRect& rect) const { 155 if (this == &fragment) 156 return; 157 const auto& from_transform = LocalBorderBoxProperties().Transform(); 158 const auto& to_transform = fragment.LocalBorderBoxProperties().Transform(); 159 rect.MoveBy(RoundedIntPoint(PaintOffset())); 160 GeometryMapper::SourceToDestinationRect(from_transform, to_transform, rect); 161 rect.MoveBy(-RoundedIntPoint(fragment.PaintOffset())); 162 } 163 164 } // namespace blink 165