1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  * Copyright (C) 2004, 2005, 2006, 2007, 2009 Apple Inc. All rights reserved.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  *
20  */
21 
22 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_REPLACED_H_
23 #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_REPLACED_H_
24 
25 #include "third_party/blink/renderer/core/core_export.h"
26 #include "third_party/blink/renderer/core/layout/layout_box.h"
27 
28 namespace blink {
29 
30 struct IntrinsicSizingInfo;
31 
32 // LayoutReplaced is the base class for a replaced element as defined by CSS:
33 //
34 // "An element whose content is outside the scope of the CSS formatting model,
35 // such as an image, embedded document, or applet."
36 // http://www.w3.org/TR/CSS2/conform.html#defs
37 //
38 // Blink consider that replaced elements have an intrinsic sizes (e.g. the
39 // natural size of an image or a video). The intrinsic size is stored by
40 // m_intrinsicSize.
41 //
42 // The computation sometimes ask for the intrinsic ratio, defined as follow:
43 //
44 //                      intrinsicWidth
45 //   intrinsicRatio = -------------------
46 //                      intrinsicHeight
47 //
48 // The intrinsic ratio is used to keep the same proportion as the intrinsic
49 // size (thus avoiding visual distortions if width / height doesn't match
50 // the intrinsic value).
51 class CORE_EXPORT LayoutReplaced : public LayoutBox {
52  public:
53   LayoutReplaced(Element*);
54   LayoutReplaced(Element*, const LayoutSize& intrinsic_size);
55   ~LayoutReplaced() override;
56 
57   LayoutUnit ComputeReplacedLogicalWidth(
58       ShouldComputePreferred = kComputeActual) const override;
59   LayoutUnit ComputeReplacedLogicalHeight(
60       LayoutUnit estimated_used_width = LayoutUnit()) const override;
61 
62   bool HasReplacedLogicalHeight() const;
63   // This function returns the local rect of the replaced content.
64   virtual PhysicalRect ReplacedContentRect() const;
65 
66   // This is used by a few special elements, e.g. <video>, <iframe> to ensure
67   // a persistent sizing under different subpixel offset, because these
68   // elements have a high cost to resize. The drawback is that we may overflow
69   // or underflow the final content box by 1px.
70   static PhysicalRect PreSnappedRectForPersistentSizing(const PhysicalRect&);
71 
72   bool NeedsPreferredWidthsRecalculation() const override;
73 
74   void RecalcVisualOverflow() override;
75 
76   // These values are specified to be 300 and 150 pixels in the CSS 2.1 spec.
77   // http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-width
78   static const int kDefaultWidth;
79   static const int kDefaultHeight;
CanHaveChildren()80   bool CanHaveChildren() const override {
81     NOT_DESTROYED();
82     return false;
83   }
PaintReplaced(const PaintInfo &,const PhysicalOffset & paint_offset)84   virtual void PaintReplaced(const PaintInfo&,
85                              const PhysicalOffset& paint_offset) const {
86     NOT_DESTROYED();
87   }
88 
89   PhysicalRect LocalSelectionVisualRect() const final;
90 
HasObjectFit()91   bool HasObjectFit() const {
92     NOT_DESTROYED();
93     return StyleRef().GetObjectFit() !=
94            ComputedStyleInitialValues::InitialObjectFit();
95   }
96 
97   void Paint(const PaintInfo&) const override;
98 
99   // This function is public only so we can call it when computing
100   // intrinsic size in LayoutNG.
101   virtual void ComputeIntrinsicSizingInfo(IntrinsicSizingInfo&) const;
102 
103   // This callback must be invoked whenever the underlying intrinsic size has
104   // changed.
105   //
106   // The intrinsic size can change due to the network (from the default
107   // intrinsic size [see above] to the actual intrinsic size) or to some
108   // CSS properties like 'zoom' or 'image-orientation'.
109   virtual void IntrinsicSizeChanged();
110 
111  protected:
112   void WillBeDestroyed() override;
113 
114   void UpdateLayout() override;
115 
IntrinsicSize()116   LayoutSize IntrinsicSize() const final {
117     NOT_DESTROYED();
118     return LayoutSize(IntrinsicWidth(), IntrinsicHeight());
119   }
120 
IntrinsicWidth()121   LayoutUnit IntrinsicWidth() const {
122     NOT_DESTROYED();
123     if (HasOverrideIntrinsicContentWidth())
124       return OverrideIntrinsicContentWidth();
125     else if (ShouldApplySizeContainment())
126       return LayoutUnit();
127     return intrinsic_size_.Width();
128   }
IntrinsicHeight()129   LayoutUnit IntrinsicHeight() const {
130     NOT_DESTROYED();
131     if (HasOverrideIntrinsicContentHeight())
132       return OverrideIntrinsicContentHeight();
133     else if (ShouldApplySizeContainment())
134       return LayoutUnit();
135     return intrinsic_size_.Height();
136   }
137 
138   void ComputePositionedLogicalWidth(
139       LogicalExtentComputedValues&) const override;
140   void ComputePositionedLogicalHeight(
141       LogicalExtentComputedValues&) const override;
142 
143   MinMaxSizes ComputeIntrinsicLogicalWidths() const final;
144 
145   // This function calculates the placement of the replaced contents. It takes
146   // intrinsic size of the replaced contents, stretch to fit CSS content box
147   // according to object-fit.
148   PhysicalRect ComputeObjectFit(
149       const LayoutSize* overridden_intrinsic_size = nullptr) const;
150 
IntrinsicContentLogicalHeight()151   LayoutUnit IntrinsicContentLogicalHeight() const override {
152     NOT_DESTROYED();
153     return IntrinsicLogicalHeight();
154   }
155 
MinimumReplacedHeight()156   virtual LayoutUnit MinimumReplacedHeight() const {
157     NOT_DESTROYED();
158     return LayoutUnit();
159   }
160 
161   void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
162 
SetIntrinsicSize(const LayoutSize & intrinsic_size)163   void SetIntrinsicSize(const LayoutSize& intrinsic_size) {
164     NOT_DESTROYED();
165     intrinsic_size_ = intrinsic_size;
166   }
167 
168   PositionWithAffinity PositionForPoint(const PhysicalOffset&) const override;
169 
IsOfType(LayoutObjectType type)170   bool IsOfType(LayoutObjectType type) const override {
171     NOT_DESTROYED();
172     return type == kLayoutObjectReplaced || LayoutBox::IsOfType(type);
173   }
174 
175  private:
176   MinMaxSizes PreferredLogicalWidths() const final;
177 
178   void ComputeIntrinsicSizingInfoForReplacedContent(IntrinsicSizingInfo&) const;
179   FloatSize ConstrainIntrinsicSizeToMinMax(const IntrinsicSizingInfo&) const;
180 
181   LayoutUnit ComputeConstrainedLogicalWidth(ShouldComputePreferred) const;
182 
183   mutable LayoutSize intrinsic_size_;
184 };
185 
186 template <>
187 struct DowncastTraits<LayoutReplaced> {
188   static bool AllowFrom(const LayoutObject& object) {
189     return object.IsLayoutReplaced();
190   }
191 };
192 
193 }  // namespace blink
194 
195 #endif
196