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