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