1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  * Copyright (C) 2003, 2006, 2007 Apple Inc. All rights reserved.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB.  If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_BOX_H_
24 #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_BOX_H_
25 
26 #include <memory>
27 
28 #include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink-forward.h"
29 #include "third_party/blink/renderer/core/core_export.h"
30 #include "third_party/blink/renderer/core/frame/local_frame.h"
31 #include "third_party/blink/renderer/core/layout/layout_box_model_object.h"
32 #include "third_party/blink/renderer/core/layout/min_max_sizes.h"
33 #include "third_party/blink/renderer/core/layout/overflow_model.h"
34 #include "third_party/blink/renderer/core/page/page.h"
35 #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
36 #include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
37 #include "third_party/blink/renderer/platform/graphics/overlay_scrollbar_clip_behavior.h"
38 
39 namespace blink {
40 
41 class CustomLayoutChild;
42 class LayoutBlockFlow;
43 class LayoutMultiColumnSpannerPlaceholder;
44 class NGBoxFragmentBuilder;
45 class NGBreakToken;
46 class NGConstraintSpace;
47 class NGEarlyBreak;
48 class NGLayoutResult;
49 class ShapeOutsideInfo;
50 enum class NGLayoutCacheStatus;
51 struct BoxLayoutExtraInput;
52 struct NGFragmentGeometry;
53 struct NGPhysicalBoxStrut;
54 struct PaintInfo;
55 
56 enum SizeType { kMainOrPreferredSize, kMinSize, kMaxSize };
57 enum AvailableLogicalHeightType {
58   kExcludeMarginBorderPadding,
59   kIncludeMarginBorderPadding
60 };
61 // When painting, overlay scrollbars do not take up space and should not affect
62 // clipping behavior. During hit testing, overlay scrollbars behave like regular
63 // scrollbars and should change how hit testing is clipped.
64 enum MarginDirection { kBlockDirection, kInlineDirection };
65 enum BackgroundRectType { kBackgroundClipRect, kBackgroundKnownOpaqueRect };
66 
67 enum ShouldComputePreferred { kComputeActual, kComputePreferred };
68 
69 enum ShouldClampToContentBox { kDoNotClampToContentBox, kClampToContentBox };
70 
71 using SnapAreaSet = HashSet<LayoutBox*>;
72 
73 struct LayoutBoxRareData final : public GarbageCollected<LayoutBoxRareData> {
74  public:
75   LayoutBoxRareData();
76   LayoutBoxRareData(const LayoutBoxRareData&) = delete;
77   LayoutBoxRareData& operator=(const LayoutBoxRareData&) = delete;
78 
79   void Trace(Visitor* visitor) const;
80 
81   // For spanners, the spanner placeholder that lays us out within the multicol
82   // container.
83   LayoutMultiColumnSpannerPlaceholder* spanner_placeholder_;
84 
85   LayoutUnit override_logical_width_;
86   LayoutUnit override_logical_height_;
87 
88   bool has_override_containing_block_content_logical_width_ : 1;
89   bool has_override_containing_block_content_logical_height_ : 1;
90   bool has_override_percentage_resolution_block_size_ : 1;
91   bool has_previous_content_box_rect_ : 1;
92 
93   LayoutUnit override_containing_block_content_logical_width_;
94   LayoutUnit override_containing_block_content_logical_height_;
95   LayoutUnit override_percentage_resolution_block_size_;
96 
97   LayoutUnit offset_to_next_page_;
98 
99   LayoutUnit pagination_strut_;
100 
101   LayoutBlock* percent_height_container_;
102   // For snap area, the owning snap container.
103   LayoutBox* snap_container_;
104   // For snap container, the descendant snap areas that contribute snap
105   // points.
106   std::unique_ptr<SnapAreaSet> snap_areas_;
107 
EnsureSnapAreasfinal108   SnapAreaSet& EnsureSnapAreas() {
109     if (!snap_areas_)
110       snap_areas_ = std::make_unique<SnapAreaSet>();
111 
112     return *snap_areas_;
113   }
114 
115   // Used by BoxPaintInvalidator. Stores the previous content rect after the
116   // last paint invalidation. It's valid if has_previous_content_box_rect_ is
117   // true.
118   PhysicalRect previous_physical_content_box_rect_;
119 
120   PhysicalRect partial_invalidation_rect_;
121 
122   // Used by CSSLayoutDefinition::Instance::Layout. Represents the script
123   // object for this box that web developers can query style, and perform
124   // layout upon. Only created if IsCustomItem() is true.
125   Member<CustomLayoutChild> layout_child_;
126 };
127 
128 // LayoutBox implements the full CSS box model.
129 //
130 // LayoutBoxModelObject only introduces some abstractions for LayoutInline and
131 // LayoutBox. The logic for the model is in LayoutBox, e.g. the storage for the
132 // rectangle and offset forming the CSS box (frame_rect_) and the getters for
133 // the different boxes.
134 //
135 // LayoutBox is also the uppermost class to support scrollbars, however the
136 // logic is delegated to PaintLayerScrollableArea.
137 // Per the CSS specification, scrollbars should "be inserted between the inner
138 // border edge and the outer padding edge".
139 // (see http://www.w3.org/TR/CSS21/visufx.html#overflow)
140 // Also the scrollbar width / height are removed from the content box. Taking
141 // the following example:
142 //
143 // <!DOCTYPE html>
144 // <style>
145 // ::-webkit-scrollbar {
146 //     /* Force non-overlay scrollbars */
147 //     width: 10px;
148 //     height: 20px;
149 // }
150 // </style>
151 // <div style="overflow:scroll; width: 100px; height: 100px">
152 //
153 // The <div>'s content box is not 100x100 as specified in the style but 90x80 as
154 // we remove the scrollbars from the box.
155 //
156 // The presence of scrollbars is determined by the 'overflow' property and can
157 // be conditioned on having layout overflow (see OverflowModel for more details
158 // on how we track overflow).
159 //
160 // There are 2 types of scrollbars:
161 // - non-overlay scrollbars take space from the content box.
162 // - overlay scrollbars don't and just overlay hang off from the border box,
163 //   potentially overlapping with the padding box's content.
164 // For more details on scrollbars, see PaintLayerScrollableArea.
165 //
166 //
167 // ***** THE BOX MODEL *****
168 // The CSS box model is based on a series of nested boxes:
169 // http://www.w3.org/TR/CSS21/box.html
170 //
171 //       |----------------------------------------------------|
172 //       |                                                    |
173 //       |                   margin-top                       |
174 //       |                                                    |
175 //       |     |-----------------------------------------|    |
176 //       |     |                                         |    |
177 //       |     |             border-top                  |    |
178 //       |     |                                         |    |
179 //       |     |    |--------------------------|----|    |    |
180 //       |     |    |                          |    |    |    |
181 //       |     |    |       padding-top        |####|    |    |
182 //       |     |    |                          |####|    |    |
183 //       |     |    |    |----------------|    |####|    |    |
184 //       |     |    |    |                |    |    |    |    |
185 //       | ML  | BL | PL |  content box   | PR | SW | BR | MR |
186 //       |     |    |    |                |    |    |    |    |
187 //       |     |    |    |----------------|    |    |    |    |
188 //       |     |    |                          |    |    |    |
189 //       |     |    |      padding-bottom      |    |    |    |
190 //       |     |    |--------------------------|----|    |    |
191 //       |     |    |                      ####|    |    |    |
192 //       |     |    |     scrollbar height ####| SC |    |    |
193 //       |     |    |                      ####|    |    |    |
194 //       |     |    |-------------------------------|    |    |
195 //       |     |                                         |    |
196 //       |     |           border-bottom                 |    |
197 //       |     |                                         |    |
198 //       |     |-----------------------------------------|    |
199 //       |                                                    |
200 //       |                 margin-bottom                      |
201 //       |                                                    |
202 //       |----------------------------------------------------|
203 //
204 // BL = border-left
205 // BR = border-right
206 // ML = margin-left
207 // MR = margin-right
208 // PL = padding-left
209 // PR = padding-right
210 // SC = scroll corner (contains UI for resizing (see the 'resize' property)
211 // SW = scrollbar width
212 //
213 // Note that the vertical scrollbar (if existing) will be on the left in
214 // right-to-left direction and horizontal writing-mode. The horizontal scrollbar
215 // (if existing) is always at the bottom.
216 //
217 // Those are just the boxes from the CSS model. Extra boxes are tracked by Blink
218 // (e.g. the overflows). Thus it is paramount to know which box a function is
219 // manipulating. Also of critical importance is the coordinate system used (see
220 // the COORDINATE SYSTEMS section in LayoutBoxModelObject).
221 class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
222  public:
223   explicit LayoutBox(ContainerNode*);
224 
225   PaintLayerType LayerTypeRequired() const override;
226 
227   bool BackgroundIsKnownToBeOpaqueInRect(
228       const PhysicalRect& local_rect) const override;
229   bool TextIsKnownToBeOnOpaqueBackground() const override;
230 
BackgroundShouldAlwaysBeClipped()231   virtual bool BackgroundShouldAlwaysBeClipped() const {
232     NOT_DESTROYED();
233     return false;
234   }
235 
236   // Returns whether this object needs a scroll paint property tree node. These
237   // are a requirement for composited scrolling but are also created for
238   // non-composited scrollers.
239   bool NeedsScrollNode(CompositingReasons direct_compositing_reasons) const;
240 
241   // Use this with caution! No type checking is done!
242   LayoutBox* FirstChildBox() const;
243   LayoutBox* FirstInFlowChildBox() const;
244   LayoutBox* LastChildBox() const;
245 
246   // TODO(crbug.com/962299): This is incorrect in some cases.
PixelSnappedWidth()247   int PixelSnappedWidth() const {
248     NOT_DESTROYED();
249     return frame_rect_.PixelSnappedWidth();
250   }
PixelSnappedHeight()251   int PixelSnappedHeight() const {
252     NOT_DESTROYED();
253     return frame_rect_.PixelSnappedHeight();
254   }
255 
SetX(LayoutUnit x)256   void SetX(LayoutUnit x) {
257     NOT_DESTROYED();
258     if (x == frame_rect_.X())
259       return;
260     frame_rect_.SetX(x);
261     LocationChanged();
262   }
SetY(LayoutUnit y)263   void SetY(LayoutUnit y) {
264     NOT_DESTROYED();
265     if (y == frame_rect_.Y())
266       return;
267     frame_rect_.SetY(y);
268     LocationChanged();
269   }
SetWidth(LayoutUnit width)270   void SetWidth(LayoutUnit width) {
271     NOT_DESTROYED();
272     if (width == frame_rect_.Width())
273       return;
274     frame_rect_.SetWidth(width);
275     SizeChanged();
276   }
SetHeight(LayoutUnit height)277   void SetHeight(LayoutUnit height) {
278     NOT_DESTROYED();
279     if (height == frame_rect_.Height())
280       return;
281     frame_rect_.SetHeight(height);
282     SizeChanged();
283   }
284 
LogicalLeft()285   LayoutUnit LogicalLeft() const {
286     NOT_DESTROYED();
287     return StyleRef().IsHorizontalWritingMode() ? frame_rect_.X()
288                                                 : frame_rect_.Y();
289   }
LogicalRight()290   LayoutUnit LogicalRight() const {
291     NOT_DESTROYED();
292     return LogicalLeft() + LogicalWidth();
293   }
LogicalTop()294   LayoutUnit LogicalTop() const {
295     NOT_DESTROYED();
296     return StyleRef().IsHorizontalWritingMode() ? frame_rect_.Y()
297                                                 : frame_rect_.X();
298   }
LogicalBottom()299   LayoutUnit LogicalBottom() const {
300     NOT_DESTROYED();
301     return LogicalTop() + LogicalHeight();
302   }
LogicalWidth()303   LayoutUnit LogicalWidth() const {
304     NOT_DESTROYED();
305     return StyleRef().IsHorizontalWritingMode() ? frame_rect_.Width()
306                                                 : frame_rect_.Height();
307   }
LogicalHeight()308   LayoutUnit LogicalHeight() const {
309     NOT_DESTROYED();
310     return StyleRef().IsHorizontalWritingMode() ? frame_rect_.Height()
311                                                 : frame_rect_.Width();
312   }
313 
314   // Logical height of the object, including content overflowing the
315   // border-after edge.
316   virtual LayoutUnit LogicalHeightWithVisibleOverflow() const;
317 
318   LayoutUnit ConstrainLogicalWidthByMinMax(LayoutUnit,
319                                            LayoutUnit,
320                                            const LayoutBlock*,
321                                            bool allow_intrinsic = true) const;
322   LayoutUnit ConstrainLogicalHeightByMinMax(
323       LayoutUnit logical_height,
324       LayoutUnit intrinsic_content_height) const;
325   LayoutUnit ConstrainContentBoxLogicalHeightByMinMax(
326       LayoutUnit logical_height,
327       LayoutUnit intrinsic_content_height) const;
328 
329   // TODO(crbug.com/962299): This is incorrect in some cases.
PixelSnappedLogicalHeight()330   int PixelSnappedLogicalHeight() const {
331     NOT_DESTROYED();
332     return StyleRef().IsHorizontalWritingMode() ? PixelSnappedHeight()
333                                                 : PixelSnappedWidth();
334   }
PixelSnappedLogicalWidth()335   int PixelSnappedLogicalWidth() const {
336     NOT_DESTROYED();
337     return StyleRef().IsHorizontalWritingMode() ? PixelSnappedWidth()
338                                                 : PixelSnappedHeight();
339   }
340 
MinimumLogicalHeightForEmptyLine()341   LayoutUnit MinimumLogicalHeightForEmptyLine() const {
342     NOT_DESTROYED();
343     return BorderAndPaddingLogicalHeight() +
344            ComputeLogicalScrollbars().BlockSum() + LogicalHeightForEmptyLine();
345   }
LogicalHeightForEmptyLine()346   LayoutUnit LogicalHeightForEmptyLine() const {
347     NOT_DESTROYED();
348     return LineHeight(
349         true, IsHorizontalWritingMode() ? kHorizontalLine : kVerticalLine,
350         kPositionOfInteriorLineBoxes);
351   }
352 
SetLogicalLeft(LayoutUnit left)353   void SetLogicalLeft(LayoutUnit left) {
354     NOT_DESTROYED();
355     if (StyleRef().IsHorizontalWritingMode())
356       SetX(left);
357     else
358       SetY(left);
359   }
SetLogicalTop(LayoutUnit top)360   void SetLogicalTop(LayoutUnit top) {
361     NOT_DESTROYED();
362     if (StyleRef().IsHorizontalWritingMode())
363       SetY(top);
364     else
365       SetX(top);
366   }
SetLogicalLocation(const LayoutPoint & location)367   void SetLogicalLocation(const LayoutPoint& location) {
368     NOT_DESTROYED();
369     if (StyleRef().IsHorizontalWritingMode())
370       SetLocation(location);
371     else
372       SetLocation(location.TransposedPoint());
373   }
SetLogicalWidth(LayoutUnit size)374   void SetLogicalWidth(LayoutUnit size) {
375     NOT_DESTROYED();
376     if (StyleRef().IsHorizontalWritingMode())
377       SetWidth(size);
378     else
379       SetHeight(size);
380   }
SetLogicalHeight(LayoutUnit size)381   void SetLogicalHeight(LayoutUnit size) {
382     NOT_DESTROYED();
383     if (StyleRef().IsHorizontalWritingMode())
384       SetHeight(size);
385     else
386       SetWidth(size);
387   }
388 
389   // See frame_rect_.
Location()390   LayoutPoint Location() const {
391     NOT_DESTROYED();
392     return frame_rect_.Location();
393   }
LocationOffset()394   LayoutSize LocationOffset() const {
395     NOT_DESTROYED();
396     return LayoutSize(frame_rect_.X(), frame_rect_.Y());
397   }
Size()398   LayoutSize Size() const {
399     NOT_DESTROYED();
400     return frame_rect_.Size();
401   }
402   // TODO(crbug.com/962299): This is incorrect in some cases.
PixelSnappedSize()403   IntSize PixelSnappedSize() const {
404     NOT_DESTROYED();
405     return frame_rect_.PixelSnappedSize();
406   }
407 
SetLocation(const LayoutPoint & location)408   void SetLocation(const LayoutPoint& location) {
409     NOT_DESTROYED();
410     if (location == frame_rect_.Location())
411       return;
412     frame_rect_.SetLocation(location);
413     LocationChanged();
414   }
415 
416   // The ancestor box that this object's Location and PhysicalLocation are
417   // relative to.
418   virtual LayoutBox* LocationContainer() const;
419 
420   // FIXME: Currently scrollbars are using int geometry and positioned based on
421   // pixelSnappedBorderBoxRect whose size may change when location changes
422   // because of pixel snapping. This function is used to change location of the
423   // LayoutBox outside of LayoutBox::layout(). Will remove when we use
424   // LayoutUnits for scrollbars.
425   void SetLocationAndUpdateOverflowControlsIfNeeded(const LayoutPoint&);
426 
SetSize(const LayoutSize & size)427   void SetSize(const LayoutSize& size) {
428     NOT_DESTROYED();
429     if (size == frame_rect_.Size())
430       return;
431     frame_rect_.SetSize(size);
432     SizeChanged();
433   }
Move(LayoutUnit dx,LayoutUnit dy)434   void Move(LayoutUnit dx, LayoutUnit dy) {
435     NOT_DESTROYED();
436     if (!dx && !dy)
437       return;
438     frame_rect_.Move(dx, dy);
439     LocationChanged();
440   }
441 
442   // See frame_rect_.
FrameRect()443   LayoutRect FrameRect() const {
444     NOT_DESTROYED();
445     return frame_rect_;
446   }
SetFrameRect(const LayoutRect & rect)447   void SetFrameRect(const LayoutRect& rect) {
448     NOT_DESTROYED();
449     SetLocation(rect.Location());
450     SetSize(rect.Size());
451   }
452 
453   // Note that those functions have their origin at this box's CSS border box.
454   // As such their location doesn't account for 'top'/'left'. About its
455   // coordinate space, it can be treated as in either physical coordinates
456   // or "physical coordinates in flipped block-flow direction", and
457   // FlipForWritingMode() will do nothing on it.
BorderBoxRect()458   LayoutRect BorderBoxRect() const {
459     NOT_DESTROYED();
460     return LayoutRect(LayoutPoint(), Size());
461   }
PhysicalBorderBoxRect()462   PhysicalRect PhysicalBorderBoxRect() const {
463     NOT_DESTROYED();
464     // This doesn't need flipping because the result would be the same.
465     DCHECK_EQ(PhysicalRect(BorderBoxRect()),
466               FlipForWritingMode(BorderBoxRect()));
467     return PhysicalRect(BorderBoxRect());
468   }
469 
470   // Client rect and padding box rect are the same concept.
471   // TODO(crbug.com/877518): Some callers of this method may actually want
472   // "physical coordinates in flipped block-flow direction".
PhysicalPaddingBoxRect()473   DISABLE_CFI_PERF PhysicalRect PhysicalPaddingBoxRect() const {
474     NOT_DESTROYED();
475     return PhysicalRect(ClientLeft(), ClientTop(), ClientWidth(),
476                         ClientHeight());
477   }
478 
479   // TODO(crbug.com/962299): This method snaps to pixels incorrectly because
480   // Location() is not the correct paint offset. It's also incorrect in flipped
481   // blocks writing mode.
PixelSnappedBorderBoxRect()482   IntRect PixelSnappedBorderBoxRect() const {
483     NOT_DESTROYED();
484     return IntRect(IntPoint(),
485                    PixelSnappedBorderBoxSize(PhysicalOffset(Location())));
486   }
487   // TODO(crbug.com/962299): This method is only correct when |offset| is the
488   // correct paint offset.
PixelSnappedBorderBoxSize(const PhysicalOffset & offset)489   IntSize PixelSnappedBorderBoxSize(const PhysicalOffset& offset) const {
490     NOT_DESTROYED();
491     return PixelSnappedIntSize(Size(), offset.ToLayoutPoint());
492   }
BorderBoundingBox()493   IntRect BorderBoundingBox() const final {
494     NOT_DESTROYED();
495     return PixelSnappedBorderBoxRect();
496   }
497 
498   // The content area of the box (excludes padding - and intrinsic padding for
499   // table cells, etc... - and scrollbars and border).
500   // TODO(crbug.com/877518): Some callers of this method may actually want
501   // "physical coordinates in flipped block-flow direction".
PhysicalContentBoxRect()502   DISABLE_CFI_PERF PhysicalRect PhysicalContentBoxRect() const {
503     NOT_DESTROYED();
504     return PhysicalRect(ContentLeft(), ContentTop(), ContentWidth(),
505                         ContentHeight());
506   }
507   // TODO(crbug.com/877518): Some callers of this method may actually want
508   // "physical coordinates in flipped block-flow direction".
PhysicalContentBoxOffset()509   PhysicalOffset PhysicalContentBoxOffset() const {
510     NOT_DESTROYED();
511     return PhysicalOffset(ContentLeft(), ContentTop());
512   }
513   // The content box converted to absolute coords (taking transforms into
514   // account).
515   FloatQuad AbsoluteContentQuad(MapCoordinatesFlags = 0) const;
516 
517   // The enclosing rectangle of the background with given opacity requirement.
518   // TODO(crbug.com/877518): Some callers of this method may actually want
519   // "physical coordinates in flipped block-flow direction".
520   PhysicalRect PhysicalBackgroundRect(BackgroundRectType) const;
521 
522   // This returns the content area of the box (excluding padding and border).
523   // The only difference with contentBoxRect is that computedCSSContentBoxRect
524   // does include the intrinsic padding in the content box as this is what some
525   // callers expect (like getComputedStyle).
ComputedCSSContentBoxRect()526   LayoutRect ComputedCSSContentBoxRect() const {
527     NOT_DESTROYED();
528     return LayoutRect(
529         BorderLeft() + ComputedCSSPaddingLeft(),
530         BorderTop() + ComputedCSSPaddingTop(),
531         ClientWidth() - ComputedCSSPaddingLeft() - ComputedCSSPaddingRight(),
532         ClientHeight() - ComputedCSSPaddingTop() - ComputedCSSPaddingBottom());
533   }
534 
535   void AddOutlineRects(Vector<PhysicalRect>&,
536                        const PhysicalOffset& additional_offset,
537                        NGOutlineType) const override;
538 
539   // Use this with caution! No type checking is done!
540   LayoutBox* PreviousSiblingBox() const;
541   LayoutBox* PreviousInFlowSiblingBox() const;
542   LayoutBox* NextSiblingBox() const;
543   LayoutBox* NextInFlowSiblingBox() const;
544   LayoutBox* ParentBox() const;
545 
546   // Return the previous sibling column set or spanner placeholder. Only to be
547   // used on multicol container children.
548   LayoutBox* PreviousSiblingMultiColumnBox() const;
549   // Return the next sibling column set or spanner placeholder. Only to be used
550   // on multicol container children.
551   LayoutBox* NextSiblingMultiColumnBox() const;
552 
553   bool CanResize() const;
554 
555   LayoutUnit ContainerWidthInInlineDirection() const;
556   // Whether we should (and are able to) compute the logical width using the
557   // aspect ratio. Since we compute the logical *height* as part of this check,
558   // we provide it in an optional out parameter in case the caller needs it
559   // (only valid if this function returns true).
560   bool ShouldComputeLogicalWidthFromAspectRatio(
561       LayoutUnit* logical_height = nullptr) const;
ShouldComputeLogicalHeightFromAspectRatio()562   bool ShouldComputeLogicalHeightFromAspectRatio() const {
563     NOT_DESTROYED();
564     if (ShouldComputeLogicalWidthFromAspectRatioAndInsets())
565       return false;
566     Length h = StyleRef().LogicalHeight();
567     return !StyleRef().AspectRatio().IsAuto() &&
568            (h.IsAuto() ||
569             (!IsOutOfFlowPositioned() && h.IsPercentOrCalc() &&
570              ComputePercentageLogicalHeight(h) == kIndefiniteSize));
571   }
ShouldComputeLogicalWidthFromAspectRatioAndInsets()572   bool ShouldComputeLogicalWidthFromAspectRatioAndInsets() const {
573     NOT_DESTROYED();
574     const ComputedStyle& style = StyleRef();
575     if (style.AspectRatio().IsAuto() || !IsOutOfFlowPositioned())
576       return false;
577     if (style.Width().IsAuto() && style.Height().IsAuto() &&
578         !style.LogicalTop().IsAuto() && !style.LogicalBottom().IsAuto() &&
579         (style.LogicalLeft().IsAuto() || style.LogicalRight().IsAuto()))
580       return true;
581     return false;
582   }
583   bool ComputeLogicalWidthFromAspectRatio(LayoutUnit* logical_width) const;
584 
585   MinMaxSizes ComputeMinMaxLogicalWidthFromAspectRatio() const;
586 
587   // Like most of the other box geometries, visual and layout overflow are also
588   // in the "physical coordinates in flipped block-flow direction" of the box.
589   LayoutRect NoOverflowRect() const;
LayoutOverflowRect()590   LayoutRect LayoutOverflowRect() const {
591     NOT_DESTROYED();
592     return LayoutOverflowIsSet()
593                ? overflow_->layout_overflow->LayoutOverflowRect()
594                : NoOverflowRect();
595   }
PhysicalLayoutOverflowRect()596   PhysicalRect PhysicalLayoutOverflowRect() const {
597     NOT_DESTROYED();
598     return FlipForWritingMode(LayoutOverflowRect());
599   }
600   // TODO(crbug.com/962299): This is incorrect in some cases.
PixelSnappedLayoutOverflowRect()601   IntRect PixelSnappedLayoutOverflowRect() const {
602     NOT_DESTROYED();
603     return PixelSnappedIntRect(LayoutOverflowRect());
604   }
MaxLayoutOverflow()605   LayoutSize MaxLayoutOverflow() const {
606     NOT_DESTROYED();
607     return LayoutSize(LayoutOverflowRect().MaxX(), LayoutOverflowRect().MaxY());
608   }
609 
610   LayoutRect VisualOverflowRect() const;
PhysicalVisualOverflowRect()611   PhysicalRect PhysicalVisualOverflowRect() const final {
612     NOT_DESTROYED();
613     return FlipForWritingMode(VisualOverflowRect());
614   }
LogicalLeftVisualOverflow()615   LayoutUnit LogicalLeftVisualOverflow() const {
616     NOT_DESTROYED();
617     return StyleRef().IsHorizontalWritingMode() ? VisualOverflowRect().X()
618                                                 : VisualOverflowRect().Y();
619   }
LogicalRightVisualOverflow()620   LayoutUnit LogicalRightVisualOverflow() const {
621     NOT_DESTROYED();
622     return StyleRef().IsHorizontalWritingMode() ? VisualOverflowRect().MaxX()
623                                                 : VisualOverflowRect().MaxY();
624   }
625 
SelfVisualOverflowRect()626   LayoutRect SelfVisualOverflowRect() const {
627     NOT_DESTROYED();
628     return VisualOverflowIsSet()
629                ? overflow_->visual_overflow->SelfVisualOverflowRect()
630                : BorderBoxRect();
631   }
PhysicalSelfVisualOverflowRect()632   PhysicalRect PhysicalSelfVisualOverflowRect() const {
633     NOT_DESTROYED();
634     return FlipForWritingMode(SelfVisualOverflowRect());
635   }
ContentsVisualOverflowRect()636   LayoutRect ContentsVisualOverflowRect() const {
637     NOT_DESTROYED();
638     return VisualOverflowIsSet()
639                ? overflow_->visual_overflow->ContentsVisualOverflowRect()
640                : LayoutRect();
641   }
PhysicalContentsVisualOverflowRect()642   PhysicalRect PhysicalContentsVisualOverflowRect() const {
643     NOT_DESTROYED();
644     return FlipForWritingMode(ContentsVisualOverflowRect());
645   }
646 
647   // Returns the visual overflow rect, expanded to the area affected by any
648   // filters that paint outside of the box, in physical coordinates.
649   PhysicalRect PhysicalVisualOverflowRectIncludingFilters() const;
650 
651   // These methods don't mean the box *actually* has top/left overflow. They
652   // mean that *if* the box overflows, it will overflow to the top/left rather
653   // than the bottom/right. This happens when child content is laid out
654   // right-to-left (e.g. direction:rtl) or or bottom-to-top (e.g. direction:rtl
655   // writing-mode:vertical-rl).
656   virtual bool HasTopOverflow() const;
657   virtual bool HasLeftOverflow() const;
658 
659   // Sets the layout-overflow from the current set of layout-results.
660   void SetLayoutOverflowFromLayoutResults();
661 
662   void AddLayoutOverflow(const LayoutRect&);
AddSelfVisualOverflow(const PhysicalRect & r)663   void AddSelfVisualOverflow(const PhysicalRect& r) {
664     NOT_DESTROYED();
665     AddSelfVisualOverflow(FlipForWritingMode(r));
666   }
667   void AddSelfVisualOverflow(const LayoutRect&);
AddContentsVisualOverflow(const PhysicalRect & r)668   void AddContentsVisualOverflow(const PhysicalRect& r) {
669     NOT_DESTROYED();
670     AddContentsVisualOverflow(FlipForWritingMode(r));
671   }
672   void AddContentsVisualOverflow(const LayoutRect&);
673 
674   virtual void AddVisualEffectOverflow();
675   LayoutRectOutsets ComputeVisualEffectOverflowOutsets();
AddVisualOverflowFromChild(const LayoutBox & child)676   void AddVisualOverflowFromChild(const LayoutBox& child) {
677     NOT_DESTROYED();
678     AddVisualOverflowFromChild(child, child.LocationOffset());
679   }
AddLayoutOverflowFromChild(const LayoutBox & child)680   void AddLayoutOverflowFromChild(const LayoutBox& child) {
681     NOT_DESTROYED();
682     AddLayoutOverflowFromChild(child, child.LocationOffset());
683   }
684   void AddVisualOverflowFromChild(const LayoutBox& child,
685                                   const LayoutSize& delta);
686   void AddLayoutOverflowFromChild(const LayoutBox& child,
687                                   const LayoutSize& delta);
688   void SetLayoutClientAfterEdge(LayoutUnit client_after_edge);
689   LayoutUnit LayoutClientAfterEdge() const;
690 
691   void ClearLayoutOverflow();
692   void ClearVisualOverflow();
693 
694   virtual void UpdateAfterLayout();
695 
ContentLeft()696   DISABLE_CFI_PERF LayoutUnit ContentLeft() const {
697     NOT_DESTROYED();
698     return ClientLeft() + PaddingLeft();
699   }
ContentTop()700   DISABLE_CFI_PERF LayoutUnit ContentTop() const {
701     NOT_DESTROYED();
702     return ClientTop() + PaddingTop();
703   }
ContentWidth()704   DISABLE_CFI_PERF LayoutUnit ContentWidth() const {
705     NOT_DESTROYED();
706     // We're dealing with LayoutUnit and saturated arithmetic here, so we need
707     // to guard against negative results. The value returned from clientWidth()
708     // may in itself be a victim of saturated arithmetic; e.g. if both border
709     // sides were sufficiently wide (close to LayoutUnit::max()).  Here we
710     // subtract two padding values from that result, which is another source of
711     // saturated arithmetic.
712     return (ClientWidth() - PaddingLeft() - PaddingRight())
713         .ClampNegativeToZero();
714   }
ContentHeight()715   DISABLE_CFI_PERF LayoutUnit ContentHeight() const {
716     NOT_DESTROYED();
717     // We're dealing with LayoutUnit and saturated arithmetic here, so we need
718     // to guard against negative results. The value returned from clientHeight()
719     // may in itself be a victim of saturated arithmetic; e.g. if both border
720     // sides were sufficiently wide (close to LayoutUnit::max()).  Here we
721     // subtract two padding values from that result, which is another source of
722     // saturated arithmetic.
723     return (ClientHeight() - PaddingTop() - PaddingBottom())
724         .ClampNegativeToZero();
725   }
ContentSize()726   LayoutSize ContentSize() const {
727     NOT_DESTROYED();
728     return LayoutSize(ContentWidth(), ContentHeight());
729   }
ContentLogicalWidth()730   LayoutUnit ContentLogicalWidth() const {
731     NOT_DESTROYED();
732     return StyleRef().IsHorizontalWritingMode() ? ContentWidth()
733                                                 : ContentHeight();
734   }
ContentLogicalHeight()735   LayoutUnit ContentLogicalHeight() const {
736     NOT_DESTROYED();
737     return StyleRef().IsHorizontalWritingMode() ? ContentHeight()
738                                                 : ContentWidth();
739   }
740 
741   // CSS intrinsic sizing getters.
742   // https://drafts.csswg.org/css-sizing-4/#intrinsic-size-override
743   // Physical:
744   bool HasOverrideIntrinsicContentWidth() const;
745   bool HasOverrideIntrinsicContentHeight() const;
746   LayoutUnit OverrideIntrinsicContentWidth() const;
747   LayoutUnit OverrideIntrinsicContentHeight() const;
748   // Logical:
HasOverrideIntrinsicContentLogicalWidth()749   bool HasOverrideIntrinsicContentLogicalWidth() const {
750     NOT_DESTROYED();
751     return StyleRef().IsHorizontalWritingMode()
752                ? HasOverrideIntrinsicContentWidth()
753                : HasOverrideIntrinsicContentHeight();
754   }
HasOverrideIntrinsicContentLogicalHeight()755   bool HasOverrideIntrinsicContentLogicalHeight() const {
756     NOT_DESTROYED();
757     return StyleRef().IsHorizontalWritingMode()
758                ? HasOverrideIntrinsicContentHeight()
759                : HasOverrideIntrinsicContentWidth();
760   }
OverrideIntrinsicContentLogicalWidth()761   LayoutUnit OverrideIntrinsicContentLogicalWidth() const {
762     NOT_DESTROYED();
763     return StyleRef().IsHorizontalWritingMode()
764                ? OverrideIntrinsicContentWidth()
765                : OverrideIntrinsicContentHeight();
766   }
OverrideIntrinsicContentLogicalHeight()767   LayoutUnit OverrideIntrinsicContentLogicalHeight() const {
768     NOT_DESTROYED();
769     return StyleRef().IsHorizontalWritingMode()
770                ? OverrideIntrinsicContentHeight()
771                : OverrideIntrinsicContentWidth();
772   }
773 
774   // Returns element-native intrinsic size. Returns kIndefiniteSize if no such
775   // size.
776   LayoutUnit DefaultIntrinsicContentInlineSize() const;
777   LayoutUnit DefaultIntrinsicContentBlockSize() const;
778 
779   // IE extensions. Used to calculate offsetWidth/Height. Overridden by inlines
780   // (LayoutFlow) to return the remaining width on a given line (and the height
781   // of a single line).
OffsetWidth()782   LayoutUnit OffsetWidth() const final {
783     NOT_DESTROYED();
784     return frame_rect_.Width();
785   }
OffsetHeight()786   LayoutUnit OffsetHeight() const final {
787     NOT_DESTROYED();
788     return frame_rect_.Height();
789   }
790 
791   // TODO(crbug.com/962299): This is incorrect in some cases.
792   int PixelSnappedOffsetWidth(const Element*) const final;
793   int PixelSnappedOffsetHeight(const Element*) const final;
794 
UsesOverlayScrollbars()795   bool UsesOverlayScrollbars() const {
796     NOT_DESTROYED();
797     if (StyleRef().HasPseudoElementStyle(kPseudoIdScrollbar))
798       return false;
799     if (GetFrame()->GetPage()->GetScrollbarTheme().UsesOverlayScrollbars())
800       return true;
801     return false;
802   }
803 
804   // Clamps the left scrollbar size so it is not wider than the content box.
LogicalLeftScrollbarWidth()805   DISABLE_CFI_PERF LayoutUnit LogicalLeftScrollbarWidth() const {
806     NOT_DESTROYED();
807     if (CanSkipComputeScrollbars())
808       return LayoutUnit();
809     else if (StyleRef().IsHorizontalWritingMode())
810       return ComputeScrollbarsInternal(kClampToContentBox).left;
811     else
812       return ComputeScrollbarsInternal(kClampToContentBox).top;
813   }
LogicalTopScrollbarHeight()814   DISABLE_CFI_PERF LayoutUnit LogicalTopScrollbarHeight() const {
815     NOT_DESTROYED();
816     if (CanSkipComputeScrollbars())
817       return LayoutUnit();
818     else if (HasFlippedBlocksWritingMode())
819       return ComputeScrollbarsInternal(kClampToContentBox).right;
820     else
821       return ComputeScrollbarsInternal(kClampToContentBox).top;
822   }
823 
824   // Physical client rect (a.k.a. PhysicalPaddingBoxRect(), defined by
825   // ClientLeft, ClientTop, ClientWidth and ClientHeight) represents the
826   // interior of an object excluding borders and scrollbars.
827   // Clamps the left scrollbar size so it is not wider than the content box.
ClientLeft()828   DISABLE_CFI_PERF LayoutUnit ClientLeft() const {
829     NOT_DESTROYED();
830     if (CanSkipComputeScrollbars())
831       return BorderLeft();
832     else
833       return BorderLeft() + ComputeScrollbarsInternal(kClampToContentBox).left;
834   }
ClientTop()835   DISABLE_CFI_PERF LayoutUnit ClientTop() const {
836     NOT_DESTROYED();
837     if (CanSkipComputeScrollbars())
838       return BorderTop();
839     else
840       return BorderTop() + ComputeScrollbarsInternal(kClampToContentBox).top;
841   }
842   LayoutUnit ClientWidth() const;
843   LayoutUnit ClientHeight() const;
ClientLogicalWidth()844   DISABLE_CFI_PERF LayoutUnit ClientLogicalWidth() const {
845     NOT_DESTROYED();
846     return IsHorizontalWritingMode() ? ClientWidth() : ClientHeight();
847   }
ClientLogicalHeight()848   DISABLE_CFI_PERF LayoutUnit ClientLogicalHeight() const {
849     NOT_DESTROYED();
850     return IsHorizontalWritingMode() ? ClientHeight() : ClientWidth();
851   }
ClientLogicalBottom()852   DISABLE_CFI_PERF LayoutUnit ClientLogicalBottom() const {
853     NOT_DESTROYED();
854     return BorderBefore() + LogicalTopScrollbarHeight() + ClientLogicalHeight();
855   }
856 
857   // TODO(crbug.com/962299): This is incorrect in some cases.
858   int PixelSnappedClientWidth() const;
859   int PixelSnappedClientHeight() const;
860   int PixelSnappedClientWidthWithTableSpecialBehavior() const;
861   int PixelSnappedClientHeightWithTableSpecialBehavior() const;
862 
863   // scrollWidth/scrollHeight will be the same as clientWidth/clientHeight
864   // unless the object has overflow:hidden/scroll/auto specified and also has
865   // overflow. These methods are virtual so that objects like textareas can
866   // scroll shadow content (but pretend that they are the objects that are
867   // scrolling).
868 
869   // Replaced ScrollLeft/Top by using Element::GetLayoutBoxForScrolling to
870   // return the correct ScrollableArea.
871   // TODO(cathiechen): We should do the same with ScrollWidth|Height .
872   virtual LayoutUnit ScrollWidth() const;
873   virtual LayoutUnit ScrollHeight() const;
874   // TODO(crbug.com/962299): This is incorrect in some cases.
875   int PixelSnappedScrollWidth() const;
876   int PixelSnappedScrollHeight() const;
877 
878   void ScrollByRecursively(const ScrollOffset& delta);
879   // If makeVisibleInVisualViewport is set, the visual viewport will be scrolled
880   // if required to make the rect visible.
881   PhysicalRect ScrollRectToVisibleRecursive(
882       const PhysicalRect&,
883       mojom::blink::ScrollIntoViewParamsPtr);
884 
MarginBoxOutsets()885   LayoutRectOutsets MarginBoxOutsets() const {
886     NOT_DESTROYED();
887     return margin_box_outsets_;
888   }
MarginTop()889   LayoutUnit MarginTop() const override {
890     NOT_DESTROYED();
891     return margin_box_outsets_.Top();
892   }
MarginBottom()893   LayoutUnit MarginBottom() const override {
894     NOT_DESTROYED();
895     return margin_box_outsets_.Bottom();
896   }
MarginLeft()897   LayoutUnit MarginLeft() const override {
898     NOT_DESTROYED();
899     return margin_box_outsets_.Left();
900   }
MarginRight()901   LayoutUnit MarginRight() const override {
902     NOT_DESTROYED();
903     return margin_box_outsets_.Right();
904   }
905   void SetMargin(const NGPhysicalBoxStrut&);
SetMarginTop(LayoutUnit margin)906   void SetMarginTop(LayoutUnit margin) {
907     NOT_DESTROYED();
908     margin_box_outsets_.SetTop(margin);
909   }
SetMarginBottom(LayoutUnit margin)910   void SetMarginBottom(LayoutUnit margin) {
911     NOT_DESTROYED();
912     margin_box_outsets_.SetBottom(margin);
913   }
SetMarginLeft(LayoutUnit margin)914   void SetMarginLeft(LayoutUnit margin) {
915     NOT_DESTROYED();
916     margin_box_outsets_.SetLeft(margin);
917   }
SetMarginRight(LayoutUnit margin)918   void SetMarginRight(LayoutUnit margin) {
919     NOT_DESTROYED();
920     margin_box_outsets_.SetRight(margin);
921   }
922 
923   void SetMarginBefore(LayoutUnit value,
924                        const ComputedStyle* override_style = nullptr) {
925     NOT_DESTROYED();
926     LogicalMarginToPhysicalSetter(override_style).SetBefore(value);
927   }
928   void SetMarginAfter(LayoutUnit value,
929                       const ComputedStyle* override_style = nullptr) {
930     NOT_DESTROYED();
931     LogicalMarginToPhysicalSetter(override_style).SetAfter(value);
932   }
933   void SetMarginStart(LayoutUnit value,
934                       const ComputedStyle* override_style = nullptr) {
935     NOT_DESTROYED();
936     LogicalMarginToPhysicalSetter(override_style).SetStart(value);
937   }
938   void SetMarginEnd(LayoutUnit value,
939                     const ComputedStyle* override_style = nullptr) {
940     NOT_DESTROYED();
941     LogicalMarginToPhysicalSetter(override_style).SetEnd(value);
942   }
943 
944   // The following functions are used to implement collapsing margins.
945   // All objects know their maximal positive and negative margins. The formula
946   // for computing a collapsed margin is |maxPosMargin| - |maxNegmargin|.
947   // For a non-collapsing box, such as a leaf element, this formula will simply
948   // return the margin of the element.  Blocks override the maxMarginBefore and
949   // maxMarginAfter methods.
IsSelfCollapsingBlock()950   virtual bool IsSelfCollapsingBlock() const {
951     NOT_DESTROYED();
952     return false;
953   }
CollapsedMarginBefore()954   virtual LayoutUnit CollapsedMarginBefore() const {
955     NOT_DESTROYED();
956     return MarginBefore();
957   }
CollapsedMarginAfter()958   virtual LayoutUnit CollapsedMarginAfter() const {
959     NOT_DESTROYED();
960     return MarginAfter();
961   }
CollapsedMarginBoxLogicalOutsets()962   LayoutRectOutsets CollapsedMarginBoxLogicalOutsets() const {
963     NOT_DESTROYED();
964     return LayoutRectOutsets(CollapsedMarginBefore(), LayoutUnit(),
965                              CollapsedMarginAfter(), LayoutUnit());
966   }
967 
968   void AbsoluteQuads(Vector<FloatQuad>&,
969                      MapCoordinatesFlags mode = 0) const override;
970   FloatRect LocalBoundingBoxRectForAccessibility() const final;
971 
SetBoxLayoutExtraInput(const BoxLayoutExtraInput * input)972   void SetBoxLayoutExtraInput(const BoxLayoutExtraInput* input) {
973     NOT_DESTROYED();
974     extra_input_ = input;
975   }
GetBoxLayoutExtraInput()976   const BoxLayoutExtraInput* GetBoxLayoutExtraInput() const {
977     NOT_DESTROYED();
978     return extra_input_;
979   }
980 
981   void LayoutSubtreeRoot();
982 
983   void UpdateLayout() override;
984   void Paint(const PaintInfo&) const override;
985 
IsInSelfHitTestingPhase(HitTestAction hit_test_action)986   virtual bool IsInSelfHitTestingPhase(HitTestAction hit_test_action) const {
987     NOT_DESTROYED();
988     return hit_test_action == kHitTestForeground;
989   }
990 
991   bool HitTestAllPhases(HitTestResult&,
992                         const HitTestLocation&,
993                         const PhysicalOffset& accumulated_offset,
994                         HitTestFilter = kHitTestAll) final;
995   bool NodeAtPoint(HitTestResult&,
996                    const HitTestLocation&,
997                    const PhysicalOffset& accumulated_offset,
998                    HitTestAction) override;
999   // Fast check if |NodeAtPoint| may find a hit.
1000   bool MayIntersect(const HitTestResult& result,
1001                     const HitTestLocation& hit_test_location,
1002                     const PhysicalOffset& accumulated_offset) const;
1003 
1004   // This function calculates the preferred widths for an object.
1005   //
1006   // See INTRINSIC SIZES / PREFERRED LOGICAL WIDTHS in layout_object.h for more
1007   // details about those widths.
1008   MinMaxSizes PreferredLogicalWidths() const override;
1009 
1010   LayoutUnit OverrideLogicalHeight() const;
1011   LayoutUnit OverrideLogicalWidth() const;
1012   bool IsOverrideLogicalHeightDefinite() const;
1013   bool HasOverrideLogicalHeight() const;
1014   bool HasOverrideLogicalWidth() const;
1015   void SetOverrideLogicalHeight(LayoutUnit);
1016   void SetOverrideLogicalWidth(LayoutUnit);
1017   void ClearOverrideLogicalHeight();
1018   void ClearOverrideLogicalWidth();
1019   void ClearOverrideSize();
1020 
1021   LayoutUnit OverrideContentLogicalWidth() const;
1022   LayoutUnit OverrideContentLogicalHeight() const;
1023 
1024   LayoutUnit OverrideContainingBlockContentWidth() const override;
1025   LayoutUnit OverrideContainingBlockContentHeight() const override;
1026   bool HasOverrideContainingBlockContentWidth() const override;
1027   bool HasOverrideContainingBlockContentHeight() const override;
1028   LayoutUnit OverrideContainingBlockContentLogicalWidth() const;
1029   LayoutUnit OverrideContainingBlockContentLogicalHeight() const;
1030   bool HasOverrideContainingBlockContentLogicalWidth() const;
1031   bool HasOverrideContainingBlockContentLogicalHeight() const;
1032   void SetOverrideContainingBlockContentLogicalWidth(LayoutUnit);
1033   void SetOverrideContainingBlockContentLogicalHeight(LayoutUnit);
1034   void ClearOverrideContainingBlockContentSize();
1035 
1036   // When a percentage resolution block size override has been set, we'll use
1037   // that size to resolve block-size percentages on this box, rather than
1038   // deducing it from the containing block.
1039   LayoutUnit OverridePercentageResolutionBlockSize() const;
1040   bool HasOverridePercentageResolutionBlockSize() const;
1041   void SetOverridePercentageResolutionBlockSize(LayoutUnit);
1042   void ClearOverridePercentageResolutionBlockSize();
1043 
1044   // When an available inline size override has been set, we'll use that to fill
1045   // available inline size, rather than deducing it from the containing block
1046   // (and then subtract space taken up by adjacent floats).
1047   LayoutUnit OverrideAvailableInlineSize() const;
HasOverrideAvailableInlineSize()1048   bool HasOverrideAvailableInlineSize() const {
1049     NOT_DESTROYED();
1050     return extra_input_;
1051   }
1052 
1053   LayoutUnit AdjustBorderBoxLogicalWidthForBoxSizing(float width) const;
1054   LayoutUnit AdjustBorderBoxLogicalHeightForBoxSizing(float height) const;
1055   LayoutUnit AdjustContentBoxLogicalWidthForBoxSizing(float width) const;
1056   LayoutUnit AdjustContentBoxLogicalHeightForBoxSizing(float height) const;
1057 
1058   // ComputedMarginValues holds the actual values for margins. It ignores
1059   // margin collapsing as they are handled in LayoutBlockFlow.
1060   // The margins are stored in logical coordinates (see COORDINATE
1061   // SYSTEMS in LayoutBoxModel) for use during layout.
1062   struct ComputedMarginValues {
1063     DISALLOW_NEW();
1064     ComputedMarginValues() = default;
1065 
1066     LayoutUnit before_;
1067     LayoutUnit after_;
1068     LayoutUnit start_;
1069     LayoutUnit end_;
1070   };
1071 
1072   // LogicalExtentComputedValues is used both for the
1073   // block-flow and inline-direction axis.
1074   struct LogicalExtentComputedValues {
1075     STACK_ALLOCATED();
1076 
1077    public:
1078     LogicalExtentComputedValues() = default;
1079 
CopyExceptBlockMarginsLogicalExtentComputedValues1080     void CopyExceptBlockMargins(LogicalExtentComputedValues* out) const {
1081       out->extent_ = extent_;
1082       out->position_ = position_;
1083       out->margins_.start_ = margins_.start_;
1084       out->margins_.end_ = margins_.end_;
1085     }
1086 
1087     // This is the dimension in the measured direction
1088     // (logical height or logical width).
1089     LayoutUnit extent_;
1090 
1091     // This is the offset in the measured direction
1092     // (logical top or logical left).
1093     LayoutUnit position_;
1094 
1095     // |margins_| represents the margins in the measured direction.
1096     // Note that ComputedMarginValues has also the margins in
1097     // the orthogonal direction to have clearer names but they are
1098     // ignored in the code.
1099     ComputedMarginValues margins_;
1100   };
1101 
1102   // Resolve auto margins in the chosen direction of the containing block so
1103   // that objects can be pushed to the start, middle or end of the containing
1104   // block.
1105   void ComputeMarginsForDirection(MarginDirection for_direction,
1106                                   const LayoutBlock* containing_block,
1107                                   LayoutUnit container_width,
1108                                   LayoutUnit child_width,
1109                                   LayoutUnit& margin_start,
1110                                   LayoutUnit& margin_end,
1111                                   Length margin_start_length,
1112                                   Length margin_start_end) const;
1113 
1114   // Used to resolve margins in the containing block's block-flow direction.
1115   void ComputeAndSetBlockDirectionMargins(const LayoutBlock* containing_block);
1116 
1117   LayoutUnit OffsetFromLogicalTopOfFirstPage() const;
1118 
1119   // The block offset from the logical top of this object to the end of the
1120   // first fragmentainer it lives in. If it only lives in one fragmentainer, 0
1121   // is returned.
OffsetToNextPage()1122   LayoutUnit OffsetToNextPage() const {
1123     NOT_DESTROYED();
1124     return rare_data_ ? rare_data_->offset_to_next_page_ : LayoutUnit();
1125   }
1126   void SetOffsetToNextPage(LayoutUnit);
1127 
1128   // Specify which page or column to associate with an offset, if said offset is
1129   // exactly at a page or column boundary.
1130   enum PageBoundaryRule { kAssociateWithFormerPage, kAssociateWithLatterPage };
1131   LayoutUnit PageLogicalHeightForOffset(LayoutUnit) const;
1132   bool IsPageLogicalHeightKnown() const;
1133   LayoutUnit PageRemainingLogicalHeightForOffset(LayoutUnit,
1134                                                  PageBoundaryRule) const;
1135 
1136   int CurrentPageNumber(LayoutUnit child_logical_top) const;
1137 
1138   bool CrossesPageBoundary(LayoutUnit offset, LayoutUnit logical_height) const;
1139 
1140   // Calculate the strut to insert in order fit content of size
1141   // |content_logical_height|. Usually this will merely return the distance to
1142   // the next fragmentainer. However, in cases where the next fragmentainer
1143   // isn't tall enough to fit the content, and there's a likelihood of taller
1144   // fragmentainers further ahead, we'll search for one and return the distance
1145   // to the first fragmentainer that can fit this piece of content.
1146   LayoutUnit CalculatePaginationStrutToFitContent(
1147       LayoutUnit offset,
1148       LayoutUnit content_logical_height) const;
1149 
1150   void PositionLineBox(InlineBox*);
1151   void MoveWithEdgeOfInlineContainerIfNecessary(bool is_horizontal);
1152 
1153   virtual InlineBox* CreateInlineBox();
1154   void DirtyLineBoxes(bool full_layout);
1155 
1156   // For atomic inline elements, this function returns the inline box that
1157   // contains us. Enables the atomic inline LayoutObject to quickly determine
1158   // what line it is contained on and to easily iterate over structures on the
1159   // line.
1160   //
1161   // InlineBoxWrapper() and FirstInlineFragment() are mutually exclusive,
1162   // depends on IsInLayoutNGInlineFormattingContext().
1163   InlineBox* InlineBoxWrapper() const;
1164   void SetInlineBoxWrapper(InlineBox*);
1165   void DeleteLineBoxWrapper();
1166 
1167   bool HasInlineFragments() const final;
1168   NGPaintFragment* FirstInlineFragment() const final;
1169   void SetFirstInlineFragment(NGPaintFragment*) final;
1170   wtf_size_t FirstInlineFragmentItemIndex() const final;
1171   void ClearFirstInlineFragmentItemIndex() final;
1172   void SetFirstInlineFragmentItemIndex(wtf_size_t) final;
1173 
1174   void InvalidateItems(const NGLayoutResult&);
1175 
1176   void SetCachedLayoutResult(scoped_refptr<const NGLayoutResult>);
1177 
1178   // Store one layout result (with its physical fragment) at the specified
1179   // index, and delete all entries following it.
1180   void AddLayoutResult(scoped_refptr<const NGLayoutResult>, wtf_size_t index);
1181   void ReplaceLayoutResult(scoped_refptr<const NGLayoutResult>,
1182                            wtf_size_t index);
1183 
1184   void ShrinkLayoutResults(wtf_size_t results_to_keep);
1185   void ClearLayoutResults();
1186 
1187   const NGLayoutResult* GetCachedLayoutResult() const;
1188   const NGLayoutResult* GetCachedMeasureResult() const;
1189 
1190   // Returns the last layout result for this block flow with the given
1191   // constraint space and break token, or null if it is not up-to-date or
1192   // otherwise unavailable.
1193   //
1194   // This method (while determining if the layout result can be reused), *may*
1195   // calculate the |initial_fragment_geometry| of the node.
1196   //
1197   // |out_cache_status| indicates what type of layout pass is required.
1198   //
1199   // TODO(ikilpatrick): Move this function into NGBlockNode.
1200   scoped_refptr<const NGLayoutResult> CachedLayoutResult(
1201       const NGConstraintSpace&,
1202       const NGBreakToken*,
1203       const NGEarlyBreak*,
1204       base::Optional<NGFragmentGeometry>* initial_fragment_geometry,
1205       NGLayoutCacheStatus* out_cache_status);
1206 
1207   using NGLayoutResultList = Vector<scoped_refptr<const NGLayoutResult>, 1>;
1208   class NGPhysicalFragmentList {
1209     STACK_ALLOCATED();
1210 
1211    public:
NGPhysicalFragmentList(const NGLayoutResultList & layout_results)1212     explicit NGPhysicalFragmentList(const NGLayoutResultList& layout_results)
1213         : layout_results_(layout_results) {}
1214 
Size()1215     wtf_size_t Size() const { return layout_results_.size(); }
IsEmpty()1216     bool IsEmpty() const { return layout_results_.IsEmpty(); }
1217 
1218     bool HasFragmentItems() const;
1219 
1220     class CORE_EXPORT Iterator : public std::iterator<std::forward_iterator_tag,
1221                                                       NGPhysicalBoxFragment> {
1222      public:
Iterator(const NGLayoutResultList::const_iterator & iterator)1223       explicit Iterator(const NGLayoutResultList::const_iterator& iterator)
1224           : iterator_(iterator) {}
1225 
1226       const NGPhysicalBoxFragment& operator*() const;
1227 
1228       void operator++() { ++iterator_; }
1229 
1230       bool operator==(const Iterator& other) const {
1231         return iterator_ == other.iterator_;
1232       }
1233       bool operator!=(const Iterator& other) const {
1234         return !operator==(other);
1235       }
1236 
1237      private:
1238       NGLayoutResultList::const_iterator iterator_;
1239     };
1240 
begin()1241     Iterator begin() const { return Iterator(layout_results_.begin()); }
end()1242     Iterator end() const { return Iterator(layout_results_.end()); }
1243 
1244    private:
1245     const NGLayoutResultList& layout_results_;
1246   };
1247 
PhysicalFragments()1248   NGPhysicalFragmentList PhysicalFragments() const {
1249     NOT_DESTROYED();
1250     return NGPhysicalFragmentList(layout_results_);
1251   }
1252   const NGPhysicalBoxFragment* GetPhysicalFragment(wtf_size_t i) const;
1253   const FragmentData* FragmentDataFromPhysicalFragment(
1254       const NGPhysicalBoxFragment&) const;
PhysicalFragmentCount()1255   wtf_size_t PhysicalFragmentCount() const {
1256     NOT_DESTROYED();
1257     return layout_results_.size();
1258   }
1259 
1260   void SetSpannerPlaceholder(LayoutMultiColumnSpannerPlaceholder&);
1261   void ClearSpannerPlaceholder();
SpannerPlaceholder()1262   LayoutMultiColumnSpannerPlaceholder* SpannerPlaceholder() const final {
1263     NOT_DESTROYED();
1264     return rare_data_ ? rare_data_->spanner_placeholder_ : nullptr;
1265   }
1266 
1267   // A pagination strut is the amount of space needed to push an in-flow block-
1268   // level object (or float) to the logical top of the next page or column. It
1269   // will be set both for forced breaks (e.g. page-break-before:always) and soft
1270   // breaks (when there's not enough space in the current page / column for the
1271   // object). The strut is baked into the logicalTop() of the object, so that
1272   // logicalTop() - paginationStrut() == the original position in the previous
1273   // column before deciding to break.
1274   //
1275   // Pagination struts are either set in front of a block-level box (here) or
1276   // before a line (RootInlineBox::paginationStrut()).
PaginationStrut()1277   LayoutUnit PaginationStrut() const {
1278     NOT_DESTROYED();
1279     return rare_data_ ? rare_data_->pagination_strut_ : LayoutUnit();
1280   }
1281   void SetPaginationStrut(LayoutUnit);
ResetPaginationStrut()1282   void ResetPaginationStrut() {
1283     NOT_DESTROYED();
1284     if (rare_data_)
1285       rare_data_->pagination_strut_ = LayoutUnit();
1286   }
1287 
1288   // Is the specified break-before or break-after value supported on this
1289   // object? It needs to be in-flow all the way up to a fragmentation context
1290   // that supports the specified value.
1291   bool IsBreakBetweenControllable(EBreakBetween) const;
1292 
1293   // Is the specified break-inside value supported on this object? It needs to
1294   // be contained by a fragmentation context that supports the specified value.
1295   bool IsBreakInsideControllable(EBreakInside) const;
1296 
1297   virtual EBreakBetween BreakAfter() const;
1298   virtual EBreakBetween BreakBefore() const;
1299   EBreakInside BreakInside() const;
1300 
1301   static bool IsForcedFragmentainerBreakValue(EBreakBetween);
1302 
1303   EBreakBetween ClassABreakPointValue(
1304       EBreakBetween previous_break_after_value) const;
1305 
1306   // Return true if we should insert a break in front of this box. The box needs
1307   // to start at a valid class A break point in order to allow a forced break.
1308   // To determine whether or not to break, we also need to know the break-after
1309   // value of the previous in-flow sibling.
1310   bool NeedsForcedBreakBefore(EBreakBetween previous_break_after_value) const;
1311 
1312   // Get the name of the start page name for this object; see
1313   // https://drafts.csswg.org/css-page-3/#start-page-value
1314   virtual const AtomicString StartPageName() const;
1315 
1316   // Get the name of the end page name for this object; see
1317   // https://drafts.csswg.org/css-page-3/#end-page-value
1318   virtual const AtomicString EndPageName() const;
1319 
1320   bool MapToVisualRectInAncestorSpaceInternal(
1321       const LayoutBoxModelObject* ancestor,
1322       TransformState&,
1323       VisualRectFlags = kDefaultVisualRectFlags) const override;
1324 
1325   LayoutUnit ContainingBlockLogicalHeightForGetComputedStyle() const;
1326 
1327   LayoutUnit ContainingBlockLogicalWidthForContent() const override;
1328   LayoutUnit ContainingBlockLogicalHeightForContent(
1329       AvailableLogicalHeightType) const;
1330 
1331   LayoutUnit ContainingBlockAvailableLineWidth() const;
1332   LayoutUnit PerpendicularContainingBlockLogicalHeight() const;
1333 
1334   virtual void UpdateLogicalWidth();
1335   void UpdateLogicalHeight();
1336   void ComputeLogicalHeight(LogicalExtentComputedValues&) const;
1337   virtual void ComputeLogicalHeight(LayoutUnit logical_height,
1338                                     LayoutUnit logical_top,
1339                                     LogicalExtentComputedValues&) const;
1340   // This function will compute the logical border-box height, without laying
1341   // out the box. This means that the result is only "correct" when the height
1342   // is explicitly specified. This function exists so that intrinsic width
1343   // calculations have a way to deal with children that have orthogonal flows.
1344   // When there is no explicit height, this function assumes a content height of
1345   // zero (and returns just border+padding).
1346   LayoutUnit ComputeLogicalHeightWithoutLayout() const;
1347 
1348   void ComputeLogicalWidth(LogicalExtentComputedValues&) const;
1349 
StretchesToViewport()1350   bool StretchesToViewport() const {
1351     NOT_DESTROYED();
1352     return GetDocument().InQuirksMode() && StretchesToViewportInQuirksMode();
1353   }
1354 
IntrinsicSize()1355   virtual LayoutSize IntrinsicSize() const {
1356     NOT_DESTROYED();
1357     return LayoutSize();
1358   }
IntrinsicLogicalWidth()1359   LayoutUnit IntrinsicLogicalWidth() const {
1360     NOT_DESTROYED();
1361     return StyleRef().IsHorizontalWritingMode() ? IntrinsicSize().Width()
1362                                                 : IntrinsicSize().Height();
1363   }
IntrinsicLogicalHeight()1364   LayoutUnit IntrinsicLogicalHeight() const {
1365     NOT_DESTROYED();
1366     return StyleRef().IsHorizontalWritingMode() ? IntrinsicSize().Height()
1367                                                 : IntrinsicSize().Width();
1368   }
IntrinsicContentLogicalHeight()1369   virtual LayoutUnit IntrinsicContentLogicalHeight() const {
1370     NOT_DESTROYED();
1371     return HasOverrideIntrinsicContentLogicalHeight()
1372                ? OverrideIntrinsicContentLogicalHeight()
1373                : intrinsic_content_logical_height_;
1374   }
1375 
1376   // Whether or not the element shrinks to its intrinsic width (rather than
1377   // filling the width of a containing block). HTML4 buttons, <select>s,
1378   // <input>s, legends, and floating/compact elements do this.
1379   bool SizesLogicalWidthToFitContent(const Length& logical_width) const;
1380 
1381   LayoutUnit ShrinkLogicalWidthToAvoidFloats(LayoutUnit child_margin_start,
1382                                              LayoutUnit child_margin_end,
1383                                              const LayoutBlockFlow* cb) const;
1384   bool AutoWidthShouldFitContent() const;
1385 
1386   LayoutUnit ComputeLogicalWidthUsing(
1387       SizeType,
1388       const Length& logical_width,
1389       LayoutUnit available_logical_width,
1390       const LayoutBlock* containing_block) const;
1391   LayoutUnit ComputeLogicalHeightUsing(
1392       SizeType,
1393       const Length& height,
1394       LayoutUnit intrinsic_content_height) const;
1395   LayoutUnit ComputeContentLogicalHeight(
1396       SizeType,
1397       const Length& height,
1398       LayoutUnit intrinsic_content_height) const;
1399   LayoutUnit ComputeContentAndScrollbarLogicalHeightUsing(
1400       SizeType,
1401       const Length& height,
1402       LayoutUnit intrinsic_content_height) const;
1403   LayoutUnit ComputeReplacedLogicalWidthUsing(SizeType,
1404                                               const Length& width) const;
1405   LayoutUnit ComputeReplacedLogicalWidthRespectingMinMaxWidth(
1406       LayoutUnit logical_width,
1407       ShouldComputePreferred = kComputeActual) const;
1408   LayoutUnit ComputeReplacedLogicalHeightUsing(SizeType,
1409                                                const Length& height) const;
1410   LayoutUnit ComputeReplacedLogicalHeightRespectingMinMaxHeight(
1411       LayoutUnit logical_height) const;
1412 
1413   virtual LayoutUnit ComputeReplacedLogicalWidth(
1414       ShouldComputePreferred = kComputeActual) const;
1415   virtual LayoutUnit ComputeReplacedLogicalHeight(
1416       LayoutUnit estimated_used_width = LayoutUnit()) const;
1417 
ShouldComputeSizeAsReplaced()1418   virtual bool ShouldComputeSizeAsReplaced() const {
1419     NOT_DESTROYED();
1420     return IsAtomicInlineLevel() && !IsInlineBlockOrInlineTable();
1421   }
1422 
1423   // Returns the size that percentage logical heights of this box should be
1424   // resolved against. This function will walk the ancestor chain of this
1425   // object to determine this size.
1426   //  - out_cb returns the LayoutBlock which provided the size.
1427   //  - out_skipped_auto_height_containing_block returns if any auto height
1428   //    blocks were skipped to obtain out_cb.
1429   LayoutUnit ContainingBlockLogicalHeightForPercentageResolution(
1430       LayoutBlock** out_cb = nullptr,
1431       bool* out_skipped_auto_height_containing_block = nullptr) const;
1432 
1433   bool PercentageLogicalHeightIsResolvable() const;
1434   LayoutUnit ComputePercentageLogicalHeight(const Length& height) const;
1435 
1436   // Block flows subclass availableWidth/Height to handle multi column layout
1437   // (shrinking the width/height available to children when laying out.)
AvailableLogicalWidth()1438   LayoutUnit AvailableLogicalWidth() const {
1439     NOT_DESTROYED();
1440     return ContentLogicalWidth();
1441   }
1442   LayoutUnit AvailableLogicalHeight(AvailableLogicalHeightType) const;
1443   LayoutUnit AvailableLogicalHeightUsing(const Length&,
1444                                          AvailableLogicalHeightType) const;
1445 
1446   // There are a few cases where we need to refer specifically to the available
1447   // physical width and available physical height. Relative positioning is one
1448   // of those cases, since left/top offsets are physical.
AvailableWidth()1449   LayoutUnit AvailableWidth() const {
1450     NOT_DESTROYED();
1451     return StyleRef().IsHorizontalWritingMode()
1452                ? AvailableLogicalWidth()
1453                : AvailableLogicalHeight(kIncludeMarginBorderPadding);
1454   }
AvailableHeight()1455   LayoutUnit AvailableHeight() const {
1456     NOT_DESTROYED();
1457     return StyleRef().IsHorizontalWritingMode()
1458                ? AvailableLogicalHeight(kIncludeMarginBorderPadding)
1459                : AvailableLogicalWidth();
1460   }
1461 
1462   // Return both scrollbars and scrollbar gutters (defined by scrollbar-gutter).
ComputeScrollbars()1463   inline NGPhysicalBoxStrut ComputeScrollbars() const {
1464     NOT_DESTROYED();
1465     if (CanSkipComputeScrollbars())
1466       return NGPhysicalBoxStrut();
1467     else
1468       return ComputeScrollbarsInternal();
1469   }
ComputeLogicalScrollbars()1470   inline NGBoxStrut ComputeLogicalScrollbars() const {
1471     NOT_DESTROYED();
1472     if (CanSkipComputeScrollbars()) {
1473       return NGBoxStrut();
1474     } else {
1475       return ComputeScrollbarsInternal().ConvertToLogical(
1476           StyleRef().GetWritingDirection());
1477     }
1478   }
1479 
1480   bool CanBeScrolledAndHasScrollableArea() const;
1481   virtual bool CanBeProgramaticallyScrolled() const;
1482   virtual void Autoscroll(const PhysicalOffset&);
1483   bool CanAutoscroll() const;
1484   PhysicalOffset CalculateAutoscrollDirection(
1485       const FloatPoint& point_in_root_frame) const;
1486   static LayoutBox* FindAutoscrollable(LayoutObject*,
1487                                        bool is_middle_click_autoscroll);
1488   static bool HasHorizontallyScrollableAncestor(LayoutObject*);
1489 
HasAutoVerticalScrollbar()1490   DISABLE_CFI_PERF bool HasAutoVerticalScrollbar() const {
1491     NOT_DESTROYED();
1492     return HasNonVisibleOverflow() && StyleRef().HasAutoVerticalScroll();
1493   }
HasAutoHorizontalScrollbar()1494   DISABLE_CFI_PERF bool HasAutoHorizontalScrollbar() const {
1495     NOT_DESTROYED();
1496     return HasNonVisibleOverflow() && StyleRef().HasAutoHorizontalScroll();
1497   }
ScrollsOverflow()1498   DISABLE_CFI_PERF bool ScrollsOverflow() const {
1499     NOT_DESTROYED();
1500     return HasNonVisibleOverflow() && StyleRef().ScrollsOverflow();
1501   }
1502   // We place block-direction scrollbar on the left only if the writing-mode
1503   // is horizontal, so ShouldPlaceVerticalScrollbarOnLeft() is the same as
1504   // ShouldPlaceBlockDirectionScrollbarOnLogicalLeft(). The two forms can be
1505   // used in different contexts, e.g. the former for physical coordinate
1506   // contexts, and the later for logical coordinate contexts.
ShouldPlaceVerticalScrollbarOnLeft()1507   bool ShouldPlaceVerticalScrollbarOnLeft() const {
1508     NOT_DESTROYED();
1509     return ShouldPlaceBlockDirectionScrollbarOnLogicalLeft();
1510   }
ShouldPlaceBlockDirectionScrollbarOnLogicalLeft()1511   virtual bool ShouldPlaceBlockDirectionScrollbarOnLogicalLeft() const {
1512     NOT_DESTROYED();
1513     return StyleRef().ShouldPlaceBlockDirectionScrollbarOnLogicalLeft();
1514   }
1515 
HasScrollableOverflowX()1516   bool HasScrollableOverflowX() const {
1517     NOT_DESTROYED();
1518     return ScrollsOverflowX() &&
1519            PixelSnappedScrollWidth() != PixelSnappedClientWidth();
1520   }
HasScrollableOverflowY()1521   bool HasScrollableOverflowY() const {
1522     NOT_DESTROYED();
1523     return ScrollsOverflowY() &&
1524            PixelSnappedScrollHeight() != PixelSnappedClientHeight();
1525   }
ScrollsOverflowX()1526   virtual bool ScrollsOverflowX() const {
1527     NOT_DESTROYED();
1528     return HasNonVisibleOverflow() && StyleRef().ScrollsOverflowX();
1529   }
ScrollsOverflowY()1530   virtual bool ScrollsOverflowY() const {
1531     NOT_DESTROYED();
1532     return HasNonVisibleOverflow() && StyleRef().ScrollsOverflowY();
1533   }
1534 
1535   // Elements such as the <input> field override this to specify that they are
1536   // scrollable outside the context of the CSS overflow style
IsIntrinsicallyScrollable(ScrollbarOrientation orientation)1537   virtual bool IsIntrinsicallyScrollable(
1538       ScrollbarOrientation orientation) const {
1539     NOT_DESTROYED();
1540     return false;
1541   }
1542 
1543   bool HasUnsplittableScrollingOverflow() const;
1544 
1545   // Page / column breakability inside block-level objects.
1546   enum PaginationBreakability {
1547     kAllowAnyBreaks,  // No restrictions on breaking. May examine children to
1548                       // find possible break points.
1549     kForbidBreaks,  // Forbid breaks inside this object. Content cannot be split
1550                     // nicely into smaller pieces.
1551     kAvoidBreaks  // Preferably avoid breaks. If not possible, examine children
1552                   // to find possible break points.
1553   };
1554   enum FragmentationEngine {
1555     kLegacyFragmentationEngine,
1556     kNGFragmentationEngine,
1557     kUnknownFragmentationEngine
1558   };
1559   // |is_ng_fragmentation| must be true if we're in an NG block fragmentation
1560   // context. We need to specify which engine we're using for fragmentation,
1561   // since anything being laid out by the other engine will need to be treated
1562   // as monolithic (kForbidBreaks), since the two engines cannot cooperate on
1563   // block fragmentation.
1564   virtual PaginationBreakability GetPaginationBreakability(
1565       FragmentationEngine) const;
GetLegacyPaginationBreakability()1566   PaginationBreakability GetLegacyPaginationBreakability() const {
1567     NOT_DESTROYED();
1568     return GetPaginationBreakability(kLegacyFragmentationEngine);
1569   }
GetNGPaginationBreakability()1570   PaginationBreakability GetNGPaginationBreakability() const {
1571     NOT_DESTROYED();
1572     return GetPaginationBreakability(kNGFragmentationEngine);
1573   }
1574 
1575   LayoutRect LocalCaretRect(
1576       const InlineBox*,
1577       int caret_offset,
1578       LayoutUnit* extra_width_to_end_of_line = nullptr) const override;
1579 
1580   // Returns the intersection of all overflow clips which apply.
1581   virtual PhysicalRect OverflowClipRect(
1582       const PhysicalOffset& location,
1583       OverlayScrollbarClipBehavior = kIgnoreOverlayScrollbarSize) const;
1584   PhysicalRect ClipRect(const PhysicalOffset& location) const;
1585 
1586   // This version is for legacy code that has not switched to the new physical
1587   // geometry yet.
1588   LayoutRect OverflowClipRect(const LayoutPoint& location,
1589                               OverlayScrollbarClipBehavior behavior =
1590                                   kIgnoreOverlayScrollbarSize) const {
1591     NOT_DESTROYED();
1592     return OverflowClipRect(PhysicalOffset(location), behavior).ToLayoutRect();
1593   }
1594 
1595   // Returns the combination of overflow clip, contain: paint clip and CSS clip
1596   // for this object.
1597   PhysicalRect ClippingRect(const PhysicalOffset& location) const;
1598 
1599   virtual void PaintBoxDecorationBackground(
1600       const PaintInfo&,
1601       const PhysicalOffset& paint_offset) const;
1602   virtual void PaintMask(const PaintInfo&,
1603                          const PhysicalOffset& paint_offset) const;
1604   void ImageChanged(WrappedImagePtr, CanDeferInvalidation) override;
1605   ResourcePriority ComputeResourcePriority() const final;
1606 
1607   void LogicalExtentAfterUpdatingLogicalWidth(const LayoutUnit& logical_top,
1608                                               LogicalExtentComputedValues&);
1609 
1610   PositionWithAffinity PositionForPoint(const PhysicalOffset&) const override;
1611 
1612   void RemoveFloatingOrPositionedChildFromBlockLists();
1613 
1614   PaintLayer* EnclosingFloatPaintingLayer() const;
1615 
1616   const LayoutBlock& EnclosingScrollportBox() const;
1617 
FirstLineBoxBaseline()1618   virtual LayoutUnit FirstLineBoxBaseline() const {
1619     NOT_DESTROYED();
1620     return LayoutUnit(-1);
1621   }
InlineBlockBaseline(LineDirectionMode)1622   virtual LayoutUnit InlineBlockBaseline(LineDirectionMode) const {
1623     NOT_DESTROYED();
1624     return LayoutUnit(-1);
1625   }  // Returns -1 if we should skip this box when computing the baseline of an
1626      // inline-block.
1627 
1628   bool ShrinkToAvoidFloats() const;
CreatesNewFormattingContext()1629   virtual bool CreatesNewFormattingContext() const {
1630     NOT_DESTROYED();
1631     return true;
1632   }
1633   bool ShouldBeConsideredAsReplaced() const;
1634 
1635   void UpdateFragmentationInfoForChild(LayoutBox&);
1636   bool ChildNeedsRelayoutForPagination(const LayoutBox&) const;
1637   void MarkChildForPaginationRelayoutIfNeeded(LayoutBox&, SubtreeLayoutScope&);
1638 
IsWritingModeRoot()1639   bool IsWritingModeRoot() const {
1640     NOT_DESTROYED();
1641     return !Parent() ||
1642            Parent()->StyleRef().GetWritingMode() != StyleRef().GetWritingMode();
1643   }
IsOrthogonalWritingModeRoot()1644   bool IsOrthogonalWritingModeRoot() const {
1645     NOT_DESTROYED();
1646     return Parent() &&
1647            Parent()->IsHorizontalWritingMode() != IsHorizontalWritingMode();
1648   }
1649   void MarkOrthogonalWritingModeRoot();
1650   void UnmarkOrthogonalWritingModeRoot();
1651 
1652   bool IsCustomItem() const;
1653   bool IsCustomItemShrinkToFit() const;
1654 
IsFlexItemIncludingDeprecatedAndNG()1655   bool IsFlexItemIncludingDeprecatedAndNG() const {
1656     NOT_DESTROYED();
1657     return IsFlexItemCommon() &&
1658            Parent()->IsFlexibleBoxIncludingDeprecatedAndNG();
1659   }
1660 
1661   // TODO(dgrogan): Replace the rest of the calls to IsFlexItem with
1662   // IsFlexItemIncludingNG when all the callsites can handle an item with an NG
1663   // parent.
IsFlexItem()1664   bool IsFlexItem() const {
1665     NOT_DESTROYED();
1666     return IsFlexItemCommon() && Parent()->IsFlexibleBox();
1667   }
IsFlexItemIncludingNG()1668   bool IsFlexItemIncludingNG() const {
1669     NOT_DESTROYED();
1670     return IsFlexItemCommon() && Parent()->IsFlexibleBoxIncludingNG();
1671   }
IsFlexItemCommon()1672   bool IsFlexItemCommon() const {
1673     NOT_DESTROYED();
1674     return !IsInline() && !IsOutOfFlowPositioned() && Parent();
1675   }
1676 
IsGridItemIncludingNG()1677   bool IsGridItemIncludingNG() const {
1678     NOT_DESTROYED();
1679     return IsGridItem() || (Parent() && Parent()->IsLayoutNGGrid());
1680   }
1681 
IsGridItem()1682   bool IsGridItem() const {
1683     NOT_DESTROYED();
1684     return Parent() && Parent()->IsLayoutGrid();
1685   }
1686 
IsMathItem()1687   bool IsMathItem() const {
1688     NOT_DESTROYED();
1689     return Parent() && Parent()->IsMathML();
1690   }
1691 
1692   LayoutUnit LineHeight(
1693       bool first_line,
1694       LineDirectionMode,
1695       LinePositionMode = kPositionOnContainingLine) const override;
1696   LayoutUnit BaselinePosition(
1697       FontBaseline,
1698       bool first_line,
1699       LineDirectionMode,
1700       LinePositionMode = kPositionOnContainingLine) const override;
1701 
1702   PhysicalOffset OffsetPoint(const Element* parent) const;
1703   LayoutUnit OffsetLeft(const Element*) const final;
1704   LayoutUnit OffsetTop(const Element*) const final;
1705 
1706   WARN_UNUSED_RESULT LayoutUnit
1707   FlipForWritingMode(LayoutUnit position,
1708                      LayoutUnit width = LayoutUnit()) const {
1709     NOT_DESTROYED();
1710     // The offset is in the block direction (y for horizontal writing modes, x
1711     // for vertical writing modes).
1712     if (LIKELY(!HasFlippedBlocksWritingMode()))
1713       return position;
1714     DCHECK(!IsHorizontalWritingMode());
1715     return frame_rect_.Width() - (position + width);
1716   }
1717   // Inherit other flipping methods from LayoutObject.
1718   using LayoutObject::FlipForWritingMode;
1719 
1720   WARN_UNUSED_RESULT LayoutPoint
DeprecatedFlipForWritingMode(const LayoutPoint & position)1721   DeprecatedFlipForWritingMode(const LayoutPoint& position) const {
1722     NOT_DESTROYED();
1723     return LayoutPoint(FlipForWritingMode(position.X()), position.Y());
1724   }
DeprecatedFlipForWritingMode(LayoutRect & rect)1725   void DeprecatedFlipForWritingMode(LayoutRect& rect) const {
1726     NOT_DESTROYED();
1727     if (LIKELY(!HasFlippedBlocksWritingMode()))
1728       return;
1729     rect = FlipForWritingMode(rect).ToLayoutRect();
1730   }
1731 
1732   // Passing |flipped_blocks_container| causes flipped-block flipping w.r.t.
1733   // that container, or LocationContainer() otherwise.
1734   PhysicalOffset PhysicalLocation(
1735       const LayoutBox* flipped_blocks_container = nullptr) const {
1736     NOT_DESTROYED();
1737     return PhysicalLocationInternal(flipped_blocks_container
1738                                         ? flipped_blocks_container
1739                                         : LocationContainer());
1740   }
1741 
1742   // Convert a local rect in this box's blocks direction into parent's blocks
1743   // direction, for parent to accumulate layout or visual overflow.
1744   LayoutRect RectForOverflowPropagation(const LayoutRect&) const;
1745 
1746   LayoutRect LogicalVisualOverflowRectForPropagation() const;
VisualOverflowRectForPropagation()1747   LayoutRect VisualOverflowRectForPropagation() const {
1748     NOT_DESTROYED();
1749     return RectForOverflowPropagation(VisualOverflowRect());
1750   }
1751   LayoutRect LogicalLayoutOverflowRectForPropagation(
1752       LayoutObject* container) const;
1753   LayoutRect LayoutOverflowRectForPropagation(LayoutObject* container) const;
1754 
HasSelfVisualOverflow()1755   bool HasSelfVisualOverflow() const {
1756     NOT_DESTROYED();
1757     return VisualOverflowIsSet() &&
1758            !BorderBoxRect().Contains(
1759                overflow_->visual_overflow->SelfVisualOverflowRect());
1760   }
1761 
HasVisualOverflow()1762   bool HasVisualOverflow() const {
1763     NOT_DESTROYED();
1764     return VisualOverflowIsSet();
1765   }
HasLayoutOverflow()1766   bool HasLayoutOverflow() const {
1767     NOT_DESTROYED();
1768     return LayoutOverflowIsSet();
1769   }
1770 
1771   // Return true if re-laying out the containing block of this object means that
1772   // we need to recalculate the preferred min/max logical widths of this object.
1773   //
1774   // Calculating min/max widths for an object should ideally only take itself
1775   // and its children as input. However, some objects don't adhere strictly to
1776   // this rule, and also take input from their containing block to figure out
1777   // their min/max widths. This is the case for e.g. shrink-to-fit containers
1778   // with percentage inline-axis padding. This isn't good practise, but that's
1779   // how it is and how it's going to stay, unless we want to undertake a
1780   // substantial maintenance task of the min/max preferred widths machinery.
1781   virtual bool NeedsPreferredWidthsRecalculation() const;
1782 
1783   // See README.md for an explanation of scroll origin.
1784   IntSize OriginAdjustmentForScrollbars() const;
1785   IntPoint ScrollOrigin() const;
1786   LayoutSize ScrolledContentOffset() const;
1787 
1788   // Scroll offset as snapped to physical pixels. This value should be used in
1789   // any values used after layout and inside "layout code" that cares about
1790   // where the content is displayed, rather than what the ideal offset is. For
1791   // most other cases ScrolledContentOffset is probably more appropriate. This
1792   // is the offset that's actually drawn to the screen.
1793   LayoutSize PixelSnappedScrolledContentOffset() const;
1794 
1795   // Maps from scrolling contents space to box space and apply overflow
1796   // clip if needed. Returns true if no clipping applied or the flattened quad
1797   // bounds actually intersects the clipping region. If edgeInclusive is true,
1798   // then this method may return true even if the resulting rect has zero area.
1799   //
1800   // When applying offsets and not clips, the TransformAccumulation is
1801   // respected. If there is a clip, the TransformState is flattened first.
1802   bool MapContentsRectToBoxSpace(
1803       TransformState&,
1804       TransformState::TransformAccumulation,
1805       const LayoutObject& contents,
1806       VisualRectFlags = kDefaultVisualRectFlags) const;
1807 
1808   // True if the contents scroll relative to this object. |this| must be a
1809   // containing block for |contents|.
1810   bool ContainedContentsScroll(const LayoutObject& contents) const;
1811 
1812   // Applies the box clip. This is like mapScrollingContentsRectToBoxSpace,
1813   // except it does not apply scroll.
1814   bool ApplyBoxClips(TransformState&,
1815                      TransformState::TransformAccumulation,
1816                      VisualRectFlags) const;
1817 
1818   // The optional |size| parameter is used if the size of the object isn't
1819   // correct yet.
1820   FloatPoint PerspectiveOrigin(const PhysicalSize* size = nullptr) const;
1821 
1822   // Maps the visual rect state |transform_state| from this box into its
1823   // container, applying adjustments for the given container offset,
1824   // scrolling, container clipping, and transform (including container
1825   // perspective).
1826   bool MapVisualRectToContainer(const LayoutObject* container_object,
1827                                 const PhysicalOffset& container_offset,
1828                                 const LayoutObject* ancestor,
1829                                 VisualRectFlags,
1830                                 TransformState&) const;
1831 
1832   bool HasRelativeLogicalWidth() const;
1833   bool HasRelativeLogicalHeight() const;
1834 
CreateAnonymousBoxWithSameTypeAs(const LayoutObject *)1835   virtual LayoutBox* CreateAnonymousBoxWithSameTypeAs(
1836       const LayoutObject*) const {
1837     NOT_DESTROYED();
1838     NOTREACHED();
1839     return nullptr;
1840   }
1841 
HasSameDirectionAs(const LayoutBox * object)1842   bool HasSameDirectionAs(const LayoutBox* object) const {
1843     NOT_DESTROYED();
1844     return StyleRef().Direction() == object->StyleRef().Direction();
1845   }
1846 
1847   ShapeOutsideInfo* GetShapeOutsideInfo() const;
1848 
MarkShapeOutsideDependentsForLayout()1849   void MarkShapeOutsideDependentsForLayout() {
1850     NOT_DESTROYED();
1851     if (IsFloating())
1852       RemoveFloatingOrPositionedChildFromBlockLists();
1853   }
1854 
SetIntrinsicContentLogicalHeight(LayoutUnit intrinsic_content_logical_height)1855   void SetIntrinsicContentLogicalHeight(
1856       LayoutUnit intrinsic_content_logical_height) const {
1857     NOT_DESTROYED();
1858     intrinsic_content_logical_height_ = intrinsic_content_logical_height;
1859   }
1860 
1861   bool CanRenderBorderImage() const;
1862 
1863   void MapLocalToAncestor(const LayoutBoxModelObject* ancestor,
1864                           TransformState&,
1865                           MapCoordinatesFlags) const override;
1866   void MapAncestorToLocal(const LayoutBoxModelObject*,
1867                           TransformState&,
1868                           MapCoordinatesFlags) const override;
1869 
PercentHeightContainer()1870   LayoutBlock* PercentHeightContainer() const {
1871     NOT_DESTROYED();
1872     return rare_data_ ? rare_data_->percent_height_container_ : nullptr;
1873   }
1874   void SetPercentHeightContainer(LayoutBlock*);
1875   void RemoveFromPercentHeightContainer();
1876   void ClearPercentHeightDescendants();
1877   // For snap areas, returns the snap container that owns us.
1878   LayoutBox* SnapContainer() const;
1879   void SetSnapContainer(LayoutBox*);
1880   // For snap containers, returns all associated snap areas.
1881   SnapAreaSet* SnapAreas() const;
1882   void ClearSnapAreas();
1883   // Moves all snap areas to the new container.
1884   void ReassignSnapAreas(LayoutBox& new_container);
1885 
1886   // CustomLayoutChild only exists if this LayoutBox is a IsCustomItem (aka. a
1887   // child of a LayoutCustom). This is created/destroyed when this LayoutBox is
1888   // inserted/removed from the layout tree.
1889   CustomLayoutChild* GetCustomLayoutChild() const;
1890   void AddCustomLayoutChildIfNeeded();
1891   void ClearCustomLayoutChild();
1892 
1893   bool HitTestClippedOutByBorder(
1894       const HitTestLocation&,
1895       const PhysicalOffset& border_box_location) const;
1896 
HitTestOverflowControl(HitTestResult &,const HitTestLocation &,const PhysicalOffset &)1897   virtual bool HitTestOverflowControl(HitTestResult&,
1898                                       const HitTestLocation&,
1899                                       const PhysicalOffset&) const {
1900     NOT_DESTROYED();
1901     return false;
1902   }
1903 
1904   // Returns true if the box intersects the viewport visible to the user.
1905   bool IntersectsVisibleViewport() const;
1906 
1907   void EnsureIsReadyForPaintInvalidation() override;
1908   void ClearPaintFlags() override;
1909 
1910   bool HasControlClip() const;
1911 
1912   class MutableForPainting : public LayoutObject::MutableForPainting {
1913    public:
SavePreviousSize()1914     void SavePreviousSize() {
1915       GetLayoutBox().previous_size_ = GetLayoutBox().Size();
1916     }
ClearPreviousSize()1917     void ClearPreviousSize() { GetLayoutBox().previous_size_ = LayoutSize(); }
1918     void SavePreviousOverflowData();
ClearPreviousOverflowData()1919     void ClearPreviousOverflowData() {
1920       DCHECK(!GetLayoutBox().HasVisualOverflow());
1921       DCHECK(!GetLayoutBox().HasLayoutOverflow());
1922       GetLayoutBox().overflow_.reset();
1923     }
SavePreviousContentBoxRect()1924     void SavePreviousContentBoxRect() {
1925       auto& rare_data = GetLayoutBox().EnsureRareData();
1926       rare_data.has_previous_content_box_rect_ = true;
1927       rare_data.previous_physical_content_box_rect_ =
1928           GetLayoutBox().PhysicalContentBoxRect();
1929     }
ClearPreviousContentBoxRect()1930     void ClearPreviousContentBoxRect() {
1931       if (auto* rare_data = GetLayoutBox().rare_data_.Get())
1932         rare_data->has_previous_content_box_rect_ = false;
1933     }
1934 
1935     // Called from LayoutShiftTracker when we attach this LayoutBox to a node
1936     // for which we saved these values when the node was detached from its
1937     // original LayoutBox.
1938     void SetPreviousGeometryForLayoutShiftTracking(
1939         const PhysicalOffset& paint_offset,
1940         const LayoutSize& size,
1941         const PhysicalRect& visual_overflow_rect);
1942 
1943    protected:
1944     friend class LayoutBox;
MutableForPainting(const LayoutBox & box)1945     MutableForPainting(const LayoutBox& box)
1946         : LayoutObject::MutableForPainting(box) {}
GetLayoutBox()1947     LayoutBox& GetLayoutBox() {
1948       return static_cast<LayoutBox&>(layout_object_);
1949     }
1950   };
1951 
GetMutableForPainting()1952   MutableForPainting GetMutableForPainting() const {
1953     NOT_DESTROYED();
1954     return MutableForPainting(*this);
1955   }
1956 
PreviousSize()1957   LayoutSize PreviousSize() const {
1958     NOT_DESTROYED();
1959     return previous_size_;
1960   }
PreviousPhysicalContentBoxRect()1961   PhysicalRect PreviousPhysicalContentBoxRect() const {
1962     NOT_DESTROYED();
1963     return rare_data_ && rare_data_->has_previous_content_box_rect_
1964                ? rare_data_->previous_physical_content_box_rect_
1965                : PhysicalRect(PhysicalOffset(), PreviousSize());
1966   }
PreviousPhysicalVisualOverflowRect()1967   PhysicalRect PreviousPhysicalVisualOverflowRect() const {
1968     NOT_DESTROYED();
1969     return overflow_ && overflow_->previous_overflow_data
1970                ? overflow_->previous_overflow_data
1971                      ->previous_physical_visual_overflow_rect
1972                : PhysicalRect(PhysicalOffset(), PreviousSize());
1973   }
PreviousPhysicalLayoutOverflowRect()1974   PhysicalRect PreviousPhysicalLayoutOverflowRect() const {
1975     NOT_DESTROYED();
1976     return overflow_ && overflow_->previous_overflow_data
1977                ? overflow_->previous_overflow_data
1978                      ->previous_physical_layout_overflow_rect
1979                : PhysicalRect(PhysicalOffset(), PreviousSize());
1980   }
PreviousPhysicalSelfVisualOverflowRect()1981   PhysicalRect PreviousPhysicalSelfVisualOverflowRect() const {
1982     NOT_DESTROYED();
1983     return overflow_ && overflow_->previous_overflow_data
1984                ? overflow_->previous_overflow_data
1985                      ->previous_physical_self_visual_overflow_rect
1986                : PhysicalRect(PhysicalOffset(), PreviousSize());
1987   }
1988 
1989   // Calculates the intrinsic logical widths for this layout box.
1990   // https://drafts.csswg.org/css-sizing-3/#intrinsic
1991   //
1992   // intrinsicWidth is defined as:
1993   //     intrinsic size of content (with our border and padding) +
1994   //     scrollbarWidth.
1995   //
1996   // preferredWidth is defined as:
1997   //     fixedWidth OR (intrinsicWidth plus border and padding).
1998   //     Note: fixedWidth includes border and padding and scrollbarWidth.
1999   //
2000   // This is public only for use by LayoutNG. Do not call this elsewhere.
2001   virtual MinMaxSizes ComputeIntrinsicLogicalWidths() const = 0;
2002 
2003   // Returns the (maybe cached) intrinsic logical widths for this layout box.
2004   MinMaxSizes IntrinsicLogicalWidths(
2005       MinMaxSizesType type = MinMaxSizesType::kContent) const;
2006 
2007   // If |IntrinsicLogicalWidthsDirty()| is true, recalculates the intrinsic
2008   // logical widths.
2009   void UpdateCachedIntrinsicLogicalWidthsIfNeeded();
2010 
2011   // LayoutNG can use this function to update our cache of intrinsic logical
2012   // widths when the layout object is managed by NG. Should not be called by
2013   // regular code.
2014   //
2015   // Also clears the "dirty" flag for the intrinsic logical widths.
SetIntrinsicLogicalWidthsFromNG(LayoutUnit intrinsic_logical_widths_percentage_resolution_block_size,bool depends_on_percentage_block_size,bool child_depends_on_percentage_block_size,const MinMaxSizes * sizes)2016   void SetIntrinsicLogicalWidthsFromNG(
2017       LayoutUnit intrinsic_logical_widths_percentage_resolution_block_size,
2018       bool depends_on_percentage_block_size,
2019       bool child_depends_on_percentage_block_size,
2020       const MinMaxSizes* sizes) {
2021     NOT_DESTROYED();
2022     intrinsic_logical_widths_percentage_resolution_block_size_ =
2023         intrinsic_logical_widths_percentage_resolution_block_size;
2024     SetIntrinsicLogicalWidthsDependsOnPercentageBlockSize(
2025         depends_on_percentage_block_size);
2026     SetIntrinsicLogicalWidthsChildDependsOnPercentageBlockSize(
2027         child_depends_on_percentage_block_size);
2028     if (sizes)
2029       intrinsic_logical_widths_ = *sizes;
2030     ClearIntrinsicLogicalWidthsDirty();
2031   }
2032 
2033   // Returns what %-resolution-block-size was used in the intrinsic logical
2034   // widths phase.
2035   //
2036   // For non-LayoutNG code this is always LayoutUnit::Min(), and should not be
2037   // used for caching purposes.
IntrinsicLogicalWidthsPercentageResolutionBlockSize()2038   LayoutUnit IntrinsicLogicalWidthsPercentageResolutionBlockSize() const {
2039     NOT_DESTROYED();
2040     return intrinsic_logical_widths_percentage_resolution_block_size_;
2041   }
2042 
2043   // Make it public.
2044   using LayoutObject::BackgroundIsKnownToBeObscured;
2045 
2046   // Invalidate the raster of a specific sub-rectangle within the object. The
2047   // rect is in the object's local coordinate space. This is useful e.g. when
2048   // a small region of a canvas changes.
2049   void InvalidatePaintRectangle(const PhysicalRect&);
HasPartialInvalidationRect()2050   bool HasPartialInvalidationRect() const {
2051     NOT_DESTROYED();
2052     return rare_data_ && !rare_data_->partial_invalidation_rect_.IsEmpty();
2053   }
2054 
2055   // Sets the coordinates of find-in-page scrollbar tickmarks, bypassing
2056   // DocumentMarkerController.  This is used by the PDF plugin.
2057   void OverrideTickmarks(Vector<IntRect> tickmarks);
2058 
2059   // Issues a paint invalidation on the layout viewport's vertical scrollbar
2060   // (which is responsible for painting the tickmarks).
2061   void InvalidatePaintForTickmarks();
2062 
2063  protected:
2064   ~LayoutBox() override;
2065 
2066   // Applies 'overflow:clip' as necessary to the accumulated layout overflow.
2067   // During layout overflow is accumulated, once all the overflow has been
2068   // accumulated 'overflow:clip' is then applied.
2069   void ApplyOverflowClipToLayoutOverflowRect();
2070 
2071   virtual OverflowClipAxes ComputeOverflowClipAxes() const;
2072 
2073   void WillBeDestroyed() override;
2074 
2075   void InsertedIntoTree() override;
2076   void WillBeRemovedFromTree() override;
2077 
2078   void StyleWillChange(StyleDifference,
2079                        const ComputedStyle& new_style) override;
2080   void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
2081   void UpdateFromStyle() override;
2082 
2083   void InLayoutNGInlineFormattingContextWillChange(bool) final;
2084 
2085   virtual ItemPosition SelfAlignmentNormalBehavior(
2086       const LayoutBox* child = nullptr) const {
2087     NOT_DESTROYED();
2088     DCHECK(!child);
2089     return ItemPosition::kStretch;
2090   }
2091 
2092   // Returns false if it could not cheaply compute the extent (e.g. fixed
2093   // background), in which case the returned rect may be incorrect.
2094   bool GetBackgroundPaintedExtent(PhysicalRect&) const;
2095   virtual bool ForegroundIsKnownToBeOpaqueInRect(
2096       const PhysicalRect& local_rect,
2097       unsigned max_depth_to_test) const;
2098   virtual bool ComputeBackgroundIsKnownToBeObscured() const;
2099 
2100   virtual void ComputePositionedLogicalWidth(
2101       LogicalExtentComputedValues&) const;
2102 
2103   LayoutUnit ComputeIntrinsicLogicalWidthUsing(
2104       const Length& logical_width_length,
2105       LayoutUnit available_logical_width) const;
2106   LayoutUnit ComputeIntrinsicLogicalContentHeightUsing(
2107       SizeType height_type,
2108       const Length& logical_height_length,
2109       LayoutUnit intrinsic_content_height,
2110       LayoutUnit border_and_padding) const;
2111 
2112   LayoutObject* SplitAnonymousBoxesAroundChild(LayoutObject* before_child);
2113 
2114   virtual bool HitTestChildren(HitTestResult&,
2115                                const HitTestLocation&,
2116                                const PhysicalOffset& accumulated_offset,
2117                                HitTestAction);
2118 
2119   void InvalidatePaint(const PaintInvalidatorContext&) const override;
2120 
2121   bool ColumnFlexItemHasStretchAlignment() const;
2122   bool IsStretchingColumnFlexItem() const;
2123   bool HasStretchedLogicalWidth() const;
2124 
2125   void ExcludeScrollbars(
2126       PhysicalRect&,
2127       OverlayScrollbarClipBehavior = kIgnoreOverlayScrollbarSize) const;
2128 
2129   LayoutUnit ContainingBlockLogicalWidthForPositioned(
2130       const LayoutBoxModelObject* containing_block,
2131       bool check_for_perpendicular_writing_mode = true) const;
2132   LayoutUnit ContainingBlockLogicalHeightForPositioned(
2133       const LayoutBoxModelObject* containing_block,
2134       bool check_for_perpendicular_writing_mode = true) const;
2135 
2136   static void ComputeBlockStaticDistance(
2137       Length& logical_top,
2138       Length& logical_bottom,
2139       const LayoutBox* child,
2140       const LayoutBoxModelObject* container_block,
2141       const NGBoxFragmentBuilder* = nullptr);
2142   static void ComputeInlineStaticDistance(
2143       Length& logical_left,
2144       Length& logical_right,
2145       const LayoutBox* child,
2146       const LayoutBoxModelObject* container_block,
2147       LayoutUnit container_logical_width,
2148       const NGBoxFragmentBuilder* = nullptr);
2149   static void ComputeLogicalLeftPositionedOffset(
2150       LayoutUnit& logical_left_pos,
2151       const LayoutBox* child,
2152       LayoutUnit logical_width_value,
2153       const LayoutBoxModelObject* container_block,
2154       LayoutUnit container_logical_width);
2155   static void ComputeLogicalTopPositionedOffset(
2156       LayoutUnit& logical_top_pos,
2157       const LayoutBox* child,
2158       LayoutUnit logical_height_value,
2159       const LayoutBoxModelObject* container_block,
2160       LayoutUnit container_logical_height);
2161   static bool SkipContainingBlockForPercentHeightCalculation(
2162       const LayoutBox* containing_block);
2163 
2164   PhysicalRect LocalVisualRectIgnoringVisibility() const override;
2165 
2166   PhysicalOffset OffsetFromContainerInternal(
2167       const LayoutObject*,
2168       bool ignore_scroll_offset) const override;
2169 
2170   // For atomic inlines, returns its resolved direction in text flow. Not to be
2171   // confused with the CSS property 'direction'.
2172   // Returns the CSS 'direction' property value when it is not atomic inline.
2173   TextDirection ResolvedDirection() const;
2174 
2175  private:
HasFragmentItems()2176   bool HasFragmentItems() const {
2177     NOT_DESTROYED();
2178     return ChildrenInline() && PhysicalFragments().HasFragmentItems();
2179   }
2180 
LayoutOverflowIsSet()2181   inline bool LayoutOverflowIsSet() const {
2182     NOT_DESTROYED();
2183     return overflow_ && overflow_->layout_overflow;
2184   }
VisualOverflowIsSet()2185   inline bool VisualOverflowIsSet() const {
2186     NOT_DESTROYED();
2187     return overflow_ && overflow_->visual_overflow;
2188   }
2189 
2190   void UpdateShapeOutsideInfoAfterStyleChange(const ComputedStyle&,
2191                                               const ComputedStyle* old_style);
2192   void UpdateGridPositionAfterStyleChange(const ComputedStyle*);
2193   void UpdateScrollSnapMappingAfterStyleChange(const ComputedStyle& old_style);
2194   void ClearScrollSnapMapping();
2195   void AddScrollSnapMapping();
2196 
2197   LayoutUnit ShrinkToFitLogicalWidth(LayoutUnit available_logical_width,
2198                                      LayoutUnit borders_plus_padding) const;
2199 
2200   bool StretchesToViewportInQuirksMode() const;
2201 
2202   virtual void ComputePositionedLogicalHeight(
2203       LogicalExtentComputedValues&) const;
2204   void ComputePositionedLogicalWidthUsing(
2205       SizeType,
2206       const Length& logical_width,
2207       const LayoutBoxModelObject* container_block,
2208       TextDirection container_direction,
2209       LayoutUnit container_logical_width,
2210       LayoutUnit borders_plus_padding,
2211       const Length& logical_left,
2212       const Length& logical_right,
2213       const Length& margin_logical_left,
2214       const Length& margin_logical_right,
2215       LogicalExtentComputedValues&) const;
2216   void ComputePositionedLogicalHeightUsing(
2217       SizeType,
2218       Length logical_height_length,
2219       const LayoutBoxModelObject* container_block,
2220       LayoutUnit container_logical_height,
2221       LayoutUnit borders_plus_padding,
2222       LayoutUnit logical_height,
2223       const Length& logical_top,
2224       const Length& logical_bottom,
2225       const Length& margin_logical_top,
2226       const Length& margin_logical_bottom,
2227       LogicalExtentComputedValues&) const;
2228 
2229   LayoutUnit FillAvailableMeasure(LayoutUnit available_logical_width) const;
2230   LayoutUnit FillAvailableMeasure(LayoutUnit available_logical_width,
2231                                   LayoutUnit& margin_start,
2232                                   LayoutUnit& margin_end) const;
2233 
EnsureRareData()2234   LayoutBoxRareData& EnsureRareData() {
2235     NOT_DESTROYED();
2236     if (!rare_data_)
2237       rare_data_ = MakeGarbageCollected<LayoutBoxRareData>();
2238     return *rare_data_.Get();
2239   }
2240 
2241   bool LogicalHeightComputesAsNone(SizeType) const;
2242 
2243   bool IsBox() const =
2244       delete;  // This will catch anyone doing an unnecessary check.
2245 
2246   void LocationChanged();
2247   void SizeChanged();
2248 
2249   void UpdateBackgroundAttachmentFixedStatusAfterStyleChange();
2250 
2251   void InflateVisualRectForFilter(TransformState&) const;
2252   void InflateVisualRectForFilterUnderContainer(
2253       TransformState&,
2254       const LayoutObject& container,
2255       const LayoutBoxModelObject* ancestor_to_stop_at) const;
2256 
2257   LayoutRectOutsets margin_box_outsets_;
2258 
2259   void AddSnapArea(LayoutBox&);
2260   void RemoveSnapArea(const LayoutBox&);
2261 
2262   // Returns true when the current recursive scroll into visible could propagate
2263   // to parent frame.
2264   bool AllowedToPropagateRecursiveScrollToParentFrame(
2265       const mojom::blink::ScrollIntoViewParamsPtr&);
2266 
2267   PhysicalRect DebugRect() const override;
2268 
2269   RasterEffectOutset VisualRectOutsetForRasterEffects() const override;
2270 
CanSkipComputeScrollbars()2271   inline bool CanSkipComputeScrollbars() const {
2272     NOT_DESTROYED();
2273     return (StyleRef().IsOverflowVisibleAlongBothAxes() ||
2274             !HasNonVisibleOverflow() ||
2275             (GetScrollableArea() &&
2276              !GetScrollableArea()->HasHorizontalScrollbar() &&
2277              !GetScrollableArea()->HasVerticalScrollbar())) &&
2278            StyleRef().IsScrollbarGutterAuto();
2279   }
2280 
2281   bool HasScrollbarGutters(ScrollbarOrientation orientation) const;
2282   NGPhysicalBoxStrut ComputeScrollbarsInternal(
2283       ShouldClampToContentBox = kDoNotClampToContentBox,
2284       OverlayScrollbarClipBehavior = kIgnoreOverlayScrollbarSize) const;
2285 
FlipForWritingModeInternal(LayoutUnit position,LayoutUnit width,const LayoutBox * box_for_flipping)2286   LayoutUnit FlipForWritingModeInternal(
2287       LayoutUnit position,
2288       LayoutUnit width,
2289       const LayoutBox* box_for_flipping) const final {
2290     NOT_DESTROYED();
2291     DCHECK(!box_for_flipping || box_for_flipping == this);
2292     return FlipForWritingMode(position, width);
2293   }
2294 
PhysicalLocationInternal(const LayoutBox * container_box)2295   PhysicalOffset PhysicalLocationInternal(
2296       const LayoutBox* container_box) const {
2297     NOT_DESTROYED();
2298     DCHECK_EQ(container_box, LocationContainer());
2299     if (LIKELY(!container_box || !container_box->HasFlippedBlocksWritingMode()))
2300       return PhysicalOffset(Location());
2301 
2302     return PhysicalOffset(
2303         container_box->Size().Width() - Size().Width() - Location().X(),
2304         Location().Y());
2305   }
2306 
2307   // DisplayItemClient methods.
2308   void ClearPartialInvalidationVisualRect() const final;
2309   IntRect PartialInvalidationVisualRect() const final;
2310 
2311   // The CSS border box rect for this box.
2312   //
2313   // The rectangle is in LocationContainer's physical coordinates in flipped
2314   // block-flow direction of LocationContainer (see the COORDINATE SYSTEMS
2315   // section in LayoutBoxModelObject). The location is the distance from this
2316   // object's border edge to the LocationContainer's border edge. Thus it
2317   // includes any logical top/left along with this box's margins. It doesn't
2318   // include transforms, relative position offsets etc.
2319   LayoutRect frame_rect_;
2320 
2321   // Previous size of frame_rect_, updated after paint invalidation.
2322   LayoutSize previous_size_;
2323 
2324   // Our intrinsic height, used for min-height: min-content etc. Maintained by
2325   // updateLogicalHeight. This is logicalHeight() before it is clamped to
2326   // min/max.
2327   mutable LayoutUnit intrinsic_content_logical_height_;
2328 
2329  protected:
2330   MinMaxSizes intrinsic_logical_widths_;
2331   LayoutUnit intrinsic_logical_widths_percentage_resolution_block_size_;
2332 
2333   scoped_refptr<const NGLayoutResult> measure_result_;
2334   NGLayoutResultList layout_results_;
2335 
2336   // LayoutBoxUtils is used for the LayoutNG code querying protected methods on
2337   // this class, e.g. determining the static-position of OOF elements.
2338   friend class LayoutBoxUtils;
2339   friend class LayoutBoxTest;
2340 
2341  private:
LogicalMarginToPhysicalSetter(const ComputedStyle * override_style)2342   LogicalToPhysicalSetter<LayoutUnit, LayoutBox> LogicalMarginToPhysicalSetter(
2343       const ComputedStyle* override_style) {
2344     NOT_DESTROYED();
2345     const auto& style = override_style ? *override_style : StyleRef();
2346     return LogicalToPhysicalSetter<LayoutUnit, LayoutBox>(
2347         style.GetWritingDirection(), *this, &LayoutBox::SetMarginTop,
2348         &LayoutBox::SetMarginRight, &LayoutBox::SetMarginBottom,
2349         &LayoutBox::SetMarginLeft);
2350   }
2351 
2352   std::unique_ptr<BoxOverflowModel> overflow_;
2353 
2354   // Extra layout input data. This one may be set during layout, and cleared
2355   // afterwards. Always nullptr when this object isn't in the process of being
2356   // laid out.
2357   const BoxLayoutExtraInput* extra_input_ = nullptr;
2358 
2359   union {
2360     // The inline box containing this LayoutBox, for atomic inline elements.
2361     // Valid only when !IsInLayoutNGInlineFormattingContext().
2362     InlineBox* inline_box_wrapper_;
2363     // The first fragment of the inline box containing this LayoutBox, for
2364     // atomic inline elements. Valid only when
2365     // IsInLayoutNGInlineFormattingContext().
2366     NGPaintFragment* first_paint_fragment_;
2367     // The index of the first fragment item associated with this object in
2368     // |NGFragmentItems::Items()|. Zero means there are no such item.
2369     // Valid only when IsInLayoutNGInlineFormattingContext().
2370     wtf_size_t first_fragment_item_index_;
2371   };
2372 
2373   Persistent<LayoutBoxRareData> rare_data_;
2374 };
2375 
2376 template <>
2377 struct DowncastTraits<LayoutBox> {
2378   static bool AllowFrom(const LayoutObject& object) { return object.IsBox(); }
2379 };
2380 
2381 inline LayoutBox* LayoutBox::PreviousSiblingBox() const {
2382   return To<LayoutBox>(PreviousSibling());
2383 }
2384 
2385 inline LayoutBox* LayoutBox::PreviousInFlowSiblingBox() const {
2386   LayoutBox* previous = PreviousSiblingBox();
2387   while (previous && previous->IsOutOfFlowPositioned())
2388     previous = previous->PreviousSiblingBox();
2389   return previous;
2390 }
2391 
2392 inline LayoutBox* LayoutBox::NextSiblingBox() const {
2393   return To<LayoutBox>(NextSibling());
2394 }
2395 
2396 inline LayoutBox* LayoutBox::NextInFlowSiblingBox() const {
2397   LayoutBox* next = NextSiblingBox();
2398   while (next && next->IsOutOfFlowPositioned())
2399     next = next->NextSiblingBox();
2400   return next;
2401 }
2402 
2403 inline LayoutBox* LayoutBox::ParentBox() const {
2404   return To<LayoutBox>(Parent());
2405 }
2406 
2407 inline LayoutBox* LayoutBox::FirstInFlowChildBox() const {
2408   LayoutBox* first = FirstChildBox();
2409   return (first && first->IsOutOfFlowPositioned())
2410              ? first->NextInFlowSiblingBox()
2411              : first;
2412 }
2413 
2414 inline LayoutBox* LayoutBox::FirstChildBox() const {
2415   return To<LayoutBox>(SlowFirstChild());
2416 }
2417 
2418 inline LayoutBox* LayoutBox::LastChildBox() const {
2419   return To<LayoutBox>(SlowLastChild());
2420 }
2421 
2422 inline LayoutBox* LayoutBox::PreviousSiblingMultiColumnBox() const {
2423   DCHECK(IsLayoutMultiColumnSpannerPlaceholder() || IsLayoutMultiColumnSet());
2424   LayoutBox* previous_box = PreviousSiblingBox();
2425   if (previous_box->IsLayoutFlowThread())
2426     return nullptr;
2427   return previous_box;
2428 }
2429 
2430 inline LayoutBox* LayoutBox::NextSiblingMultiColumnBox() const {
2431   DCHECK(IsLayoutMultiColumnSpannerPlaceholder() || IsLayoutMultiColumnSet());
2432   return NextSiblingBox();
2433 }
2434 
2435 inline InlineBox* LayoutBox::InlineBoxWrapper() const {
2436   return IsInLayoutNGInlineFormattingContext() ? nullptr : inline_box_wrapper_;
2437 }
2438 
2439 inline void LayoutBox::SetInlineBoxWrapper(InlineBox* box_wrapper) {
2440   CHECK(!IsInLayoutNGInlineFormattingContext());
2441 
2442   if (box_wrapper) {
2443     DCHECK(!inline_box_wrapper_);
2444     // inline_box_wrapper_ should already be nullptr. Deleting it is a safeguard
2445     // against security issues. Otherwise, there will two line box wrappers
2446     // keeping the reference to this layoutObject, and only one will be notified
2447     // when the layoutObject is getting destroyed. The second line box wrapper
2448     // will keep a stale reference.
2449     if (UNLIKELY(inline_box_wrapper_ != nullptr))
2450       DeleteLineBoxWrapper();
2451   }
2452 
2453   inline_box_wrapper_ = box_wrapper;
2454 }
2455 
2456 inline NGPaintFragment* LayoutBox::FirstInlineFragment() const {
2457   if (!IsInLayoutNGInlineFormattingContext())
2458     return nullptr;
2459   if (!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
2460     return first_paint_fragment_;
2461   NOTREACHED();
2462   return nullptr;
2463 }
2464 
2465 inline wtf_size_t LayoutBox::FirstInlineFragmentItemIndex() const {
2466   if (!IsInLayoutNGInlineFormattingContext())
2467     return 0u;
2468   DCHECK(RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled());
2469   return first_fragment_item_index_;
2470 }
2471 
2472 inline bool LayoutBox::IsForcedFragmentainerBreakValue(
2473     EBreakBetween break_value) {
2474   return break_value == EBreakBetween::kColumn ||
2475          break_value == EBreakBetween::kLeft ||
2476          break_value == EBreakBetween::kPage ||
2477          break_value == EBreakBetween::kRecto ||
2478          break_value == EBreakBetween::kRight ||
2479          break_value == EBreakBetween::kVerso;
2480 }
2481 
2482 }  // namespace blink
2483 
2484 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_BOX_H_
2485