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