Title: [129530] trunk
Revision
129530
Author
[email protected]
Date
2012-09-25 11:22:39 -0700 (Tue, 25 Sep 2012)

Log Message

[CSS Exclusions] Enable css exclusions for multiple blocks per element
https://bugs.webkit.org/show_bug.cgi?id=89993

Patch by Bear Travis <[email protected]> on 2012-09-25
Reviewed by Julien Chaffraix.

Source/WebCore:

Similar to multi-column layout, a parent RenderBlock's WrapShapeInfo may affect
the inline content of its children. This patch follows the example of ColumnInfo
and adds WrapShapeInfo to LayoutState, which tracks the current shape-inside that
inline content should respect.

Tests: fast/exclusions/shape-inside/shape-inside-multiple-blocks.html
       fast/exclusions/shape-inside/shape-inside-multiple-blocks-vertical.html

* rendering/LayoutState.cpp:
(WebCore::LayoutState::LayoutState): Initialize m_wrapShapeInfo.
* rendering/LayoutState.h:
(WebCore):
(WebCore::LayoutState::LayoutState): Initialize m_wrapShapeInfo.
(LayoutState):
(WebCore::LayoutState::wrapShapeInfo): Getter for m_wrapShapeInfo.
* rendering/RenderBlockLineLayout.cpp:
(WebCore::LineWidth::LineWidth): Use LayoutState to lookup WrapShapeInfo.
(WebCore::RenderBlock::computeInlineDirectionPositionsForLine): Ditto.
(WebCore::RenderBlock::layoutRunsAndFloatsInRange): Ditto.
* rendering/RenderView.h:
(WebCore::RenderView::pushLayoutState): Push LayoutState if a WrapShapeInfo
is present.

LayoutTests:

Adding tests to cover the case where a shape-inside affects block children's
inline content.

* fast/exclusions/shape-inside/shape-inside-multiple-blocks-expected.html: Added.
* fast/exclusions/shape-inside/shape-inside-multiple-blocks-vertical-expected.html: Added.
* fast/exclusions/shape-inside/shape-inside-multiple-blocks-vertical.html: Added.
* fast/exclusions/shape-inside/shape-inside-multiple-blocks.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (129529 => 129530)


--- trunk/LayoutTests/ChangeLog	2012-09-25 18:19:45 UTC (rev 129529)
+++ trunk/LayoutTests/ChangeLog	2012-09-25 18:22:39 UTC (rev 129530)
@@ -1,3 +1,18 @@
+2012-09-25  Bear Travis  <[email protected]>
+
+        [CSS Exclusions] Enable css exclusions for multiple blocks per element
+        https://bugs.webkit.org/show_bug.cgi?id=89993
+
+        Reviewed by Julien Chaffraix.
+
+        Adding tests to cover the case where a shape-inside affects block children's
+        inline content.
+
+        * fast/exclusions/shape-inside/shape-inside-multiple-blocks-expected.html: Added.
+        * fast/exclusions/shape-inside/shape-inside-multiple-blocks-vertical-expected.html: Added.
+        * fast/exclusions/shape-inside/shape-inside-multiple-blocks-vertical.html: Added.
+        * fast/exclusions/shape-inside/shape-inside-multiple-blocks.html: Added.
+
 2012-09-24  Emil A Eklund  <[email protected]>
 
         [chromium] REGRESSION: Incorrect preferred width calculation for table cells

Added: trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-multiple-blocks-expected.html (0 => 129530)


--- trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-multiple-blocks-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-multiple-blocks-expected.html	2012-09-25 18:22:39 UTC (rev 129530)
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+    #shape-inside {
+        width: 170px;
+        height: 280px;
+        padding: 15px 20px 5px 10px;
+        position: relative;
+    }
+    #border {
+        position: absolute;
+        top: 13px;
+        left: 8px;
+        width: 170px;
+        height: 280px;
+        border: 2px solid blue;
+    }
+    p { margin-top: 0; }
+</style>
+</head>
+<body>
+    <div id="shape-inside">
+        <div id="border"></div>
+        <div>
+            <p>Paragraph 1. This paragraph should be just below the top edge of the blue
+            rectangle. It's left and right edges should be within the blue rectangle.
+        </div>
+        <p>Paragraph 2. This paragraph should be just below paragraph 1. Its left
+        and right edges should also be within the blue rectangle.
+    </div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-multiple-blocks-vertical-expected.html (0 => 129530)


--- trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-multiple-blocks-vertical-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-multiple-blocks-vertical-expected.html	2012-09-25 18:22:39 UTC (rev 129530)
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+    .shape-inside {
+        width: 170px;
+        height: 280px;
+        padding: 15px 20px 5px 10px;
+        position: relative;
+    }
+    .rl { -webkit-writing-mode: vertical-rl; }
+    .lr { -webkit-writing-mode: vertical-lr; }
+    .border {
+        position: absolute;
+        top: 13px;
+        left: 8px;
+        width: 170px;
+        height: 280px;
+        border: 2px solid blue;
+    }
+    p { -webkit-margin-before: 0; }
+</style>
+</head>
+<body>
+    <div class="shape-inside rl">
+        <div class="border"></div>
+        <div>
+            <p>Paragraph 1. This paragraph should start at the top right corner of the blue
+            rectangle. Its top and bottom edges should be within the blue rectangle.
+        </div>
+        <p>Paragraph 2. This paragraph should be to the left of paragraph 1. Its top
+        and bottom edges should also be within the blue rectangle.
+    </div>
+    <div class="shape-inside lr">
+        <div class="border"></div>
+        <div>
+            <p>Paragraph 1. This paragraph should start at the top left corner of the blue
+            rectangle. Its top and bottom edges should be within the blue rectangle.
+        </div>
+        <p>Paragraph 2. This paragraph should be to the right of paragraph 1. Its top
+        and bottom edges should also be within the blue rectangle.
+    </div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-multiple-blocks-vertical.html (0 => 129530)


--- trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-multiple-blocks-vertical.html	                        (rev 0)
+++ trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-multiple-blocks-vertical.html	2012-09-25 18:22:39 UTC (rev 129530)
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+    if (window.internals)
+        window.internals.settings.setCSSExclusionsEnabled(true);
+</script>
+<style>
+    .shape-inside {
+        width: 200px;
+        height: 300px;
+        -webkit-shape-inside: rectangle(10px, 15px, 170px, 280px);
+        position: relative;
+    }
+    .rl { -webkit-writing-mode: vertical-rl; }
+    .lr { -webkit-writing-mode: vertical-lr; }
+    .border {
+        position: absolute;
+        top: 13px;
+        left: 8px;
+        width: 170px;
+        height: 280px;
+        border: 2px solid blue;
+    }
+    p { -webkit-margin-before: 0; }
+</style>
+</head>
+<body>
+    <div class="shape-inside rl">
+        <div class="border"></div>
+        <div>
+            <p>Paragraph 1. This paragraph should start at the top right corner of the blue
+            rectangle. Its top and bottom edges should be within the blue rectangle.
+        </div>
+        <p>Paragraph 2. This paragraph should be to the left of paragraph 1. Its top
+        and bottom edges should also be within the blue rectangle.
+    </div>
+    <div class="shape-inside lr">
+        <div class="border"></div>
+        <div>
+            <p>Paragraph 1. This paragraph should start at the top left corner of the blue
+            rectangle. Its top and bottom edges should be within the blue rectangle.
+        </div>
+        <p>Paragraph 2. This paragraph should be to the right of paragraph 1. Its top
+        and bottom edges should also be within the blue rectangle.
+    </div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-multiple-blocks.html (0 => 129530)


--- trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-multiple-blocks.html	                        (rev 0)
+++ trunk/LayoutTests/fast/exclusions/shape-inside/shape-inside-multiple-blocks.html	2012-09-25 18:22:39 UTC (rev 129530)
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+    if (window.internals)
+        window.internals.settings.setCSSExclusionsEnabled(true);
+</script>
+<style>
+    #shape-inside {
+        width: 200px;
+        height: 300px;
+        -webkit-shape-inside: rectangle(10px, 15px, 170px, 280px);
+        position: relative;
+    }
+    #border {
+        position: absolute;
+        top: 13px;
+        left: 8px;
+        width: 170px;
+        height: 280px;
+        border: 2px solid blue;
+    }
+    p { margin-top: 0; }
+</style>
+</head>
+<body>
+    <div id="shape-inside">
+        <div id="border"></div>
+        <div>
+            <p>Paragraph 1. This paragraph should be just below the top edge of the blue
+            rectangle. It's left and right edges should be within the blue rectangle.
+        </div>
+        <p>Paragraph 2. This paragraph should be just below paragraph 1. Its left
+        and right edges should also be within the blue rectangle.
+    </div>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (129529 => 129530)


--- trunk/Source/WebCore/ChangeLog	2012-09-25 18:19:45 UTC (rev 129529)
+++ trunk/Source/WebCore/ChangeLog	2012-09-25 18:22:39 UTC (rev 129530)
@@ -1,3 +1,33 @@
+2012-09-25  Bear Travis  <[email protected]>
+
+        [CSS Exclusions] Enable css exclusions for multiple blocks per element
+        https://bugs.webkit.org/show_bug.cgi?id=89993
+
+        Reviewed by Julien Chaffraix.
+
+        Similar to multi-column layout, a parent RenderBlock's WrapShapeInfo may affect
+        the inline content of its children. This patch follows the example of ColumnInfo
+        and adds WrapShapeInfo to LayoutState, which tracks the current shape-inside that
+        inline content should respect.
+
+        Tests: fast/exclusions/shape-inside/shape-inside-multiple-blocks.html
+               fast/exclusions/shape-inside/shape-inside-multiple-blocks-vertical.html
+
+        * rendering/LayoutState.cpp:
+        (WebCore::LayoutState::LayoutState): Initialize m_wrapShapeInfo.
+        * rendering/LayoutState.h:
+        (WebCore):
+        (WebCore::LayoutState::LayoutState): Initialize m_wrapShapeInfo.
+        (LayoutState):
+        (WebCore::LayoutState::wrapShapeInfo): Getter for m_wrapShapeInfo.
+        * rendering/RenderBlockLineLayout.cpp:
+        (WebCore::LineWidth::LineWidth): Use LayoutState to lookup WrapShapeInfo.
+        (WebCore::RenderBlock::computeInlineDirectionPositionsForLine): Ditto.
+        (WebCore::RenderBlock::layoutRunsAndFloatsInRange): Ditto.
+        * rendering/RenderView.h:
+        (WebCore::RenderView::pushLayoutState): Push LayoutState if a WrapShapeInfo
+        is present.
+
 2012-09-24  Emil A Eklund  <[email protected]>
 
         [chromium] REGRESSION: Incorrect preferred width calculation for table cells

Modified: trunk/Source/WebCore/rendering/LayoutState.cpp (129529 => 129530)


--- trunk/Source/WebCore/rendering/LayoutState.cpp	2012-09-25 18:19:45 UTC (rev 129529)
+++ trunk/Source/WebCore/rendering/LayoutState.cpp	2012-09-25 18:22:39 UTC (rev 129530)
@@ -42,6 +42,9 @@
 #ifndef NDEBUG
     , m_renderer(renderer)
 #endif
+#if ENABLE(CSS_EXCLUSIONS)
+    , m_wrapShapeInfo(0)
+#endif
 {
     ASSERT(m_next);
 
@@ -107,6 +110,14 @@
     if (!m_columnInfo)
         m_columnInfo = m_next->m_columnInfo;
 
+#if ENABLE(CSS_EXCLUSIONS)
+    if (renderer->isRenderBlock()) {
+        m_wrapShapeInfo = toRenderBlock(renderer)->wrapShapeInfo();
+        if (!m_wrapShapeInfo)
+            m_wrapShapeInfo = m_next->m_wrapShapeInfo;
+    }
+#endif
+
     m_layoutDelta = m_next->m_layoutDelta;
     
     m_isPaginated = m_pageLogicalHeight || m_columnInfo || renderer->isRenderFlowThread();
@@ -132,6 +143,9 @@
 #ifndef NDEBUG
     , m_renderer(root)
 #endif
+#if ENABLE(CSS_EXCLUSIONS)
+    , m_wrapShapeInfo(0)
+#endif
 {
     RenderObject* container = root->container();
     FloatPoint absContentPoint = container->localToAbsolute(FloatPoint(), false, true);

Modified: trunk/Source/WebCore/rendering/LayoutState.h (129529 => 129530)


--- trunk/Source/WebCore/rendering/LayoutState.h	2012-09-25 18:19:45 UTC (rev 129529)
+++ trunk/Source/WebCore/rendering/LayoutState.h	2012-09-25 18:22:39 UTC (rev 129530)
@@ -38,6 +38,9 @@
 class RenderBox;
 class RenderObject;
 class RenderFlowThread;
+#if ENABLE(CSS_EXCLUSIONS)
+class WrapShapeInfo;
+#endif
 
 class LayoutState {
     WTF_MAKE_NONCOPYABLE(LayoutState);
@@ -53,6 +56,9 @@
 #ifndef NDEBUG
         , m_renderer(0)
 #endif
+#if ENABLE(CSS_EXCLUSIONS)
+        , m_wrapShapeInfo(0)
+#endif
     {
     }
 
@@ -88,6 +94,9 @@
 
     bool needsBlockDirectionLocationSetBeforeLayout() const { return m_lineGrid || (m_isPaginated && m_pageLogicalHeight); }
 
+#if ENABLE(CSS_EXCLUSIONS)
+    WrapShapeInfo* wrapShapeInfo() const { return m_wrapShapeInfo; }
+#endif
 private:
     // The normal operator new is disallowed.
     void* operator new(size_t) throw();
@@ -129,6 +138,9 @@
 #ifndef NDEBUG
     RenderObject* m_renderer;
 #endif
+#if ENABLE(CSS_EXCLUSIONS)
+    WrapShapeInfo* m_wrapShapeInfo;
+#endif
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp (129529 => 129530)


--- trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp	2012-09-25 18:19:45 UTC (rev 129529)
+++ trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp	2012-09-25 18:22:39 UTC (rev 129530)
@@ -63,6 +63,13 @@
 // We don't let our line box tree for a single line get any deeper than this.
 const unsigned cMaxLineDepth = 200;
 
+#if ENABLE(CSS_EXCLUSIONS)
+static inline WrapShapeInfo* layoutWrapShapeInfo(const RenderBlock* block)
+{
+    return block->view()->layoutState()->wrapShapeInfo();
+}
+#endif
+
 class LineWidth {
 public:
     LineWidth(RenderBlock* block, bool isFirstLine)
@@ -80,7 +87,7 @@
     {
         ASSERT(block);
 #if ENABLE(CSS_EXCLUSIONS)
-        WrapShapeInfo* wrapShapeInfo = m_block->wrapShapeInfo();
+        WrapShapeInfo* wrapShapeInfo = layoutWrapShapeInfo(m_block);
         // FIXME: Bug 91878: Add support for multiple segments, currently we only support one
         if (wrapShapeInfo && wrapShapeInfo->lineState() == WrapShapeInfo::LINE_INSIDE_SHAPE) {
             // All interior shape positions should have at least one segment
@@ -804,7 +811,7 @@
     float logicalLeft = pixelSnappedLogicalLeftOffsetForLine(logicalHeight(), firstLine, lineLogicalHeight);
     float logicalRight = pixelSnappedLogicalRightOffsetForLine(logicalHeight(), firstLine, lineLogicalHeight);
 #if ENABLE(CSS_EXCLUSIONS)
-    WrapShapeInfo* wrapShapeInfo = this->wrapShapeInfo();
+    WrapShapeInfo* wrapShapeInfo = layoutWrapShapeInfo(this);
     if (wrapShapeInfo && wrapShapeInfo->lineState() == WrapShapeInfo::LINE_INSIDE_SHAPE) {
         logicalLeft = max<float>(roundToInt(wrapShapeInfo->segments()[0].logicalLeft), logicalLeft);
         logicalRight = min<float>(floorToInt(wrapShapeInfo->segments()[0].logicalRight), logicalRight);
@@ -1296,10 +1303,18 @@
     LineBreaker lineBreaker(this);
 
 #if ENABLE(CSS_EXCLUSIONS)
-    WrapShapeInfo* wrapShapeInfo = this->wrapShapeInfo();
-    // Move to the top of the shape inside to begin layout
-    if (wrapShapeInfo && logicalHeight() < wrapShapeInfo->shapeLogicalTop())
-        setLogicalHeight(wrapShapeInfo->shapeLogicalTop());
+    LayoutUnit absoluteLogicalTop;
+    WrapShapeInfo* wrapShapeInfo = layoutWrapShapeInfo(this);
+    if (wrapShapeInfo) {
+        if (wrapShapeInfo != this->wrapShapeInfo()) {
+            // FIXME: If layout state is disabled, the offset will be incorrect.
+            LayoutSize layoutOffset = view()->layoutState()->layoutOffset();
+            absoluteLogicalTop = logicalTop() + (isHorizontalWritingMode() ? layoutOffset.height() : layoutOffset.width());
+        }
+        // Begin layout at the logical top of our shape inside.
+        if (logicalHeight() + absoluteLogicalTop < wrapShapeInfo->shapeLogicalTop())
+            setLogicalHeight(wrapShapeInfo->shapeLogicalTop() - absoluteLogicalTop);
+    }
 #endif
 
     while (!end.atEnd()) {
@@ -1321,10 +1336,8 @@
         bool isNewUBAParagraph = layoutState.lineInfo().previousLineBrokeCleanly();
         FloatingObject* lastFloatFromPreviousLine = (m_floatingObjects && !m_floatingObjects->set().isEmpty()) ? m_floatingObjects->set().last() : 0;
 #if ENABLE(CSS_EXCLUSIONS)
-        // FIXME: Bug 89993: If the wrap shape comes from a parent, we will need to adjust
-        // the height coordinate
         if (wrapShapeInfo)
-            wrapShapeInfo->computeSegmentsForLine(logicalHeight());
+            wrapShapeInfo->computeSegmentsForLine(logicalHeight() + absoluteLogicalTop);
 #endif
         end = lineBreaker.nextLineBreak(resolver, layoutState.lineInfo(), renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines);
         if (resolver.position().atEnd()) {

Modified: trunk/Source/WebCore/rendering/RenderView.h (129529 => 129530)


--- trunk/Source/WebCore/rendering/RenderView.h	2012-09-25 18:19:45 UTC (rev 129529)
+++ trunk/Source/WebCore/rendering/RenderView.h	2012-09-25 18:22:39 UTC (rev 129530)
@@ -223,7 +223,11 @@
     {
         // We push LayoutState even if layoutState is disabled because it stores layoutDelta too.
         if (!doingFullRepaint() || m_layoutState->isPaginated() || renderer->hasColumns() || renderer->inRenderFlowThread()
-            || m_layoutState->lineGrid() || (renderer->style()->lineGrid() != RenderStyle::initialLineGrid() && renderer->isBlockFlow())) {
+            || m_layoutState->lineGrid() || (renderer->style()->lineGrid() != RenderStyle::initialLineGrid() && renderer->isBlockFlow())
+#if ENABLE(CSS_EXCLUSIONS)
+            || (renderer->isRenderBlock() && toRenderBlock(renderer)->wrapShapeInfo())
+#endif
+            ) {
             m_layoutState = new (renderArena()) LayoutState(m_layoutState, renderer, offset, pageHeight, pageHeightChanged, colInfo);
             return true;
         }
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to