WebKit Bugzilla
Attachment 347920 Details for
Bug 188886
: [LFC][Floating] Decouple the incoming floats and floats already placed in the list
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-188886-20180823075144.patch (text/plain), 34.05 KB, created by
zalan
on 2018-08-23 07:51:47 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
zalan
Created:
2018-08-23 07:51:47 PDT
Size:
34.05 KB
patch
obsolete
>Subversion Revision: 235222 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index a5b01281f5f13ee33f270d61ef53613e0dbc4f2b..b1e9c63e498124b47fe62bcf9db3ec5fd91874c4 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,59 @@ >+2018-08-23 Zalan Bujtas <zalan@apple.com> >+ >+ [LFC][Floating] Decouple the incoming floats and floats already placed in the list >+ https://bugs.webkit.org/show_bug.cgi?id=188886 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This is in preparation for the float avoidance feature where formatting context root boxes avoid existing floats. >+ >+ 1. Introduce FloatBox class for the incoming floats (This will need to be renamed when adding support for avoidance -incoming box is actually not a float). >+ 2. Use the existing FloatState::FloatItem class for placed floats. >+ >+ * Sources.txt: >+ * WebCore.xcodeproj/project.pbxproj: >+ * layout/LayoutUnits.h: >+ * layout/Verification.cpp: >+ (WebCore::Layout::LayoutContext::verifyAndOutputMismatchingLayoutTree const): >+ * layout/displaytree/DisplayBox.h: >+ * layout/floats/FloatBox.cpp: Added. >+ (WebCore::Layout::FloatBox::FloatBox): >+ (WebCore::Layout::FloatBox::initializePosition): >+ (WebCore::Layout::FloatBox::isLeftAligned const): >+ (WebCore::Layout::FloatBox::setLeft): >+ (WebCore::Layout::FloatBox::setTopLeft): >+ (WebCore::Layout::FloatBox::resetVertically): >+ (WebCore::Layout::FloatBox::resetHorizontally): >+ (WebCore::Layout::FloatBox::topLeftInContainingBlock const): >+ * layout/floats/FloatBox.h: Copied from Source/WebCore/layout/floats/FloatingContext.h. >+ (WebCore::Layout::FloatBox::top const): >+ (WebCore::Layout::FloatBox::left const): >+ (WebCore::Layout::FloatBox::marginTop const): >+ (WebCore::Layout::FloatBox::marginLeft const): >+ (WebCore::Layout::FloatBox::marginBottom const): >+ (WebCore::Layout::FloatBox::marginRight const): >+ (WebCore::Layout::FloatBox::rectWithMargin const): >+ (WebCore::Layout::FloatBox::setTop): >+ * layout/floats/FloatingContext.cpp: >+ (WebCore::Layout::FloatingPair::verticalPosition const): >+ (WebCore::Layout::begin): >+ (WebCore::Layout::FloatingContext::positionForFloat const): >+ (WebCore::Layout::FloatingContext::verticalPositionWithClearance const): >+ (WebCore::Layout::FloatingContext::floatingPosition const): >+ (WebCore::Layout::FloatingPair::horiztonalPosition const): >+ (WebCore::Layout::FloatingPair::bottom const): >+ (WebCore::Layout::Iterator::Iterator): >+ (WebCore::Layout::Iterator::operator++): >+ (WebCore::Layout::Iterator::set): >+ (WebCore::Layout::FloatingContext::initialVerticalPosition const): Deleted. >+ (WebCore::Layout::FloatingContext::alignWithContainingBlock const): Deleted. >+ (WebCore::Layout::FloatingContext::alignWithFloatings const): Deleted. >+ (WebCore::Layout::FloatingContext::toContainingBlock const): Deleted. >+ * layout/floats/FloatingContext.h: >+ * layout/floats/FloatingState.h: >+ (WebCore::Layout::FloatingState::root const): >+ (WebCore::Layout::FloatingState::layoutContext const): >+ > 2018-08-23 Zan Dobersek <zdobersek@igalia.com> > > [CoordGraphics] Remove the remaining CoordinatedGraphicsLayerState cruft >diff --git a/Source/WebCore/Sources.txt b/Source/WebCore/Sources.txt >index 819a5d298aab733f6795d67b606cb08417669a18..a512eba4576db7f7a0f1f3ce7046822a8bbeae1c 100644 >--- a/Source/WebCore/Sources.txt >+++ b/Source/WebCore/Sources.txt >@@ -1229,6 +1229,7 @@ layout/blockformatting/BlockFormattingState.cpp > layout/blockformatting/BlockMarginCollapse.cpp > layout/blockformatting/BlockInvalidation.cpp > layout/displaytree/DisplayBox.cpp >+layout/floats/FloatBox.cpp > layout/floats/FloatingContext.cpp > layout/floats/FloatingState.cpp > layout/inlineformatting/InlineFormattingContext.cpp >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index b0c2b0cd15a0f224cb09906b2290cae16eda4b6c..2b841154e76847a85ce978ba23a821a51c94d881 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -1989,6 +1989,7 @@ > 6F995A381A70833700A735F4 /* JSWebGLTransformFeedback.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F995A2E1A70833700A735F4 /* JSWebGLTransformFeedback.h */; }; > 6F995A3A1A70833700A735F4 /* JSWebGLVertexArrayObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F995A301A70833700A735F4 /* JSWebGLVertexArrayObject.h */; }; > 6FA4454E898F2FC168BC38C1 /* JSBeforeUnloadEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 29E04A27BED2F81F98E9022B /* JSBeforeUnloadEvent.h */; }; >+ 6FFDC442212EFF1700A9CA91 /* FloatBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 6FFDC440212EFF1600A9CA91 /* FloatBox.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 709A01FE1E3D0BDD006B0D4C /* ModuleFetchFailureKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 709A01FD1E3D0BCC006B0D4C /* ModuleFetchFailureKind.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 71025ECD1F99F0CE004A250C /* AnimationTimeline.h in Headers */ = {isa = PBXBuildFile; fileRef = 71025EC71F99F096004A250C /* AnimationTimeline.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 71025ED01F99F0CE004A250C /* DocumentTimeline.h in Headers */ = {isa = PBXBuildFile; fileRef = 71025EC51F99F096004A250C /* DocumentTimeline.h */; settings = {ATTRIBUTES = (Private, ); }; }; >@@ -8966,6 +8967,8 @@ > 6FCD19C120F9727A00FD4529 /* TextContentProvider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TextContentProvider.h; sourceTree = "<group>"; }; > 6FCD19C720F9727D00FD4529 /* TextContentProvider.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TextContentProvider.cpp; sourceTree = "<group>"; }; > 6FCF975220F02B3500214960 /* Runs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Runs.h; sourceTree = "<group>"; }; >+ 6FFDC43E212EFF1600A9CA91 /* FloatBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FloatBox.cpp; sourceTree = "<group>"; }; >+ 6FFDC440212EFF1600A9CA91 /* FloatBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FloatBox.h; sourceTree = "<group>"; }; > 709A01FD1E3D0BCC006B0D4C /* ModuleFetchFailureKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModuleFetchFailureKind.h; sourceTree = "<group>"; }; > 71004B9D1DC1398800A52A38 /* playback-support.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "playback-support.js"; sourceTree = "<group>"; }; > 71025EC21F99F096004A250C /* WebAnimation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebAnimation.h; sourceTree = "<group>"; }; >@@ -19474,6 +19477,8 @@ > 6FCFC055212DACC2007695D2 /* floats */ = { > isa = PBXGroup; > children = ( >+ 6FFDC43E212EFF1600A9CA91 /* FloatBox.cpp */, >+ 6FFDC440212EFF1600A9CA91 /* FloatBox.h */, > 115CFA85208B9066001E6991 /* FloatingContext.cpp */, > 115CFA84208B9066001E6991 /* FloatingContext.h */, > 115CFA81208B8EDA001E6991 /* FloatingState.cpp */, >@@ -27862,6 +27867,7 @@ > 49ECEB701499790D00CDD3A4 /* FilterOperations.h in Headers */, > 372C00D9129619F8005C9575 /* FindOptions.h in Headers */, > A8CFF04F0A154F09000A4234 /* FixedTableLayout.h in Headers */, >+ 6FFDC442212EFF1700A9CA91 /* FloatBox.h in Headers */, > BC073BAA0C399B1F000F5979 /* FloatConversion.h in Headers */, > 115CFA86208B9066001E6991 /* FloatingContext.h in Headers */, > 9A528E8417D7F52F00AA9518 /* FloatingObjects.h in Headers */, >diff --git a/Source/WebCore/layout/LayoutUnits.h b/Source/WebCore/layout/LayoutUnits.h >index d39e50a4b6fb65ea8d706097501fede524e472ba..1b61edb3722313fec2ee4c0a1842d4792df7fb1d 100644 >--- a/Source/WebCore/layout/LayoutUnits.h >+++ b/Source/WebCore/layout/LayoutUnits.h >@@ -46,6 +46,12 @@ struct Position { > operator LayoutPoint() const { return { x, y }; } > }; > >+// FIXME: Wrap these into structs. >+using PointInContextRoot = Position; >+using PointInContainingBlock = Position; >+using PositionInContextRoot = LayoutUnit; >+using PositionInContainingBlock = LayoutUnit; >+ > inline Position::Position(LayoutPoint point) > : x(point.x()) > , y(point.y()) >diff --git a/Source/WebCore/layout/displaytree/DisplayBox.h b/Source/WebCore/layout/displaytree/DisplayBox.h >index f722a18774f89cc36759e3935f65d2b88bee2a54..22851f7646fc9f3f50fdb9340976c398b85cc836 100644 >--- a/Source/WebCore/layout/displaytree/DisplayBox.h >+++ b/Source/WebCore/layout/displaytree/DisplayBox.h >@@ -36,6 +36,7 @@ namespace WebCore { > class RenderStyle; > > namespace Layout { >+class FloatBox; > class BlockFormattingContext; > class FormattingContext; > class FloatingContext; >@@ -47,6 +48,7 @@ namespace Display { > class Box { > WTF_MAKE_ISO_ALLOCATED(Box); > public: >+ friend class Layout::FloatBox; > friend class Layout::BlockFormattingContext; > friend class Layout::FormattingContext; > friend class Layout::FloatingContext; >diff --git a/Source/WebCore/layout/floats/FloatBox.cpp b/Source/WebCore/layout/floats/FloatBox.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..d4010ce02032bf67f4d03f4e307e8bdebe4516ed >--- /dev/null >+++ b/Source/WebCore/layout/floats/FloatBox.cpp >@@ -0,0 +1,118 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "FloatBox.h" >+ >+#if ENABLE(LAYOUT_FORMATTING_CONTEXT) >+ >+#include "LayoutBox.h" >+#include "LayoutContainer.h" >+#include "LayoutContext.h" >+#include <wtf/IsoMallocInlines.h> >+ >+namespace WebCore { >+namespace Layout { >+ >+WTF_MAKE_ISO_ALLOCATED_IMPL(FloatBox); >+ >+FloatBox::FloatBox(const Box& layoutBox, const FloatingState& floatingState, const LayoutContext& layoutContext) >+ : m_layoutBox(makeWeakPtr(const_cast<Box&>(layoutBox))) >+ , m_floatingState(floatingState) >+ , m_absoluteDisplayBox(FormattingContext::mapBoxToAncestor(layoutContext, layoutBox, downcast<Container>(floatingState.root()))) >+ , m_containingBlockAbsoluteDisplayBox(FormattingContext::mapBoxToAncestor(layoutContext, *layoutBox.containingBlock(), downcast<Container>(floatingState.root()))) >+{ >+ initializePosition(); >+} >+ >+void FloatBox::initializePosition() >+{ >+ resetVertically(); >+ resetHorizontally(); >+} >+ >+bool FloatBox::isLeftAligned() const >+{ >+ return m_layoutBox->isLeftFloatingPositioned(); >+} >+ >+void FloatBox::setLeft(PositionInContextRoot left) >+{ >+ // Horizontal position is constrained by the containing block's content box. >+ // Compute the horizontal position for the new floating by taking both the contining block and the current left/right floats into account. >+ auto containingBlockContentBoxLeft = m_containingBlockAbsoluteDisplayBox.left() + m_containingBlockAbsoluteDisplayBox.contentBoxLeft(); >+ auto containingBlockContentBoxRight = containingBlockContentBoxLeft + m_containingBlockAbsoluteDisplayBox.contentBoxWidth(); >+ >+ // Align it with the containing block's left edge first. >+ left = std::max(containingBlockContentBoxLeft + marginLeft(), left); >+ // Make sure it does not overflow the containing block on the right. >+ auto marginBoxSize = m_absoluteDisplayBox.marginBox().width(); >+ left = std::min(left, containingBlockContentBoxRight - marginBoxSize + marginLeft()); >+ >+ m_absoluteDisplayBox.setLeft(left); >+} >+ >+void FloatBox::setTopLeft(PointInContextRoot topLeft) >+{ >+ setTop(topLeft.y); >+ setLeft(topLeft.x); >+} >+ >+void FloatBox::resetVertically() >+{ >+ // Incoming float cannot be placed higher than existing floats (margin box of the last float). >+ // Take the static position (where the box would go if it wasn't floating) and adjust it with the last float. >+ auto top = m_absoluteDisplayBox.rectWithMargin().top(); >+ if (auto lastFloat = m_floatingState.last()) >+ top = std::max(top, lastFloat->displayBox().rectWithMargin().top()); >+ top += m_absoluteDisplayBox.marginTop(); >+ >+ m_absoluteDisplayBox.setTop(top); >+} >+ >+void FloatBox::resetHorizontally() >+{ >+ // Align the box with the containing block's content box. >+ auto containingBlockContentBoxLeft = m_containingBlockAbsoluteDisplayBox.left() + m_containingBlockAbsoluteDisplayBox.contentBoxLeft(); >+ auto containingBlockContentBoxRight = containingBlockContentBoxLeft + m_containingBlockAbsoluteDisplayBox.contentBoxWidth(); >+ >+ auto left = isLeftAligned() ? containingBlockContentBoxLeft : containingBlockContentBoxRight - m_absoluteDisplayBox.marginBox().width(); >+ left += m_absoluteDisplayBox.marginLeft(); >+ >+ m_absoluteDisplayBox.setLeft(left); >+} >+ >+PointInContainingBlock FloatBox::topLeftInContainingBlock() const >+{ >+ // From formatting root coordinate system back to containing block's. >+ if (m_layoutBox->containingBlock() == &m_floatingState.root()) >+ return m_absoluteDisplayBox.topLeft(); >+ >+ return { m_absoluteDisplayBox.left() - m_containingBlockAbsoluteDisplayBox.left(), m_absoluteDisplayBox.top() - m_containingBlockAbsoluteDisplayBox.top() }; >+} >+ >+} >+} >+#endif >diff --git a/Source/WebCore/layout/floats/FloatBox.h b/Source/WebCore/layout/floats/FloatBox.h >new file mode 100644 >index 0000000000000000000000000000000000000000..9ba6f907e5f510848942baa11002314907ac091e >--- /dev/null >+++ b/Source/WebCore/layout/floats/FloatBox.h >@@ -0,0 +1,80 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#if ENABLE(LAYOUT_FORMATTING_CONTEXT) >+ >+#include "DisplayBox.h" >+#include "LayoutUnit.h" >+#include <wtf/IsoMalloc.h> >+#include <wtf/WeakPtr.h> >+ >+namespace WebCore { >+ >+namespace Layout { >+ >+class Box; >+class FloatingState; >+class LayoutContext; >+ >+class FloatBox { >+ WTF_MAKE_ISO_ALLOCATED(FloatBox); >+public: >+ FloatBox(const Box&, const FloatingState&, const LayoutContext&); >+ >+ PositionInContextRoot top() const { return m_absoluteDisplayBox.top(); } >+ PositionInContextRoot left() const { return m_absoluteDisplayBox.left(); } >+ PointInContainingBlock topLeftInContainingBlock() const; >+ >+ LayoutUnit marginTop() const { return m_absoluteDisplayBox.marginTop(); } >+ LayoutUnit marginLeft() const { return m_absoluteDisplayBox.marginLeft(); } >+ LayoutUnit marginBottom() const { return m_absoluteDisplayBox.marginBottom(); } >+ LayoutUnit marginRight() const { return m_absoluteDisplayBox.marginRight(); } >+ >+ Display::Box::Rect rectWithMargin() const { return m_absoluteDisplayBox.rectWithMargin(); } >+ >+ void setTop(PositionInContextRoot top) { m_absoluteDisplayBox.setTop(top); } >+ void setLeft(PositionInContextRoot); >+ void setTopLeft(PointInContextRoot); >+ >+ void resetHorizontally(); >+ void resetVertically(); >+ >+ bool isLeftAligned() const; >+ >+private: >+ void initializePosition(); >+ >+ WeakPtr<Box> m_layoutBox; >+ const FloatingState& m_floatingState; >+ >+ Display::Box m_absoluteDisplayBox; >+ Display::Box m_containingBlockAbsoluteDisplayBox; >+}; >+ >+} >+} >+#endif >diff --git a/Source/WebCore/layout/floats/FloatingContext.cpp b/Source/WebCore/layout/floats/FloatingContext.cpp >index 4feaea27be180c5c10f4ed9258b0abf42c38a77a..5e462d49c2ce36f36017aba7b809fa4df7b40d61 100644 >--- a/Source/WebCore/layout/floats/FloatingContext.cpp >+++ b/Source/WebCore/layout/floats/FloatingContext.cpp >@@ -29,6 +29,7 @@ > #if ENABLE(LAYOUT_FORMATTING_CONTEXT) > > #include "DisplayBox.h" >+#include "FloatBox.h" > #include "LayoutBox.h" > #include "LayoutContainer.h" > #include "LayoutContext.h" >@@ -66,8 +67,9 @@ public: > const Display::Box* left() const; > const Display::Box* right() const; > bool intersects(const Display::Box::Rect&) const; >- LayoutUnit verticalPosition() const { return m_verticalPosition; } >- LayoutUnit bottom() const; >+ PositionInContextRoot verticalPosition() const { return m_verticalPosition; } >+ std::optional<PositionInContextRoot> horiztonalPosition(Float) const; >+ PositionInContextRoot bottom() const; > bool operator==(const FloatingPair&) const; > > private: >@@ -78,12 +80,12 @@ private: > > std::optional<unsigned> m_leftIndex; > std::optional<unsigned> m_rightIndex; >- LayoutUnit m_verticalPosition; >+ PositionInContextRoot m_verticalPosition; > }; > > class Iterator { > public: >- Iterator(const FloatingState::FloatList&, std::optional<LayoutUnit> verticalPosition); >+ Iterator(const FloatingState::FloatList&, std::optional<PositionInContextRoot> verticalPosition); > > const FloatingPair& operator*() const { return m_current; } > Iterator& operator++(); >@@ -91,13 +93,13 @@ public: > bool operator!=(const Iterator&) const; > > private: >- void set(LayoutUnit verticalPosition); >+ void set(PositionInContextRoot verticalPosition); > > const FloatingState::FloatList& m_floats; > FloatingPair m_current; > }; > >-static Iterator begin(const FloatingState& floatingState, LayoutUnit initialVerticalPosition) >+static Iterator begin(const FloatingState& floatingState, PositionInContextRoot initialVerticalPosition) > { > // Start with the inner-most floating pair for the initial vertical position. > return Iterator(floatingState.floats(), initialVerticalPosition); >@@ -113,25 +115,34 @@ FloatingContext::FloatingContext(FloatingState& floatingState) > { > } > >-Position FloatingContext::positionForFloat(const Box& layoutBox) const >+PointInContainingBlock FloatingContext::positionForFloat(const Box& layoutBox) const > { > ASSERT(layoutBox.isFloatingPositioned()); >- FloatingState::FloatItem floatItem = { layoutBox, m_floatingState }; > >- Position floatPosition; > if (m_floatingState.isEmpty()) { >+ auto& displayBox = *layoutContext().displayBoxForLayoutBox(layoutBox); >+ >+ auto alignWithContainingBlock = [&]() -> PositionInContainingBlock { >+ // If there is no floating to align with, push the box to the left/right edge of its containing block's content box. >+ auto& containingBlockDisplayBox = *layoutContext().displayBoxForLayoutBox(*layoutBox.containingBlock()); >+ >+ if (layoutBox.isLeftFloatingPositioned()) >+ return containingBlockDisplayBox.contentBoxLeft() + displayBox.marginLeft(); >+ >+ return containingBlockDisplayBox.contentBoxRight() - displayBox.marginRight() - displayBox.width(); >+ }; >+ > // No float box on the context yet -> align it with the containing block's left/right edge. >- auto& displayBox = floatItem.displayBox(); >- floatPosition = { alignWithContainingBlock(floatItem) + displayBox.marginLeft(), displayBox.top() }; >- } else { >- // Find the top most position where the float box fits. >- floatPosition = floatingPosition(floatItem); >+ return { alignWithContainingBlock(), displayBox.top() }; > } > >- return toContainingBlock(floatItem, floatPosition); >+ // Find the top most position where the float box fits. >+ FloatBox alignedBox = { layoutBox, m_floatingState, layoutContext() }; >+ floatingPosition(alignedBox); >+ return alignedBox.topLeftInContainingBlock(); > } > >-std::optional<LayoutUnit> FloatingContext::verticalPositionWithClearance(const Box& layoutBox) const >+std::optional<PositionInContainingBlock> FloatingContext::verticalPositionWithClearance(const Box& layoutBox) const > { > ASSERT(layoutBox.hasFloatClear()); > ASSERT(layoutBox.isBlockLevelBox()); >@@ -139,7 +150,7 @@ std::optional<LayoutUnit> FloatingContext::verticalPositionWithClearance(const B > if (m_floatingState.isEmpty()) > return { }; > >- auto bottom = [&](std::optional<LayoutUnit> floatBottom) -> std::optional<LayoutUnit> { >+ auto bottom = [&](std::optional<PositionInContextRoot> floatBottom) -> std::optional<PositionInContainingBlock> { > // 'bottom' is in the formatting root's coordinate system. > if (!floatBottom) > return { }; >@@ -202,104 +213,40 @@ std::optional<LayoutUnit> FloatingContext::verticalPositionWithClearance(const B > return { }; > } > >-Position FloatingContext::floatingPosition(const FloatingState::FloatItem& floatItem) const >+void FloatingContext::floatingPosition(FloatBox& floatBox) const > { >- auto initialVerticalPosition = this->initialVerticalPosition(floatItem); >- auto& displayBox = floatItem.displayBox(); >- auto marginBoxSize = displayBox.marginBox().size(); >- >+ std::optional<PositionInContextRoot> bottomMost; >+ auto initialLeft = floatBox.left(); > auto end = Layout::end(m_floatingState); >- auto top = initialVerticalPosition; >- auto bottomMost = top; >- for (auto iterator = begin(m_floatingState, initialVerticalPosition); iterator != end; ++iterator) { >+ for (auto iterator = begin(m_floatingState, floatBox.rectWithMargin().top()); iterator != end; ++iterator) { > ASSERT(!(*iterator).isEmpty()); >- > auto floats = *iterator; >- top = floats.verticalPosition(); > >- // Move the box horizontally so that it aligns with the current floating pair. >- auto left = alignWithFloatings(floats, floatItem); >- // Check if the box fits at this vertical position. >- if (!floats.intersects({ top, left, marginBoxSize.width(), marginBoxSize.height() })) >- return { left + displayBox.marginLeft(), top + displayBox.marginTop() }; >+ floatBox.setTop(floats.verticalPosition() + floatBox.marginTop()); >+ // Move the box horizontally so that it either >+ // 1. aligns with the current floating pair >+ // 2. or with the containing block's content box if there's no float to align with at this vertical position. >+ if (auto horiztonalPosition = floats.horiztonalPosition(floatBox.isLeftAligned() ? Float::Left : Float::Right)) { >+ if (!floatBox.isLeftAligned()) >+ horiztonalPosition = *horiztonalPosition - floatBox.rectWithMargin().width(); >+ floatBox.setLeft(*horiztonalPosition + floatBox.marginLeft()); >+ } else >+ floatBox.resetHorizontally(); >+ >+ // Check if the box fits at this position. >+ if (!floats.intersects(floatBox.rectWithMargin())) >+ return; > > bottomMost = floats.bottom(); > // Move to the next floating pair. > } > >- // Passed all the floats and still does not fit? >- return { alignWithContainingBlock(floatItem) + displayBox.marginLeft(), bottomMost + displayBox.marginTop() }; >-} >- >-LayoutUnit FloatingContext::initialVerticalPosition(const FloatingState::FloatItem& floatItem) const >-{ >- // Incoming floating cannot be placed higher than existing floats. >- // Take the static position (where the box would go if it wasn't floating) and adjust it with the last floating. >- auto marginBoxTop = floatItem.displayBox().rectWithMargin().top(); >- >- if (auto lastFloat = m_floatingState.last()) >- return std::max(marginBoxTop, lastFloat->displayBox().rectWithMargin().top()); >- >- return marginBoxTop; >-} >- >-LayoutUnit FloatingContext::alignWithContainingBlock(const FloatingState::FloatItem& floatItem) const >-{ >- // If there is no floating to align with, push the box to the left/right edge of its containing block's content box. >- // (Either there's no floats at all or this box does not fit at any vertical positions where the floats are.) >- auto& containingBlockDisplayBox = floatItem.containingBlockDisplayBox(); >- auto containingBlockContentBoxLeft = containingBlockDisplayBox.left() + containingBlockDisplayBox.contentBoxLeft(); >- >- if (floatItem.layoutBox().isLeftFloatingPositioned()) >- return containingBlockContentBoxLeft; >- >- return containingBlockContentBoxLeft + containingBlockDisplayBox.contentBoxWidth() - floatItem.displayBox().marginBox().width(); >-} >- >-LayoutUnit FloatingContext::alignWithFloatings(const FloatingPair& floatingPair, const FloatingState::FloatItem& floatItem) const >-{ >- // Compute the horizontal position for the new floating by taking both the contining block and the current left/right floats into account. >- auto& containingBlockDisplayBox = floatItem.containingBlockDisplayBox(); >- auto containingBlockContentBoxLeft = containingBlockDisplayBox.left() + containingBlockDisplayBox.contentBoxLeft(); >- auto containingBlockContentBoxRight = containingBlockDisplayBox.left() + containingBlockDisplayBox.contentBoxRight(); >- auto marginBoxWidth = floatItem.displayBox().marginBox().width(); >- >- auto leftAlignedBoxLeft = containingBlockContentBoxLeft; >- auto rightAlignedBoxLeft = containingBlockContentBoxRight - marginBoxWidth; >- >- if (floatingPair.isEmpty()) { >- ASSERT_NOT_REACHED(); >- return floatItem.layoutBox().isLeftFloatingPositioned() ? leftAlignedBoxLeft : rightAlignedBoxLeft; >- } >- >- if (floatItem.layoutBox().isLeftFloatingPositioned()) { >- if (auto* leftDisplayBox = floatingPair.left()) { >- auto leftFloatingBoxRight = leftDisplayBox->rectWithMargin().right(); >- return std::min(std::max(leftAlignedBoxLeft, leftFloatingBoxRight), rightAlignedBoxLeft); >- } >- >- return leftAlignedBoxLeft; >- } >- >- ASSERT(floatItem.layoutBox().isRightFloatingPositioned()); >- >- if (auto* rightDisplayBox = floatingPair.right()) { >- auto rightFloatingBoxLeft = rightDisplayBox->rectWithMargin().left(); >- return std::max(std::min(rightAlignedBoxLeft, rightFloatingBoxLeft - marginBoxWidth), leftAlignedBoxLeft); >- } >- >- return rightAlignedBoxLeft; >-} >- >-// FIXME: find a better place for this. >-Position FloatingContext::toContainingBlock(const FloatingState::FloatItem& floatItem, Position position) const >-{ >- // From formatting root coordinate system back to containing block's. >- if (&floatItem.containingBlock() == &m_floatingState.root()) >- return position; >+ // The candidate box is already below of all the floats. >+ if (!bottomMost) >+ return; > >- auto& containingBlockDisplayBox = floatItem.containingBlockDisplayBox(); >- return { position.x - containingBlockDisplayBox.left(), position.y - containingBlockDisplayBox.top() }; >+ // Passed all the floats and still does not fit? Push it below the last float. >+ floatBox.setTopLeft({ initialLeft, *bottomMost + floatBox.marginTop() }); > } > > FloatingPair::FloatingPair(const FloatingState::FloatList& floats) >@@ -359,14 +306,25 @@ bool FloatingPair::operator ==(const FloatingPair& other) const > return m_leftIndex == other.m_leftIndex && m_rightIndex == other.m_rightIndex; > } > >-LayoutUnit FloatingPair::bottom() const >+std::optional<PositionInContextRoot> FloatingPair::horiztonalPosition(Float floatType) const >+{ >+ if (floatType == Float::Left && left()) >+ return left()->rectWithMargin().right(); >+ >+ if (floatType == Float::Right && right()) >+ return right()->rectWithMargin().left(); >+ >+ return { }; >+} >+ >+PositionInContextRoot FloatingPair::bottom() const > { > auto* left = this->left(); > auto* right = this->right(); > ASSERT(left || right); > >- auto leftBottom = left ? std::optional<LayoutUnit>(left->rectWithMargin().bottom()) : std::nullopt; >- auto rightBottom = right ? std::optional<LayoutUnit>(right->rectWithMargin().bottom()) : std::nullopt; >+ auto leftBottom = left ? std::optional<PositionInContextRoot>(left->rectWithMargin().bottom()) : std::nullopt; >+ auto rightBottom = right ? std::optional<PositionInContextRoot>(right->rectWithMargin().bottom()) : std::nullopt; > > if (leftBottom && rightBottom) > return std::max(*leftBottom, *rightBottom); >@@ -377,7 +335,7 @@ LayoutUnit FloatingPair::bottom() const > return *rightBottom; > } > >-Iterator::Iterator(const FloatingState::FloatList& floats, std::optional<LayoutUnit> verticalPosition) >+Iterator::Iterator(const FloatingState::FloatList& floats, std::optional<PositionInContextRoot> verticalPosition) > : m_floats(floats) > , m_current(floats) > { >@@ -435,8 +393,8 @@ Iterator& Iterator::operator++() > // Ensure that the new floating's bottom edge is positioned lower than the current one -which essentially means skipping in-between floats that are positioned higher). > // 3. Reset the vertical position and align it with the new left-right pair. These floats are now the inner-most boxes for the current vertical position. > // As the result we have more horizontal space on the current vertical position. >- auto leftBottom = m_current.left() ? std::optional<LayoutUnit>(m_current.left()->bottom()) : std::nullopt; >- auto rightBottom = m_current.right() ? std::optional<LayoutUnit>(m_current.right()->bottom()) : std::nullopt; >+ auto leftBottom = m_current.left() ? std::optional<PositionInContextRoot>(m_current.left()->bottom()) : std::nullopt; >+ auto rightBottom = m_current.right() ? std::optional<PositionInContextRoot>(m_current.right()->bottom()) : std::nullopt; > > auto updateLeft = (leftBottom == rightBottom) || (!rightBottom || (leftBottom && leftBottom < rightBottom)); > auto updateRight = (leftBottom == rightBottom) || (!leftBottom || (rightBottom && leftBottom > rightBottom)); >@@ -456,7 +414,7 @@ Iterator& Iterator::operator++() > return *this; > } > >-void Iterator::set(LayoutUnit verticalPosition) >+void Iterator::set(PositionInContextRoot verticalPosition) > { > // Move the iterator to the initial vertical position by starting at the inner-most floating pair (last floats on left/right). > // 1. Check if the inner-most pair covers the vertical position. >diff --git a/Source/WebCore/layout/floats/FloatingContext.h b/Source/WebCore/layout/floats/FloatingContext.h >index d903a93da332c622bd5c7a3f4723f12fa95696a9..9988e5bae544da7df97f95de19d802fb1e7cf492 100644 >--- a/Source/WebCore/layout/floats/FloatingContext.h >+++ b/Source/WebCore/layout/floats/FloatingContext.h >@@ -35,6 +35,7 @@ namespace WebCore { > > namespace Layout { > >+class FloatBox; > class Box; > class Container; > class FloatingPair; >@@ -49,18 +50,13 @@ public: > > FloatingState& floatingState() const { return m_floatingState; } > >- Position positionForFloat(const Box&) const; >- std::optional<LayoutUnit> verticalPositionWithClearance(const Box&) const; >+ PointInContainingBlock positionForFloat(const Box&) const; >+ std::optional<PositionInContainingBlock> verticalPositionWithClearance(const Box&) const; > > private: > LayoutContext& layoutContext() const { return m_floatingState.layoutContext(); } > >- Position floatingPosition(const FloatingState::FloatItem&) const; >- >- LayoutUnit initialVerticalPosition(const FloatingState::FloatItem&) const; >- LayoutUnit alignWithContainingBlock(const FloatingState::FloatItem&) const; >- LayoutUnit alignWithFloatings(const FloatingPair&, const FloatingState::FloatItem&) const; >- Position toContainingBlock(const FloatingState::FloatItem&, Position) const; >+ void floatingPosition(FloatBox&) const; > > FloatingState& m_floatingState; > }; >diff --git a/Source/WebCore/layout/floats/FloatingState.h b/Source/WebCore/layout/floats/FloatingState.h >index 9a7e2b424f8c79e4423ad3692bdca69c2b172b77..77d7130c30abcf7d35378a1f5b1795d2ebe72dd7 100644 >--- a/Source/WebCore/layout/floats/FloatingState.h >+++ b/Source/WebCore/layout/floats/FloatingState.h >@@ -52,6 +52,8 @@ public: > > bool isEmpty() const { return m_floats.isEmpty(); } > >+ const Box& root() const { return *m_formattingContextRoot; } >+ > std::optional<LayoutUnit> leftBottom(const Box& formattingContextRoot) const; > std::optional<LayoutUnit> rightBottom(const Box& formattingContextRoot) const; > std::optional<LayoutUnit> bottom(const Box& formattingContextRoot) const; >@@ -82,7 +84,6 @@ private: > FloatingState(LayoutContext&, const Box& formattingContextRoot); > > LayoutContext& layoutContext() const { return m_layoutContext; } >- const Box& root() const { return *m_formattingContextRoot; } > > std::optional<LayoutUnit> bottom(const Box& formattingContextRoot, Clear) const; >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
koivisto
:
review+
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 188886
: 347920