1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2006 Allan Sandfeld Jensen (kde@carewolf.com)
5  *           (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
6  * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2011 Apple Inc.
7  *               All rights reserved.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public License
20  * along with this library; see the file COPYING.LIB.  If not, write to
21  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  * Boston, MA 02110-1301, USA.
23  *
24  */
25 
26 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_IMAGE_H_
27 #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_IMAGE_H_
28 
29 #include "third_party/blink/renderer/core/core_export.h"
30 #include "third_party/blink/renderer/core/layout/layout_image_resource.h"
31 #include "third_party/blink/renderer/core/layout/layout_replaced.h"
32 #include "third_party/blink/renderer/platform/loader/fetch/resource_client.h"
33 
34 namespace blink {
35 
36 class HTMLAreaElement;
37 class HTMLMapElement;
38 class SVGImage;
39 
40 // LayoutImage is used to display any image type.
41 //
42 // There is 2 types of images:
43 // * normal images, e.g. <image>, <picture>.
44 // * content images with "content: url(path/to/image.png)".
45 // We store the type inside |is_generated_content_|.
46 //
47 // The class is image type agnostic as it only manipulates decoded images.
48 // See LayoutImageResource that holds this image.
49 class CORE_EXPORT LayoutImage : public LayoutReplaced {
50  public:
51   LayoutImage(Element*);
52   ~LayoutImage() override;
53 
54   static LayoutImage* CreateAnonymous(PseudoElement&);
55 
56   void SetImageResource(LayoutImageResource*);
57 
ImageResource()58   LayoutImageResource* ImageResource() { return image_resource_.Get(); }
ImageResource()59   const LayoutImageResource* ImageResource() const {
60     return image_resource_.Get();
61   }
CachedImage()62   ImageResourceContent* CachedImage() const {
63     return image_resource_ ? image_resource_->CachedImage() : nullptr;
64   }
65 
66   HTMLMapElement* ImageMap() const;
67   void AreaElementFocusChanged(HTMLAreaElement*);
68 
69   void SetIsGeneratedContent(bool generated = true) {
70     is_generated_content_ = generated;
71   }
72 
IsGeneratedContent()73   bool IsGeneratedContent() const { return is_generated_content_; }
74 
SetImageDevicePixelRatio(float factor)75   inline void SetImageDevicePixelRatio(float factor) {
76     image_device_pixel_ratio_ = factor;
77   }
ImageDevicePixelRatio()78   float ImageDevicePixelRatio() const { return image_device_pixel_ratio_; }
79 
IntrinsicSizeChanged()80   void IntrinsicSizeChanged() override {
81     // The replaced content transform depends on the intrinsic size (see:
82     // FragmentPaintPropertyTreeBuilder::UpdateReplacedContentTransform).
83     SetNeedsPaintPropertyUpdate();
84     if (image_resource_)
85       ImageChanged(image_resource_->ImagePtr(), CanDeferInvalidation::kNo);
86   }
87 
GetName()88   const char* GetName() const override { return "LayoutImage"; }
89 
90   void UpdateAfterLayout() override;
91 
92  protected:
93   bool NeedsPreferredWidthsRecalculation() const final;
94   SVGImage* EmbeddedSVGImage() const;
95   void ComputeIntrinsicSizingInfo(IntrinsicSizingInfo&) const override;
96 
97   void ImageChanged(WrappedImagePtr, CanDeferInvalidation) override;
98 
99   void Paint(const PaintInfo&) const final;
100 
IsOfType(LayoutObjectType type)101   bool IsOfType(LayoutObjectType type) const override {
102     return type == kLayoutObjectLayoutImage || LayoutReplaced::IsOfType(type);
103   }
104 
105   void WillBeDestroyed() override;
106 
107   void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
108 
CanBeSelectionLeafInternal()109   bool CanBeSelectionLeafInternal() const final { return true; }
110 
111  private:
IsImage()112   bool IsImage() const override { return true; }
113 
114   void PaintReplaced(const PaintInfo&,
115                      const PhysicalOffset& paint_offset) const override;
116 
117   bool ForegroundIsKnownToBeOpaqueInRect(
118       const PhysicalRect& local_rect,
119       unsigned max_depth_to_test) const final;
120   bool ComputeBackgroundIsKnownToBeObscured() const final;
121 
BackgroundShouldAlwaysBeClipped()122   bool BackgroundShouldAlwaysBeClipped() const override { return true; }
123 
124   LayoutUnit MinimumReplacedHeight() const override;
125 
126   void ImageNotifyFinished(ImageResourceContent*) final;
127   bool NodeAtPoint(HitTestResult&,
128                    const HitTestLocation&,
129                    const PhysicalOffset& accumulated_offset,
130                    HitTestAction) final;
131 
132   void InvalidatePaintAndMarkForLayoutIfNeeded(CanDeferInvalidation);
133   void UpdateIntrinsicSizeIfNeeded(const LayoutSize&);
134   bool NeedsLayoutOnIntrinsicSizeChange() const;
135   // Override intrinsic sizing info to default if "unsized-media"
136   // is disabled and the element has no sizing info.
137   bool OverrideIntrinsicSizingInfo(IntrinsicSizingInfo&) const;
138   bool HasOverriddenIntrinsicSize() const;
139   FloatSize ImageSizeOverriddenByIntrinsicSize(float multiplier) const;
140 
141   // This member wraps the associated decoded image.
142   //
143   // This field is set using setImageResource above which can be called in
144   // several ways:
145   // * For normal images, from the network stack (ImageLoader) once we have
146   // some image data.
147   // * For generated content, the resource is loaded during style resolution
148   // and thus is stored in ComputedStyle (see ContentData::image) that gets
149   // propagated to the anonymous LayoutImage in LayoutObject::createObject.
150   Persistent<LayoutImageResource> image_resource_;
151   bool did_increment_visually_non_empty_pixel_count_;
152 
153   // This field stores whether this image is generated with 'content'.
154   bool is_generated_content_;
155   float image_device_pixel_ratio_;
156 };
157 
158 DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutImage, IsLayoutImage());
159 
160 }  // namespace blink
161 
162 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_IMAGE_H_
163