Title: [148056] trunk
Revision
148056
Author
[email protected]
Date
2013-04-09 15:31:55 -0700 (Tue, 09 Apr 2013)

Log Message

[CSS Exclusions] Properly position multiple stacked floats with non rectangular shape outside
https://bugs.webkit.org/show_bug.cgi?id=110372

Patch by Bem Jones-Bey <[email protected]> on 2013-04-09
Reviewed by Dean Jackson.

Source/WebCore:

Stacked floats get positioned based on the bounding box of the shape,
not on the shape contours itself. This patch causes that to happen.

Test: fast/exclusions/shape-outside-floats/shape-outside-floats-stacked.html

* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::computeLogicalLocationForFloat): Use the
    "BoundingBoxOffset" mode so that we compute offsets based on the shape
    bounding boxes of previous floats, not the shape contour.
(WebCore::RenderBlock::logicalLeftOffsetForLine): Check the
    ShapeOutsideFloatOffsetMode to determine if the offset should be
    adjusted for the shape contour or not.
(WebCore::RenderBlock::logicalRightOffsetForLine): Ditto.
* rendering/RenderBlock.h:
(WebCore::RenderBlock::logicalRightOffsetForLine): Add parameter for offset mode.
(WebCore::RenderBlock::logicalLeftOffsetForLine): Ditto.
(RenderBlock):
* rendering/RenderBlockLineLayout.cpp:
(WebCore::LineWidth::shrinkAvailableWidthForNewFloatIfNeeded): If the
    new float is being added on top of a previous float on the same line,
    undo the offset for the previous float's shape contour so that we
    position the new float based on the bounding box.

LayoutTests:

Tests demonstrating stacked floats properly working with shape-outside.

* fast/exclusions/shape-outside-floats/shape-outside-floats-stacked-expected.html: Added.
* fast/exclusions/shape-outside-floats/shape-outside-floats-stacked.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (148055 => 148056)


--- trunk/LayoutTests/ChangeLog	2013-04-09 22:02:17 UTC (rev 148055)
+++ trunk/LayoutTests/ChangeLog	2013-04-09 22:31:55 UTC (rev 148056)
@@ -1,3 +1,15 @@
+2013-04-09  Bem Jones-Bey  <[email protected]>
+
+        [CSS Exclusions] Properly position multiple stacked floats with non rectangular shape outside
+        https://bugs.webkit.org/show_bug.cgi?id=110372
+
+        Reviewed by Dean Jackson.
+
+        Tests demonstrating stacked floats properly working with shape-outside.
+
+        * fast/exclusions/shape-outside-floats/shape-outside-floats-stacked-expected.html: Added.
+        * fast/exclusions/shape-outside-floats/shape-outside-floats-stacked.html: Added.
+
 2013-04-09  Eric Carlson  <[email protected]>
 
         [Mac] user caption styles not applied to correct element

Added: trunk/LayoutTests/fast/exclusions/shape-outside-floats/shape-outside-floats-stacked-expected.html (0 => 148056)


--- trunk/LayoutTests/fast/exclusions/shape-outside-floats/shape-outside-floats-stacked-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/exclusions/shape-outside-floats/shape-outside-floats-stacked-expected.html	2013-04-09 22:31:55 UTC (rev 148056)
@@ -0,0 +1,106 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <style>
+    .container {
+      width: 500px;
+      font: 40px/1 Ahem, sans-serif;
+    }
+    .left {
+      position: relative;
+      float: left;
+      clear: left;
+      height: 40px;
+    }
+    .triangle-left:before {
+      display: block;
+      position: absolute;
+      content: ' ';
+      z-index: -1;
+      top: 0px;
+      left: 0px;
+      width: 0; height: 0;
+      background-color: transparent;
+      border-top: 100px solid transparent;
+      border-left: 100px solid rgba(0, 0, 255, 0.5);
+    }
+    .triangle-left2:before {
+      display: block;
+      position: absolute;
+      content: ' ';
+      z-index: -1;
+      top: 0px;
+      left: 100px;
+      width: 0; height: 0;
+      background-color: transparent;
+      border-top: 100px solid transparent;
+      border-left: 100px solid rgba(0, 0, 255, 0.5);
+    }
+    .right {
+      position: relative;
+      float: right;
+      clear: right;
+      height: 40px;
+    }
+    .triangle-right:before {
+      display: block;
+      position: absolute;
+      content: ' ';
+      z-index: -1;
+      top: 0px;
+      right: 0px;
+      width: 0; height: 0;
+      background-color: transparent;
+      border-top: 100px solid transparent;
+      border-right: 100px solid rgba(0, 0, 255, 0.5);
+    }
+    .triangle-right2:before {
+      display: block;
+      position: absolute;
+      content: ' ';
+      z-index: -1;
+      top: 0px;
+      right: 100px;
+      width: 0; height: 0;
+      background-color: transparent;
+      border-top: 100px solid transparent;
+      border-right: 100px solid rgba(0, 0, 255, 0.5);
+    }
+  </style>
+</head>
+<body>
+  <h1>Bug <a href="" - [CSS Exclusions] Properly position multiple stacked floats with non rectangular shape outside</h1>
+  <h2>There should be two trianges on the left, and one on the right. None of
+    the triangles shoud overlap, and the black boxes should wrap around the triangles on the left.</h2>
+  <div class="container">
+    <div style="width:40px;" class="left triangle-left"></div>
+    X X X X
+    <div style="height: 100px; width: 100px;" class="right triangle-left"></div>
+    <div style="width:80px;" class="left"></div>
+    X X X X
+    <div style="width:140px;" class="left triangle-left2"></div>
+    <div style="width:180px;" class="left"></div>
+    <div style="width:200px;" class="left"></div>
+    X X X X
+    X X X X
+    X X X X
+    X X X X X X
+  </div>
+  <h2>There should be two trianges on the right, and one on the left. None of
+    the triangles shoud overlap, and the black boxes should wrap around the triangles on the right.</h2>
+  <div style="text-align: right" class="container">
+    <div style="width:40px;" class="right triangle-right"></div>
+    X X X X
+    <div style="height: 100px; width: 100px;" class="left triangle-right"></div>
+    <div style="width:80px;" class="right"></div>
+    X X X X
+    <div style="width:140px;" class="right triangle-right2"></div>
+    <div style="width:180px;" class="right"></div>
+    <div style="width:200px;" class="right"></div>
+    X X X X
+    X X X X
+    X X X X
+    X X X X X X
+  </div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/exclusions/shape-outside-floats/shape-outside-floats-stacked.html (0 => 148056)


--- trunk/LayoutTests/fast/exclusions/shape-outside-floats/shape-outside-floats-stacked.html	                        (rev 0)
+++ trunk/LayoutTests/fast/exclusions/shape-outside-floats/shape-outside-floats-stacked.html	2013-04-09 22:31:55 UTC (rev 148056)
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <script>
+    if (window.internals)
+      window.internals.settings.setCSSExclusionsEnabled(true);
+  </script>
+  <style>
+    .container {
+      width: 500px;
+      font: 40px/1 Ahem, sans-serif;
+    }
+    .triangle-left {
+      position: relative;
+      width: 100px;
+      height: 100px;
+      float: left;
+      -webkit-shape-outside: polygon(0 0, 0 100%, 100% 100%);
+    }
+    .triangle-left:before {
+      display: block;
+      position: absolute;
+      content: ' ';
+      z-index: -1;
+      top: 0px;
+      left: 0px;
+      width: 0; height: 0;
+      background-color: transparent;
+      border-top: 100px solid transparent;
+      border-left: 100px solid rgba(0, 0, 255, 0.5);
+    }
+    .triangle-right {
+      position: relative;
+      width: 100px;
+      height: 100px;
+      float: right;
+      -webkit-shape-outside: polygon(100% 0, 100% 100%, 0% 100%);
+    }
+    .triangle-right:before {
+      display: block;
+      position: absolute;
+      content: ' ';
+      z-index: -1;
+      top: 0px;
+      left: 0px;
+      width: 0; height: 0;
+      background-color: transparent;
+      border-top: 100px solid transparent;
+      border-right: 100px solid rgba(0, 0, 255, 0.5);
+    }
+  </style>
+</head>
+<body>
+  <h1>Bug <a href="" - [CSS Exclusions] Properly position multiple stacked floats with non rectangular shape outside</h1>
+  <h2>There should be two trianges on the left, and one on the right. None of
+    the triangles shoud overlap, and the black boxes should wrap around the triangles on the left.</h2>
+  <div class="container">
+    <div class="triangle-left"></div>
+    X X X X
+    <div style="float:right" class="triangle-left"></div>
+    X X X X
+    <div class="triangle-left"></div>
+    X X X X
+    X X X X
+    X X X X
+    X X X X X X
+  </div>
+  <h2>There should be two trianges on the right, and one on the left. None of
+    the triangles shoud overlap, and the black boxes should wrap around the triangles on the right.</h2>
+  <div style="text-align: right" class="container">
+    <div class="triangle-right"></div>
+    X X X X
+    <div style="float:left" class="triangle-right"></div>
+    X X X X
+    <div class="triangle-right"></div>
+    X X X X
+    X X X X
+    X X X X
+    X X X X X X
+  </div>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (148055 => 148056)


--- trunk/Source/WebCore/ChangeLog	2013-04-09 22:02:17 UTC (rev 148055)
+++ trunk/Source/WebCore/ChangeLog	2013-04-09 22:31:55 UTC (rev 148056)
@@ -1,3 +1,33 @@
+2013-04-09  Bem Jones-Bey  <[email protected]>
+
+        [CSS Exclusions] Properly position multiple stacked floats with non rectangular shape outside
+        https://bugs.webkit.org/show_bug.cgi?id=110372
+
+        Reviewed by Dean Jackson.
+
+        Stacked floats get positioned based on the bounding box of the shape,
+        not on the shape contours itself. This patch causes that to happen.
+
+        Test: fast/exclusions/shape-outside-floats/shape-outside-floats-stacked.html
+
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::computeLogicalLocationForFloat): Use the
+            "BoundingBoxOffset" mode so that we compute offsets based on the shape
+            bounding boxes of previous floats, not the shape contour.
+        (WebCore::RenderBlock::logicalLeftOffsetForLine): Check the
+            ShapeOutsideFloatOffsetMode to determine if the offset should be
+            adjusted for the shape contour or not.
+        (WebCore::RenderBlock::logicalRightOffsetForLine): Ditto.
+        * rendering/RenderBlock.h:
+        (WebCore::RenderBlock::logicalRightOffsetForLine): Add parameter for offset mode.
+        (WebCore::RenderBlock::logicalLeftOffsetForLine): Ditto.
+        (RenderBlock):
+        * rendering/RenderBlockLineLayout.cpp:
+        (WebCore::LineWidth::shrinkAvailableWidthForNewFloatIfNeeded): If the
+            new float is being added on top of a previous float on the same line,
+            undo the offset for the previous float's shape contour so that we
+            position the new float based on the bounding box.
+
 2013-04-09  Eric Carlson  <[email protected]>
 
         Unreviewed, fix the Windows build after r148050.

Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (148055 => 148056)


--- trunk/Source/WebCore/rendering/RenderBlock.cpp	2013-04-09 22:02:17 UTC (rev 148055)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp	2013-04-09 22:31:55 UTC (rev 148056)
@@ -4024,10 +4024,10 @@
     if (childBox->style()->floating() == LeftFloat) {
         LayoutUnit heightRemainingLeft = 1;
         LayoutUnit heightRemainingRight = 1;
-        floatLogicalLeft = logicalLeftOffsetForLine(logicalTopOffset, logicalLeftOffset, false, &heightRemainingLeft);
-        while (logicalRightOffsetForLine(logicalTopOffset, logicalRightOffset, false, &heightRemainingRight) - floatLogicalLeft < floatLogicalWidth) {
+        floatLogicalLeft = logicalLeftOffsetForLine(logicalTopOffset, logicalLeftOffset, false, &heightRemainingLeft, 0, ShapeOutsideFloatBoundingBoxOffset);
+        while (logicalRightOffsetForLine(logicalTopOffset, logicalRightOffset, false, &heightRemainingRight, 0, ShapeOutsideFloatBoundingBoxOffset) - floatLogicalLeft < floatLogicalWidth) {
             logicalTopOffset += min(heightRemainingLeft, heightRemainingRight);
-            floatLogicalLeft = logicalLeftOffsetForLine(logicalTopOffset, logicalLeftOffset, false, &heightRemainingLeft);
+            floatLogicalLeft = logicalLeftOffsetForLine(logicalTopOffset, logicalLeftOffset, false, &heightRemainingLeft, 0, ShapeOutsideFloatBoundingBoxOffset);
             if (insideFlowThread) {
                 // Have to re-evaluate all of our offsets, since they may have changed.
                 logicalRightOffset = logicalRightOffsetForContent(logicalTopOffset); // Constant part of right offset.
@@ -4039,10 +4039,10 @@
     } else {
         LayoutUnit heightRemainingLeft = 1;
         LayoutUnit heightRemainingRight = 1;
-        floatLogicalLeft = logicalRightOffsetForLine(logicalTopOffset, logicalRightOffset, false, &heightRemainingRight);
-        while (floatLogicalLeft - logicalLeftOffsetForLine(logicalTopOffset, logicalLeftOffset, false, &heightRemainingLeft) < floatLogicalWidth) {
+        floatLogicalLeft = logicalRightOffsetForLine(logicalTopOffset, logicalRightOffset, false, &heightRemainingRight, 0, ShapeOutsideFloatBoundingBoxOffset);
+        while (floatLogicalLeft - logicalLeftOffsetForLine(logicalTopOffset, logicalLeftOffset, false, &heightRemainingLeft, 0, ShapeOutsideFloatBoundingBoxOffset) < floatLogicalWidth) {
             logicalTopOffset += min(heightRemainingLeft, heightRemainingRight);
-            floatLogicalLeft = logicalRightOffsetForLine(logicalTopOffset, logicalRightOffset, false, &heightRemainingRight);
+            floatLogicalLeft = logicalRightOffsetForLine(logicalTopOffset, logicalRightOffset, false, &heightRemainingRight, 0, ShapeOutsideFloatBoundingBoxOffset);
             if (insideFlowThread) {
                 // Have to re-evaluate all of our offsets, since they may have changed.
                 logicalRightOffset = logicalRightOffsetForContent(logicalTopOffset); // Constant part of right offset.
@@ -4331,7 +4331,7 @@
     return logicalRightOffset - (logicalWidth() - (isHorizontalWritingMode() ? boxRect.maxX() : boxRect.maxY()));
 }
 
-LayoutUnit RenderBlock::logicalLeftOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining, LayoutUnit logicalHeight) const
+LayoutUnit RenderBlock::logicalLeftOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining, LayoutUnit logicalHeight, ShapeOutsideFloatOffsetMode offsetMode) const
 {
     LayoutUnit left = fixedOffset;
     if (m_floatingObjects && m_floatingObjects->hasLeftObjects()) {
@@ -4342,7 +4342,8 @@
         m_floatingObjects->placedFloatsTree().allOverlapsWithAdapter(adapter);
 
 #if ENABLE(CSS_EXCLUSIONS)
-        if (const FloatingObject* lastFloat = adapter.lastFloat()) {
+        const FloatingObject* lastFloat = adapter.lastFloat();
+        if (offsetMode == ShapeOutsideFloatShapeOffset && lastFloat) {
             if (ExclusionShapeOutsideInfo* shapeOutside = lastFloat->renderer()->exclusionShapeOutsideInfo()) {
                 shapeOutside->computeSegmentsForLine(logicalTop - logicalTopForFloat(lastFloat) + shapeOutside->shapeLogicalTop(), logicalHeight);
                 left += shapeOutside->rightSegmentShapeBoundingBoxDelta();
@@ -4387,7 +4388,7 @@
     return left;
 }
 
-LayoutUnit RenderBlock::logicalRightOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining, LayoutUnit logicalHeight) const
+LayoutUnit RenderBlock::logicalRightOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining, LayoutUnit logicalHeight, ShapeOutsideFloatOffsetMode offsetMode) const
 {
     LayoutUnit right = fixedOffset;
     if (m_floatingObjects && m_floatingObjects->hasRightObjects()) {
@@ -4399,7 +4400,8 @@
         m_floatingObjects->placedFloatsTree().allOverlapsWithAdapter(adapter);
 
 #if ENABLE(CSS_EXCLUSIONS)
-        if (const FloatingObject* lastFloat = adapter.lastFloat()) {
+        const FloatingObject* lastFloat = adapter.lastFloat();
+        if (offsetMode == ShapeOutsideFloatShapeOffset && lastFloat) {
             if (ExclusionShapeOutsideInfo* shapeOutside = lastFloat->renderer()->exclusionShapeOutsideInfo()) {
                 shapeOutside->computeSegmentsForLine(logicalTop - logicalTopForFloat(lastFloat) + shapeOutside->shapeLogicalTop(), logicalHeight);
                 rightFloatOffset += shapeOutside->leftSegmentShapeBoundingBoxDelta();

Modified: trunk/Source/WebCore/rendering/RenderBlock.h (148055 => 148056)


--- trunk/Source/WebCore/rendering/RenderBlock.h	2013-04-09 22:02:17 UTC (rev 148055)
+++ trunk/Source/WebCore/rendering/RenderBlock.h	2013-04-09 22:31:55 UTC (rev 148056)
@@ -71,6 +71,7 @@
 
 enum CaretType { CursorCaret, DragCaret };
 enum ContainingBlockState { NewContainingBlock, SameContainingBlock };
+enum ShapeOutsideFloatOffsetMode { ShapeOutsideFloatShapeOffset, ShapeOutsideFloatBoundingBoxOffset };
 
 enum TextRunFlag {
     DefaultTextRunFlags = 0,
@@ -170,13 +171,13 @@
         return max<LayoutUnit>(0, logicalRightOffsetForLine(position, shouldIndentText, region, offsetFromLogicalTopOfFirstPage, logicalHeight)
             - logicalLeftOffsetForLine(position, shouldIndentText, region, offsetFromLogicalTopOfFirstPage, logicalHeight));
     }
-    LayoutUnit logicalRightOffsetForLine(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage, LayoutUnit logicalHeight = 0) const 
+    LayoutUnit logicalRightOffsetForLine(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage, LayoutUnit logicalHeight = 0, ShapeOutsideFloatOffsetMode offsetMode = ShapeOutsideFloatShapeOffset) const 
     {
-        return logicalRightOffsetForLine(position, logicalRightOffsetForContent(region, offsetFromLogicalTopOfFirstPage), shouldIndentText, 0, logicalHeight);
+        return logicalRightOffsetForLine(position, logicalRightOffsetForContent(region, offsetFromLogicalTopOfFirstPage), shouldIndentText, 0, logicalHeight, offsetMode);
     }
-    LayoutUnit logicalLeftOffsetForLine(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage, LayoutUnit logicalHeight = 0) const 
+    LayoutUnit logicalLeftOffsetForLine(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage, LayoutUnit logicalHeight = 0, ShapeOutsideFloatOffsetMode offsetMode = ShapeOutsideFloatShapeOffset) const 
     {
-        return logicalLeftOffsetForLine(position, logicalLeftOffsetForContent(region, offsetFromLogicalTopOfFirstPage), shouldIndentText, 0, logicalHeight);
+        return logicalLeftOffsetForLine(position, logicalLeftOffsetForContent(region, offsetFromLogicalTopOfFirstPage), shouldIndentText, 0, logicalHeight, offsetMode);
     }
     LayoutUnit startOffsetForLine(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage, LayoutUnit logicalHeight = 0) const
     {
@@ -193,13 +194,13 @@
     {
         return availableLogicalWidthForLine(position, shouldIndentText, regionAtBlockOffset(position), offsetFromLogicalTopOfFirstPage(), logicalHeight);
     }
-    LayoutUnit logicalRightOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const 
+    LayoutUnit logicalRightOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0, ShapeOutsideFloatOffsetMode offsetMode = ShapeOutsideFloatShapeOffset) const 
     {
-        return logicalRightOffsetForLine(position, logicalRightOffsetForContent(position), shouldIndentText, 0, logicalHeight);
+        return logicalRightOffsetForLine(position, logicalRightOffsetForContent(position), shouldIndentText, 0, logicalHeight, offsetMode);
     }
-    LayoutUnit logicalLeftOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const 
+    LayoutUnit logicalLeftOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0, ShapeOutsideFloatOffsetMode offsetMode = ShapeOutsideFloatShapeOffset) const 
     {
-        return logicalLeftOffsetForLine(position, logicalLeftOffsetForContent(position), shouldIndentText, 0, logicalHeight);
+        return logicalLeftOffsetForLine(position, logicalLeftOffsetForContent(position), shouldIndentText, 0, logicalHeight, offsetMode);
     }
     LayoutUnit pixelSnappedLogicalLeftOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const 
     {
@@ -518,8 +519,8 @@
     virtual void paintChildren(PaintInfo& forSelf, const LayoutPoint&, PaintInfo& forChild, bool usePrintRect);
     bool paintChild(RenderBox*, PaintInfo& forSelf, const LayoutPoint&, PaintInfo& forChild, bool usePrintRect);
    
-    LayoutUnit logicalRightOffsetForLine(LayoutUnit position, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* logicalHeightRemaining = 0, LayoutUnit logicalHeight = 0) const;
-    LayoutUnit logicalLeftOffsetForLine(LayoutUnit position, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* logicalHeightRemaining = 0, LayoutUnit logicalHeight = 0) const;
+    LayoutUnit logicalRightOffsetForLine(LayoutUnit position, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* logicalHeightRemaining = 0, LayoutUnit logicalHeight = 0, ShapeOutsideFloatOffsetMode = ShapeOutsideFloatShapeOffset) const;
+    LayoutUnit logicalLeftOffsetForLine(LayoutUnit position, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* logicalHeightRemaining = 0, LayoutUnit logicalHeight = 0, ShapeOutsideFloatOffsetMode = ShapeOutsideFloatShapeOffset) const;
 
     virtual ETextAlign textAlignmentForLine(bool endsWithSoftBreak) const;
     virtual void adjustInlineDirectionLineBounds(int /* expansionOpportunityCount */, float& /* logicalLeft */, float& /* logicalWidth */) const { }

Modified: trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp (148055 => 148056)


--- trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp	2013-04-09 22:02:17 UTC (rev 148055)
+++ trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp	2013-04-09 22:31:55 UTC (rev 148056)
@@ -188,6 +188,25 @@
         return;
 
 #if ENABLE(CSS_EXCLUSIONS)
+    // When floats with shape outside are stacked, the floats are positioned based on the bounding box of the shape,
+    // not the shape's contour. Since we computed the width based on the shape contour when we added the float,
+    // when we add a subsequent float on the same line, we need to undo the shape delta in order to position
+    // based on the bounding box. In order to do this, we need to walk back through the floating object list to find
+    // the first previous float that is on the same side as our newFloat.
+    ExclusionShapeOutsideInfo* lastShapeOutsideInfo = 0;
+    const RenderBlock::FloatingObjectSet& floatingObjectSet = m_block->m_floatingObjects->set();
+    RenderBlock::FloatingObjectSetIterator it = floatingObjectSet.end();
+    RenderBlock::FloatingObjectSetIterator begin = floatingObjectSet.begin();
+    for (--it; it != begin; --it) {
+        RenderBlock::FloatingObject* lastFloat = *it;
+        if (lastFloat != newFloat && lastFloat->type() == newFloat->type()) {
+            lastShapeOutsideInfo = lastFloat->renderer()->exclusionShapeOutsideInfo();
+            if (lastShapeOutsideInfo)
+                lastShapeOutsideInfo->computeSegmentsForLine(m_block->logicalHeight() - m_block->logicalTopForFloat(lastFloat) + lastShapeOutsideInfo->shapeLogicalTop(), logicalHeightForLine(m_block, m_isFirstLine));
+            break;
+        }
+    }
+
     ExclusionShapeOutsideInfo* shapeOutsideInfo = newFloat->renderer()->exclusionShapeOutsideInfo();
     if (shapeOutsideInfo)
         shapeOutsideInfo->computeSegmentsForLine(m_block->logicalHeight() - m_block->logicalTopForFloat(newFloat) + shapeOutsideInfo->shapeLogicalTop(), logicalHeightForLine(m_block, m_isFirstLine));
@@ -196,6 +215,8 @@
     if (newFloat->type() == RenderBlock::FloatingObject::FloatLeft) {
         float newLeft = m_block->logicalRightForFloat(newFloat);
 #if ENABLE(CSS_EXCLUSIONS)
+        if (lastShapeOutsideInfo)
+            newLeft -= lastShapeOutsideInfo->rightSegmentShapeBoundingBoxDelta();
         if (shapeOutsideInfo)
             newLeft += shapeOutsideInfo->rightSegmentShapeBoundingBoxDelta();
 #endif
@@ -206,6 +227,8 @@
     } else {
         float newRight = m_block->logicalLeftForFloat(newFloat);
 #if ENABLE(CSS_EXCLUSIONS)
+        if (lastShapeOutsideInfo)
+            newRight -= lastShapeOutsideInfo->leftSegmentShapeBoundingBoxDelta();
         if (shapeOutsideInfo)
             newRight += shapeOutsideInfo->leftSegmentShapeBoundingBoxDelta();
 #endif
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to