1 /*
2  * Copyright (C) 2012 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #include "third_party/blink/renderer/core/style/style_fetched_image_set.h"
27 
28 #include "third_party/blink/renderer/core/css/css_image_set_value.h"
29 #include "third_party/blink/renderer/core/loader/resource/image_resource_content.h"
30 #include "third_party/blink/renderer/core/style/computed_style.h"
31 #include "third_party/blink/renderer/core/svg/graphics/svg_image_for_container.h"
32 #include "third_party/blink/renderer/platform/graphics/bitmap_image.h"
33 #include "third_party/blink/renderer/platform/graphics/placeholder_image.h"
34 
35 namespace blink {
36 
StyleFetchedImageSet(ImageResourceContent * image,float image_scale_factor,CSSImageSetValue * value,const KURL & url)37 StyleFetchedImageSet::StyleFetchedImageSet(ImageResourceContent* image,
38                                            float image_scale_factor,
39                                            CSSImageSetValue* value,
40                                            const KURL& url)
41     : best_fit_image_(image),
42       image_scale_factor_(image_scale_factor),
43       image_set_value_(value),
44       url_(url) {
45   is_image_resource_set_ = true;
46   best_fit_image_->AddObserver(this);
47 }
48 
49 StyleFetchedImageSet::~StyleFetchedImageSet() = default;
50 
Dispose()51 void StyleFetchedImageSet::Dispose() {
52   best_fit_image_->RemoveObserver(this);
53   best_fit_image_ = nullptr;
54 }
55 
IsEqual(const StyleImage & other) const56 bool StyleFetchedImageSet::IsEqual(const StyleImage& other) const {
57   if (!other.IsImageResourceSet())
58     return false;
59   const auto& other_image = To<StyleFetchedImageSet>(other);
60   if (best_fit_image_ != other_image.best_fit_image_)
61     return false;
62   return url_ == other_image.url_;
63 }
64 
Data() const65 WrappedImagePtr StyleFetchedImageSet::Data() const {
66   return best_fit_image_.Get();
67 }
68 
CachedImage() const69 ImageResourceContent* StyleFetchedImageSet::CachedImage() const {
70   return best_fit_image_.Get();
71 }
72 
CssValue() const73 CSSValue* StyleFetchedImageSet::CssValue() const {
74   return image_set_value_;
75 }
76 
ComputedCSSValue(const ComputedStyle & style,bool allow_visited_style) const77 CSSValue* StyleFetchedImageSet::ComputedCSSValue(
78     const ComputedStyle& style,
79     bool allow_visited_style) const {
80   return image_set_value_->ValueWithURLsMadeAbsolute();
81 }
82 
CanRender() const83 bool StyleFetchedImageSet::CanRender() const {
84   return !best_fit_image_->ErrorOccurred() &&
85          !best_fit_image_->GetImage()->IsNull();
86 }
87 
IsLoaded() const88 bool StyleFetchedImageSet::IsLoaded() const {
89   return best_fit_image_->IsLoaded();
90 }
91 
ErrorOccurred() const92 bool StyleFetchedImageSet::ErrorOccurred() const {
93   return best_fit_image_->ErrorOccurred();
94 }
95 
ImageSize(const Document &,float multiplier,const FloatSize & default_object_size,RespectImageOrientationEnum respect_orientation) const96 FloatSize StyleFetchedImageSet::ImageSize(
97     const Document&,
98     float multiplier,
99     const FloatSize& default_object_size,
100     RespectImageOrientationEnum respect_orientation) const {
101   Image* image = best_fit_image_->GetImage();
102   if (auto* svg_image = DynamicTo<SVGImage>(image)) {
103     return ImageSizeForSVGImage(svg_image, multiplier, default_object_size);
104   }
105   FloatSize natural_size(image->Size(respect_orientation));
106   FloatSize scaled_image_size(ApplyZoom(natural_size, multiplier));
107   scaled_image_size.Scale(1 / image_scale_factor_);
108   return scaled_image_size;
109 }
110 
HasIntrinsicSize() const111 bool StyleFetchedImageSet::HasIntrinsicSize() const {
112   return best_fit_image_->GetImage()->HasIntrinsicSize();
113 }
114 
AddClient(ImageResourceObserver * observer)115 void StyleFetchedImageSet::AddClient(ImageResourceObserver* observer) {
116   best_fit_image_->AddObserver(observer);
117 }
118 
RemoveClient(ImageResourceObserver * observer)119 void StyleFetchedImageSet::RemoveClient(ImageResourceObserver* observer) {
120   best_fit_image_->RemoveObserver(observer);
121 }
122 
GetImage(const ImageResourceObserver &,const Document &,const ComputedStyle & style,const FloatSize & target_size) const123 scoped_refptr<Image> StyleFetchedImageSet::GetImage(
124     const ImageResourceObserver&,
125     const Document&,
126     const ComputedStyle& style,
127     const FloatSize& target_size) const {
128   Image* image = best_fit_image_->GetImage();
129   if (image->IsPlaceholderImage()) {
130     static_cast<PlaceholderImage*>(image)->SetIconAndTextScaleFactor(
131         style.EffectiveZoom());
132   }
133 
134   auto* svg_image = DynamicTo<SVGImage>(image);
135   if (!svg_image)
136     return image;
137   return SVGImageForContainer::Create(svg_image, target_size,
138                                       style.EffectiveZoom(), url_);
139 }
140 
KnownToBeOpaque(const Document &,const ComputedStyle &) const141 bool StyleFetchedImageSet::KnownToBeOpaque(const Document&,
142                                            const ComputedStyle&) const {
143   return best_fit_image_->GetImage()->CurrentFrameKnownToBeOpaque();
144 }
145 
Trace(Visitor * visitor) const146 void StyleFetchedImageSet::Trace(Visitor* visitor) const {
147   visitor->Trace(best_fit_image_);
148   visitor->Trace(image_set_value_);
149   StyleImage::Trace(visitor);
150 }
151 
152 }  // namespace blink
153