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