Title: [96149] trunk
Revision
96149
Author
hy...@apple.com
Date
2011-09-27 13:39:57 -0700 (Tue, 27 Sep 2011)

Log Message

https://bugs.webkit.org/show_bug.cgi?id=68922

Source/WebCore: 

Paginated floats should not grow the height of a block when they don't end
up being tied to a line. Floats encountered in skipLeadingWhitespace that
paginate can't immediately grow the height of the block, since there may not
end up being any actual line content. We only want to push the height of the
block down if we have actual line content that we want to keep with the
float.
        
Make positionNewFloatOnLine check if the line is empty or not, and if it is,
it just puts the desired pagination strut into LineInfo. If and when actual
line content is encountered and setEmpty becomes false, we'll grow the block
height then.
        
Reviewed by Dan Bernstein.

Added fast/multicol/float-paginate-empty-lines.html and
fast/regions/webkit-flow-double-pagination-float-push.html.

* rendering/RenderBlock.h:
* rendering/RenderBlockLineLayout.cpp:
(WebCore::LineWidth::LineWidth):
(WebCore::LineWidth::fitsOnLine):
(WebCore::LineWidth::currentWidth):
(WebCore::LineWidth::uncommittedWidth):
(WebCore::LineWidth::committedWidth):
(WebCore::LineWidth::availableWidth):
(WebCore::LineWidth::addUncommittedWidth):
(WebCore::LineWidth::commit):
(WebCore::LineWidth::computeAvailableWidthFromLeftAndRight):
(WebCore::LineWidth::updateAvailableWidth):
(WebCore::LineWidth::shrinkAvailableWidthForNewFloatIfNeeded):
(WebCore::LineWidth::applyOverhang):
(WebCore::LineWidth::fitBelowFloats):
(WebCore::LineInfo::LineInfo):
(WebCore::LineInfo::floatPaginationStrut):
(WebCore::LineInfo::setEmpty):
(WebCore::LineInfo::setFloatPaginationStrut):
(WebCore::RenderBlock::LineBreaker::skipLeadingWhitespace):
(WebCore::RenderBlock::LineBreaker::nextLineBreak):
(WebCore::RenderBlock::positionNewFloatOnLine):

LayoutTests: 

Paginated floats should not grow the height of a block when they don't end
up being tied to a line.

Reviewed by Dan Bernstein.

* fast/multicol/float-paginate-empty-lines.html: Added.
* fast/regions/webkit-flow-double-pagination-float-push.html: Added.
* platform/mac/fast/multicol/float-paginate-empty-lines-expected.png: Added.
* platform/mac/fast/regions/webkit-flow-double-pagination-float-push-expected.png: Added.
* platform/mac/fast/regions/webkit-flow-double-pagination-float-push-expected.txt: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (96148 => 96149)


--- trunk/LayoutTests/ChangeLog	2011-09-27 20:29:38 UTC (rev 96148)
+++ trunk/LayoutTests/ChangeLog	2011-09-27 20:39:57 UTC (rev 96149)
@@ -1,3 +1,18 @@
+2011-09-27  David Hyatt  <hy...@apple.com>
+
+        https://bugs.webkit.org/show_bug.cgi?id=68922
+
+        Paginated floats should not grow the height of a block when they don't end
+        up being tied to a line.
+
+        Reviewed by Dan Bernstein.
+
+        * fast/multicol/float-paginate-empty-lines.html: Added.
+        * fast/regions/webkit-flow-double-pagination-float-push.html: Added.
+        * platform/mac/fast/multicol/float-paginate-empty-lines-expected.png: Added.
+        * platform/mac/fast/regions/webkit-flow-double-pagination-float-push-expected.png: Added.
+        * platform/mac/fast/regions/webkit-flow-double-pagination-float-push-expected.txt: Added.
+
 2011-09-27  Sheriff Bot  <webkit.review....@gmail.com>
 
         Unreviewed, rolling out r96131.

Added: trunk/LayoutTests/fast/multicol/float-paginate-empty-lines.html (0 => 96149)


--- trunk/LayoutTests/fast/multicol/float-paginate-empty-lines.html	                        (rev 0)
+++ trunk/LayoutTests/fast/multicol/float-paginate-empty-lines.html	2011-09-27 20:39:57 UTC (rev 96149)
@@ -0,0 +1,11 @@
+<p>This test is ensuring we don't grow the height of a block improperly when a float has no line association (e.g., when it's at the end of a
+block). The complete dashed border should be in the first column, with none of it appearing in the second column.</p>
+
+<div style="-webkit-column-width:300px;-moz-column-width:300px; height:400px">
+<div style="border:10px dashed maroon">
+This is some text.<br>
+This is some text.<br>This is some text.<br>This is some text.<br>This is some text.<br>This is some text.<br>This is some text.<br>
+This is some text.<br>This is some text.<br>This is some text.<br>This is some text.<br>
+This is some text.<br>
+<img style="float:right;width:100px;height:200px;background-color:#cccccc">
+</div>
\ No newline at end of file

Added: trunk/LayoutTests/fast/regions/webkit-flow-double-pagination-float-push.html (0 => 96149)


--- trunk/LayoutTests/fast/regions/webkit-flow-double-pagination-float-push.html	                        (rev 0)
+++ trunk/LayoutTests/fast/regions/webkit-flow-double-pagination-float-push.html	2011-09-27 20:39:57 UTC (rev 96149)
@@ -0,0 +1,70 @@
+<!doctype html>
+
+ <style>
+    #content {
+        -webkit-flow: "flow1";
+        text-align: justify;
+        padding: 5px;
+    }
+    
+    #first-box {
+        border: 1px solid blue;
+    }
+    
+    #second-box {
+        margin:10px;
+        border: 1px solid green;
+    }
+    
+    #float1 {
+        float: left;
+        width: 130px;
+        height: 110px;
+        background-color:green
+    }
+    
+    #float2 {
+        float: right;
+        width: 130px;
+        height: 130px;
+        background-color:yellow
+    }
+
+    #region1, #region2, #region3 {
+        border: 1px solid black;
+        content: -webkit-from-flow("flow1");
+    }
+
+    #region1 {
+        width: 400px;
+        height: 100px;
+    }
+    
+    #region2 {
+        width: 300px;
+        height: 120px;
+    }
+    
+    #region3 {
+        width: 400px;
+        height: 300px;
+    }
+</style>
+
+<p>In the example below, the first float pushes content into region #2, and the second float pushes both floats into region #3.</p>
+
+<div id="content">
+    <div id="first-box">
+        <div id="second-box">
+            <p><img id="float1"> <img id="float2"> This line of text should not get out of the  region. This line of text should not get out of the region. This line of text should not get out of the region. This line of text should not get out of the region.</p>
+            <p>This line of text should not get out of the region. This line of text should not get out of the region. This line of text should not get out of the region. This line of text should not get out of the region.</p>
+            <p>This line of text should not get out of the region.</p>
+        </div>
+    </div>
+</div>
+
+<div id="container">
+    <div id="region1"></div>
+    <div id="region2"></div>
+    <div id="region3"></div>
+</div>

Added: trunk/LayoutTests/platform/mac/fast/multicol/float-paginate-empty-lines-expected.png


(Binary files differ)
Property changes on: trunk/LayoutTests/platform/mac/fast/multicol/float-paginate-empty-lines-expected.png ___________________________________________________________________

Added: svn:mime-type

Added: trunk/LayoutTests/platform/mac/fast/regions/webkit-flow-double-pagination-float-push-expected.png


(Binary files differ)
Property changes on: trunk/LayoutTests/platform/mac/fast/regions/webkit-flow-double-pagination-float-push-expected.png ___________________________________________________________________

Added: svn:mime-type

Added: trunk/LayoutTests/platform/mac/fast/regions/webkit-flow-double-pagination-float-push-expected.txt (0 => 96149)


--- trunk/LayoutTests/platform/mac/fast/regions/webkit-flow-double-pagination-float-push-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac/fast/regions/webkit-flow-double-pagination-float-push-expected.txt	2011-09-27 20:39:57 UTC (rev 96149)
@@ -0,0 +1,45 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x584
+  RenderBlock {HTML} at (0,0) size 800x584
+    RenderBody {BODY} at (8,16) size 784x560
+      RenderBlock {P} at (0,0) size 784x18
+        RenderText {#text} at (0,0) size 759x18
+          text run at (0,0) width 759: "In the example below, the first float pushes content into region #2, and the second float pushes both floats into region #3."
+      RenderBlock {DIV} at (0,34) size 784x526
+        RenderRegion {DIV} at (0,0) size 402x102 [border: (1px solid #000000)]
+        RenderRegion {DIV} at (0,102) size 302x122 [border: (1px solid #000000)]
+        RenderRegion {DIV} at (0,224) size 402x302 [border: (1px solid #000000)]
+Flow Threads
+  Thread with flow-name 'flow1'
+    layer at (0,0) size 400x520
+      RenderFlowThread at (0,0) size 400x520
+        RenderBlock {DIV} at (0,0) size 400x537
+          RenderBlock {DIV} at (5,5) size 390x527 [border: (1px solid #0000FF)]
+            RenderBlock {DIV} at (11,11) size 368x505 [border: (1px solid #008000)]
+              RenderBlock {P} at (1,17) size 366x349
+                RenderImage {IMG} at (0,187) size 130x110 [bgcolor=#008000]
+                RenderImage {IMG} at (236,187) size 130x130 [bgcolor=#FFFF00]
+                RenderText {#text} at (130,187) size 352x162
+                  text run at (130,187) width 106: "This line of text"
+                  text run at (130,205) width 106: "should not get"
+                  text run at (130,223) width 106: "out of the"
+                  text run at (130,241) width 106: "region. This line"
+                  text run at (130,259) width 106: "of text should"
+                  text run at (130,277) width 106: "not get out of"
+                  text run at (130,295) width 106: "the region. This"
+                  text run at (0,313) width 236: "line of text should not get out of the"
+                  text run at (0,331) width 352: "region. This line of text should not get out of the region."
+              RenderBlock {P} at (1,382) size 366x72
+                RenderText {#text} at (0,0) size 366x72
+                  text run at (0,0) width 366: "This line of text should not get out of the region. This line"
+                  text run at (0,18) width 366: "of text should not get out of the region. This line of text"
+                  text run at (0,36) width 366: "should not get out of the region. This line of text should"
+                  text run at (0,54) width 155: "not get out of the region."
+              RenderBlock {P} at (1,470) size 366x18
+                RenderText {#text} at (0,0) size 304x18
+                  text run at (0,0) width 304: "This line of text should not get out of the region."
+  Regions for flow 'flow1'
+    RenderRegion {DIV} #region1 with index 0
+    RenderRegion {DIV} #region2 with index 0
+    RenderRegion {DIV} #region3 with index 0

Modified: trunk/Source/WebCore/ChangeLog (96148 => 96149)


--- trunk/Source/WebCore/ChangeLog	2011-09-27 20:29:38 UTC (rev 96148)
+++ trunk/Source/WebCore/ChangeLog	2011-09-27 20:39:57 UTC (rev 96149)
@@ -1,3 +1,47 @@
+2011-09-27  David Hyatt  <hy...@apple.com>
+
+        https://bugs.webkit.org/show_bug.cgi?id=68922
+
+        Paginated floats should not grow the height of a block when they don't end
+        up being tied to a line. Floats encountered in skipLeadingWhitespace that
+        paginate can't immediately grow the height of the block, since there may not
+        end up being any actual line content. We only want to push the height of the
+        block down if we have actual line content that we want to keep with the
+        float.
+        
+        Make positionNewFloatOnLine check if the line is empty or not, and if it is,
+        it just puts the desired pagination strut into LineInfo. If and when actual
+        line content is encountered and setEmpty becomes false, we'll grow the block
+        height then.
+        
+        Reviewed by Dan Bernstein.
+
+        Added fast/multicol/float-paginate-empty-lines.html and
+        fast/regions/webkit-flow-double-pagination-float-push.html.
+
+        * rendering/RenderBlock.h:
+        * rendering/RenderBlockLineLayout.cpp:
+        (WebCore::LineWidth::LineWidth):
+        (WebCore::LineWidth::fitsOnLine):
+        (WebCore::LineWidth::currentWidth):
+        (WebCore::LineWidth::uncommittedWidth):
+        (WebCore::LineWidth::committedWidth):
+        (WebCore::LineWidth::availableWidth):
+        (WebCore::LineWidth::addUncommittedWidth):
+        (WebCore::LineWidth::commit):
+        (WebCore::LineWidth::computeAvailableWidthFromLeftAndRight):
+        (WebCore::LineWidth::updateAvailableWidth):
+        (WebCore::LineWidth::shrinkAvailableWidthForNewFloatIfNeeded):
+        (WebCore::LineWidth::applyOverhang):
+        (WebCore::LineWidth::fitBelowFloats):
+        (WebCore::LineInfo::LineInfo):
+        (WebCore::LineInfo::floatPaginationStrut):
+        (WebCore::LineInfo::setEmpty):
+        (WebCore::LineInfo::setFloatPaginationStrut):
+        (WebCore::RenderBlock::LineBreaker::skipLeadingWhitespace):
+        (WebCore::RenderBlock::LineBreaker::nextLineBreak):
+        (WebCore::RenderBlock::positionNewFloatOnLine):
+
 2011-09-27  Dean Jackson  <d...@apple.com>
 
         Add 'filter' value to RenderStyle

Modified: trunk/Source/WebCore/rendering/RenderBlock.h (96148 => 96149)


--- trunk/Source/WebCore/rendering/RenderBlock.h	2011-09-27 20:29:38 UTC (rev 96148)
+++ trunk/Source/WebCore/rendering/RenderBlock.h	2011-09-27 20:39:57 UTC (rev 96149)
@@ -578,7 +578,7 @@
         void reset();
         
         void skipTrailingWhitespace(InlineIterator&, const LineInfo&);
-        void skipLeadingWhitespace(InlineBidiResolver&, const LineInfo&, FloatingObject* lastFloatFromPreviousLine, LineWidth&);
+        void skipLeadingWhitespace(InlineBidiResolver&, LineInfo&, FloatingObject* lastFloatFromPreviousLine, LineWidth&);
         
         RenderBlock* m_block;
         bool m_hyphenated;
@@ -604,7 +604,7 @@
 
     // Positions new floats and also adjust all floats encountered on the line if any of them
     // have to move to the next page/column.
-    bool positionNewFloatOnLine(FloatingObject* newFloat, FloatingObject* lastFloatFromPreviousLine, LineWidth&);
+    bool positionNewFloatOnLine(FloatingObject* newFloat, FloatingObject* lastFloatFromPreviousLine, LineInfo&, LineWidth&);
     void appendFloatingObjectToLastLine(FloatingObject*);
 
     // End of functions defined in RenderBlockLineLayout.cpp.

Modified: trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp (96148 => 96149)


--- trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp	2011-09-27 20:29:38 UTC (rev 96148)
+++ trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp	2011-09-27 20:39:57 UTC (rev 96149)
@@ -60,6 +60,131 @@
 // We don't let our line box tree for a single line get any deeper than this.
 const unsigned cMaxLineDepth = 200;
 
+class LineWidth {
+public:
+    LineWidth(RenderBlock* block, bool isFirstLine)
+        : m_block(block)
+        , m_uncommittedWidth(0)
+        , m_committedWidth(0)
+        , m_overhangWidth(0)
+        , m_left(0)
+        , m_right(0)
+        , m_availableWidth(0)
+        , m_isFirstLine(isFirstLine)
+    {
+        ASSERT(block);
+        updateAvailableWidth();
+    }
+    bool fitsOnLine() const { return currentWidth() <= m_availableWidth; }
+    bool fitsOnLine(float extra) const { return currentWidth() + extra <= m_availableWidth; }
+    float currentWidth() const { return m_committedWidth + m_uncommittedWidth; }
+
+    // FIXME: We should eventually replace these three functions by ones that work on a higher abstraction.
+    float uncommittedWidth() const { return m_uncommittedWidth; }
+    float committedWidth() const { return m_committedWidth; }
+    float availableWidth() const { return m_availableWidth; }
+
+    void updateAvailableWidth();
+    void shrinkAvailableWidthForNewFloatIfNeeded(RenderBlock::FloatingObject*);
+    void addUncommittedWidth(float delta) { m_uncommittedWidth += delta; }
+    void commit()
+    {
+        m_committedWidth += m_uncommittedWidth;
+        m_uncommittedWidth = 0;
+    }
+    void applyOverhang(RenderRubyRun*, RenderObject* startRenderer, RenderObject* endRenderer);
+    void fitBelowFloats();
+
+private:
+    void computeAvailableWidthFromLeftAndRight()
+    {
+        m_availableWidth = max(0, m_right - m_left) + m_overhangWidth;
+    }
+
+private:
+    RenderBlock* m_block;
+    float m_uncommittedWidth;
+    float m_committedWidth;
+    float m_overhangWidth; // The amount by which |m_availableWidth| has been inflated to account for possible contraction due to ruby overhang.
+    int m_left;
+    int m_right;
+    float m_availableWidth;
+    bool m_isFirstLine;
+};
+
+inline void LineWidth::updateAvailableWidth()
+{
+    int height = m_block->logicalHeight();
+    m_left = m_block->logicalLeftOffsetForLine(height, m_isFirstLine);
+    m_right = m_block->logicalRightOffsetForLine(height, m_isFirstLine);
+
+    computeAvailableWidthFromLeftAndRight();
+}
+
+inline void LineWidth::shrinkAvailableWidthForNewFloatIfNeeded(RenderBlock::FloatingObject* newFloat)
+{
+    int height = m_block->logicalHeight();
+    if (height < m_block->logicalTopForFloat(newFloat) || height >= m_block->logicalBottomForFloat(newFloat))
+        return;
+
+    if (newFloat->type() == RenderBlock::FloatingObject::FloatLeft) {
+        m_left = m_block->logicalRightForFloat(newFloat);
+        if (m_isFirstLine && m_block->style()->isLeftToRightDirection())
+            m_left += m_block->textIndentOffset();
+    } else {
+        m_right = m_block->logicalLeftForFloat(newFloat);
+        if (m_isFirstLine && !m_block->style()->isLeftToRightDirection())
+            m_right -= m_block->textIndentOffset();
+    }
+
+    computeAvailableWidthFromLeftAndRight();
+}
+
+void LineWidth::applyOverhang(RenderRubyRun* rubyRun, RenderObject* startRenderer, RenderObject* endRenderer)
+{
+    int startOverhang;
+    int endOverhang;
+    rubyRun->getOverhang(m_isFirstLine, startRenderer, endRenderer, startOverhang, endOverhang);
+
+    startOverhang = min<int>(startOverhang, m_committedWidth);
+    m_availableWidth += startOverhang;
+
+    endOverhang = max(min<int>(endOverhang, m_availableWidth - currentWidth()), 0);
+    m_availableWidth += endOverhang;
+    m_overhangWidth += startOverhang + endOverhang;
+}
+
+void LineWidth::fitBelowFloats()
+{
+    ASSERT(!m_committedWidth);
+    ASSERT(!fitsOnLine());
+
+    int floatLogicalBottom;
+    int lastFloatLogicalBottom = m_block->logicalHeight();
+    float newLineWidth = m_availableWidth;
+    float newLineLeft = m_left;
+    float newLineRight = m_right;
+    while (true) {
+        floatLogicalBottom = m_block->nextFloatLogicalBottomBelow(lastFloatLogicalBottom);
+        if (!floatLogicalBottom)
+            break;
+
+        newLineLeft = m_block->logicalLeftOffsetForLine(floatLogicalBottom, m_isFirstLine);
+        newLineRight = m_block->logicalRightOffsetForLine(floatLogicalBottom, m_isFirstLine);
+        newLineWidth = max(0.0f, newLineRight - newLineLeft);
+        lastFloatLogicalBottom = floatLogicalBottom;
+        if (newLineWidth >= m_uncommittedWidth)
+            break;
+    }
+
+    if (newLineWidth > m_availableWidth) {
+        m_block->setLogicalHeight(lastFloatLogicalBottom);
+        m_availableWidth = newLineWidth + m_overhangWidth;
+        m_left = newLineLeft;
+        m_right = newLineRight;
+    }
+}
+
 class LineInfo {
 public:
     LineInfo()
@@ -67,23 +192,38 @@
         , m_isLastLine(false)
         , m_isEmpty(true)
         , m_previousLineBrokeCleanly(true)
+        , m_floatPaginationStrut(0)
     { }
 
     bool isFirstLine() const { return m_isFirstLine; }
     bool isLastLine() const { return m_isLastLine; }
     bool isEmpty() const { return m_isEmpty; }
     bool previousLineBrokeCleanly() const { return m_previousLineBrokeCleanly; }
+    LayoutUnit floatPaginationStrut() const { return m_floatPaginationStrut; }
 
     void setFirstLine(bool firstLine) { m_isFirstLine = firstLine; }
     void setLastLine(bool lastLine) { m_isLastLine = lastLine; }
-    void setEmpty(bool empty) { m_isEmpty = empty; }
+    void setEmpty(bool empty, RenderBlock* block = 0, LineWidth* lineWidth = 0)
+    {
+        if (m_isEmpty == empty)
+            return;
+        m_isEmpty = empty;
+        if (!empty && block && floatPaginationStrut()) {
+            block->setLogicalHeight(block->logicalHeight() + floatPaginationStrut());
+            setFloatPaginationStrut(0);
+            lineWidth->updateAvailableWidth();
+        }
+    }
+
     void setPreviousLineBrokeCleanly(bool previousLineBrokeCleanly) { m_previousLineBrokeCleanly = previousLineBrokeCleanly; }
+    void setFloatPaginationStrut(LayoutUnit strut) { m_floatPaginationStrut = strut; }
 
 private:
     bool m_isFirstLine;
     bool m_isLastLine;
     bool m_isEmpty;
     bool m_previousLineBrokeCleanly;
+    LayoutUnit m_floatPaginationStrut;
 };
 
 static inline int borderPaddingMarginStart(RenderInline* child)
@@ -1710,13 +1850,13 @@
     }
 }
 
-void RenderBlock::LineBreaker::skipLeadingWhitespace(InlineBidiResolver& resolver, const LineInfo& lineInfo,
+void RenderBlock::LineBreaker::skipLeadingWhitespace(InlineBidiResolver& resolver, LineInfo& lineInfo,
                                                      FloatingObject* lastFloatFromPreviousLine, LineWidth& width)
 {
     while (!resolver.position().atEnd() && !requiresLineBox(resolver.position(), lineInfo, LeadingWhitespace)) {
         RenderObject* object = resolver.position().m_obj;
         if (object->isFloating())
-            m_block->positionNewFloatOnLine(m_block->insertFloatingObject(toRenderBox(object)), lastFloatFromPreviousLine, width);
+            m_block->positionNewFloatOnLine(m_block->insertFloatingObject(toRenderBox(object)), lastFloatFromPreviousLine, lineInfo, width);
         else if (object->isPositioned())
             setStaticPositions(m_block, toRenderBox(object));
         resolver.increment();
@@ -1809,131 +1949,6 @@
     hyphenated = true;
 }
 
-class LineWidth {
-public:
-    LineWidth(RenderBlock* block, bool isFirstLine)
-        : m_block(block)
-        , m_uncommittedWidth(0)
-        , m_committedWidth(0)
-        , m_overhangWidth(0)
-        , m_left(0)
-        , m_right(0)
-        , m_availableWidth(0)
-        , m_isFirstLine(isFirstLine)
-    {
-        ASSERT(block);
-        updateAvailableWidth();
-    }
-    bool fitsOnLine() const { return currentWidth() <= m_availableWidth; }
-    bool fitsOnLine(float extra) const { return currentWidth() + extra <= m_availableWidth; }
-    float currentWidth() const { return m_committedWidth + m_uncommittedWidth; }
-
-    // FIXME: We should eventually replace these three functions by ones that work on a higher abstraction.
-    float uncommittedWidth() const { return m_uncommittedWidth; }
-    float committedWidth() const { return m_committedWidth; }
-    float availableWidth() const { return m_availableWidth; }
-
-    void updateAvailableWidth();
-    void shrinkAvailableWidthForNewFloatIfNeeded(RenderBlock::FloatingObject*);
-    void addUncommittedWidth(float delta) { m_uncommittedWidth += delta; }
-    void commit()
-    {
-        m_committedWidth += m_uncommittedWidth;
-        m_uncommittedWidth = 0;
-    }
-    void applyOverhang(RenderRubyRun*, RenderObject* startRenderer, RenderObject* endRenderer);
-    void fitBelowFloats();
-
-private:
-    void computeAvailableWidthFromLeftAndRight()
-    {
-        m_availableWidth = max(0, m_right - m_left) + m_overhangWidth;
-    }
-
-private:
-    RenderBlock* m_block;
-    float m_uncommittedWidth;
-    float m_committedWidth;
-    float m_overhangWidth; // The amount by which |m_availableWidth| has been inflated to account for possible contraction due to ruby overhang.
-    int m_left;
-    int m_right;
-    float m_availableWidth;
-    bool m_isFirstLine;
-};
-
-inline void LineWidth::updateAvailableWidth()
-{
-    int height = m_block->logicalHeight();
-    m_left = m_block->logicalLeftOffsetForLine(height, m_isFirstLine);
-    m_right = m_block->logicalRightOffsetForLine(height, m_isFirstLine);
-
-    computeAvailableWidthFromLeftAndRight();
-}
-
-inline void LineWidth::shrinkAvailableWidthForNewFloatIfNeeded(RenderBlock::FloatingObject* newFloat)
-{
-    int height = m_block->logicalHeight();
-    if (height < m_block->logicalTopForFloat(newFloat) || height >= m_block->logicalBottomForFloat(newFloat))
-        return;
-
-    if (newFloat->type() == RenderBlock::FloatingObject::FloatLeft) {
-        m_left = m_block->logicalRightForFloat(newFloat);
-        if (m_isFirstLine && m_block->style()->isLeftToRightDirection())
-            m_left += m_block->textIndentOffset();
-    } else {
-        m_right = m_block->logicalLeftForFloat(newFloat);
-        if (m_isFirstLine && !m_block->style()->isLeftToRightDirection())
-            m_right -= m_block->textIndentOffset();
-    }
-
-    computeAvailableWidthFromLeftAndRight();
-}
-
-void LineWidth::applyOverhang(RenderRubyRun* rubyRun, RenderObject* startRenderer, RenderObject* endRenderer)
-{
-    int startOverhang;
-    int endOverhang;
-    rubyRun->getOverhang(m_isFirstLine, startRenderer, endRenderer, startOverhang, endOverhang);
-
-    startOverhang = min<int>(startOverhang, m_committedWidth);
-    m_availableWidth += startOverhang;
-
-    endOverhang = max(min<int>(endOverhang, m_availableWidth - currentWidth()), 0);
-    m_availableWidth += endOverhang;
-    m_overhangWidth += startOverhang + endOverhang;
-}
-
-void LineWidth::fitBelowFloats()
-{
-    ASSERT(!m_committedWidth);
-    ASSERT(!fitsOnLine());
-
-    int floatLogicalBottom;
-    int lastFloatLogicalBottom = m_block->logicalHeight();
-    float newLineWidth = m_availableWidth;
-    float newLineLeft = m_left;
-    float newLineRight = m_right;
-    while (true) {
-        floatLogicalBottom = m_block->nextFloatLogicalBottomBelow(lastFloatLogicalBottom);
-        if (!floatLogicalBottom)
-            break;
-
-        newLineLeft = m_block->logicalLeftOffsetForLine(floatLogicalBottom, m_isFirstLine);
-        newLineRight = m_block->logicalRightOffsetForLine(floatLogicalBottom, m_isFirstLine);
-        newLineWidth = max(0.0f, newLineRight - newLineLeft);
-        lastFloatLogicalBottom = floatLogicalBottom;
-        if (newLineWidth >= m_uncommittedWidth)
-            break;
-    }
-
-    if (newLineWidth > m_availableWidth) {
-        m_block->setLogicalHeight(lastFloatLogicalBottom);
-        m_availableWidth = newLineWidth + m_overhangWidth;
-        m_left = newLineLeft;
-        m_right = newLineRight;
-    }
-}
-
 class TrailingObjects {
 public:
     TrailingObjects();
@@ -2107,7 +2122,7 @@
                 // cleanly.  Otherwise the <br> has no effect on whether the line is
                 // empty or not.
                 if (startingNewParagraph)
-                    lineInfo.setEmpty(false);
+                    lineInfo.setEmpty(false, m_block, &width);
                 trailingObjects.clear();
                 lineInfo.setPreviousLineBrokeCleanly(true);
 
@@ -2124,7 +2139,7 @@
             // If it does, position it now, otherwise, position
             // it after moving to next line (in newLine() func)
             if (floatsFitOnLine && width.fitsOnLine(m_block->logicalWidthForFloat(f))) {
-                m_block->positionNewFloatOnLine(f, lastFloatFromPreviousLine, width);
+                m_block->positionNewFloatOnLine(f, lastFloatFromPreviousLine, lineInfo, width);
                 if (lBreak.m_obj == current.m_obj) {
                     ASSERT(!lBreak.m_pos);
                     lBreak.increment();
@@ -2167,7 +2182,7 @@
             // If this object is at the start of the line, we need to behave like list markers and
             // start ignoring spaces.
             if (inlineFlowRequiresLineBox(flowBox)) {
-                lineInfo.setEmpty(false);
+                lineInfo.setEmpty(false, m_block, &width);
                 if (ignoringSpaces) {
                     trailingObjects.clear();
                     addMidpoint(lineMidpointState, InlineIterator(0, current.m_obj, 0)); // Stop ignoring spaces.
@@ -2195,7 +2210,7 @@
             if (ignoringSpaces)
                 addMidpoint(lineMidpointState, InlineIterator(0, current.m_obj, 0));
 
-            lineInfo.setEmpty(false);
+            lineInfo.setEmpty(false, m_block, &width);
             ignoringSpaces = false;
             currentCharacterIsSpace = false;
             currentCharacterIsWS = false;
@@ -2267,7 +2282,7 @@
                 currentCharacterIsSpace = c == ' ' || c == '\t' || (!preserveNewline && (c == '\n'));
 
                 if (!collapseWhiteSpace || !currentCharacterIsSpace)
-                    lineInfo.setEmpty(false);
+                    lineInfo.setEmpty(false, m_block, &width);
 
                 if (c == softHyphen && autoWrap && !hyphenWidth && style->hyphens() != HyphensNone) {
                     hyphenWidth = measureHyphenWidth(t, f);
@@ -2631,7 +2646,7 @@
     }
 }
 
-bool RenderBlock::positionNewFloatOnLine(FloatingObject* newFloat, FloatingObject* lastFloatFromPreviousLine, LineWidth& width)
+bool RenderBlock::positionNewFloatOnLine(FloatingObject* newFloat, FloatingObject* lastFloatFromPreviousLine, LineInfo& lineInfo, LineWidth& width)
 {
     if (!positionNewFloats())
         return false;
@@ -2647,7 +2662,7 @@
     int floatLogicalTop = logicalTopForFloat(newFloat);
     int paginationStrut = newFloat->m_paginationStrut;
 
-    if (floatLogicalTop - paginationStrut != logicalHeight())
+    if (floatLogicalTop - paginationStrut != logicalHeight() + lineInfo.floatPaginationStrut())
         return true;
 
     FloatingObjectSetIterator it = floatingObjectSet.end();
@@ -2658,9 +2673,8 @@
         FloatingObject* f = *it;
         if (f == lastFloatFromPreviousLine)
             break;
-        if (logicalTopForFloat(f) == logicalHeight()) {
-            ASSERT(!f->m_paginationStrut);
-            f->m_paginationStrut = paginationStrut;
+        if (logicalTopForFloat(f) == logicalHeight() + lineInfo.floatPaginationStrut()) {
+            f->m_paginationStrut += paginationStrut;
             RenderBox* o = f->m_renderer;
             setLogicalTopForChild(o, logicalTopForChild(o) + marginBeforeForChild(o) + paginationStrut);
             if (o->isRenderBlock())
@@ -2670,13 +2684,20 @@
             // isPlaced to false. Otherwise it will trigger an assert in logicalTopForFloat.
             LayoutUnit oldLogicalTop = logicalTopForFloat(f);
             m_floatingObjects->removePlacedObject(f);
-            setLogicalTopForFloat(f, oldLogicalTop + f->m_paginationStrut);
+            setLogicalTopForFloat(f, oldLogicalTop + paginationStrut);
             m_floatingObjects->addPlacedObject(f);
         }
     }
 
-    setLogicalHeight(logicalHeight() + paginationStrut);
-    width.updateAvailableWidth();
+    if (lineInfo.isEmpty()) {
+        // Just update the line info's pagination strut without altering our logical height yet. If the line ends up containing
+        // no content, then we don't want to improperly grow the height of the block.
+        lineInfo.setFloatPaginationStrut(lineInfo.floatPaginationStrut() + paginationStrut);
+    } else {
+        // The line already has content on it, so we want to go ahead and shift everything down.
+        setLogicalHeight(logicalHeight() + paginationStrut);
+        width.updateAvailableWidth();
+    }
 
     return true;
 }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to