summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/layout/layout_replaced.h
blob: a945fcf357b91944b5d64289fd9693e6b5a22ab5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 * Copyright (C) 2004, 2005, 2006, 2007, 2009 Apple Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_REPLACED_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_REPLACED_H_

#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"

namespace blink {

struct IntrinsicSizingInfo;

// LayoutReplaced is the base class for a replaced element as defined by CSS:
//
// "An element whose content is outside the scope of the CSS formatting model,
// such as an image, embedded document, or applet."
// http://www.w3.org/TR/CSS2/conform.html#defs
//
// Blink consider that replaced elements have an intrinsic sizes (e.g. the
// natural size of an image or a video). The intrinsic size is stored by
// m_intrinsicSize.
//
// The computation sometimes ask for the intrinsic ratio, defined as follow:
//
//                      intrinsicWidth
//   intrinsicRatio = -------------------
//                      intrinsicHeight
//
// The intrinsic ratio is used to keep the same proportion as the intrinsic
// size (thus avoiding visual distortions if width / height doesn't match
// the intrinsic value).
class CORE_EXPORT LayoutReplaced : public LayoutBox {
 public:
  LayoutReplaced(Element*);
  LayoutReplaced(Element*, const LayoutSize& intrinsic_size);
  ~LayoutReplaced() override;

  LayoutUnit ComputeReplacedLogicalWidth(
      ShouldComputePreferred = kComputeActual) const override;
  LayoutUnit ComputeReplacedLogicalHeight(
      LayoutUnit estimated_used_width = LayoutUnit()) const override;

  bool HasReplacedLogicalHeight() const;
  // This function returns the local rect of the replaced content.
  virtual PhysicalRect ReplacedContentRect() const;

  // This is used by a few special elements, e.g. <video>, <iframe> to ensure
  // a persistent sizing under different subpixel offset, because these
  // elements have a high cost to resize. The drawback is that we may overflow
  // or underflow the final content box by 1px.
  static PhysicalRect PreSnappedRectForPersistentSizing(const PhysicalRect&);

  bool NeedsPreferredWidthsRecalculation() const override;

  void RecalcVisualOverflow() override;

  // These values are specified to be 300 and 150 pixels in the CSS 2.1 spec.
  // http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-width
  static const int kDefaultWidth;
  static const int kDefaultHeight;
  bool CanHaveChildren() const override { return false; }
  virtual void PaintReplaced(const PaintInfo&,
                             const PhysicalOffset& paint_offset) const {}

  PhysicalRect LocalSelectionVisualRect() const final;

  bool HasObjectFit() const {
    return StyleRef().GetObjectFit() !=
           ComputedStyleInitialValues::InitialObjectFit();
  }

  void Paint(const PaintInfo&) const override;

  // Replaced objects often have contents to paint.
  bool PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const override {
    return false;
  }

  // This function is public only so we can call it when computing
  // intrinsic size in LayoutNG.
  virtual void ComputeIntrinsicSizingInfo(IntrinsicSizingInfo&) const;

  // This callback is invoked whenever the intrinsic size changed.
  //
  // The intrinsic size can change due to the network (from the default
  // intrinsic size [see above] to the actual intrinsic size) or to some
  // CSS properties like 'zoom' or 'image-orientation'.
  virtual void IntrinsicSizeChanged();

 protected:
  void WillBeDestroyed() override;

  void UpdateLayout() override;

  LayoutSize IntrinsicSize() const final { return intrinsic_size_; }

  void ComputePositionedLogicalWidth(
      LogicalExtentComputedValues&) const override;
  void ComputePositionedLogicalHeight(
      LogicalExtentComputedValues&) const override;

  void ComputeIntrinsicLogicalWidths(LayoutUnit& min_logical_width,
                                     LayoutUnit& max_logical_width) const final;

  // This function calculates the placement of the replaced contents. It takes
  // intrinsic size of the replaced contents, stretch to fit CSS content box
  // according to object-fit.
  PhysicalRect ComputeObjectFit(
      const LayoutSize* overridden_intrinsic_size = nullptr) const;

  LayoutUnit IntrinsicContentLogicalHeight() const override {
    return IntrinsicLogicalHeight();
  }

  virtual LayoutUnit MinimumReplacedHeight() const { return LayoutUnit(); }

  void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;

  void SetIntrinsicSize(const LayoutSize& intrinsic_size) {
    intrinsic_size_ = intrinsic_size;
  }

  PositionWithAffinity PositionForPoint(const PhysicalOffset&) const override;

  bool IsOfType(LayoutObjectType type) const override {
    return type == kLayoutObjectLayoutReplaced || LayoutBox::IsOfType(type);
  }

 private:
  void ComputePreferredLogicalWidths() final;

  void ComputeIntrinsicSizingInfoForReplacedContent(IntrinsicSizingInfo&) const;
  FloatSize ConstrainIntrinsicSizeToMinMax(const IntrinsicSizingInfo&) const;

  LayoutUnit ComputeConstrainedLogicalWidth(ShouldComputePreferred) const;

  mutable LayoutSize intrinsic_size_;
};

DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutReplaced, IsLayoutReplaced());

}  // namespace blink

#endif