[LFC][IFC] Introduce InlineFormattingContextGeometry class
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 30 Oct 2018 14:29:43 +0000 (14:29 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 30 Oct 2018 14:29:43 +0000 (14:29 +0000)
https://bugs.webkit.org/show_bug.cgi?id=191054

Reviewed by Antti Koivisto.

This is in preparation for inline-block support.

Move float and inline-block elements layout to layoutFormattingContextRoot().
computeWidthAndHeightForInlineBox takes care of replaced elements.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* layout/inlineformatting/InlineFormattingContext.cpp:
(WebCore::Layout::InlineFormattingContext::layout const):
(WebCore::Layout::InlineFormattingContext::layoutFormattingContextRoot const):
(WebCore::Layout::InlineFormattingContext::computeWidthAndHeightForInlineBox const):
(WebCore::Layout::InlineFormattingContext::computeWidthAndHeight const): Deleted.
* layout/inlineformatting/InlineFormattingContext.h:
* layout/inlineformatting/InlineFormattingContextGeometry.cpp: Added.
(WebCore::Layout::InlineFormattingContext::Geometry::inlineBlockWidthAndMargin):
(WebCore::Layout::InlineFormattingContext::Geometry::inlineBlockHeightAndMargin):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@237588 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/Sources.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp
Source/WebCore/layout/inlineformatting/InlineFormattingContext.h
Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp [new file with mode: 0644]

index 8110ab1..3c41eb6 100644 (file)
@@ -1,3 +1,27 @@
+2018-10-29  Zalan Bujtas  <zalan@apple.com>
+
+        [LFC][IFC] Introduce InlineFormattingContextGeometry class
+        https://bugs.webkit.org/show_bug.cgi?id=191054
+
+        Reviewed by Antti Koivisto.
+
+        This is in preparation for inline-block support.
+
+        Move float and inline-block elements layout to layoutFormattingContextRoot().
+        computeWidthAndHeightForInlineBox takes care of replaced elements.
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * layout/inlineformatting/InlineFormattingContext.cpp:
+        (WebCore::Layout::InlineFormattingContext::layout const):
+        (WebCore::Layout::InlineFormattingContext::layoutFormattingContextRoot const):
+        (WebCore::Layout::InlineFormattingContext::computeWidthAndHeightForInlineBox const):
+        (WebCore::Layout::InlineFormattingContext::computeWidthAndHeight const): Deleted.
+        * layout/inlineformatting/InlineFormattingContext.h:
+        * layout/inlineformatting/InlineFormattingContextGeometry.cpp: Added.
+        (WebCore::Layout::InlineFormattingContext::Geometry::inlineBlockWidthAndMargin):
+        (WebCore::Layout::InlineFormattingContext::Geometry::inlineBlockHeightAndMargin):
+
 2018-10-28  Antoine Quint  <graouts@apple.com>
 
         [Web Animations] Implement the update animations and send events procedure
index aeb662e..14b4b9f 100644 (file)
@@ -1262,6 +1262,7 @@ layout/floats/FloatBox.cpp
 layout/floats/FloatingContext.cpp
 layout/floats/FloatingState.cpp
 layout/inlineformatting/InlineFormattingContext.cpp
+layout/inlineformatting/InlineFormattingContextGeometry.cpp
 layout/inlineformatting/InlineFormattingState.cpp
 layout/inlineformatting/InlineInvalidation.cpp
 layout/inlineformatting/InlineLineBreaker.cpp
index 837a574..21d25fd 100644 (file)
                6F219D762178D37100BB033C /* Line.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Line.cpp; sourceTree = "<group>"; };
                6F222B741AB52D640094651A /* WebGLVertexArrayObjectBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebGLVertexArrayObjectBase.h; sourceTree = "<group>"; };
                6F222B751AB52D8A0094651A /* WebGLVertexArrayObjectBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebGLVertexArrayObjectBase.cpp; sourceTree = "<group>"; };
+               6F35EFAF2187CBD50044E0F4 /* InlineFormattingContextGeometry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InlineFormattingContextGeometry.cpp; sourceTree = "<group>"; };
                6F3E1F5F2136141700A65A08 /* FloatBox.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FloatBox.cpp; sourceTree = "<group>"; };
                6F3E1F612136141700A65A08 /* FloatBox.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FloatBox.h; sourceTree = "<group>"; };
                6F5217C42177F5A6006583BB /* InlineRunProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InlineRunProvider.h; sourceTree = "<group>"; };
                                6FE7DDDD20EC6E8B008B5B4E /* text */,
                                6F7CA3C9208C2B2E002F29AB /* InlineFormattingContext.cpp */,
                                6F7CA3C8208C2B2E002F29AB /* InlineFormattingContext.h */,
+                               6F35EFAF2187CBD50044E0F4 /* InlineFormattingContextGeometry.cpp */,
                                115CFA7D208B8E10001E6991 /* InlineFormattingState.cpp */,
                                115CFA7C208B8E10001E6991 /* InlineFormattingState.h */,
                                1123AFDD209ABBBA00736ACC /* InlineInvalidation.cpp */,
                                B2A10B930B3818D700099AA4 /* ImageBufferCG.cpp */,
                                2292B27B1356669400CF11EF /* ImageBufferDataCG.cpp */,
                                22BD9F80135364FE009BD102 /* ImageBufferDataCG.h */,
-                               CD3E21DB21833F5100E66F55 /* ImageBufferUtilitiesCG.h */,
                                CD58949321874064004F424A /* ImageBufferUtilitiesCG.cpp */,
+                               CD3E21DB21833F5100E66F55 /* ImageBufferUtilitiesCG.h */,
                                555B87EA1CAAF0AB00349425 /* ImageDecoderCG.cpp */,
                                555B87EB1CAAF0AB00349425 /* ImageDecoderCG.h */,
                                4B3480920EEF50D400AC1B41 /* ImageSourceCG.h */,
                                B2A10B920B3818BD00099AA4 /* ImageBuffer.h in Headers */,
                                22BD9F7F1353625C009BD102 /* ImageBufferData.h in Headers */,
                                22BD9F81135364FE009BD102 /* ImageBufferDataCG.h in Headers */,
+                               CD3E21DD2183444A00E66F55 /* ImageBufferUtilitiesCG.h in Headers */,
                                2D25396318CE7F6200270222 /* ImageControlsButtonElementMac.h in Headers */,
                                510192D618B6B9B7007FC7A1 /* ImageControlsRootElement.h in Headers */,
                                510192D218B6B9AB007FC7A1 /* ImageControlsRootElementMac.h in Headers */,
                                4B3480940EEF50D400AC1B41 /* ImageSourceCG.h in Headers */,
                                078ED193216D079500775B33 /* ImageTransferSessionVT.h in Headers */,
                                5550CB421E955E3C00111AA0 /* ImageTypes.h in Headers */,
-                               CD3E21DD2183444A00E66F55 /* ImageBufferUtilitiesCG.h in Headers */,
                                26F756B31B3B66F70005DD79 /* ImmutableNFA.h in Headers */,
                                26F756B51B3B68F20005DD79 /* ImmutableNFANodeBuilder.h in Headers */,
                                316FE1180E6E1DA700BF6088 /* ImplicitAnimation.h in Headers */,
                                7C3E510B18DF8F3500C112F7 /* HTMLConverter.mm in Sources */,
                                A8D06B3A0A265DCD005E7203 /* HTMLNames.cpp in Sources */,
                                1AC900C31943C0FC008625B5 /* HTTPHeaderNames.cpp in Sources */,
+                               CD58949521874064004F424A /* ImageBufferUtilitiesCG.cpp in Sources */,
                                CD19FEAF1F574B6D000C42FB /* ImageDecoderAVFObjC.mm in Sources */,
                                BE961C5418AD338500D07DC5 /* InbandDataTextTrack.cpp in Sources */,
                                BE16C59217CFE17200852C04 /* InbandGenericTextTrack.cpp in Sources */,
                                DE5F860A1FA2386A006DB63A /* UnifiedSource475.cpp in Sources */,
                                DE5F860B1FA2386A006DB63A /* UnifiedSource476.cpp in Sources */,
                                DE5F860C1FA2386A006DB63A /* UnifiedSource477.cpp in Sources */,
-                               CD58949521874064004F424A /* ImageBufferUtilitiesCG.cpp in Sources */,
                                DE5F860D1FA2386B006DB63A /* UnifiedSource478.cpp in Sources */,
                                DE5F860E1FA2386B006DB63A /* UnifiedSource479.cpp in Sources */,
                                DE5F860F1FA2386B006DB63A /* UnifiedSource480.cpp in Sources */,
index 1a50ad7..347e76e 100644 (file)
@@ -64,6 +64,15 @@ void InlineFormattingContext::layout(LayoutContext& layoutContext, FormattingSta
     auto* layoutBox = formattingRoot.firstInFlowOrFloatingChild();
     // Casually walk through the block's descendants and place the inline boxes one after the other as much as we can (yeah, I am looking at you floats).
     while (layoutBox) {
+
+        if (layoutBox->establishesFormattingContext()) {
+            layoutFormattingContextRoot(layoutContext, *layoutBox);
+            // Formatting context roots take care of their entire subtree. Continue with next sibling.
+            inlineRunProvider.append(*layoutBox);
+            layoutBox = layoutBox->nextInFlowOrFloatingSibling();
+            continue;
+        }
+
         if (is<Container>(layoutBox)) {
             ASSERT(is<InlineContainer>(layoutBox));
             layoutBox = downcast<Container>(*layoutBox).firstInFlowOrFloatingChild();
@@ -71,7 +80,7 @@ void InlineFormattingContext::layout(LayoutContext& layoutContext, FormattingSta
         }
 
         inlineRunProvider.append(*layoutBox);
-        computeWidthAndHeight(layoutContext, *layoutBox);
+        computeWidthAndHeightForInlineBox(layoutContext, *layoutBox);
 
         for (; layoutBox; layoutBox = layoutBox->parent()) {
             if (layoutBox == &formattingRoot) {
@@ -193,32 +202,68 @@ void InlineFormattingContext::layoutInlineContent(const LayoutContext& layoutCon
     line.close(Line::LastLine::Yes);
 }
 
-void InlineFormattingContext::computeWidthAndHeight(LayoutContext& layoutContext, const Box& layoutBox) const
+void InlineFormattingContext::layoutFormattingContextRoot(LayoutContext& layoutContext, const Box& layoutBox) const
 {
+    ASSERT(layoutBox.isFloatingPositioned() || layoutBox.isInlineBlockBox());
+    auto& displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
+
+    auto computeWidthAndMargin = [&]() {
+        WidthAndMargin widthAndMargin;
+
+        if (layoutBox.isFloatingPositioned())
+            widthAndMargin = Geometry::floatingWidthAndMargin(layoutContext, *this, layoutBox);
+        else if (layoutBox.isInlineBlockBox())
+            widthAndMargin = Geometry::inlineBlockWidthAndMargin(layoutContext, layoutBox);
+        else
+            ASSERT_NOT_REACHED();
+
+        displayBox.setContentBoxWidth(widthAndMargin.width);
+        displayBox.setHorizontalMargin(widthAndMargin.margin);
+        displayBox.setHorizontalNonComputedMargin(widthAndMargin.nonComputedMargin);
+    };
+
+    auto computeHeightAndMargin = [&]() {
+        HeightAndMargin heightAndMargin;
+
+        if (layoutBox.isFloatingPositioned())
+            heightAndMargin = Geometry::floatingHeightAndMargin(layoutContext, layoutBox);
+        else if (layoutBox.isInlineBlockBox())
+            heightAndMargin = Geometry::inlineBlockHeightAndMargin(layoutContext, layoutBox);
+        else
+            ASSERT_NOT_REACHED();
+
+        displayBox.setContentBoxHeight(heightAndMargin.height);
+        displayBox.setVerticalNonCollapsedMargin(heightAndMargin.margin);
+        displayBox.setVerticalMargin(heightAndMargin.collapsedMargin.value_or(heightAndMargin.margin));
+    };
+
+    computeBorderAndPadding(layoutContext, layoutBox);
+    computeWidthAndMargin();
+
+    // Swich over to the new formatting context (the one that the root creates).
+    layoutContext.formattingContext(layoutBox)->layout(layoutContext, layoutContext.createFormattingStateForFormattingRootIfNeeded(layoutBox));
+
+    // Come back and finalize the root's height and margin.
+    computeHeightAndMargin();
+}
+
+void InlineFormattingContext::computeWidthAndHeightForInlineBox(LayoutContext& layoutContext, const Box& layoutBox) const
+{
+    ASSERT(!layoutBox.isContainer());
+    ASSERT(!layoutBox.establishesFormattingContext());
+
     if (is<InlineBox>(layoutBox) && downcast<InlineBox>(layoutBox).hasTextContent()) {
         // Text content width is computed during text run generation. -It does not make any sense to measure unprocessed text here, since it will likely be
         // split up (or concatenated).
         return;
     }
 
-    if (layoutBox.isInlineBlockBox()) {
-        ASSERT_NOT_IMPLEMENTED_YET();
-        return;
-    }
-
+    // This is pretty much only for replaced inline boxes atm.
+    ASSERT(layoutBox.replaced());
     computeBorderAndPadding(layoutContext, layoutBox);
 
-    WidthAndMargin widthAndMargin;
-    HeightAndMargin heightAndMargin;
-
-    if (layoutBox.isFloatingPositioned()) {
-        widthAndMargin = Geometry::floatingWidthAndMargin(layoutContext, *this, layoutBox);
-        heightAndMargin = Geometry::floatingHeightAndMargin(layoutContext, layoutBox);
-    } else if (layoutBox.replaced()) {
-        widthAndMargin = Geometry::inlineReplacedWidthAndMargin(layoutContext, layoutBox);
-        heightAndMargin = Geometry::inlineReplacedHeightAndMargin(layoutContext, layoutBox);
-    } else
-        ASSERT_NOT_REACHED();
+    auto widthAndMargin = Geometry::inlineReplacedWidthAndMargin(layoutContext, layoutBox);
+    auto heightAndMargin = Geometry::inlineReplacedHeightAndMargin(layoutContext, layoutBox);
 
     auto& displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
     displayBox.setContentBoxWidth(widthAndMargin.width);
@@ -228,7 +273,6 @@ void InlineFormattingContext::computeWidthAndHeight(LayoutContext& layoutContext
     displayBox.setContentBoxHeight(heightAndMargin.height);
     displayBox.setVerticalNonCollapsedMargin(heightAndMargin.margin);
     displayBox.setVerticalMargin(heightAndMargin.collapsedMargin.value_or(heightAndMargin.margin));
-    return;
 }
 
 void InlineFormattingContext::computeFloatPosition(const LayoutContext& layoutContext, const FloatingContext& floatingContext, Line& line, const Box& floatBox) const
index cea2dab..a4e00b0 100644 (file)
@@ -95,10 +95,18 @@ private:
         bool m_closed { true };
     };
 
+    // This class implements positioning and sizing for boxes participating in a block formatting context.
+    class Geometry : public FormattingContext::Geometry {
+    public:
+        static HeightAndMargin inlineBlockHeightAndMargin(const LayoutContext&, const Box&);
+        static WidthAndMargin inlineBlockWidthAndMargin(const LayoutContext&, const Box&);
+    };
+
     void layoutInlineContent(const LayoutContext&, InlineFormattingState&, const InlineRunProvider&) const;
     void initializeNewLine(const LayoutContext&, InlineFormattingState&, Line&) const;
 
-    void computeWidthAndHeight(LayoutContext&, const Box&) const;
+    void layoutFormattingContextRoot(LayoutContext&, const Box&) const;
+    void computeWidthAndHeightForInlineBox(LayoutContext&, const Box&) const;
     void computeFloatPosition(const LayoutContext&, const FloatingContext&, Line&, const Box&) const;
     void computeStaticPosition(const LayoutContext&, const Box&) const override;
     void computeInFlowPositionedPosition(const LayoutContext&, const Box&) const override;
diff --git a/Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp b/Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp
new file mode 100644 (file)
index 0000000..795c7ee
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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 "InlineFormattingContext.h"
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include "FormattingContext.h"
+
+namespace WebCore {
+namespace Layout {
+
+WidthAndMargin InlineFormattingContext::Geometry::inlineBlockWidthAndMargin(const LayoutContext&, const Box&)
+{
+    return { };
+}
+
+HeightAndMargin InlineFormattingContext::Geometry::inlineBlockHeightAndMargin(const LayoutContext&, const Box&)
+{
+    return { };
+}
+
+}
+}
+
+#endif