1 /*
2  * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
3  *           (C) 2000 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2000 Dirk Mueller (mueller@kde.org)
5  * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public License
18  * along with this library; see the file COPYING.LIB.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  *
22  */
23 
24 #include "third_party/blink/renderer/core/style/style_fetched_image.h"
25 
26 #include "third_party/blink/public/web/web_local_frame_client.h"
27 #include "third_party/blink/renderer/core/css/css_image_value.h"
28 #include "third_party/blink/renderer/core/dom/document.h"
29 #include "third_party/blink/renderer/core/frame/local_frame.h"
30 #include "third_party/blink/renderer/core/frame/local_frame_client.h"
31 #include "third_party/blink/renderer/core/frame/settings.h"
32 #include "third_party/blink/renderer/core/loader/resource/image_resource_content.h"
33 #include "third_party/blink/renderer/core/paint/image_element_timing.h"
34 #include "third_party/blink/renderer/core/style/computed_style.h"
35 #include "third_party/blink/renderer/core/svg/graphics/svg_image.h"
36 #include "third_party/blink/renderer/core/svg/graphics/svg_image_for_container.h"
37 #include "third_party/blink/renderer/platform/geometry/layout_size.h"
38 #include "third_party/blink/renderer/platform/graphics/bitmap_image.h"
39 #include "third_party/blink/renderer/platform/graphics/placeholder_image.h"
40 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
41 
42 namespace blink {
43 
StyleFetchedImage(const Document & document,FetchParameters & params,bool is_lazyload_possibly_deferred)44 StyleFetchedImage::StyleFetchedImage(const Document& document,
45                                      FetchParameters& params,
46                                      bool is_lazyload_possibly_deferred)
47     : document_(&document),
48       url_(params.Url()),
49       origin_clean_(!params.IsFromOriginDirtyStyleSheet()),
50       is_ad_related_(params.GetResourceRequest().IsAdResource()) {
51   is_image_resource_ = true;
52   is_lazyload_possibly_deferred_ = is_lazyload_possibly_deferred;
53 
54   image_ = ImageResourceContent::Fetch(params, document_->Fetcher());
55   image_->AddObserver(this);
56   // ResourceFetcher is not determined from StyleFetchedImage and it is
57   // impossible to send a request for refetching.
58   image_->SetNotRefetchableDataFromDiskCache();
59 }
60 
61 StyleFetchedImage::~StyleFetchedImage() = default;
62 
Dispose()63 void StyleFetchedImage::Dispose() {
64   image_->RemoveObserver(this);
65   image_ = nullptr;
66 }
67 
IsEqual(const StyleImage & other) const68 bool StyleFetchedImage::IsEqual(const StyleImage& other) const {
69   if (!other.IsImageResource())
70     return false;
71   const auto& other_image = To<StyleFetchedImage>(other);
72   if (image_ != other_image.image_)
73     return false;
74   return url_ == other_image.url_;
75 }
76 
Data() const77 WrappedImagePtr StyleFetchedImage::Data() const {
78   return image_.Get();
79 }
80 
CachedImage() const81 ImageResourceContent* StyleFetchedImage::CachedImage() const {
82   return image_.Get();
83 }
84 
CssValue() const85 CSSValue* StyleFetchedImage::CssValue() const {
86   return MakeGarbageCollected<CSSImageValue>(
87       AtomicString(url_.GetString()), url_, Referrer(),
88       origin_clean_ ? OriginClean::kTrue : OriginClean::kFalse, is_ad_related_,
89       const_cast<StyleFetchedImage*>(this));
90 }
91 
ComputedCSSValue(const ComputedStyle &,bool allow_visited_style) const92 CSSValue* StyleFetchedImage::ComputedCSSValue(const ComputedStyle&,
93                                               bool allow_visited_style) const {
94   return CssValue();
95 }
96 
CanRender() const97 bool StyleFetchedImage::CanRender() const {
98   return !image_->ErrorOccurred() && !image_->GetImage()->IsNull();
99 }
100 
IsLoaded() const101 bool StyleFetchedImage::IsLoaded() const {
102   return image_->IsLoaded();
103 }
104 
ErrorOccurred() const105 bool StyleFetchedImage::ErrorOccurred() const {
106   return image_->ErrorOccurred();
107 }
108 
ImageSize(const Document &,float multiplier,const FloatSize & default_object_size,RespectImageOrientationEnum respect_orientation) const109 FloatSize StyleFetchedImage::ImageSize(
110     const Document&,
111     float multiplier,
112     const FloatSize& default_object_size,
113     RespectImageOrientationEnum respect_orientation) const {
114   Image* image = image_->GetImage();
115   if (image_->HasDevicePixelRatioHeaderValue()) {
116     multiplier /= image_->DevicePixelRatioHeaderValue();
117   }
118   if (auto* svg_image = DynamicTo<SVGImage>(image)) {
119     return ImageSizeForSVGImage(svg_image, multiplier, default_object_size);
120   }
121 
122   FloatSize size(image->Size(respect_orientation));
123   return ApplyZoom(size, multiplier);
124 }
125 
HasIntrinsicSize() const126 bool StyleFetchedImage::HasIntrinsicSize() const {
127   return image_->GetImage()->HasIntrinsicSize();
128 }
129 
AddClient(ImageResourceObserver * observer)130 void StyleFetchedImage::AddClient(ImageResourceObserver* observer) {
131   image_->AddObserver(observer);
132 }
133 
RemoveClient(ImageResourceObserver * observer)134 void StyleFetchedImage::RemoveClient(ImageResourceObserver* observer) {
135   image_->RemoveObserver(observer);
136 }
137 
ImageNotifyFinished(ImageResourceContent *)138 void StyleFetchedImage::ImageNotifyFinished(ImageResourceContent*) {
139   if (image_ && image_->HasImage()) {
140     Image& image = *image_->GetImage();
141 
142     auto* svg_image = DynamicTo<SVGImage>(image);
143     if (document_ && svg_image)
144       svg_image->UpdateUseCounters(*document_);
145   }
146 
147   if (document_) {
148     if (LocalDOMWindow* window = document_->domWindow())
149       ImageElementTiming::From(*window).NotifyBackgroundImageFinished(this);
150   }
151 
152   // Oilpan: do not prolong the Document's lifetime.
153   document_.Clear();
154 }
155 
GetImage(const ImageResourceObserver &,const Document &,const ComputedStyle & style,const FloatSize & target_size) const156 scoped_refptr<Image> StyleFetchedImage::GetImage(
157     const ImageResourceObserver&,
158     const Document&,
159     const ComputedStyle& style,
160     const FloatSize& target_size) const {
161   Image* image = image_->GetImage();
162   if (image->IsPlaceholderImage()) {
163     static_cast<PlaceholderImage*>(image)->SetIconAndTextScaleFactor(
164         style.EffectiveZoom());
165   }
166 
167   auto* svg_image = DynamicTo<SVGImage>(image);
168   if (!svg_image)
169     return image;
170   return SVGImageForContainer::Create(svg_image, target_size,
171                                       style.EffectiveZoom(), url_);
172 }
173 
KnownToBeOpaque(const Document &,const ComputedStyle &) const174 bool StyleFetchedImage::KnownToBeOpaque(const Document&,
175                                         const ComputedStyle&) const {
176   return image_->GetImage()->CurrentFrameKnownToBeOpaque();
177 }
178 
LoadDeferredImage(const Document & document)179 void StyleFetchedImage::LoadDeferredImage(const Document& document) {
180   DCHECK(is_lazyload_possibly_deferred_);
181   is_lazyload_possibly_deferred_ = false;
182   document_ = &document;
183   if (document.GetFrame() && document.GetFrame()->Client()) {
184     document.GetFrame()->Client()->DidObserveLazyLoadBehavior(
185         WebLocalFrameClient::LazyLoadBehavior::kLazyLoadedImage);
186   }
187   image_->LoadDeferredImage(document_->Fetcher());
188 }
189 
GetImageAnimationPolicy(mojom::blink::ImageAnimationPolicy & policy)190 bool StyleFetchedImage::GetImageAnimationPolicy(
191     mojom::blink::ImageAnimationPolicy& policy) {
192   if (!document_ || !document_->GetSettings()) {
193     return false;
194   }
195   policy = document_->GetSettings()->GetImageAnimationPolicy();
196   return true;
197 }
198 
Trace(Visitor * visitor) const199 void StyleFetchedImage::Trace(Visitor* visitor) const {
200   visitor->Trace(image_);
201   visitor->Trace(document_);
202   StyleImage::Trace(visitor);
203 }
204 
205 }  // namespace blink
206