| Differences between
and this patch
- WebCore/rendering/ColumnInfo.h -8 / +20 lines
Lines 36-41 public: WebCore/rendering/ColumnInfo.h_sec1
36
    ColumnInfo()
36
    ColumnInfo()
37
        : m_desiredColumnWidth(0)
37
        : m_desiredColumnWidth(0)
38
        , m_desiredColumnCount(1)
38
        , m_desiredColumnCount(1)
39
        , m_columnCount(1)
40
        , m_columnHeight(0)
41
        , m_minimumColumnHeight(0)
39
        { }
42
        { }
40
    
43
    
41
    int desiredColumnWidth() const { return m_desiredColumnWidth; }
44
    int desiredColumnWidth() const { return m_desiredColumnWidth; }
Lines 44-62 public: WebCore/rendering/ColumnInfo.h_sec2
44
    unsigned desiredColumnCount() const { return m_desiredColumnCount; }
47
    unsigned desiredColumnCount() const { return m_desiredColumnCount; }
45
    void setDesiredColumnCount(unsigned count) { m_desiredColumnCount = count; }
48
    void setDesiredColumnCount(unsigned count) { m_desiredColumnCount = count; }
46
49
47
    // Encapsulated for the future where we can avoid storing the rects and just compute them dynamically.
50
    unsigned columnCount() const { return m_columnCount; }
48
    size_t columnCount() const { return m_columnRects.size(); }
51
    int columnHeight() const { return m_columnHeight; }
49
    const IntRect& columnRectAt(size_t i) const { return m_columnRects[i]; }
50
52
51
    void clearColumns() { m_columnRects.clear(); }
53
    // Set our count and height.  This is enough info for a RenderBlock to compute page rects
54
    // dynamically.
55
    void setColumnCountAndHeight(int c, int h)
56
    { 
57
        m_columnCount = c;
58
        m_columnHeight = h;
59
    }
60
    void setColumnHeight(int h) { m_columnHeight = h; }
61
62
    void updateMinimumColumnHeight(int h) { m_minimumColumnHeight = max(h, m_minimumColumnHeight); }
63
    int minimumColumnHeight() const { return m_minimumColumnHeight; }
52
64
53
    // FIXME: Will go away once we don't use the Vector.
54
    void addColumnRect(const IntRect& rect) { m_columnRects.append(rect); }
55
    
56
private:
65
private:
57
    int m_desiredColumnWidth;
66
    int m_desiredColumnWidth;
58
    unsigned m_desiredColumnCount;
67
    unsigned m_desiredColumnCount;
59
    Vector<IntRect> m_columnRects;
68
    
69
    unsigned m_columnCount;
70
    int m_columnHeight;
71
    int m_minimumColumnHeight;
60
};
72
};
61
73
62
}
74
}
- WebCore/rendering/LayoutState.cpp -15 / +55 lines
Lines 33-40 WebCore/rendering/LayoutState.cpp_sec1
33
33
34
namespace WebCore {
34
namespace WebCore {
35
35
36
LayoutState::LayoutState(LayoutState* prev, RenderBox* renderer, const IntSize& offset)
36
LayoutState::LayoutState(LayoutState* prev, RenderBox* renderer, const IntSize& offset, int pageHeight, ColumnInfo* colInfo)
37
    : m_next(prev)
37
    : m_columnInfo(colInfo)
38
    , m_next(prev)
38
#ifndef NDEBUG
39
#ifndef NDEBUG
39
    , m_renderer(renderer)
40
    , m_renderer(renderer)
40
#endif
41
#endif
Lines 45-87 LayoutState::LayoutState(LayoutState* pr WebCore/rendering/LayoutState.cpp_sec2
45
    if (fixed) {
46
    if (fixed) {
46
        // FIXME: This doesn't work correctly with transforms.
47
        // FIXME: This doesn't work correctly with transforms.
47
        FloatPoint fixedOffset = renderer->view()->localToAbsolute(FloatPoint(), true);
48
        FloatPoint fixedOffset = renderer->view()->localToAbsolute(FloatPoint(), true);
48
        m_offset = IntSize(fixedOffset.x(), fixedOffset.y()) + offset;
49
        m_paintOffset = IntSize(fixedOffset.x(), fixedOffset.y()) + offset;
49
    } else
50
    } else
50
        m_offset = prev->m_offset + offset;
51
        m_paintOffset = prev->m_paintOffset + offset;
51
52
52
    if (renderer->isRelPositioned()) {
53
    if (renderer->isPositioned() && !fixed) {
53
        if (renderer->hasLayer())
54
            m_offset += renderer->layer()->relativePositionOffset();
55
    } else if (renderer->isPositioned() && !fixed) {
56
        if (RenderObject* container = renderer->container()) {
54
        if (RenderObject* container = renderer->container()) {
57
            if (container->isRelPositioned() && container->isRenderInline())
55
            if (container->isRelPositioned() && container->isRenderInline())
58
                m_offset += toRenderInline(container)->relativePositionedInlineOffset(renderer);
56
                m_paintOffset += toRenderInline(container)->relativePositionedInlineOffset(renderer);
59
        }
57
        }
60
    }
58
    }
61
59
60
    m_layoutOffset = m_paintOffset;
61
62
    if (renderer->isRelPositioned() && renderer->hasLayer())
63
        m_paintOffset += renderer->layer()->relativePositionOffset();
64
62
    m_clipped = !fixed && prev->m_clipped;
65
    m_clipped = !fixed && prev->m_clipped;
63
    if (m_clipped)
66
    if (m_clipped)
64
        m_clipRect = prev->m_clipRect;
67
        m_clipRect = prev->m_clipRect;
65
68
66
    if (renderer->hasOverflowClip()) {
69
    if (renderer->hasOverflowClip()) {
67
        RenderLayer* layer = renderer->layer();
70
        RenderLayer* layer = renderer->layer();
68
        IntRect clipRect(toPoint(m_offset) + renderer->view()->layoutDelta(), layer->size());
71
        IntRect clipRect(toPoint(m_paintOffset) + renderer->view()->layoutDelta(), layer->size());
69
        if (m_clipped)
72
        if (m_clipped)
70
            m_clipRect.intersect(clipRect);
73
            m_clipRect.intersect(clipRect);
71
        else {
74
        else {
72
            m_clipRect = clipRect;
75
            m_clipRect = clipRect;
73
            m_clipped = true;
76
            m_clipped = true;
74
        }
77
        }
75
        m_offset -= layer->scrolledContentOffset();
78
79
        m_paintOffset -= layer->scrolledContentOffset();
76
    }
80
    }
77
81
78
    m_layoutDelta = m_next->m_layoutDelta;
82
    // Disable pagination for objects we don't support.  For now this includes overflow:scroll/auto and inline blocks.
83
    if (renderer->isReplaced() || renderer->scrollsOverflow())
84
        m_pageHeight = 0;
85
86
    // If we establish a new page height, then cache the offset to the top of the first page.
87
    // We can compare this later on to figure out what part of the page we're actually on,
88
    if (pageHeight) {
89
        m_pageHeight = pageHeight;
90
        m_pageOffset = IntSize(m_paintOffset.width() + renderer->borderLeft() + renderer->paddingLeft(),
91
                               m_paintOffset.height() + renderer->borderTop() + renderer->paddingTop());
92
    } else {
93
        // If we don't establish a new page height, then propagate the old page height and offset down.
94
        m_pageHeight = m_next->m_pageHeight;
95
        m_pageOffset = m_next->m_pageOffset;
96
    }
97
    
98
    if (!m_columnInfo)
99
        m_columnInfo = m_next->m_columnInfo;
79
100
101
    m_layoutDelta = m_next->m_layoutDelta;
102
    
80
    // FIXME: <http://bugs.webkit.org/show_bug.cgi?id=13443> Apply control clip if present.
103
    // FIXME: <http://bugs.webkit.org/show_bug.cgi?id=13443> Apply control clip if present.
81
}
104
}
82
105
83
LayoutState::LayoutState(RenderObject* root)
106
LayoutState::LayoutState(RenderObject* root)
84
    : m_clipped(false)
107
    : m_clipped(false)
108
    , m_pageHeight(0)
109
    , m_columnInfo(0)
85
    , m_next(0)
110
    , m_next(0)
86
#ifndef NDEBUG
111
#ifndef NDEBUG
87
    , m_renderer(root)
112
    , m_renderer(root)
Lines 89-101 LayoutState::LayoutState(RenderObject* r WebCore/rendering/LayoutState.cpp_sec3
89
{
114
{
90
    RenderObject* container = root->container();
115
    RenderObject* container = root->container();
91
    FloatPoint absContentPoint = container->localToAbsolute(FloatPoint(), false, true);
116
    FloatPoint absContentPoint = container->localToAbsolute(FloatPoint(), false, true);
92
    m_offset = IntSize(absContentPoint.x(), absContentPoint.y());
117
    m_paintOffset = IntSize(absContentPoint.x(), absContentPoint.y());
93
118
94
    if (container->hasOverflowClip()) {
119
    if (container->hasOverflowClip()) {
95
        RenderLayer* layer = toRenderBoxModelObject(container)->layer();
120
        RenderLayer* layer = toRenderBoxModelObject(container)->layer();
96
        m_clipped = true;
121
        m_clipped = true;
97
        m_clipRect = IntRect(toPoint(m_offset), layer->size());
122
        m_clipRect = IntRect(toPoint(m_paintOffset), layer->size());
98
        m_offset -= layer->scrolledContentOffset();
123
        m_paintOffset -= layer->scrolledContentOffset();
99
    }
124
    }
100
}
125
}
101
126
Lines 126-129 void LayoutState::operator delete(void* WebCore/rendering/LayoutState.cpp_sec4
126
    *(size_t*)ptr = sz;
151
    *(size_t*)ptr = sz;
127
}
152
}
128
153
154
void LayoutState::clearPaginationInformation()
155
{
156
    m_pageHeight = m_next->m_pageHeight;
157
    m_pageOffset = m_next->m_pageOffset;
158
    m_columnInfo = m_next->m_columnInfo;
159
}
160
161
int LayoutState::pageY(int childY) const
162
{
163
    ASSERT(m_pageHeight);
164
    int layoutY = m_layoutOffset.height() + childY;
165
    int pageY = m_pageOffset.height();
166
    return layoutY - pageY;
167
}
168
129
} // namespace WebCore
169
} // namespace WebCore
- WebCore/rendering/LayoutState.h -2 / +16 lines
Lines 32-37 WebCore/rendering/LayoutState.h_sec1
32
32
33
namespace WebCore {
33
namespace WebCore {
34
34
35
class ColumnInfo;
35
class RenderArena;
36
class RenderArena;
36
class RenderBox;
37
class RenderBox;
37
class RenderObject;
38
class RenderObject;
Lines 40-45 class LayoutState : public Noncopyable { WebCore/rendering/LayoutState.h_sec2
40
public:
41
public:
41
    LayoutState()
42
    LayoutState()
42
        : m_clipped(false)
43
        : m_clipped(false)
44
        , m_pageHeight(0)
45
        , m_columnInfo(0)
43
        , m_next(0)
46
        , m_next(0)
44
#ifndef NDEBUG
47
#ifndef NDEBUG
45
        , m_renderer(0)
48
        , m_renderer(0)
Lines 47-53 public: WebCore/rendering/LayoutState.h_sec3
47
    {
50
    {
48
    }
51
    }
49
52
50
    LayoutState(LayoutState*, RenderBox*, const IntSize& offset);
53
    LayoutState(LayoutState*, RenderBox*, const IntSize& offset, int pageHeight, ColumnInfo*);
51
    LayoutState(RenderObject*);
54
    LayoutState(RenderObject*);
52
55
53
    void destroy(RenderArena*);
56
    void destroy(RenderArena*);
Lines 58-63 public: WebCore/rendering/LayoutState.h_sec4
58
    // Overridden to prevent the normal delete from being called.
61
    // Overridden to prevent the normal delete from being called.
59
    void operator delete(void*, size_t);
62
    void operator delete(void*, size_t);
60
63
64
    void clearPaginationInformation();
65
    bool paginatingColumns() const { return m_columnInfo; }
66
    bool paginated() const { return m_pageHeight || m_columnInfo; }
67
    int pageY(int childY) const;
68
61
private:
69
private:
62
    // The normal operator new is disallowed.
70
    // The normal operator new is disallowed.
63
    void* operator new(size_t) throw();
71
    void* operator new(size_t) throw();
Lines 65-74 private: WebCore/rendering/LayoutState.h_sec5
65
public:
73
public:
66
    bool m_clipped;
74
    bool m_clipped;
67
    IntRect m_clipRect;
75
    IntRect m_clipRect;
68
    IntSize m_offset;       // x/y offset from container.
76
    IntSize m_paintOffset;       // x/y offset from container.  Includes relative positioning and scroll offsets.
77
    IntSize m_layoutOffset;      // x/y offset from container.  Does not include relative positioning or scroll offsets.
69
    IntSize m_layoutDelta;  // Transient offset from the final position of the object
78
    IntSize m_layoutDelta;  // Transient offset from the final position of the object
70
                            // used to ensure that repaints happen in the correct place.
79
                            // used to ensure that repaints happen in the correct place.
71
                            // This is a total delta accumulated from the root.
80
                            // This is a total delta accumulated from the root.
81
82
    int m_pageHeight;            // The current page height for the pagination model that encloses us.
83
    IntSize m_pageOffset;        // The offset of the start of the first page in the nearest enclosing pagination model.
84
    ColumnInfo* m_columnInfo;    // If the enclosing pagination model is a column model, then this will store column information for easy retrieval/manipulation.
85
72
    LayoutState* m_next;
86
    LayoutState* m_next;
73
#ifndef NDEBUG
87
#ifndef NDEBUG
74
    RenderObject* m_renderer;
88
    RenderObject* m_renderer;
- WebCore/rendering/RenderBlock.cpp -205 / +443 lines
Lines 114-120 RenderBlock::RenderBlock(Node* node) WebCore/rendering/RenderBlock.cpp_sec1
114
      , m_floatingObjects(0)
114
      , m_floatingObjects(0)
115
      , m_positionedObjects(0)
115
      , m_positionedObjects(0)
116
      , m_continuation(0)
116
      , m_continuation(0)
117
      , m_maxMargin(0)
117
      , m_rareData(0)
118
      , m_lineHeight(-1)
118
      , m_lineHeight(-1)
119
{
119
{
120
    setChildrenInline(true);
120
    setChildrenInline(true);
Lines 124-130 RenderBlock::~RenderBlock() WebCore/rendering/RenderBlock.cpp_sec2
124
{
124
{
125
    delete m_floatingObjects;
125
    delete m_floatingObjects;
126
    delete m_positionedObjects;
126
    delete m_positionedObjects;
127
    delete m_maxMargin;
127
    delete m_rareData;
128
    
128
    
129
    if (hasColumns())
129
    if (hasColumns())
130
        delete gColumnInfoMap->take(this);
130
        delete gColumnInfoMap->take(this);
Lines 1112-1118 void RenderBlock::layout() WebCore/rendering/RenderBlock.cpp_sec3
1112
        clearLayoutOverflow();
1112
        clearLayoutOverflow();
1113
}
1113
}
1114
1114
1115
void RenderBlock::layoutBlock(bool relayoutChildren)
1115
void RenderBlock::layoutBlock(bool relayoutChildren, int pageHeight)
1116
{
1116
{
1117
    ASSERT(needsLayout());
1117
    ASSERT(needsLayout());
1118
1118
Lines 1122-1130 void RenderBlock::layoutBlock(bool relay WebCore/rendering/RenderBlock.cpp_sec4
1122
    if (!relayoutChildren && layoutOnlyPositionedObjects())
1122
    if (!relayoutChildren && layoutOnlyPositionedObjects())
1123
        return;
1123
        return;
1124
1124
1125
    LayoutRepainter repainter(*this, m_everHadLayout && checkForRepaintDuringLayout());
1126
    LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection());
1127
1128
    int oldWidth = width();
1125
    int oldWidth = width();
1129
    int oldColumnWidth = desiredColumnWidth();
1126
    int oldColumnWidth = desiredColumnWidth();
1130
1127
Lines 1140-1145 void RenderBlock::layoutBlock(bool relay WebCore/rendering/RenderBlock.cpp_sec5
1140
1137
1141
    int previousHeight = height();
1138
    int previousHeight = height();
1142
    setHeight(0);
1139
    setHeight(0);
1140
    bool hasSpecifiedPageHeight = false;
1141
    ColumnInfo* colInfo = columnInfo();
1142
    if (hasColumns()) {
1143
        if (!pageHeight) {
1144
            // We need to go ahead and set our explicit page height if one exists, so that we can
1145
            // avoid doing two layout passes.
1146
            calcHeight();
1147
            int columnHeight = contentHeight();
1148
            if (columnHeight > 0) {
1149
                pageHeight = columnHeight;
1150
                hasSpecifiedPageHeight = true;
1151
            }
1152
            setHeight(0);
1153
        }
1154
        if (colInfo->columnHeight() != pageHeight && m_everHadLayout) {
1155
            colInfo->setColumnHeight(pageHeight);
1156
            markDescendantBlocksAndLinesForLayout(); // We need to dirty all descendant blocks and lines, since the column height is different now.
1157
        }
1158
    }
1159
1160
    LayoutRepainter repainter(*this, m_everHadLayout && checkForRepaintDuringLayout());
1161
    LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection(), pageHeight, colInfo);
1143
1162
1144
    // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, to track
1163
    // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, to track
1145
    // our current maximal positive and negative margins.  These values are used when we
1164
    // our current maximal positive and negative margins.  These values are used when we
Lines 1189-1198 void RenderBlock::layoutBlock(bool relay WebCore/rendering/RenderBlock.cpp_sec6
1189
    if (floatBottom() > (height() - toAdd) && expandsToEncloseOverhangingFloats())
1208
    if (floatBottom() > (height() - toAdd) && expandsToEncloseOverhangingFloats())
1190
        setHeight(floatBottom() + toAdd);
1209
        setHeight(floatBottom() + toAdd);
1191
    
1210
    
1192
    // Now lay out our columns within this intrinsic height, since they can slightly affect the intrinsic height as
1211
    if (layoutColumns(hasSpecifiedPageHeight, pageHeight, statePusher))
1193
    // we adjust for clean column breaks.
1212
        return;
1194
    int singleColumnBottom = layoutColumns();
1213
 
1195
1196
    // Calculate our new height.
1214
    // Calculate our new height.
1197
    int oldHeight = height();
1215
    int oldHeight = height();
1198
    calcHeight();
1216
    calcHeight();
Lines 1207-1227 void RenderBlock::layoutBlock(bool relay WebCore/rendering/RenderBlock.cpp_sec7
1207
                }
1225
                }
1208
            }
1226
            }
1209
        }
1227
        }
1210
        
1211
        // We have to rebalance columns to the new height.
1212
        layoutColumns(singleColumnBottom);
1213
    }
1228
    }
1214
1229
1215
    if (previousHeight != height())
1230
    if (previousHeight != height())
1216
        relayoutChildren = true;
1231
        relayoutChildren = true;
1217
1232
1218
    // This check is designed to catch anyone
1219
    // who wasn't going to propagate float information up to the parent and yet could potentially be painted by its ancestor.
1220
    if (isRoot() || expandsToEncloseOverhangingFloats())
1221
        addOverflowFromFloats();
1222
1223
    // Add overflow from children (unless we're multi-column, since in that case all our child overflow is clipped anyway).
1233
    // Add overflow from children (unless we're multi-column, since in that case all our child overflow is clipped anyway).
1224
    if (!hasColumns()) {
1234
    if (!hasColumns()) {
1235
        // This check is designed to catch anyone
1236
        // who wasn't going to propagate float information up to the parent and yet could potentially be painted by its ancestor.
1237
        if (isRoot() || expandsToEncloseOverhangingFloats())
1238
            addOverflowFromFloats();
1239
1225
        if (childrenInline())
1240
        if (childrenInline())
1226
            addOverflowFromInlineChildren();
1241
            addOverflowFromInlineChildren();
1227
        else
1242
        else
Lines 1237-1242 void RenderBlock::layoutBlock(bool relay WebCore/rendering/RenderBlock.cpp_sec8
1237
    
1252
    
1238
    statePusher.pop();
1253
    statePusher.pop();
1239
1254
1255
    if (view()->layoutState()->m_pageHeight)
1256
        setPageY(view()->layoutState()->pageY(y()));
1257
1240
    // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if
1258
    // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if
1241
    // we overflow or not.
1259
    // we overflow or not.
1242
    updateScrollInfoAfterLayout();
1260
    updateScrollInfoAfterLayout();
Lines 1485-1491 int RenderBlock::collapseMargins(RenderB WebCore/rendering/RenderBlock.cpp_sec9
1485
    if (marginInfo.quirkContainer() && marginInfo.atTopOfBlock() && (posTop - negTop))
1503
    if (marginInfo.quirkContainer() && marginInfo.atTopOfBlock() && (posTop - negTop))
1486
        marginInfo.setTopQuirk(topQuirk);
1504
        marginInfo.setTopQuirk(topQuirk);
1487
1505
1488
    int ypos = height();
1506
    int beforeCollapseY = height();
1507
    int ypos = beforeCollapseY;
1489
    if (child->isSelfCollapsingBlock()) {
1508
    if (child->isSelfCollapsingBlock()) {
1490
        // This child has no height.  We need to compute our
1509
        // This child has no height.  We need to compute our
1491
        // position before we collapse the child's margins together,
1510
        // position before we collapse the child's margins together,
Lines 1527-1532 int RenderBlock::collapseMargins(RenderB WebCore/rendering/RenderBlock.cpp_sec10
1527
            marginInfo.setBottomQuirk(child->isBottomMarginQuirk() || style()->marginBottomCollapse() == MDISCARD);
1546
            marginInfo.setBottomQuirk(child->isBottomMarginQuirk() || style()->marginBottomCollapse() == MDISCARD);
1528
    }
1547
    }
1529
    
1548
    
1549
    // If margins would pull us past the top of the next page, then we need to pull back and pretend like the margins
1550
    // collapsed into the page edge.
1551
    bool paginated = view()->layoutState()->paginated();
1552
    if (paginated && ypos > beforeCollapseY) {
1553
        int oldY = ypos;
1554
        ypos = min(ypos, nextPageTop(beforeCollapseY));
1555
        setHeight(height() + (ypos - oldY));
1556
    }
1530
    return ypos;
1557
    return ypos;
1531
}
1558
}
1532
1559
Lines 1586-1592 int RenderBlock::estimateVerticalPositio WebCore/rendering/RenderBlock.cpp_sec11
1586
        int childMarginTop = child->selfNeedsLayout() ? child->marginTop() : child->collapsedMarginTop();
1613
        int childMarginTop = child->selfNeedsLayout() ? child->marginTop() : child->collapsedMarginTop();
1587
        yPosEstimate += max(marginInfo.margin(), childMarginTop);
1614
        yPosEstimate += max(marginInfo.margin(), childMarginTop);
1588
    }
1615
    }
1616
    
1617
    bool paginated = view()->layoutState()->paginated();
1618
1619
    // Adjust yPosEstimate down to the next page if the margins are so large that we don't fit on the current
1620
    // page.
1621
    if (paginated && yPosEstimate > height())
1622
        yPosEstimate = min(yPosEstimate, nextPageTop(height()));
1623
1589
    yPosEstimate += getClearDelta(child, yPosEstimate);
1624
    yPosEstimate += getClearDelta(child, yPosEstimate);
1625
    
1626
    if (paginated) {
1627
        // If the object has a page or column break value of "before", then we should shift to the top of the next page.
1628
        yPosEstimate = applyBeforeBreak(child, yPosEstimate);
1629
    
1630
        // For replaced elements and scrolled elements, we want to shift them to the next page if they don't fit on the current one.
1631
        yPosEstimate = adjustForUnsplittableChild(child, yPosEstimate);
1632
    }
1633
1590
    return yPosEstimate;
1634
    return yPosEstimate;
1591
}
1635
}
1592
1636
Lines 1776-1783 void RenderBlock::layoutBlockChild(Rende WebCore/rendering/RenderBlock.cpp_sec12
1776
    view()->addLayoutDelta(IntSize(0, child->y() - yPosEstimate));
1820
    view()->addLayoutDelta(IntSize(0, child->y() - yPosEstimate));
1777
    child->setLocation(child->x(), yPosEstimate);
1821
    child->setLocation(child->x(), yPosEstimate);
1778
1822
1823
    RenderBlock* childBlockFlow = child->isBlockFlow() ? toRenderBlock(child) : 0;
1779
    bool markDescendantsWithFloats = false;
1824
    bool markDescendantsWithFloats = false;
1780
    if (yPosEstimate != oldRect.y() && !child->avoidsFloats() && child->isBlockFlow() && toRenderBlock(child)->containsFloats())
1825
    if (yPosEstimate != oldRect.y() && !child->avoidsFloats() && childBlockFlow && childBlockFlow->containsFloats())
1781
        markDescendantsWithFloats = true;
1826
        markDescendantsWithFloats = true;
1782
    else if (!child->avoidsFloats() || child->shrinkToAvoidFloats()) {
1827
    else if (!child->avoidsFloats() || child->shrinkToAvoidFloats()) {
1783
        // If an element might be affected by the presence of floats, then always mark it for
1828
        // If an element might be affected by the presence of floats, then always mark it for
Lines 1787-1804 void RenderBlock::layoutBlockChild(Rende WebCore/rendering/RenderBlock.cpp_sec13
1787
            markDescendantsWithFloats = true;
1832
            markDescendantsWithFloats = true;
1788
    }
1833
    }
1789
1834
1790
    if (child->isRenderBlock()) {
1835
    if (childBlockFlow) {
1791
        if (markDescendantsWithFloats)
1836
        if (markDescendantsWithFloats)
1792
            toRenderBlock(child)->markAllDescendantsWithFloatsForLayout();
1837
            childBlockFlow->markAllDescendantsWithFloatsForLayout();
1793
1794
        previousFloatBottom = max(previousFloatBottom, oldRect.y() + toRenderBlock(child)->floatBottom());
1838
        previousFloatBottom = max(previousFloatBottom, oldRect.y() + toRenderBlock(child)->floatBottom());
1795
    }
1839
    }
1796
1840
1841
    bool paginated = view()->layoutState()->paginated();
1842
    if (paginated && view()->layoutState()->m_pageHeight && childBlockFlow && view()->layoutState()->pageY(child->y()) != childBlockFlow->pageY())
1843
        childBlockFlow->setChildNeedsLayout(true, false);
1844
1797
    bool childHadLayout = child->m_everHadLayout;
1845
    bool childHadLayout = child->m_everHadLayout;
1798
    bool childNeededLayout = child->needsLayout();
1846
    bool childNeededLayout = child->needsLayout();
1799
    if (childNeededLayout)
1847
    if (childNeededLayout)
1800
        child->layout();
1848
        child->layout();
1801
1849
1850
    // Cache if we are at the top of the block right now.
1851
    bool atTopOfBlock = marginInfo.atTopOfBlock();
1852
1802
    // Now determine the correct ypos based off examination of collapsing margin
1853
    // Now determine the correct ypos based off examination of collapsing margin
1803
    // values.
1854
    // values.
1804
    int yBeforeClear = collapseMargins(child, marginInfo);
1855
    int yBeforeClear = collapseMargins(child, marginInfo);
Lines 1806-1811 void RenderBlock::layoutBlockChild(Rende WebCore/rendering/RenderBlock.cpp_sec14
1806
    // Now check for clear.
1857
    // Now check for clear.
1807
    int yAfterClear = clearFloatsIfNeeded(child, marginInfo, oldTopPosMargin, oldTopNegMargin, yBeforeClear);
1858
    int yAfterClear = clearFloatsIfNeeded(child, marginInfo, oldTopPosMargin, oldTopNegMargin, yBeforeClear);
1808
    
1859
    
1860
    if (paginated) {
1861
        int oldY = yAfterClear;
1862
        
1863
        // If the object has a page or column break value of "before", then we should shift to the top of the next page.
1864
        yAfterClear = applyBeforeBreak(child, yAfterClear);
1865
    
1866
        // For replaced elements and scrolled elements, we want to shift them to the next page if they don't fit on the current one.
1867
        yAfterClear = adjustForUnsplittableChild(child, yAfterClear);
1868
        
1869
        if (childBlockFlow->paginationStrut()) {
1870
            // We are willing to propagate out to our parent block as long as we were at the top of the block prior
1871
            // to collapsing our margins, and as long as we didn't clear or move as a result of other pagination.
1872
            if (atTopOfBlock && oldY == yBeforeClear && !isPositioned() && !isTableCell()) {
1873
                // FIXME: Should really check if we're exceeding the page height before propagating the strut, but we don't
1874
                // have all the information to do so (the strut only has the remaining amount to push).  Gecko gets this wrong too
1875
                // and pushes to the next page anyway, so not too concerned about it.
1876
                setPaginationStrut(yAfterClear + childBlockFlow->paginationStrut());
1877
                childBlockFlow->setPaginationStrut(0);
1878
            } else
1879
                yAfterClear += childBlockFlow->paginationStrut();
1880
        }
1881
1882
        // Similar to how we apply clearance.  Go ahead and boost height() to be the place where we're going to position the child.
1883
        setHeight(height() + (yAfterClear - oldY));
1884
    }
1885
1809
    view()->addLayoutDelta(IntSize(0, yPosEstimate - yAfterClear));
1886
    view()->addLayoutDelta(IntSize(0, yPosEstimate - yAfterClear));
1810
    child->setLocation(child->x(), yAfterClear);
1887
    child->setLocation(child->x(), yAfterClear);
1811
1888
Lines 1818-1825 void RenderBlock::layoutBlockChild(Rende WebCore/rendering/RenderBlock.cpp_sec15
1818
            // So go ahead and mark the item as dirty.
1895
            // So go ahead and mark the item as dirty.
1819
            child->setChildNeedsLayout(true, false);
1896
            child->setChildNeedsLayout(true, false);
1820
        }
1897
        }
1821
        if (!child->avoidsFloats() && child->isBlockFlow() && toRenderBlock(child)->containsFloats())
1898
        if (childBlockFlow) {
1822
            toRenderBlock(child)->markAllDescendantsWithFloatsForLayout();
1899
            if (!child->avoidsFloats() && childBlockFlow->containsFloats())
1900
                childBlockFlow->markAllDescendantsWithFloatsForLayout();
1901
            if (paginated && !child->needsLayout() && view()->layoutState()->m_pageHeight && view()->layoutState()->pageY(child->y()) != childBlockFlow->pageY())
1902
                child->setChildNeedsLayout(true, false);
1903
        }
1904
1823
        // Our guess was wrong. Make the child lay itself out again.
1905
        // Our guess was wrong. Make the child lay itself out again.
1824
        child->layoutIfNeeded();
1906
        child->layoutIfNeeded();
1825
    }
1907
    }
Lines 1840-1846 void RenderBlock::layoutBlockChild(Rende WebCore/rendering/RenderBlock.cpp_sec16
1840
    }
1922
    }
1841
    // If the child has overhanging floats that intrude into following siblings (or possibly out
1923
    // If the child has overhanging floats that intrude into following siblings (or possibly out
1842
    // of this block), then the parent gets notified of the floats now.
1924
    // of this block), then the parent gets notified of the floats now.
1843
    if (child->isBlockFlow() && toRenderBlock(child)->containsFloats())
1925
    if (childBlockFlow && childBlockFlow->containsFloats())
1844
        maxFloatBottom = max(maxFloatBottom, addOverhangingFloats(toRenderBlock(child), -child->x(), -child->y(), !childNeededLayout));
1926
        maxFloatBottom = max(maxFloatBottom, addOverhangingFloats(toRenderBlock(child), -child->x(), -child->y(), !childNeededLayout));
1845
1927
1846
    IntSize childOffset(child->x() - oldRect.x(), child->y() - oldRect.y());
1928
    IntSize childOffset(child->x() - oldRect.x(), child->y() - oldRect.y());
Lines 1859-1864 void RenderBlock::layoutBlockChild(Rende WebCore/rendering/RenderBlock.cpp_sec17
1859
        child->repaintOverhangingFloats(true);
1941
        child->repaintOverhangingFloats(true);
1860
    }
1942
    }
1861
1943
1944
    if (paginated) {
1945
        // Check for an after page/column break.
1946
        int newHeight = applyAfterBreak(child, height(), marginInfo);
1947
        if (newHeight != height())
1948
            setHeight(newHeight);
1949
    }
1950
1862
    ASSERT(oldLayoutDelta == view()->layoutDelta());
1951
    ASSERT(oldLayoutDelta == view()->layoutDelta());
1863
}
1952
}
1864
1953
Lines 1889-1894 bool RenderBlock::layoutOnlyPositionedOb WebCore/rendering/RenderBlock.cpp_sec18
1889
void RenderBlock::layoutPositionedObjects(bool relayoutChildren)
1978
void RenderBlock::layoutPositionedObjects(bool relayoutChildren)
1890
{
1979
{
1891
    if (m_positionedObjects) {
1980
    if (m_positionedObjects) {
1981
        if (hasColumns())
1982
            view()->layoutState()->clearPaginationInformation(); // Positioned objects are not part of the column flow, so they don't paginate with the columns.
1983
1892
        RenderBox* r;
1984
        RenderBox* r;
1893
        Iterator end = m_positionedObjects->end();
1985
        Iterator end = m_positionedObjects->end();
1894
        for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
1986
        for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
Lines 1910-1915 void RenderBlock::layoutPositionedObject WebCore/rendering/RenderBlock.cpp_sec19
1910
                r->tryLayoutDoingPositionedMovementOnly();
2002
                r->tryLayoutDoingPositionedMovementOnly();
1911
            r->layoutIfNeeded();
2003
            r->layoutIfNeeded();
1912
        }
2004
        }
2005
        
2006
        if (hasColumns())
2007
            view()->layoutState()->m_columnInfo = columnInfo(); // FIXME: Kind of gross. We just put this back into the layout state so that pop() will work.
1913
    }
2008
    }
1914
}
2009
}
1915
2010
Lines 1997-2008 void RenderBlock::paintColumnRules(Paint WebCore/rendering/RenderBlock.cpp_sec20
1997
2092
1998
    // We need to do multiple passes, breaking up our child painting into strips.
2093
    // We need to do multiple passes, breaking up our child painting into strips.
1999
    ColumnInfo* colInfo = columnInfo();
2094
    ColumnInfo* colInfo = columnInfo();
2000
    unsigned colCount = colInfo->columnCount();
2095
    unsigned colCount = columnCount(colInfo);
2001
    int currXOffset = style()->direction() == LTR ? 0 : contentWidth();
2096
    int currXOffset = style()->direction() == LTR ? 0 : contentWidth();
2002
    int ruleAdd = borderLeft() + paddingLeft();
2097
    int ruleAdd = borderLeft() + paddingLeft();
2003
    int ruleX = style()->direction() == LTR ? 0 : contentWidth();
2098
    int ruleX = style()->direction() == LTR ? 0 : contentWidth();
2004
    for (unsigned i = 0; i < colCount; i++) {
2099
    for (unsigned i = 0; i < colCount; i++) {
2005
        IntRect colRect = colInfo->columnRectAt(i);
2100
        IntRect colRect = columnRectAt(colInfo, i);
2006
2101
2007
        // Move to the next position.
2102
        // Move to the next position.
2008
        if (style()->direction() == LTR) {
2103
        if (style()->direction() == LTR) {
Lines 2033-2046 void RenderBlock::paintColumnContents(Pa WebCore/rendering/RenderBlock.cpp_sec21
2033
    GraphicsContext* context = paintInfo.context;
2128
    GraphicsContext* context = paintInfo.context;
2034
    int colGap = columnGap();
2129
    int colGap = columnGap();
2035
    ColumnInfo* colInfo = columnInfo();
2130
    ColumnInfo* colInfo = columnInfo();
2036
    unsigned colCount = colInfo->columnCount();
2131
    unsigned colCount = columnCount(colInfo);
2037
    if (!colCount)
2132
    if (!colCount)
2038
        return;
2133
        return;
2039
    int currXOffset = style()->direction() == LTR ? 0 : contentWidth() - colInfo->columnRectAt(0).width();
2134
    int currXOffset = style()->direction() == LTR ? 0 : contentWidth() - columnRectAt(colInfo, 0).width();
2040
    int currYOffset = 0;
2135
    int currYOffset = 0;
2041
    for (unsigned i = 0; i < colCount; i++) {
2136
    for (unsigned i = 0; i < colCount; i++) {
2042
        // For each rect, we clip to the rect, and then we adjust our coords.
2137
        // For each rect, we clip to the rect, and then we adjust our coords.
2043
        IntRect colRect = colInfo->columnRectAt(i);
2138
        IntRect colRect = columnRectAt(colInfo, i);
2044
        colRect.move(tx, ty);
2139
        colRect.move(tx, ty);
2045
        PaintInfo info(paintInfo);
2140
        PaintInfo info(paintInfo);
2046
        info.rect.intersect(colRect);
2141
        info.rect.intersect(colRect);
Lines 2098-2111 void RenderBlock::paintChildren(PaintInf WebCore/rendering/RenderBlock.cpp_sec22
2098
    info.updatePaintingRootForChildren(this);
2193
    info.updatePaintingRootForChildren(this);
2099
    
2194
    
2100
    RenderView* renderView = view();
2195
    RenderView* renderView = view();
2101
    bool usePrintRect = !renderView->printRect().isEmpty() && !document()->settings()->paginateDuringLayoutEnabled();
2196
    bool usePrintRect = !renderView->printRect().isEmpty();
2102
    
2197
    
2103
    bool checkPageBreaks = document()->paginated() && !document()->settings()->paginateDuringLayoutEnabled();
2198
    bool checkPageBreaks = document()->paginated() && !document()->settings()->paginateDuringLayoutEnabled();
2104
    bool checkColumnBreaks = !checkPageBreaks && usePrintRect;
2105
2199
2106
    for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {        
2200
    for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {        
2107
        // Check for page-break-before: always, and if it's set, break and bail.
2201
        // Check for page-break-before: always, and if it's set, break and bail.
2108
        bool checkBeforeAlways = !childrenInline() && ((checkPageBreaks && child->style()->pageBreakBefore() == PBALWAYS) || (checkColumnBreaks && child->style()->columnBreakBefore() == PBALWAYS));
2202
        bool checkBeforeAlways = !childrenInline() && (checkPageBreaks && child->style()->pageBreakBefore() == PBALWAYS);
2109
        if (checkBeforeAlways
2203
        if (checkBeforeAlways
2110
            && (ty + child->y()) > paintInfo.rect.y()
2204
            && (ty + child->y()) > paintInfo.rect.y()
2111
            && (ty + child->y()) < paintInfo.rect.bottom()) {
2205
            && (ty + child->y()) < paintInfo.rect.bottom()) {
Lines 2128-2134 void RenderBlock::paintChildren(PaintInf WebCore/rendering/RenderBlock.cpp_sec23
2128
            child->paint(info, tx, ty);
2222
            child->paint(info, tx, ty);
2129
2223
2130
        // Check for page-break-after: always, and if it's set, break and bail.
2224
        // Check for page-break-after: always, and if it's set, break and bail.
2131
        bool checkAfterAlways = !childrenInline() && ((checkPageBreaks && child->style()->pageBreakAfter() == PBALWAYS) || (checkColumnBreaks && child->style()->columnBreakAfter() == PBALWAYS));
2225
        bool checkAfterAlways = !childrenInline() && (checkPageBreaks && child->style()->pageBreakAfter() == PBALWAYS);
2132
        if (checkAfterAlways
2226
        if (checkAfterAlways
2133
            && (ty + child->y() + child->height()) > paintInfo.rect.y()
2227
            && (ty + child->y() + child->height()) > paintInfo.rect.y()
2134
            && (ty + child->y() + child->height()) < paintInfo.rect.bottom()) {
2228
            && (ty + child->y() + child->height()) < paintInfo.rect.bottom()) {
Lines 2776-2782 void RenderBlock::removePositionedObject WebCore/rendering/RenderBlock.cpp_sec24
2776
        m_positionedObjects->remove(deadObjects.at(i));
2870
        m_positionedObjects->remove(deadObjects.at(i));
2777
}
2871
}
2778
2872
2779
void RenderBlock::insertFloatingObject(RenderBox* o)
2873
RenderBlock::FloatingObject* RenderBlock::insertFloatingObject(RenderBox* o)
2780
{
2874
{
2781
    ASSERT(o->isFloating());
2875
    ASSERT(o->isFloating());
2782
2876
Lines 2789-2813 void RenderBlock::insertFloatingObject(R WebCore/rendering/RenderBlock.cpp_sec25
2789
        DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
2883
        DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
2790
        FloatingObject* f;
2884
        FloatingObject* f;
2791
        while ( (f = it.current()) ) {
2885
        while ( (f = it.current()) ) {
2792
            if (f->m_renderer == o) return;
2886
            if (f->m_renderer == o)
2887
                return f;
2793
            ++it;
2888
            ++it;
2794
        }
2889
        }
2795
    }
2890
    }
2796
2891
2797
    // Create the special object entry & append it to the list
2892
    // Create the special object entry & append it to the list
2798
2893
2799
    o->layoutIfNeeded();
2800
2801
    FloatingObject* newObj = new FloatingObject(o->style()->floating() == FLEFT ? FloatingObject::FloatLeft : FloatingObject::FloatRight);
2894
    FloatingObject* newObj = new FloatingObject(o->style()->floating() == FLEFT ? FloatingObject::FloatLeft : FloatingObject::FloatRight);
2802
2895
2803
    newObj->m_top = -1;
2896
    newObj->m_top = -1;
2804
    newObj->m_bottom = -1;
2897
    newObj->m_bottom = -1;
2898
    
2899
    // Our location is irrelevant if we're unsplittable or no pagination is in effect.  Just go ahead
2900
    // and lay out the float.
2901
    bool affectedByPagination = o->isRenderBlock() && view()->layoutState()->m_pageHeight;
2902
    if (!affectedByPagination)
2903
        o->layoutIfNeeded();
2904
    else {
2905
        o->calcWidth();
2906
        o->calcVerticalMargins();
2907
    }
2805
    newObj->m_width = o->width() + o->marginLeft() + o->marginRight();
2908
    newObj->m_width = o->width() + o->marginLeft() + o->marginRight();
2909
2806
    newObj->m_shouldPaint = !o->hasSelfPaintingLayer(); // If a layer exists, the float will paint itself.  Otherwise someone else will.
2910
    newObj->m_shouldPaint = !o->hasSelfPaintingLayer(); // If a layer exists, the float will paint itself.  Otherwise someone else will.
2807
    newObj->m_isDescendant = true;
2911
    newObj->m_isDescendant = true;
2808
    newObj->m_renderer = o;
2912
    newObj->m_renderer = o;
2809
2913
2810
    m_floatingObjects->append(newObj);
2914
    m_floatingObjects->append(newObj);
2915
    
2916
    return newObj;
2811
}
2917
}
2812
2918
2813
void RenderBlock::removeFloatingObject(RenderBox* o)
2919
void RenderBlock::removeFloatingObject(RenderBox* o)
Lines 2831-2836 void RenderBlock::removeFloatingObject(R WebCore/rendering/RenderBlock.cpp_sec26
2831
    }
2937
    }
2832
}
2938
}
2833
2939
2940
void RenderBlock::removeFloatingObjects(FloatingObject* f, int y)
2941
{
2942
    if (!m_floatingObjects)
2943
        return;
2944
    
2945
    FloatingObject* curr = m_floatingObjects->last();
2946
    while (curr != f && (curr->m_top == -1 || curr->m_top >= y)) {
2947
        m_floatingObjects->removeLast();
2948
        curr = m_floatingObjects->last();
2949
    }
2950
}
2951
2834
bool RenderBlock::positionNewFloats()
2952
bool RenderBlock::positionNewFloats()
2835
{
2953
{
2836
    if (!m_floatingObjects)
2954
    if (!m_floatingObjects)
Lines 2867-2882 bool RenderBlock::positionNewFloats() WebCore/rendering/RenderBlock.cpp_sec27
2867
        }
2985
        }
2868
2986
2869
        RenderBox* o = f->m_renderer;
2987
        RenderBox* o = f->m_renderer;
2870
        int _height = o->height() + o->marginTop() + o->marginBottom();
2871
2988
2872
        int ro = rightOffset(); // Constant part of right offset.
2989
        int ro = rightOffset(); // Constant part of right offset.
2873
        int lo = leftOffset(); // Constat part of left offset.
2990
        int lo = leftOffset(); // Constant part of left offset.
2874
        int fwidth = f->m_width; // The width we look for.
2991
        int fwidth = f->m_width; // The width we look for.
2875
        if (ro - lo < fwidth)
2992
        if (ro - lo < fwidth)
2876
            fwidth = ro - lo; // Never look for more than what will be available.
2993
            fwidth = ro - lo; // Never look for more than what will be available.
2877
        
2994
        
2878
        IntRect oldRect(o->x(), o->y() , o->width(), o->height());
2995
        IntRect oldRect(o->x(), o->y() , o->width(), o->height());
2879
        
2996
2880
        if (o->style()->clear() & CLEFT)
2997
        if (o->style()->clear() & CLEFT)
2881
            y = max(leftBottom(), y);
2998
            y = max(leftBottom(), y);
2882
        if (o->style()->clear() & CRIGHT)
2999
        if (o->style()->clear() & CRIGHT)
Lines 2905-2913 bool RenderBlock::positionNewFloats() WebCore/rendering/RenderBlock.cpp_sec28
2905
            o->setLocation(fx - o->marginRight() - o->width(), y + o->marginTop());
3022
            o->setLocation(fx - o->marginRight() - o->width(), y + o->marginTop());
2906
        }
3023
        }
2907
3024
2908
        f->m_top = y;
3025
        if (view()->layoutState()->paginated()) {
2909
        f->m_bottom = f->m_top + _height;
3026
            RenderBlock* childBlock = o->isRenderBlock() ? toRenderBlock(o) : 0;
2910
3027
3028
            if (childBlock && view()->layoutState()->m_pageHeight && view()->layoutState()->pageY(o->y()) != childBlock->pageY())
3029
                childBlock->setChildNeedsLayout(true, false);
3030
            o->layoutIfNeeded();
3031
3032
            // If we are unsplittable and don't fit, then we need to move down.
3033
            // We include our margins as part of the unsplittable area.
3034
            int newY = adjustForUnsplittableChild(o, y, true);
3035
            
3036
            // See if we have a pagination strut that is making us move down further.
3037
            // Note that an unsplittable child can't also have a pagination strut, so this is
3038
            // exclusive with the case above.
3039
            if (childBlock && childBlock->paginationStrut()) {
3040
                newY += childBlock->paginationStrut();
3041
                childBlock->setPaginationStrut(0);
3042
            }
3043
            
3044
            if (newY != y) {
3045
                f->m_paginationStrut = newY - y;
3046
                y = newY;
3047
                o->setY(y + o->marginTop());
3048
                if (childBlock)
3049
                    childBlock->setChildNeedsLayout(true, false);
3050
                o->layoutIfNeeded();
3051
            }
3052
        }
3053
3054
        f->m_top = y;
3055
        f->m_bottom = f->m_top + o->marginTop() + o->height() + o->marginBottom();
3056
        
2911
        // If the child moved, we have to repaint it.
3057
        // If the child moved, we have to repaint it.
2912
        if (o->checkForRepaintDuringLayout())
3058
        if (o->checkForRepaintDuringLayout())
2913
            o->repaintDuringLayoutIfMoved(oldRect);
3059
            o->repaintDuringLayoutIfMoved(oldRect);
Lines 2917-2922 bool RenderBlock::positionNewFloats() WebCore/rendering/RenderBlock.cpp_sec29
2917
    return true;
3063
    return true;
2918
}
3064
}
2919
3065
3066
bool RenderBlock::positionNewFloatOnLine(FloatingObject* newFloat, FloatingObject* lastFloatFromPreviousLine)
3067
{
3068
    bool didPosition = positionNewFloats();
3069
    if (!didPosition || !newFloat->m_paginationStrut)
3070
        return didPosition;
3071
    
3072
    int floatTop = newFloat->m_top;
3073
    int paginationStrut = newFloat->m_paginationStrut;
3074
    FloatingObject* f = m_floatingObjects->last();
3075
    
3076
    ASSERT(f == newFloat);
3077
3078
    if (floatTop - paginationStrut != height())
3079
        return didPosition;
3080
3081
    for (f = m_floatingObjects->prev(); f && f != lastFloatFromPreviousLine; f = m_floatingObjects->prev()) {
3082
        if (f->m_top == height()) {
3083
            ASSERT(!f->m_paginationStrut);
3084
            f->m_paginationStrut = paginationStrut;
3085
            RenderBox* o = f->m_renderer;
3086
            o->setY(o->y() + o->marginTop() + paginationStrut);
3087
            if (o->isRenderBlock())
3088
                toRenderBlock(o)->setChildNeedsLayout(true, false);
3089
            o->layoutIfNeeded();
3090
            f->m_top += f->m_paginationStrut;
3091
            f->m_bottom += f->m_paginationStrut;
3092
        }
3093
    }
3094
        
3095
    setHeight(height() + paginationStrut);
3096
    
3097
    return didPosition;
3098
}
3099
2920
void RenderBlock::newLine(EClear clear)
3100
void RenderBlock::newLine(EClear clear)
2921
{
3101
{
2922
    positionNewFloats();
3102
    positionNewFloats();
Lines 3158-3165 int RenderBlock::lowestPosition(bool inc WebCore/rendering/RenderBlock.cpp_sec30
3158
3338
3159
    if (hasColumns()) {
3339
    if (hasColumns()) {
3160
        ColumnInfo* colInfo = columnInfo();
3340
        ColumnInfo* colInfo = columnInfo();
3161
        for (unsigned i = 0; i < colInfo->columnCount(); i++)
3341
        for (unsigned i = 0; i < columnCount(colInfo); i++)
3162
            bottom = max(bottom, colInfo->columnRectAt(i).bottom() + relativeOffset);
3342
            bottom = max(bottom, columnRectAt(colInfo, i).bottom() + relativeOffset);
3163
        return bottom;
3343
        return bottom;
3164
    }
3344
    }
3165
3345
Lines 3253-3260 int RenderBlock::rightmostPosition(bool WebCore/rendering/RenderBlock.cpp_sec31
3253
        // This only matters for LTR
3433
        // This only matters for LTR
3254
        if (style()->direction() == LTR) {
3434
        if (style()->direction() == LTR) {
3255
            ColumnInfo* colInfo = columnInfo();
3435
            ColumnInfo* colInfo = columnInfo();
3256
            if (colInfo->columnCount())
3436
            unsigned count = columnCount(colInfo);
3257
                right = max(colInfo->columnRectAt(colInfo->columnCount() - 1).right() + relativeOffset, right);
3437
            if (count)
3438
                right = max(columnRectAt(colInfo, count - 1).right() + relativeOffset, right);
3258
        }
3439
        }
3259
        return right;
3440
        return right;
3260
    }
3441
    }
Lines 3353-3360 int RenderBlock::leftmostPosition(bool i WebCore/rendering/RenderBlock.cpp_sec32
3353
        // This only matters for RTL
3534
        // This only matters for RTL
3354
        if (style()->direction() == RTL) {
3535
        if (style()->direction() == RTL) {
3355
            ColumnInfo* colInfo = columnInfo();
3536
            ColumnInfo* colInfo = columnInfo();
3356
            if (colInfo->columnCount())
3537
            unsigned count = columnCount(colInfo);
3357
                left = min(colInfo->columnRectAt(colInfo->columnCount() - 1).x() + relativeOffset, left);
3538
            if (count)
3539
                left = min(columnRectAt(colInfo, count - 1).x() + relativeOffset, left);
3358
        }
3540
        }
3359
        return left;
3541
        return left;
3360
    }
3542
    }
Lines 3647-3652 bool RenderBlock::containsFloat(RenderOb WebCore/rendering/RenderBlock.cpp_sec33
3647
3829
3648
void RenderBlock::markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove, bool inLayout)
3830
void RenderBlock::markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove, bool inLayout)
3649
{
3831
{
3832
    if (!m_everHadLayout)
3833
        return;
3834
3650
    setChildNeedsLayout(true, !inLayout);
3835
    setChildNeedsLayout(true, !inLayout);
3651
3836
3652
    if (floatToRemove)
3837
    if (floatToRemove)
Lines 3664-3693 void RenderBlock::markAllDescendantsWith WebCore/rendering/RenderBlock.cpp_sec34
3664
    }
3849
    }
3665
}
3850
}
3666
3851
3667
int RenderBlock::visibleTopOfHighestFloatExtendingBelow(int bottom, int maxHeight) const
3852
void RenderBlock::markDescendantBlocksAndLinesForLayout(bool inLayout)
3668
{
3853
{
3669
    int top = bottom;
3854
    if (!m_everHadLayout)
3670
    if (m_floatingObjects) {
3855
        return;
3671
        FloatingObject* floatingObject;
3856
3672
        for (DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects); (floatingObject = it.current()); ++it) {
3857
    setChildNeedsLayout(true, !inLayout);
3673
            RenderBox* floatingBox = floatingObject->m_renderer;
3674
            IntRect visibleOverflow = floatingBox->visibleOverflowRect();
3675
            visibleOverflow.move(floatingBox->x(), floatingBox->y());
3676
            if (visibleOverflow.y() < top && visibleOverflow.bottom() > bottom && visibleOverflow.height() <= maxHeight && floatingBox->containingBlock() == this)
3677
                top = visibleOverflow.y();
3678
        }
3679
    }
3680
3858
3859
    // Iterate over our children and mark them as needed.
3681
    if (!childrenInline()) {
3860
    if (!childrenInline()) {
3682
        for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
3861
        for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
3683
            if (child->isFloatingOrPositioned() || !child->isRenderBlock())
3862
            if (child->isFloatingOrPositioned() || !child->isRenderBlock())
3684
                continue;
3863
                continue;
3685
            RenderBlock* childBlock = toRenderBlock(child);
3864
            toRenderBlock(child)->markDescendantBlocksAndLinesForLayout(inLayout);
3686
            top = min(top, childBlock->y() + childBlock->visibleTopOfHighestFloatExtendingBelow(bottom - childBlock->y(), maxHeight));
3865
        }
3866
    }
3867
    
3868
    // Walk our floating objects and mark them too.
3869
    if (m_floatingObjects) {
3870
        DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
3871
        while (it.current()) {
3872
            if (it.current()->m_renderer->isRenderBlock())
3873
                toRenderBlock(it.current()->m_renderer)->markDescendantBlocksAndLinesForLayout(inLayout);
3874
            ++it;
3875
        }
3876
    }
3877
3878
    if (m_positionedObjects) {
3879
        // FIXME: Technically we don't have to mark the positioned objects if we're the block
3880
        // that established the columns, but we don't really have that information here.
3881
        RenderBox* r;
3882
        Iterator end = m_positionedObjects->end();
3883
        for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
3884
            r = *it;
3885
            if (r->isRenderBlock())
3886
                toRenderBlock(r)->markDescendantBlocksAndLinesForLayout();
3687
        }
3887
        }
3688
    }
3888
    }
3689
3889
3690
    return top;
3890
    // FIXME: If we're a table, then we have to mark every single cell.
3691
}
3891
}
3692
3892
3693
int RenderBlock::getClearDelta(RenderBox* child, int yPos)
3893
int RenderBlock::getClearDelta(RenderBox* child, int yPos)
Lines 3847-3862 bool RenderBlock::hitTestColumns(const H WebCore/rendering/RenderBlock.cpp_sec35
3847
{
4047
{
3848
    // We need to do multiple passes, breaking up our hit testing into strips.
4048
    // We need to do multiple passes, breaking up our hit testing into strips.
3849
    ColumnInfo* colInfo = columnInfo();
4049
    ColumnInfo* colInfo = columnInfo();
3850
    int colCount = colInfo->columnCount();
4050
    int colCount = columnCount(colInfo);
3851
    if (!colCount)
4051
    if (!colCount)
3852
        return false;
4052
        return false;
3853
    int left = borderLeft() + paddingLeft();
4053
    int left = borderLeft() + paddingLeft();
3854
    int currYOffset = 0;
4054
    int currYOffset = 0;
3855
    int i;
4055
    int i;
3856
    for (i = 0; i < colCount; i++)
4056
    for (i = 0; i < colCount; i++)
3857
        currYOffset -= colInfo->columnRectAt(i).height();
4057
        currYOffset -= columnRectAt(colInfo, i).height();
3858
    for (i = colCount - 1; i >= 0; i--) {
4058
    for (i = colCount - 1; i >= 0; i--) {
3859
        IntRect colRect = colInfo->columnRectAt(i);
4059
        IntRect colRect = columnRectAt(colInfo, i);
3860
        int currXOffset = colRect.x() - left;
4060
        int currXOffset = colRect.x() - left;
3861
        currYOffset += colRect.height();
4061
        currYOffset += colRect.height();
3862
        colRect.move(tx, ty);
4062
        colRect.move(tx, ty);
Lines 4150-4157 void RenderBlock::setDesiredColumnCountA WebCore/rendering/RenderBlock.cpp_sec36
4150
    bool destroyColumns = !firstChild()
4350
    bool destroyColumns = !firstChild()
4151
                          || (count == 1 && style()->hasAutoColumnWidth())
4351
                          || (count == 1 && style()->hasAutoColumnWidth())
4152
                          || firstChild()->isAnonymousColumnsBlock()
4352
                          || firstChild()->isAnonymousColumnsBlock()
4153
                          || firstChild()->isAnonymousColumnSpanBlock()
4353
                          || firstChild()->isAnonymousColumnSpanBlock();
4154
                          || document()->settings()->paginateDuringLayoutEnabled();
4155
    if (destroyColumns) {
4354
    if (destroyColumns) {
4156
        if (hasColumns()) {
4355
        if (hasColumns()) {
4157
            delete gColumnInfoMap->take(this);
4356
            delete gColumnInfoMap->take(this);
Lines 4194-4326 ColumnInfo* RenderBlock::columnInfo() co WebCore/rendering/RenderBlock.cpp_sec37
4194
    return gColumnInfoMap->get(this);    
4393
    return gColumnInfoMap->get(this);    
4195
}
4394
}
4196
4395
4197
int RenderBlock::layoutColumns(int endOfContent, int requestedColumnHeight)
4396
unsigned RenderBlock::columnCount(ColumnInfo* colInfo) const
4198
{
4397
{
4199
    // Don't do anything if we have no columns
4398
    ASSERT(hasColumns() && gColumnInfoMap->get(this) == colInfo);
4200
    if (!hasColumns())
4399
    return colInfo->columnCount();
4201
        return -1;
4400
}
4202
4401
4203
    ColumnInfo* info = gColumnInfoMap->get(this);
4402
IntRect RenderBlock::columnRectAt(ColumnInfo* colInfo, unsigned index) const
4204
    int desiredColumnWidth = info->desiredColumnWidth();
4403
{
4205
    int desiredColumnCount = info->desiredColumnCount();
4404
    ASSERT(hasColumns() && gColumnInfoMap->get(this) == colInfo);
4206
    
4207
    bool computeIntrinsicHeight = (endOfContent == -1);
4208
4209
    // Fill the columns in to the available height.  Attempt to balance the height of the columns.
4210
    // Add in half our line-height to help with best-guess initial balancing.
4211
    int columnSlop = lineHeight(false) / 2;
4212
    int remainingSlopSpace = columnSlop * desiredColumnCount;
4213
    int availableHeight = contentHeight();
4214
    int colHeight;
4215
    if (computeIntrinsicHeight && requestedColumnHeight >= 0)
4216
        colHeight = requestedColumnHeight;
4217
    else if (computeIntrinsicHeight)
4218
        colHeight = min(availableHeight, availableHeight / desiredColumnCount + columnSlop);
4219
    else
4220
        colHeight = availableHeight;
4221
    int originalColHeight = colHeight;
4222
4405
4406
    // Compute the appropriate rect based off our information.
4407
    int colWidth = colInfo->desiredColumnWidth();
4408
    int colHeight = colInfo->columnHeight();
4409
    int colTop = borderTop() + paddingTop();
4223
    int colGap = columnGap();
4410
    int colGap = columnGap();
4411
    int colLeft = style()->direction() == LTR ? 
4412
                      borderLeft() + paddingLeft() + (index * (colWidth + colGap))
4413
                      : borderLeft() + paddingLeft() + contentWidth() - colWidth - (index * (colWidth + colGap));
4414
    return IntRect(colLeft, colTop, colWidth, colHeight);
4415
}
4224
4416
4225
    // Compute a collection of column rects.
4417
bool RenderBlock::layoutColumns(bool hasSpecifiedPageHeight, int pageHeight, LayoutStateMaintainer& statePusher)
4226
    info->clearColumns();
4418
{
4227
    
4419
    if (hasColumns()) {
4228
    // Then we do a simulated "paint" into the column slices and allow the content to slightly adjust our individual column rects.
4420
        ColumnInfo* colInfo = columnInfo();
4229
    // FIXME: We need to take into account layers that are affected by the columns as well here so that they can have an opportunity
4421
        int desiredColumnCount = colInfo->desiredColumnCount();
4230
    // to adjust column rects also.
4422
        if (!hasSpecifiedPageHeight && contentHeight() > pageHeight * desiredColumnCount) {
4231
    RenderView* v = view();
4423
            // Now that we know the intrinsic height of the columns, we have to rebalance them.
4232
    int left = borderLeft() + paddingLeft();
4424
            int columnHeight = max(colInfo->minimumColumnHeight(), (int)ceilf((float)contentHeight() / desiredColumnCount));
4233
    int top = borderTop() + paddingTop();
4425
            if (columnHeight > 0) {
4234
    int currX = style()->direction() == LTR ? borderLeft() + paddingLeft() : borderLeft() + paddingLeft() + contentWidth() - desiredColumnWidth;
4426
                statePusher.pop();
4235
    int currY = top;
4427
                m_everHadLayout = true;
4236
    unsigned colCount = desiredColumnCount;
4428
                layoutBlock(false, columnHeight);
4237
    int maxColBottom = borderTop() + paddingTop();
4429
                return true;
4238
    int contentBottom = top + availableHeight;
4430
            }
4239
    int minimumColumnHeight = -1;
4431
        } 
4240
    for (unsigned i = 0; i < colCount; i++) {
4241
        // If we aren't constrained, then the last column can just get all the remaining space.
4242
        if (computeIntrinsicHeight && i == colCount - 1)
4243
            colHeight = availableHeight;
4244
4245
        // This represents the real column position.
4246
        IntRect colRect(currX, top, desiredColumnWidth, colHeight);
4247
4248
        int truncationPoint = visibleTopOfHighestFloatExtendingBelow(currY + colHeight, colHeight);
4249
4250
        // For the simulated paint, we pretend like everything is in one long strip.
4251
        IntRect pageRect(left, currY, contentWidth(), truncationPoint - currY);
4252
        v->setPrintRect(pageRect);
4253
        v->setTruncatedAt(truncationPoint);
4254
        GraphicsContext context((PlatformGraphicsContext*)0);
4255
        PaintInfo paintInfo(&context, pageRect, PaintPhaseForeground, false, 0, 0);
4256
        
4257
        setHasColumns(false);
4258
        paintObject(paintInfo, 0, 0);
4259
        setHasColumns(true);
4260
4261
        if (computeIntrinsicHeight && v->minimumColumnHeight() > originalColHeight) {
4262
            // The initial column height was too small to contain one line of text.
4263
            minimumColumnHeight = max(minimumColumnHeight, v->minimumColumnHeight());
4264
        }
4265
4266
        int adjustedBottom = v->bestTruncatedAt();
4267
        if (adjustedBottom <= currY)
4268
            adjustedBottom = truncationPoint;
4269
        
4270
        colRect.setHeight(adjustedBottom - currY);
4271
        
4272
        // Add in the lost space to the subsequent columns.
4273
        // FIXME: This will create a "staircase" effect if there are enough columns, but the effect should be pretty subtle.
4274
        if (computeIntrinsicHeight) {
4275
            int lostSpace = colHeight - colRect.height();
4276
            if (lostSpace > remainingSlopSpace) {
4277
                // Redestribute the space among the remaining columns.
4278
                int spaceToRedistribute = lostSpace - remainingSlopSpace;
4279
                int remainingColumns = colCount - i + 1;
4280
                colHeight += spaceToRedistribute / remainingColumns;
4281
            } 
4282
            remainingSlopSpace = max(0, remainingSlopSpace - lostSpace);
4283
        }
4284
        
4432
        
4285
        if (style()->direction() == LTR)
4433
        if (pageHeight) // FIXME: Should we use lowestPosition (excluding our positioned objects) instead of contentHeight()?
4286
            currX += desiredColumnWidth + colGap;
4434
            colInfo->setColumnCountAndHeight(ceilf((float)contentHeight() / pageHeight), pageHeight);
4287
        else
4288
            currX -= (desiredColumnWidth + colGap);
4289
4290
        currY += colRect.height();
4291
        availableHeight -= colRect.height();
4292
4293
        maxColBottom = max(colRect.bottom(), maxColBottom);
4294
4435
4295
        info->addColumnRect(colRect);
4436
        if (columnCount(colInfo)) {
4296
        
4437
            IntRect lastRect = columnRectAt(colInfo, columnCount(colInfo) - 1);
4297
        // Start adding in more columns as long as there's still content left.
4438
            int overflowLeft = style()->direction() == RTL ? min(0, lastRect.x()) : 0;
4298
        if (currY < endOfContent && i == colCount - 1 && (computeIntrinsicHeight || contentHeight()))
4439
            int overflowRight = style()->direction() == LTR ? max(width(), lastRect.x() + lastRect.width()) : 0;
4299
            colCount++;
4440
            int overflowHeight = borderTop() + paddingTop() + colInfo->columnHeight();
4300
    }
4441
            
4442
            setHeight(overflowHeight + borderBottom() + paddingBottom() + horizontalScrollbarHeight());
4301
4443
4302
    if (minimumColumnHeight >= 0) {
4444
            m_overflow.clear();
4303
        // If originalColHeight was too small, we need to try to layout again.
4445
            addLayoutOverflow(IntRect(overflowLeft, 0, overflowRight - overflowLeft, overflowHeight));
4304
        return layoutColumns(endOfContent, minimumColumnHeight);
4446
        }
4305
    }
4447
    }
4306
4307
    int overflowRight = max(width(), currX - colGap);
4308
    int overflowLeft = min(0, currX + desiredColumnWidth + colGap);
4309
    int overflowHeight = maxColBottom;
4310
    int toAdd = borderBottom() + paddingBottom() + horizontalScrollbarHeight();
4311
        
4312
    if (computeIntrinsicHeight)
4313
        setHeight(maxColBottom + toAdd);
4314
4315
    m_overflow.clear();
4316
    addLayoutOverflow(IntRect(overflowLeft, 0, overflowRight - overflowLeft, overflowHeight));
4317
4318
    v->setPrintRect(IntRect());
4319
    v->setTruncatedAt(0);
4320
    
4321
    ASSERT(colCount == info->columnCount());
4322
    
4448
    
4323
    return contentBottom;
4449
    return false;
4324
}
4450
}
4325
4451
4326
void RenderBlock::adjustPointToColumnContents(IntPoint& point) const
4452
void RenderBlock::adjustPointToColumnContents(IntPoint& point) const
Lines 4330-4346 void RenderBlock::adjustPointToColumnCon WebCore/rendering/RenderBlock.cpp_sec38
4330
        return;
4456
        return;
4331
    
4457
    
4332
    ColumnInfo* colInfo = columnInfo();
4458
    ColumnInfo* colInfo = columnInfo();
4333
    if (!colInfo->columnCount())
4459
    if (!columnCount(colInfo))
4334
        return;
4460
        return;
4335
4461
4336
    // Determine which columns we intersect.
4462
    // Determine which columns we intersect.
4337
    int colGap = columnGap();
4463
    int colGap = columnGap();
4338
    int leftGap = colGap / 2;
4464
    int leftGap = colGap / 2;
4339
    IntPoint columnPoint(colInfo->columnRectAt(0).location());
4465
    IntPoint columnPoint(columnRectAt(colInfo, 0).location());
4340
    int yOffset = 0;
4466
    int yOffset = 0;
4341
    for (unsigned i = 0; i < colInfo->columnCount(); i++) {
4467
    for (unsigned i = 0; i < colInfo->columnCount(); i++) {
4342
        // Add in half the column gap to the left and right of the rect.
4468
        // Add in half the column gap to the left and right of the rect.
4343
        IntRect colRect = colInfo->columnRectAt(i);
4469
        IntRect colRect = columnRectAt(colInfo, i);
4344
        IntRect gapAndColumnRect(colRect.x() - leftGap, colRect.y(), colRect.width() + colGap, colRect.height());
4470
        IntRect gapAndColumnRect(colRect.x() - leftGap, colRect.y(), colRect.width() + colGap, colRect.height());
4345
4471
4346
        if (point.x() >= gapAndColumnRect.x() && point.x() < gapAndColumnRect.right()) {
4472
        if (point.x() >= gapAndColumnRect.x() && point.x() < gapAndColumnRect.right()) {
Lines 4378-4384 void RenderBlock::adjustRectForColumns(I WebCore/rendering/RenderBlock.cpp_sec39
4378
    IntRect result;
4504
    IntRect result;
4379
    
4505
    
4380
    // Determine which columns we intersect.
4506
    // Determine which columns we intersect.
4381
    unsigned colCount = colInfo->columnCount();
4507
    unsigned colCount = columnCount(colInfo);
4382
    if (!colCount)
4508
    if (!colCount)
4383
        return;
4509
        return;
4384
    
4510
    
Lines 4386-4392 void RenderBlock::adjustRectForColumns(I WebCore/rendering/RenderBlock.cpp_sec40
4386
    
4512
    
4387
    int currYOffset = 0;
4513
    int currYOffset = 0;
4388
    for (unsigned i = 0; i < colCount; i++) {
4514
    for (unsigned i = 0; i < colCount; i++) {
4389
        IntRect colRect = colInfo->columnRectAt(i);
4515
        IntRect colRect = columnRectAt(colInfo, i);
4390
        int currXOffset = colRect.x() - left;
4516
        int currXOffset = colRect.x() - left;
4391
        
4517
        
4392
        IntRect repaintRect = r;
4518
        IntRect repaintRect = r;
Lines 4412-4420 void RenderBlock::adjustForColumns(IntSi WebCore/rendering/RenderBlock.cpp_sec41
4412
4538
4413
    int left = borderLeft() + paddingLeft();
4539
    int left = borderLeft() + paddingLeft();
4414
    int yOffset = 0;
4540
    int yOffset = 0;
4415
    size_t columnCount = colInfo->columnCount();
4541
    size_t colCount = columnCount(colInfo);
4416
    for (size_t i = 0; i < columnCount; ++i) {
4542
    for (size_t i = 0; i < colCount; ++i) {
4417
        IntRect columnRect = colInfo->columnRectAt(i);
4543
        IntRect columnRect = columnRectAt(colInfo, i);
4418
        int xOffset = columnRect.x() - left;
4544
        int xOffset = columnRect.x() - left;
4419
        if (point.y() < columnRect.bottom() + yOffset) {
4545
        if (point.y() < columnRect.bottom() + yOffset) {
4420
            offset.expand(xOffset, -yOffset);
4546
            offset.expand(xOffset, -yOffset);
Lines 5392-5415 void RenderBlock::clearTruncation() WebCore/rendering/RenderBlock.cpp_sec42
5392
5518
5393
void RenderBlock::setMaxTopMargins(int pos, int neg)
5519
void RenderBlock::setMaxTopMargins(int pos, int neg)
5394
{
5520
{
5395
    if (!m_maxMargin) {
5521
    if (!m_rareData) {
5396
        if (pos == MaxMargin::topPosDefault(this) && neg == MaxMargin::topNegDefault(this))
5522
        if (pos == RenderBlockRareData::topPosDefault(this) && neg == RenderBlockRareData::topNegDefault(this))
5397
            return;
5523
            return;
5398
        m_maxMargin = new MaxMargin(this);
5524
        m_rareData = new RenderBlockRareData(this);
5399
    }
5525
    }
5400
    m_maxMargin->m_topPos = pos;
5526
    m_rareData->m_topPos = pos;
5401
    m_maxMargin->m_topNeg = neg;
5527
    m_rareData->m_topNeg = neg;
5402
}
5528
}
5403
5529
5404
void RenderBlock::setMaxBottomMargins(int pos, int neg)
5530
void RenderBlock::setMaxBottomMargins(int pos, int neg)
5405
{
5531
{
5406
    if (!m_maxMargin) {
5532
    if (!m_rareData) {
5407
        if (pos == MaxMargin::bottomPosDefault(this) && neg == MaxMargin::bottomNegDefault(this))
5533
        if (pos == RenderBlockRareData::bottomPosDefault(this) && neg == RenderBlockRareData::bottomNegDefault(this))
5408
            return;
5534
            return;
5409
        m_maxMargin = new MaxMargin(this);
5535
        m_rareData = new RenderBlockRareData(this);
5410
    }
5536
    }
5411
    m_maxMargin->m_bottomPos = pos;
5537
    m_rareData->m_bottomPos = pos;
5412
    m_maxMargin->m_bottomNeg = neg;
5538
    m_rareData->m_bottomNeg = neg;
5539
}
5540
5541
void RenderBlock::setPaginationStrut(int strut)
5542
{
5543
    if (!m_rareData) {
5544
        if (strut == 0)
5545
            return;
5546
        m_rareData = new RenderBlockRareData(this);
5547
    }
5548
    m_rareData->m_paginationStrut = strut;
5549
}
5550
5551
void RenderBlock::setPageY(int y)
5552
{
5553
    if (!m_rareData) {
5554
        if (y == 0)
5555
            return;
5556
        m_rareData = new RenderBlockRareData(this);
5557
    }
5558
    m_rareData->m_pageY = y;
5413
}
5559
}
5414
5560
5415
void RenderBlock::absoluteRects(Vector<IntRect>& rects, int tx, int ty)
5561
void RenderBlock::absoluteRects(Vector<IntRect>& rects, int tx, int ty)
Lines 5670-5675 RenderBlock* RenderBlock::createAnonymou WebCore/rendering/RenderBlock.cpp_sec43
5670
    return newBox;
5816
    return newBox;
5671
}
5817
}
5672
5818
5819
int RenderBlock::nextPageTop(int yPos) const
5820
{
5821
    LayoutState* layoutState = view()->layoutState();
5822
    if (!layoutState->m_pageHeight)
5823
        return yPos;
5824
    
5825
    // The yPos is in our coordinate space.  We can add in our pushed offset.
5826
    int pageHeight = layoutState->m_pageHeight;
5827
    int remainingHeight = pageHeight - ((layoutState->m_layoutOffset - layoutState->m_pageOffset).height() + yPos) % pageHeight;
5828
    return yPos + remainingHeight;
5829
}
5830
5831
int RenderBlock::applyBeforeBreak(RenderBox* child, int yPos)
5832
{
5833
    bool checkPageBreaks = document()->paginated() && document()->settings()->paginateDuringLayoutEnabled();
5834
    bool checkColumnBreaks = view()->layoutState()->paginatingColumns();
5835
    bool checkBeforeAlways = (checkPageBreaks && child->style()->pageBreakBefore() == PBALWAYS) || (checkColumnBreaks && child->style()->columnBreakBefore() == PBALWAYS);
5836
    if (checkBeforeAlways)
5837
        return nextPageTop(yPos);
5838
    return yPos;
5839
}
5840
5841
int RenderBlock::applyAfterBreak(RenderBox* child, int yPos, MarginInfo& marginInfo)
5842
{
5843
    bool checkPageBreaks = document()->paginated() && document()->settings()->paginateDuringLayoutEnabled();
5844
    bool checkColumnBreaks = view()->layoutState()->paginatingColumns();
5845
    bool checkAfterAlways = (checkPageBreaks && child->style()->pageBreakAfter() == PBALWAYS) || (checkColumnBreaks && child->style()->columnBreakAfter() == PBALWAYS);
5846
    if (checkAfterAlways) {
5847
        marginInfo.setBottomQuirk(true); // Cause margins to be discarded for any following content.
5848
        return nextPageTop(yPos);
5849
    }
5850
    return yPos;
5851
}
5852
5853
int RenderBlock::adjustForUnsplittableChild(RenderBox* child, int yPos, bool includeMargins)
5854
{
5855
    bool isUnsplittable = child->isReplaced() || child->scrollsOverflow();
5856
    if (!isUnsplittable)
5857
        return yPos;
5858
    int childHeight = child->height() + (includeMargins ? child->marginTop() + child->marginBottom() : 0);
5859
    LayoutState* layoutState = view()->layoutState();
5860
    if (layoutState->m_columnInfo)
5861
        layoutState->m_columnInfo->updateMinimumColumnHeight(childHeight);
5862
    int pageHeight = layoutState->m_pageHeight;
5863
    if (!pageHeight || childHeight > pageHeight)
5864
        return yPos;
5865
    int remainingHeight = pageHeight - ((layoutState->m_layoutOffset - layoutState->m_pageOffset).height() + yPos) % pageHeight;
5866
    if (remainingHeight < childHeight)
5867
        return yPos + remainingHeight;
5868
    return yPos;
5869
}
5870
5871
void RenderBlock::adjustLinePositionForPagination(RootInlineBox* lineBox, int& delta)
5872
{
5873
    // FIXME: For now we paginate using line overflow.  This ensures that lines don't overlap at all when we
5874
    // put a strut between them for pagination purposes.  However, this really isn't the desired rendering, since
5875
    // the line on the top of the next page will appear too far down relative to the same kind of line at the top
5876
    // of the first column.
5877
    //
5878
    // The rendering we would like to see is one where the lineTop is at the top of the column, and any line overflow
5879
    // simply spills out above the top of the column.  This effect would match what happens at the top of the first column.
5880
    // We can't achieve this rendering, however, until we stop columns from clipping to the column bounds (thus allowing
5881
    // for overflow to occur), and then cache visible overflow for each column rect.
5882
    //
5883
    // Furthermore, the paint we have to do when a column has overflow has to be special.  We need to exclude
5884
    // content that paints in a previous column (and content that paints in the following column).
5885
    //
5886
    // FIXME: Another problem with simply moving lines is that the available line width may change (because of floats).
5887
    // Technically if the location we move the line to has a different line width than our old position, then we need to dirty the
5888
    // line and all following lines.
5889
    LayoutState* layoutState = view()->layoutState();
5890
    int pageHeight = layoutState->m_pageHeight;
5891
    int yPos = lineBox->topVisibleOverflow();
5892
    int lineHeight = lineBox->bottomVisibleOverflow() - yPos;
5893
    if (layoutState->m_columnInfo)
5894
        layoutState->m_columnInfo->updateMinimumColumnHeight(lineHeight);
5895
    yPos += delta;
5896
    lineBox->setPaginationStrut(0);
5897
    if (!pageHeight || lineHeight > pageHeight)
5898
        return;
5899
    int remainingHeight = pageHeight - ((layoutState->m_layoutOffset - layoutState->m_pageOffset).height() + yPos) % pageHeight;
5900
    if (remainingHeight < lineHeight) {
5901
        int totalHeight = lineHeight + max(0, yPos);
5902
        if (lineBox == firstRootBox() && totalHeight < pageHeight && !isPositioned() && !isTableCell())
5903
            setPaginationStrut(remainingHeight + max(0, yPos));
5904
        else {
5905
            delta += remainingHeight;
5906
            lineBox->setPaginationStrut(remainingHeight);
5907
        }
5908
    }  
5909
}
5910
 
5673
const char* RenderBlock::renderName() const
5911
const char* RenderBlock::renderName() const
5674
{
5912
{
5675
    if (isBody())
5913
    if (isBody())
- WebCore/rendering/RenderBlock.h -53 / +83 lines
Lines 34-39 namespace WebCore { WebCore/rendering/RenderBlock.h_sec1
34
34
35
class ColumnInfo;
35
class ColumnInfo;
36
class InlineIterator;
36
class InlineIterator;
37
class LayoutStateMaintainer;
37
class RenderInline;
38
class RenderInline;
38
39
39
struct BidiRun;
40
struct BidiRun;
Lines 70-76 public: WebCore/rendering/RenderBlock.h_sec2
70
    virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0);
71
    virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0);
71
    virtual void removeChild(RenderObject*);
72
    virtual void removeChild(RenderObject*);
72
73
73
    virtual void layoutBlock(bool relayoutChildren);
74
    virtual void layoutBlock(bool relayoutChildren, int pageHeight = 0);
74
75
75
    void insertPositionedObject(RenderBox*);
76
    void insertPositionedObject(RenderBox*);
76
    void removePositionedObject(RenderBox*);
77
    void removePositionedObject(RenderBox*);
Lines 89-94 public: WebCore/rendering/RenderBlock.h_sec3
89
90
90
    void markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove = 0, bool inLayout = true);
91
    void markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove = 0, bool inLayout = true);
91
    void markPositionedObjectsForLayout();
92
    void markPositionedObjectsForLayout();
93
    void markDescendantBlocksAndLinesForLayout(bool inLayout = true);
92
94
93
    bool containsFloats() { return m_floatingObjects && !m_floatingObjects->isEmpty(); }
95
    bool containsFloats() { return m_floatingObjects && !m_floatingObjects->isEmpty(); }
94
    bool containsFloat(RenderObject*);
96
    bool containsFloat(RenderObject*);
Lines 151-156 public: WebCore/rendering/RenderBlock.h_sec4
151
153
152
    ColumnInfo* columnInfo() const;
154
    ColumnInfo* columnInfo() const;
153
    int columnGap() const;
155
    int columnGap() const;
156
    
157
    // These two functions take the ColumnInfo* to avoid repeated lookups of the info in the global HashMap.
158
    unsigned columnCount(ColumnInfo*) const;
159
    IntRect columnRectAt(ColumnInfo*, unsigned) const;
154
160
155
protected:
161
protected:
156
    // These functions are only used internally to manipulate the render tree structure via remove/insert/appendChildNode.
162
    // These functions are only used internally to manipulate the render tree structure via remove/insert/appendChildNode.
Lines 177-196 protected: WebCore/rendering/RenderBlock.h_sec5
177
    }
183
    }
178
    void moveChildrenTo(RenderBlock* to, RenderObject* startChild, RenderObject* endChild, RenderObject* beforeChild, bool fullRemoveInsert = false);
184
    void moveChildrenTo(RenderBlock* to, RenderObject* startChild, RenderObject* endChild, RenderObject* beforeChild, bool fullRemoveInsert = false);
179
    
185
    
180
    int maxTopPosMargin() const { return m_maxMargin ? m_maxMargin->m_topPos : MaxMargin::topPosDefault(this); }
186
    int maxTopPosMargin() const { return m_rareData ? m_rareData->m_topPos : RenderBlockRareData::topPosDefault(this); }
181
    int maxTopNegMargin() const { return m_maxMargin ? m_maxMargin->m_topNeg : MaxMargin::topNegDefault(this); }
187
    int maxTopNegMargin() const { return m_rareData ? m_rareData->m_topNeg : RenderBlockRareData::topNegDefault(this); }
182
    int maxBottomPosMargin() const { return m_maxMargin ? m_maxMargin->m_bottomPos : MaxMargin::bottomPosDefault(this); }
188
    int maxBottomPosMargin() const { return m_rareData ? m_rareData->m_bottomPos : RenderBlockRareData::bottomPosDefault(this); }
183
    int maxBottomNegMargin() const { return m_maxMargin ? m_maxMargin->m_bottomNeg : MaxMargin::bottomNegDefault(this); }
189
    int maxBottomNegMargin() const { return m_rareData ? m_rareData->m_bottomNeg : RenderBlockRareData::bottomNegDefault(this); }
190
    int paginationStrut() const { return m_rareData ? m_rareData->m_paginationStrut : 0; }
191
    int pageY() const { return m_rareData ? m_rareData->m_pageY : 0; }
184
    void setMaxTopMargins(int pos, int neg);
192
    void setMaxTopMargins(int pos, int neg);
185
    void setMaxBottomMargins(int pos, int neg);
193
    void setMaxBottomMargins(int pos, int neg);
186
    
194
    void setPaginationStrut(int strut);
195
    void setPageY(int y);
196
187
    void initMaxMarginValues()
197
    void initMaxMarginValues()
188
    {
198
    {
189
        if (m_maxMargin) {
199
        if (m_rareData) {
190
            m_maxMargin->m_topPos = MaxMargin::topPosDefault(this);
200
            m_rareData->m_topPos = RenderBlockRareData::topPosDefault(this);
191
            m_maxMargin->m_topNeg = MaxMargin::topNegDefault(this);
201
            m_rareData->m_topNeg = RenderBlockRareData::topNegDefault(this);
192
            m_maxMargin->m_bottomPos = MaxMargin::bottomPosDefault(this);
202
            m_rareData->m_bottomPos = RenderBlockRareData::bottomPosDefault(this);
193
            m_maxMargin->m_bottomNeg = MaxMargin::bottomNegDefault(this);
203
            m_rareData->m_bottomNeg = RenderBlockRareData::bottomNegDefault(this);
204
            m_rareData->m_paginationStrut = 0;
194
        }
205
        }
195
    }
206
    }
196
207
Lines 295-303 private: WebCore/rendering/RenderBlock.h_sec6
295
        bool everHadLayout;
306
        bool everHadLayout;
296
    };
307
    };
297
308
309
    struct FloatingObject : Noncopyable {
310
        enum Type {
311
            FloatLeft,
312
            FloatRight
313
        };
314
315
        FloatingObject(Type type)
316
            : m_renderer(0)
317
            , m_top(0)
318
            , m_bottom(0)
319
            , m_left(0)
320
            , m_width(0)
321
            , m_paginationStrut(0)
322
            , m_type(type)
323
            , m_shouldPaint(true)
324
            , m_isDescendant(false)
325
        {
326
        }
327
328
        Type type() { return static_cast<Type>(m_type); }
329
330
        RenderBox* m_renderer;
331
        int m_top;
332
        int m_bottom;
333
        int m_left;
334
        int m_width;
335
        int m_paginationStrut;
336
        unsigned m_type : 1; // Type (left or right aligned)
337
        bool m_shouldPaint : 1;
338
        bool m_isDescendant : 1;
339
    };
340
298
    // The following functions' implementations are in RenderBlockLineLayout.cpp.
341
    // The following functions' implementations are in RenderBlockLineLayout.cpp.
299
    RootInlineBox* determineStartPosition(bool& firstLine, bool& fullLayout, bool& previousLineBrokeCleanly,
342
    RootInlineBox* determineStartPosition(bool& firstLine, bool& fullLayout, bool& previousLineBrokeCleanly,
300
                                          InlineBidiResolver&, Vector<FloatWithRect>& floats, unsigned& numCleanFloats);
343
                                          InlineBidiResolver&, Vector<FloatWithRect>& floats, unsigned& numCleanFloats,
344
                                          bool& useRepaintBounds, int& repaintTop, int& repaintBottom);
301
    RootInlineBox* determineEndPosition(RootInlineBox* startBox, InlineIterator& cleanLineStart,
345
    RootInlineBox* determineEndPosition(RootInlineBox* startBox, InlineIterator& cleanLineStart,
302
                                        BidiStatus& cleanLineBidiStatus,
346
                                        BidiStatus& cleanLineBidiStatus,
303
                                        int& yPos);
347
                                        int& yPos);
Lines 305-313 private: WebCore/rendering/RenderBlock.h_sec7
305
                        RootInlineBox*& endLine, int& endYPos, int& repaintBottom, int& repaintTop);
349
                        RootInlineBox*& endLine, int& endYPos, int& repaintBottom, int& repaintTop);
306
350
307
    void skipTrailingWhitespace(InlineIterator&, bool isLineEmpty, bool previousLineBrokeCleanly);
351
    void skipTrailingWhitespace(InlineIterator&, bool isLineEmpty, bool previousLineBrokeCleanly);
308
    int skipLeadingWhitespace(InlineBidiResolver&, bool firstLine, bool isLineEmpty, bool previousLineBrokeCleanly);
352
    int skipLeadingWhitespace(InlineBidiResolver&, bool firstLine, bool isLineEmpty, bool previousLineBrokeCleanly, FloatingObject* lastFloatFromPreviousLine);
309
    void fitBelowFloats(int widthToFit, bool firstLine, int& availableWidth);
353
    void fitBelowFloats(int widthToFit, bool firstLine, int& availableWidth);
310
    InlineIterator findNextLineBreak(InlineBidiResolver&, bool firstLine, bool& isLineEmpty, bool& previousLineBrokeCleanly, bool& hyphenated, EClear* = 0);
354
    InlineIterator findNextLineBreak(InlineBidiResolver&, bool firstLine, bool& isLineEmpty, bool& previousLineBrokeCleanly, bool& hyphenated, EClear*, FloatingObject* lastFloatFromPreviousLine);
311
    RootInlineBox* constructLine(unsigned runCount, BidiRun* firstRun, BidiRun* lastRun, bool firstLine, bool lastLine, RenderObject* endObject);
355
    RootInlineBox* constructLine(unsigned runCount, BidiRun* firstRun, BidiRun* lastRun, bool firstLine, bool lastLine, RenderObject* endObject);
312
    InlineFlowBox* createLineBoxes(RenderObject*, bool firstLine);
356
    InlineFlowBox* createLineBoxes(RenderObject*, bool firstLine);
313
    void computeHorizontalPositionsForLine(RootInlineBox*, bool firstLine, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, GlyphOverflowAndFallbackFontsMap&);
357
    void computeHorizontalPositionsForLine(RootInlineBox*, bool firstLine, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, GlyphOverflowAndFallbackFontsMap&);
Lines 329-340 private: WebCore/rendering/RenderBlock.h_sec8
329
    void paintSelection(PaintInfo&, int tx, int ty);
373
    void paintSelection(PaintInfo&, int tx, int ty);
330
    void paintCaret(PaintInfo&, int tx, int ty, CaretType);
374
    void paintCaret(PaintInfo&, int tx, int ty, CaretType);
331
375
332
    void insertFloatingObject(RenderBox*);
376
    FloatingObject* insertFloatingObject(RenderBox*);
333
    void removeFloatingObject(RenderBox*);
377
    void removeFloatingObject(RenderBox*);
334
378
    void removeFloatingObjects(FloatingObject*, int y);
379
    
335
    // Called from lineWidth, to position the floats added in the last line.
380
    // Called from lineWidth, to position the floats added in the last line.
336
    // Returns ture if and only if it has positioned any floats.
381
    // Returns true if and only if it has positioned any floats.
337
    bool positionNewFloats();
382
    bool positionNewFloats();
383
    
384
    // Positions new floats and also adjust all floats encountered on the line if any of them
385
    // have to move to the next page/column.
386
    bool positionNewFloatOnLine(FloatingObject* newFloat, FloatingObject* lastFloatFromPreviousLine);
387
338
    void clearFloats();
388
    void clearFloats();
339
    int getClearDelta(RenderBox* child, int yPos);
389
    int getClearDelta(RenderBox* child, int yPos);
340
390
Lines 416-423 private: WebCore/rendering/RenderBlock.h_sec9
416
    void offsetForContents(int& tx, int& ty) const;
466
    void offsetForContents(int& tx, int& ty) const;
417
467
418
    void calcColumnWidth();
468
    void calcColumnWidth();
419
    int layoutColumns(int endOfContent = -1, int requestedColumnHeight = -1);
469
    bool layoutColumns(bool hasSpecifiedPageHeight, int pageHeight, LayoutStateMaintainer&);
420
    int visibleTopOfHighestFloatExtendingBelow(int bottom, int maxHeight) const;
421
    void makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, RenderBlock* newBlockBox, RenderObject* newChild);
470
    void makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, RenderBlock* newBlockBox, RenderObject* newChild);
422
471
423
    bool expandsToEncloseOverhangingFloats() const;
472
    bool expandsToEncloseOverhangingFloats() const;
Lines 433-468 private: WebCore/rendering/RenderBlock.h_sec10
433
    RenderBlock* continuationBefore(RenderObject* beforeChild);
482
    RenderBlock* continuationBefore(RenderObject* beforeChild);
434
    RenderBlock* containingColumnsBlock(bool allowAnonymousColumnBlock = true);
483
    RenderBlock* containingColumnsBlock(bool allowAnonymousColumnBlock = true);
435
    RenderBlock* columnsBlockForSpanningElement(RenderObject* newChild);
484
    RenderBlock* columnsBlockForSpanningElement(RenderObject* newChild);
436
    
437
    struct FloatingObject : Noncopyable {
438
        enum Type {
439
            FloatLeft,
440
            FloatRight
441
        };
442
443
        FloatingObject(Type type)
444
            : m_renderer(0)
445
            , m_top(0)
446
            , m_bottom(0)
447
            , m_left(0)
448
            , m_width(0)
449
            , m_type(type)
450
            , m_shouldPaint(true)
451
            , m_isDescendant(false)
452
        {
453
        }
454
455
        Type type() { return static_cast<Type>(m_type); }
456
457
        RenderBox* m_renderer;
458
        int m_top;
459
        int m_bottom;
460
        int m_left;
461
        int m_width;
462
        unsigned m_type : 1; // Type (left or right aligned)
463
        bool m_shouldPaint : 1;
464
        bool m_isDescendant : 1;
465
    };
466
485
467
    class MarginInfo {
486
    class MarginInfo {
468
        // Collapsing flags for whether we can collapse our margins with our children's margins.
487
        // Collapsing flags for whether we can collapse our margins with our children's margins.
Lines 539-544 private: WebCore/rendering/RenderBlock.h_sec11
539
    void setCollapsedBottomMargin(const MarginInfo&);
558
    void setCollapsedBottomMargin(const MarginInfo&);
540
    // End helper functions and structs used by layoutBlockChildren.
559
    // End helper functions and structs used by layoutBlockChildren.
541
560
561
    // Pagination routines.
562
    int nextPageTop(int yPos) const; // Returns the top of the next page following yPos.
563
    int applyBeforeBreak(RenderBox* child, int yPos); // If the child has a before break, then return a new yPos that shifts to the top of the next page/column.
564
    int applyAfterBreak(RenderBox* child, int yPos, MarginInfo& marginInfo); // If the child has an after break, then return a new yPos that shifts to the top of the next page/column.
565
    int adjustForUnsplittableChild(RenderBox* child, int yPos, bool includeMargins = false); // If the child is unsplittable and can't fit on the current page, return the top of the next page/column.
566
    void adjustLinePositionForPagination(RootInlineBox*, int& deltaY); // Computes a deltaY value that put a line at the top of the next page if it doesn't fit on the current page.
567
542
    typedef PositionedObjectsListHashSet::const_iterator Iterator;
568
    typedef PositionedObjectsListHashSet::const_iterator Iterator;
543
    DeprecatedPtrList<FloatingObject>* m_floatingObjects;
569
    DeprecatedPtrList<FloatingObject>* m_floatingObjects;
544
    
570
    
Lines 551-562 private: WebCore/rendering/RenderBlock.h_sec12
551
    RenderBoxModelObject* m_continuation;
577
    RenderBoxModelObject* m_continuation;
552
578
553
    // Allocated only when some of these fields have non-default values
579
    // Allocated only when some of these fields have non-default values
554
    struct MaxMargin : Noncopyable {
580
    struct RenderBlockRareData : Noncopyable {
555
        MaxMargin(const RenderBlock* o) 
581
        RenderBlockRareData(const RenderBlock* o) 
556
            : m_topPos(topPosDefault(o))
582
            : m_topPos(topPosDefault(o))
557
            , m_topNeg(topNegDefault(o))
583
            , m_topNeg(topNegDefault(o))
558
            , m_bottomPos(bottomPosDefault(o))
584
            , m_bottomPos(bottomPosDefault(o))
559
            , m_bottomNeg(bottomNegDefault(o))
585
            , m_bottomNeg(bottomNegDefault(o))
586
            , m_paginationStrut(0)
587
            , m_pageY(0)
560
        { 
588
        { 
561
        }
589
        }
562
590
Lines 564-577 private: WebCore/rendering/RenderBlock.h_sec13
564
        static int topNegDefault(const RenderBlock* o) { return o->marginTop() < 0 ? -o->marginTop() : 0; }
592
        static int topNegDefault(const RenderBlock* o) { return o->marginTop() < 0 ? -o->marginTop() : 0; }
565
        static int bottomPosDefault(const RenderBlock* o) { return o->marginBottom() > 0 ? o->marginBottom() : 0; }
593
        static int bottomPosDefault(const RenderBlock* o) { return o->marginBottom() > 0 ? o->marginBottom() : 0; }
566
        static int bottomNegDefault(const RenderBlock* o) { return o->marginBottom() < 0 ? -o->marginBottom() : 0; }
594
        static int bottomNegDefault(const RenderBlock* o) { return o->marginBottom() < 0 ? -o->marginBottom() : 0; }
567
595
        
568
        int m_topPos;
596
        int m_topPos;
569
        int m_topNeg;
597
        int m_topNeg;
570
        int m_bottomPos;
598
        int m_bottomPos;
571
        int m_bottomNeg;
599
        int m_bottomNeg;
600
        int m_paginationStrut;
601
        int m_pageY;
572
     };
602
     };
573
603
574
    MaxMargin* m_maxMargin;
604
    RenderBlockRareData* m_rareData;
575
605
576
    RenderObjectChildList m_children;
606
    RenderObjectChildList m_children;
577
    RenderLineBoxList m_lineBoxes;   // All of the root line boxes created for this block flow.  For example, <div>Hello<br>world.</div> will have two total lines for the <div>.
607
    RenderLineBoxList m_lineBoxes;   // All of the root line boxes created for this block flow.  For example, <div>Hello<br>world.</div> will have two total lines for the <div>.
- WebCore/rendering/RenderBlockLineLayout.cpp -20 / +79 lines
Lines 33-38 WebCore/rendering/RenderBlockLineLayout.cpp_sec1
33
#include "RenderLayer.h"
33
#include "RenderLayer.h"
34
#include "RenderListMarker.h"
34
#include "RenderListMarker.h"
35
#include "RenderView.h"
35
#include "RenderView.h"
36
#include "Settings.h"
36
#include "TrailingFloatsRootInlineBox.h"
37
#include "TrailingFloatsRootInlineBox.h"
37
#include "break_lines.h"
38
#include "break_lines.h"
38
#include <wtf/AlwaysInline.h>
39
#include <wtf/AlwaysInline.h>
Lines 570-581 void RenderBlock::layoutInlineChildren(b WebCore/rendering/RenderBlockLineLayout.cpp_sec2
570
            
571
            
571
                if (o->isPositioned())
572
                if (o->isPositioned())
572
                    o->containingBlock()->insertPositionedObject(box);
573
                    o->containingBlock()->insertPositionedObject(box);
573
                else {
574
                else if (o->isFloating())
574
                    if (o->isFloating())
575
                    floats.append(FloatWithRect(box));
575
                        floats.append(FloatWithRect(box));
576
                else if (fullLayout || o->needsLayout()) {
576
                    else if (fullLayout || o->needsLayout()) // Replaced elements
577
                    // Replaced elements
577
                        toRenderBox(o)->dirtyLineBoxes(fullLayout);
578
                    toRenderBox(o)->dirtyLineBoxes(fullLayout);
578
579
                    o->layoutIfNeeded();
579
                    o->layoutIfNeeded();
580
                }
580
                }
581
            } else if (o->isText() || (o->isRenderInline() && !endOfInline)) {
581
            } else if (o->isText() || (o->isRenderInline() && !endOfInline)) {
Lines 594-600 void RenderBlock::layoutInlineChildren(b WebCore/rendering/RenderBlockLineLayout.cpp_sec3
594
        unsigned floatIndex;
594
        unsigned floatIndex;
595
        bool firstLine = true;
595
        bool firstLine = true;
596
        bool previousLineBrokeCleanly = true;
596
        bool previousLineBrokeCleanly = true;
597
        RootInlineBox* startLine = determineStartPosition(firstLine, fullLayout, previousLineBrokeCleanly, resolver, floats, floatIndex);
597
        RootInlineBox* startLine = determineStartPosition(firstLine, fullLayout, previousLineBrokeCleanly, resolver, floats, floatIndex,
598
                                                          useRepaintBounds, repaintTop, repaintBottom);
598
599
599
        if (fullLayout && hasInlineChild && !selfNeedsLayout()) {
600
        if (fullLayout && hasInlineChild && !selfNeedsLayout()) {
600
            setNeedsLayout(true, false);  // Mark ourselves as needing a full layout. This way we'll repaint like
601
            setNeedsLayout(true, false);  // Mark ourselves as needing a full layout. This way we'll repaint like
Lines 622-630 void RenderBlock::layoutInlineChildren(b WebCore/rendering/RenderBlockLineLayout.cpp_sec4
622
                                 0 : determineEndPosition(startLine, cleanLineStart, cleanLineBidiStatus, endLineYPos);
623
                                 0 : determineEndPosition(startLine, cleanLineStart, cleanLineBidiStatus, endLineYPos);
623
624
624
        if (startLine) {
625
        if (startLine) {
625
            useRepaintBounds = true;
626
            if (!useRepaintBounds) {
626
            repaintTop = height();
627
                useRepaintBounds = true;
627
            repaintBottom = height();
628
                repaintTop = height();
629
                repaintBottom = height();
630
            }
628
            RenderArena* arena = renderArena();
631
            RenderArena* arena = renderArena();
629
            RootInlineBox* box = startLine;
632
            RootInlineBox* box = startLine;
630
            while (box) {
633
            while (box) {
Lines 659-664 void RenderBlock::layoutInlineChildren(b WebCore/rendering/RenderBlockLineLayout.cpp_sec5
659
        bool checkForFloatsFromLastLine = false;
662
        bool checkForFloatsFromLastLine = false;
660
663
661
        bool isLineEmpty = true;
664
        bool isLineEmpty = true;
665
        bool paginated = view()->layoutState()->paginated();
662
666
663
        while (!end.atEnd()) {
667
        while (!end.atEnd()) {
664
            // FIXME: Is this check necessary before the first iteration or can it be moved to the end?
668
            // FIXME: Is this check necessary before the first iteration or can it be moved to the end?
Lines 671-677 void RenderBlock::layoutInlineChildren(b WebCore/rendering/RenderBlockLineLayout.cpp_sec6
671
            
675
            
672
            EClear clear = CNONE;
676
            EClear clear = CNONE;
673
            bool hyphenated;
677
            bool hyphenated;
674
            end = findNextLineBreak(resolver, firstLine, isLineEmpty, previousLineBrokeCleanly, hyphenated, &clear);
678
            
679
            InlineIterator oldEnd = end;
680
            FloatingObject* lastFloatFromPreviousLine = m_floatingObjects ? m_floatingObjects->last() : 0;
681
            end = findNextLineBreak(resolver, firstLine, isLineEmpty, previousLineBrokeCleanly, hyphenated, &clear, lastFloatFromPreviousLine);
675
            if (resolver.position().atEnd()) {
682
            if (resolver.position().atEnd()) {
676
                resolver.deleteRuns();
683
                resolver.deleteRuns();
677
                checkForFloatsFromLastLine = true;
684
                checkForFloatsFromLastLine = true;
Lines 736-741 void RenderBlock::layoutInlineChildren(b WebCore/rendering/RenderBlockLineLayout.cpp_sec7
736
                // inline flow boxes.
743
                // inline flow boxes.
737
744
738
                RootInlineBox* lineBox = 0;
745
                RootInlineBox* lineBox = 0;
746
                int oldHeight = height();
739
                if (resolver.runCount()) {
747
                if (resolver.runCount()) {
740
                    if (hyphenated)
748
                    if (hyphenated)
741
                        resolver.logicallyLastRun()->m_hasHyphen = true;
749
                        resolver.logicallyLastRun()->m_hasHyphen = true;
Lines 786-791 void RenderBlock::layoutInlineChildren(b WebCore/rendering/RenderBlockLineLayout.cpp_sec8
786
                        repaintTop = min(repaintTop, lineBox->topVisibleOverflow());
794
                        repaintTop = min(repaintTop, lineBox->topVisibleOverflow());
787
                        repaintBottom = max(repaintBottom, lineBox->bottomVisibleOverflow());
795
                        repaintBottom = max(repaintBottom, lineBox->bottomVisibleOverflow());
788
                    }
796
                    }
797
                    
798
                    if (paginated) {
799
                        int adjustment = 0;
800
                        adjustLinePositionForPagination(lineBox, adjustment);
801
                        if (adjustment) {
802
                            int oldLineWidth = lineWidth(oldHeight, firstLine);
803
                            lineBox->adjustPosition(0, adjustment);
804
                            if (useRepaintBounds) // This can only be a positive adjustment, so no need to update repaintTop.
805
                                repaintBottom = max(repaintBottom, lineBox->bottomVisibleOverflow());
806
                                
807
                            if (lineWidth(oldHeight + adjustment, firstLine) != oldLineWidth) {
808
                                // We have to delete this line, remove all floats that got added, and let line layout re-run.
809
                                lineBox->deleteLine(renderArena());
810
                                removeFloatingObjects(lastFloatFromPreviousLine, oldHeight);
811
                                setHeight(oldHeight + adjustment);
812
                                resolver.setPosition(oldEnd);
813
                                end = oldEnd;
814
                                continue;
815
                            }
816
817
                            setHeight(lineBox->blockHeight());
818
                        }
819
                    }
789
                }
820
                }
790
821
791
                firstLine = false;
822
                firstLine = false;
Lines 820-825 void RenderBlock::layoutInlineChildren(b WebCore/rendering/RenderBlockLineLayout.cpp_sec9
820
                int delta = height() - endLineYPos;
851
                int delta = height() - endLineYPos;
821
                for (RootInlineBox* line = endLine; line; line = line->nextRootBox()) {
852
                for (RootInlineBox* line = endLine; line; line = line->nextRootBox()) {
822
                    line->attachLine();
853
                    line->attachLine();
854
                    if (paginated) {
855
                        delta -= line->paginationStrut();
856
                        adjustLinePositionForPagination(line, delta);
857
                    }
823
                    if (delta) {
858
                    if (delta) {
824
                        repaintTop = min(repaintTop, line->topVisibleOverflow() + min(delta, 0));
859
                        repaintTop = min(repaintTop, line->topVisibleOverflow() + min(delta, 0));
825
                        repaintBottom = max(repaintBottom, line->bottomVisibleOverflow() + max(delta, 0));
860
                        repaintBottom = max(repaintBottom, line->bottomVisibleOverflow() + max(delta, 0));
Lines 900-919 void RenderBlock::layoutInlineChildren(b WebCore/rendering/RenderBlockLineLayout.cpp_sec10
900
}
935
}
901
936
902
RootInlineBox* RenderBlock::determineStartPosition(bool& firstLine, bool& fullLayout, bool& previousLineBrokeCleanly, 
937
RootInlineBox* RenderBlock::determineStartPosition(bool& firstLine, bool& fullLayout, bool& previousLineBrokeCleanly, 
903
                                                   InlineBidiResolver& resolver, Vector<FloatWithRect>& floats, unsigned& numCleanFloats)
938
                                                   InlineBidiResolver& resolver, Vector<FloatWithRect>& floats, unsigned& numCleanFloats,
939
                                                   bool& useRepaintBounds, int& repaintTop, int& repaintBottom)
904
{
940
{
905
    RootInlineBox* curr = 0;
941
    RootInlineBox* curr = 0;
906
    RootInlineBox* last = 0;
942
    RootInlineBox* last = 0;
907
943
908
    bool dirtiedByFloat = false;
944
    bool dirtiedByFloat = false;
909
    if (!fullLayout) {
945
    if (!fullLayout) {
946
        // Paginate all of the clean lines.
947
        bool paginated = view()->layoutState()->paginated();
948
        int paginationDelta = 0;
910
        size_t floatIndex = 0;
949
        size_t floatIndex = 0;
911
        for (curr = firstRootBox(); curr && !curr->isDirty(); curr = curr->nextRootBox()) {
950
        for (curr = firstRootBox(); curr && !curr->isDirty(); curr = curr->nextRootBox()) {
951
            if (paginated) {
952
                paginationDelta -= curr->paginationStrut();
953
                adjustLinePositionForPagination(curr, paginationDelta);
954
                if (paginationDelta) {
955
                    if (containsFloats() || !floats.isEmpty()) {
956
                        // FIXME: Do better eventually.  For now if we ever shift because of pagination and floats are present just go to a full layout.
957
                        fullLayout = true; 
958
                        break;
959
                    }
960
                    
961
                    if (!useRepaintBounds)
962
                        useRepaintBounds = true;
963
                        
964
                    repaintTop = min(repaintTop, curr->topVisibleOverflow() + min(paginationDelta, 0));
965
                    repaintBottom = max(repaintBottom, curr->bottomVisibleOverflow() + max(paginationDelta, 0));
966
                    curr->adjustPosition(0, paginationDelta);
967
                }                
968
            }
969
            
912
            if (Vector<RenderBox*>* cleanLineFloats = curr->floatsPtr()) {
970
            if (Vector<RenderBox*>* cleanLineFloats = curr->floatsPtr()) {
913
                Vector<RenderBox*>::iterator end = cleanLineFloats->end();
971
                Vector<RenderBox*>::iterator end = cleanLineFloats->end();
914
                for (Vector<RenderBox*>::iterator o = cleanLineFloats->begin(); o != end; ++o) {
972
                for (Vector<RenderBox*>::iterator o = cleanLineFloats->begin(); o != end; ++o) {
915
                    RenderBox* f = *o;
973
                    RenderBox* f = *o;
916
                    IntSize newSize(f->width() + f->marginLeft() +f->marginRight(), f->height() + f->marginTop() + f->marginBottom());
974
                    f->layoutIfNeeded();
975
                    IntSize newSize(f->width() + f->marginLeft() + f->marginRight(), f->height() + f->marginTop() + f->marginBottom());
917
                    ASSERT(floatIndex < floats.size());
976
                    ASSERT(floatIndex < floats.size());
918
                    if (floats[floatIndex].object != f) {
977
                    if (floats[floatIndex].object != f) {
919
                        // A new float has been inserted before this line or before its last known float.
978
                        // A new float has been inserted before this line or before its last known float.
Lines 1236-1249 void RenderBlock::skipTrailingWhitespace WebCore/rendering/RenderBlockLineLayout.cpp_sec11
1236
    }
1295
    }
1237
}
1296
}
1238
1297
1239
int RenderBlock::skipLeadingWhitespace(InlineBidiResolver& resolver, bool firstLine, bool isLineEmpty, bool previousLineBrokeCleanly)
1298
int RenderBlock::skipLeadingWhitespace(InlineBidiResolver& resolver, bool firstLine, bool isLineEmpty, bool previousLineBrokeCleanly,
1299
                                       FloatingObject* lastFloatFromPreviousLine)
1240
{
1300
{
1241
    int availableWidth = lineWidth(height(), firstLine);
1301
    int availableWidth = lineWidth(height(), firstLine);
1242
    while (!resolver.position().atEnd() && !requiresLineBox(resolver.position(), isLineEmpty, previousLineBrokeCleanly)) {
1302
    while (!resolver.position().atEnd() && !requiresLineBox(resolver.position(), isLineEmpty, previousLineBrokeCleanly)) {
1243
        RenderObject* object = resolver.position().obj;
1303
        RenderObject* object = resolver.position().obj;
1244
        if (object->isFloating()) {
1304
        if (object->isFloating()) {
1245
            insertFloatingObject(toRenderBox(object));
1305
            positionNewFloatOnLine(insertFloatingObject(toRenderBox(object)), lastFloatFromPreviousLine);
1246
            positionNewFloats();
1247
            availableWidth = lineWidth(height(), firstLine);
1306
            availableWidth = lineWidth(height(), firstLine);
1248
        } else if (object->isPositioned()) {
1307
        } else if (object->isPositioned()) {
1249
            // FIXME: The math here is actually not really right.  It's a best-guess approximation that
1308
            // FIXME: The math here is actually not really right.  It's a best-guess approximation that
Lines 1349-1362 static void tryHyphenating(RenderText* t WebCore/rendering/RenderBlockLineLayout.cpp_sec12
1349
}
1408
}
1350
1409
1351
InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool firstLine,  bool& isLineEmpty, bool& previousLineBrokeCleanly, 
1410
InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool firstLine,  bool& isLineEmpty, bool& previousLineBrokeCleanly, 
1352
                                              bool& hyphenated, EClear* clear)
1411
                                              bool& hyphenated, EClear* clear, FloatingObject* lastFloatFromPreviousLine)
1353
{
1412
{
1354
    ASSERT(resolver.position().block == this);
1413
    ASSERT(resolver.position().block == this);
1355
1414
1356
    bool appliedStartWidth = resolver.position().pos > 0;
1415
    bool appliedStartWidth = resolver.position().pos > 0;
1357
    LineMidpointState& lineMidpointState = resolver.midpointState();
1416
    LineMidpointState& lineMidpointState = resolver.midpointState();
1358
    
1417
    
1359
    int width = skipLeadingWhitespace(resolver, firstLine, isLineEmpty, previousLineBrokeCleanly);
1418
    int width = skipLeadingWhitespace(resolver, firstLine, isLineEmpty, previousLineBrokeCleanly, lastFloatFromPreviousLine);
1360
1419
1361
    int w = 0;
1420
    int w = 0;
1362
    int tmpW = 0;
1421
    int tmpW = 0;
Lines 1441-1452 InlineIterator RenderBlock::findNextLine WebCore/rendering/RenderBlockLineLayout.cpp_sec13
1441
            // add to special objects...
1500
            // add to special objects...
1442
            if (o->isFloating()) {
1501
            if (o->isFloating()) {
1443
                RenderBox* floatBox = toRenderBox(o);
1502
                RenderBox* floatBox = toRenderBox(o);
1444
                insertFloatingObject(floatBox);
1503
                FloatingObject* f = insertFloatingObject(floatBox);
1445
                // check if it fits in the current line.
1504
                // check if it fits in the current line.
1446
                // If it does, position it now, otherwise, position
1505
                // If it does, position it now, otherwise, position
1447
                // it after moving to next line (in newLine() func)
1506
                // it after moving to next line (in newLine() func)
1448
                if (floatsFitOnLine && floatBox->width() + floatBox->marginLeft() + floatBox->marginRight() + w + tmpW <= width) {
1507
                if (floatsFitOnLine && floatBox->width() + floatBox->marginLeft() + floatBox->marginRight() + w + tmpW <= width) {
1449
                    positionNewFloats();
1508
                    positionNewFloatOnLine(f, lastFloatFromPreviousLine);
1450
                    width = lineWidth(height(), firstLine);
1509
                    width = lineWidth(height(), firstLine);
1451
                } else
1510
                } else
1452
                    floatsFitOnLine = false;
1511
                    floatsFitOnLine = false;
- WebCore/rendering/RenderBox.cpp -2 / +2 lines
Lines 973-979 void RenderBox::mapLocalToContainer(Rend WebCore/rendering/RenderBox.cpp_sec1
973
    if (RenderView* v = view()) {
973
    if (RenderView* v = view()) {
974
        if (v->layoutStateEnabled() && !repaintContainer) {
974
        if (v->layoutStateEnabled() && !repaintContainer) {
975
            LayoutState* layoutState = v->layoutState();
975
            LayoutState* layoutState = v->layoutState();
976
            IntSize offset = layoutState->m_offset;
976
            IntSize offset = layoutState->m_paintOffset;
977
            offset.expand(x(), y());
977
            offset.expand(x(), y());
978
            if (style()->position() == RelativePosition && layer())
978
            if (style()->position() == RelativePosition && layer())
979
                offset += layer()->relativePositionOffset();
979
                offset += layer()->relativePositionOffset();
Lines 1170-1176 void RenderBox::computeRectForRepaint(Re WebCore/rendering/RenderBox.cpp_sec2
1170
                rect.move(layer()->relativePositionOffset());
1170
                rect.move(layer()->relativePositionOffset());
1171
1171
1172
            rect.move(x(), y());
1172
            rect.move(x(), y());
1173
            rect.move(layoutState->m_offset);
1173
            rect.move(layoutState->m_paintOffset);
1174
            if (layoutState->m_clipped)
1174
            if (layoutState->m_clipped)
1175
                rect.intersect(layoutState->m_clipRect);
1175
                rect.intersect(layoutState->m_clipRect);
1176
            return;
1176
            return;
- WebCore/rendering/RenderFlexibleBox.cpp -1 / +1 lines
Lines 201-207 void RenderFlexibleBox::calcPrefWidths() WebCore/rendering/RenderFlexibleBox.cpp_sec1
201
    setPrefWidthsDirty(false);
201
    setPrefWidthsDirty(false);
202
}
202
}
203
203
204
void RenderFlexibleBox::layoutBlock(bool relayoutChildren)
204
void RenderFlexibleBox::layoutBlock(bool relayoutChildren, int /*pageHeight FIXME: Implement */)
205
{
205
{
206
    ASSERT(needsLayout());
206
    ASSERT(needsLayout());
207
207
- WebCore/rendering/RenderFlexibleBox.h -1 / +1 lines
Lines 38-44 public: WebCore/rendering/RenderFlexibleBox.h_sec1
38
    void calcHorizontalPrefWidths();
38
    void calcHorizontalPrefWidths();
39
    void calcVerticalPrefWidths();
39
    void calcVerticalPrefWidths();
40
40
41
    virtual void layoutBlock(bool relayoutChildren);
41
    virtual void layoutBlock(bool relayoutChildren, int pageHeight);
42
    void layoutHorizontalBox(bool relayoutChildren);
42
    void layoutHorizontalBox(bool relayoutChildren);
43
    void layoutVerticalBox(bool relayoutChildren);
43
    void layoutVerticalBox(bool relayoutChildren);
44
44
- WebCore/rendering/RenderInline.cpp -2 / +2 lines
Lines 647-653 void RenderInline::computeRectForRepaint WebCore/rendering/RenderInline.cpp_sec1
647
            LayoutState* layoutState = v->layoutState();
647
            LayoutState* layoutState = v->layoutState();
648
            if (style()->position() == RelativePosition && layer())
648
            if (style()->position() == RelativePosition && layer())
649
                rect.move(layer()->relativePositionOffset());
649
                rect.move(layer()->relativePositionOffset());
650
            rect.move(layoutState->m_offset);
650
            rect.move(layoutState->m_paintOffset);
651
            if (layoutState->m_clipped)
651
            if (layoutState->m_clipped)
652
                rect.intersect(layoutState->m_clipRect);
652
                rect.intersect(layoutState->m_clipRect);
653
            return;
653
            return;
Lines 734-740 void RenderInline::mapLocalToContainer(R WebCore/rendering/RenderInline.cpp_sec2
734
    if (RenderView *v = view()) {
734
    if (RenderView *v = view()) {
735
        if (v->layoutStateEnabled() && !repaintContainer) {
735
        if (v->layoutStateEnabled() && !repaintContainer) {
736
            LayoutState* layoutState = v->layoutState();
736
            LayoutState* layoutState = v->layoutState();
737
            IntSize offset = layoutState->m_offset;
737
            IntSize offset = layoutState->m_paintOffset;
738
            if (style()->position() == RelativePosition && layer())
738
            if (style()->position() == RelativePosition && layer())
739
                offset += layer()->relativePositionOffset();
739
                offset += layer()->relativePositionOffset();
740
            transformState.move(offset);
740
            transformState.move(offset);
- WebCore/rendering/RenderLayer.cpp -5 / +5 lines
Lines 2541-2551 void RenderLayer::paintChildLayerIntoCol WebCore/rendering/RenderLayer.cpp_sec1
2541
    columnBlock->layer()->convertToLayerCoords(rootLayer, layerX, layerY);
2541
    columnBlock->layer()->convertToLayerCoords(rootLayer, layerX, layerY);
2542
    
2542
    
2543
    ColumnInfo* colInfo = columnBlock->columnInfo();
2543
    ColumnInfo* colInfo = columnBlock->columnInfo();
2544
    unsigned colCount = colInfo->columnCount();
2544
    unsigned colCount = columnBlock->columnCount(colInfo);
2545
    int currYOffset = 0;
2545
    int currYOffset = 0;
2546
    for (unsigned i = 0; i < colCount; i++) {
2546
    for (unsigned i = 0; i < colCount; i++) {
2547
        // For each rect, we clip to the rect, and then we adjust our coords.
2547
        // For each rect, we clip to the rect, and then we adjust our coords.
2548
        IntRect colRect = colInfo->columnRectAt(i);
2548
        IntRect colRect = columnBlock->columnRectAt(colInfo, i);
2549
        int currXOffset = colRect.x() - (columnBlock->borderLeft() + columnBlock->paddingLeft());
2549
        int currXOffset = colRect.x() - (columnBlock->borderLeft() + columnBlock->paddingLeft());
2550
        colRect.move(layerX, layerY);
2550
        colRect.move(layerX, layerY);
2551
2551
Lines 3007-3023 RenderLayer* RenderLayer::hitTestChildLa WebCore/rendering/RenderLayer.cpp_sec2
3007
    columnBlock->layer()->convertToLayerCoords(rootLayer, layerX, layerY);
3007
    columnBlock->layer()->convertToLayerCoords(rootLayer, layerX, layerY);
3008
    
3008
    
3009
    ColumnInfo* colInfo = columnBlock->columnInfo();
3009
    ColumnInfo* colInfo = columnBlock->columnInfo();
3010
    int colCount = colInfo->columnCount();
3010
    int colCount = columnBlock->columnCount(colInfo);
3011
    
3011
    
3012
    // We have to go backwards from the last column to the first.
3012
    // We have to go backwards from the last column to the first.
3013
    int left = columnBlock->borderLeft() + columnBlock->paddingLeft();
3013
    int left = columnBlock->borderLeft() + columnBlock->paddingLeft();
3014
    int currYOffset = 0;
3014
    int currYOffset = 0;
3015
    int i;
3015
    int i;
3016
    for (i = 0; i < colCount; i++)
3016
    for (i = 0; i < colCount; i++)
3017
        currYOffset -= colInfo->columnRectAt(i).height();
3017
        currYOffset -= columnBlock->columnRectAt(colInfo, i).height();
3018
    for (i = colCount - 1; i >= 0; i--) {
3018
    for (i = colCount - 1; i >= 0; i--) {
3019
        // For each rect, we clip to the rect, and then we adjust our coords.
3019
        // For each rect, we clip to the rect, and then we adjust our coords.
3020
        IntRect colRect = colInfo->columnRectAt(i);
3020
        IntRect colRect = columnBlock->columnRectAt(colInfo, i);
3021
        int currXOffset = colRect.x() - left;
3021
        int currXOffset = colRect.x() - left;
3022
        currYOffset += colRect.height();
3022
        currYOffset += colRect.height();
3023
        colRect.move(layerX, layerY);
3023
        colRect.move(layerX, layerY);
- WebCore/rendering/RenderLineBoxList.cpp -3 / +1 lines
Lines 35-41 WebCore/rendering/RenderLineBoxList.cpp_sec1
35
#include "RenderInline.h"
35
#include "RenderInline.h"
36
#include "RenderView.h"
36
#include "RenderView.h"
37
#include "RootInlineBox.h"
37
#include "RootInlineBox.h"
38
#include "Settings.h" // FIXME: This include can be removed when paginateDuringLayoutEnabled is taken out.
39
38
40
using namespace std;
39
using namespace std;
41
40
Lines 161-167 void RenderLineBoxList::paint(RenderBoxM WebCore/rendering/RenderLineBoxList.cpp_sec2
161
        return;
160
        return;
162
161
163
    RenderView* v = renderer->view();
162
    RenderView* v = renderer->view();
164
    bool usePrintRect = !v->printRect().isEmpty() && !renderer->document()->settings()->paginateDuringLayoutEnabled();
163
    bool usePrintRect = !v->printRect().isEmpty();
165
    
164
    
166
    // We can check the first box and last box and avoid painting if we don't
165
    // We can check the first box and last box and avoid painting if we don't
167
    // intersect.  This is a quick short-circuit that we can take to avoid walking any lines.
166
    // intersect.  This is a quick short-circuit that we can take to avoid walking any lines.
Lines 215-221 void RenderLineBoxList::paint(RenderBoxM WebCore/rendering/RenderLineBoxList.cpp_sec3
215
        int bottom = curr->bottomVisibleOverflow() + renderer->maximalOutlineSize(info.phase);
214
        int bottom = curr->bottomVisibleOverflow() + renderer->maximalOutlineSize(info.phase);
216
        h = bottom - top;
215
        h = bottom - top;
217
        yPos = ty + top;
216
        yPos = ty + top;
218
        v->setMinimumColumnHeight(h);
219
        if (yPos < info.rect.bottom() && yPos + h > info.rect.y())
217
        if (yPos < info.rect.bottom() && yPos + h > info.rect.y())
220
            curr->paint(info, tx, ty);
218
            curr->paint(info, tx, ty);
221
    }
219
    }
- WebCore/rendering/RenderView.cpp -2 lines
Lines 52-58 RenderView::RenderView(Node* node, Frame WebCore/rendering/RenderView.cpp_sec1
52
    , m_maximalOutlineSize(0)
52
    , m_maximalOutlineSize(0)
53
    , m_bestTruncatedAt(0)
53
    , m_bestTruncatedAt(0)
54
    , m_truncatorWidth(0)
54
    , m_truncatorWidth(0)
55
    , m_minimumColumnHeight(0)
56
    , m_forcedPageBreak(false)
55
    , m_forcedPageBreak(false)
57
    , m_layoutState(0)
56
    , m_layoutState(0)
58
    , m_layoutStateDisableCount(0)
57
    , m_layoutStateDisableCount(0)
Lines 695-701 void RenderView::setBestTruncatedAt(int WebCore/rendering/RenderView.cpp_sec2
695
694
696
void RenderView::pushLayoutState(RenderObject* root)
695
void RenderView::pushLayoutState(RenderObject* root)
697
{
696
{
698
    ASSERT(!doingFullRepaint());
699
    ASSERT(m_layoutStateDisableCount == 0);
697
    ASSERT(m_layoutStateDisableCount == 0);
700
    ASSERT(m_layoutState == 0);
698
    ASSERT(m_layoutState == 0);
701
699
- WebCore/rendering/RenderView.h -15 / +11 lines
Lines 83-94 public: WebCore/rendering/RenderView.h_sec1
83
    IntRect printRect() const { return m_printRect; }
83
    IntRect printRect() const { return m_printRect; }
84
    void setPrintRect(const IntRect& r) { m_printRect = r; }
84
    void setPrintRect(const IntRect& r) { m_printRect = r; }
85
85
86
    void setTruncatedAt(int y) { m_truncatedAt = y; m_bestTruncatedAt = m_truncatorWidth = 0; m_minimumColumnHeight = 0; m_forcedPageBreak = false; }
86
    void setTruncatedAt(int y) { m_truncatedAt = y; m_bestTruncatedAt = m_truncatorWidth = 0; m_forcedPageBreak = false; }
87
    void setBestTruncatedAt(int y, RenderBoxModelObject* forRenderer, bool forcedBreak = false);
87
    void setBestTruncatedAt(int y, RenderBoxModelObject* forRenderer, bool forcedBreak = false);
88
    void setMinimumColumnHeight(int height) { m_minimumColumnHeight = height; }
89
    int bestTruncatedAt() const { return m_bestTruncatedAt; }
88
    int bestTruncatedAt() const { return m_bestTruncatedAt; }
90
    int minimumColumnHeight() const { return m_minimumColumnHeight; }
89
    
91
92
    int truncatedAt() const { return m_truncatedAt; }
90
    int truncatedAt() const { return m_truncatedAt; }
93
91
94
    virtual void absoluteRects(Vector<IntRect>&, int tx, int ty);
92
    virtual void absoluteRects(Vector<IntRect>&, int tx, int ty);
Lines 122-142 public: WebCore/rendering/RenderView.h_sec2
122
120
123
    bool doingFullRepaint() const { return m_frameView->needsFullRepaint(); }
121
    bool doingFullRepaint() const { return m_frameView->needsFullRepaint(); }
124
122
125
    void pushLayoutState(RenderBox* renderer, const IntSize& offset)
123
    void pushLayoutState(RenderBox* renderer, const IntSize& offset, int pageHeight = 0, ColumnInfo* colInfo = 0)
126
    {
124
    {
127
        if (doingFullRepaint())
128
            return;
129
        // We push LayoutState even if layoutState is disabled because it stores layoutDelta too.
125
        // We push LayoutState even if layoutState is disabled because it stores layoutDelta too.
130
        m_layoutState = new (renderArena()) LayoutState(m_layoutState, renderer, offset);
126
        if (!doingFullRepaint() || renderer->hasColumns() || m_layoutState->paginated())
127
            m_layoutState = new (renderArena()) LayoutState(m_layoutState, renderer, offset, pageHeight, colInfo);
131
    }
128
    }
132
129
133
    void pushLayoutState(RenderObject*);
130
    void pushLayoutState(RenderObject*);
134
131
135
    void popLayoutState()
132
    void popLayoutState()
136
    {
133
    {
137
        if (doingFullRepaint())
138
            return;
139
        LayoutState* state = m_layoutState;
134
        LayoutState* state = m_layoutState;
135
        if (doingFullRepaint() && !m_layoutState->paginated())
136
            return;
140
        m_layoutState = state->m_next;
137
        m_layoutState = state->m_next;
141
        state->destroy(renderArena());
138
        state->destroy(renderArena());
142
    }
139
    }
Lines 198-204 protected: WebCore/rendering/RenderView.h_sec3
198
private:
195
private:
199
    int m_bestTruncatedAt;
196
    int m_bestTruncatedAt;
200
    int m_truncatorWidth;
197
    int m_truncatorWidth;
201
    int m_minimumColumnHeight;
202
    bool m_forcedPageBreak;
198
    bool m_forcedPageBreak;
203
    LayoutState* m_layoutState;
199
    LayoutState* m_layoutState;
204
    unsigned m_layoutStateDisableCount;
200
    unsigned m_layoutStateDisableCount;
Lines 227-239 void toRenderView(const RenderView*); WebCore/rendering/RenderView.h_sec4
227
class LayoutStateMaintainer : public Noncopyable {
223
class LayoutStateMaintainer : public Noncopyable {
228
public:
224
public:
229
    // ctor to push now
225
    // ctor to push now
230
    LayoutStateMaintainer(RenderView* view, RenderBox* root, IntSize offset, bool disableState = false)
226
    LayoutStateMaintainer(RenderView* view, RenderBox* root, IntSize offset, bool disableState = false, int pageHeight = 0, ColumnInfo* colInfo = 0)
231
        : m_view(view)
227
        : m_view(view)
232
        , m_disabled(disableState)
228
        , m_disabled(disableState)
233
        , m_didStart(false)
229
        , m_didStart(false)
234
        , m_didEnd(false)
230
        , m_didEnd(false)
235
    {
231
    {
236
        push(root, offset);
232
        push(root, offset, pageHeight, colInfo);
237
    }
233
    }
238
    
234
    
239
    // ctor to maybe push later
235
    // ctor to maybe push later
Lines 250-260 public: WebCore/rendering/RenderView.h_sec5
250
        ASSERT(m_didStart == m_didEnd);   // if this fires, it means that someone did a push(), but forgot to pop().
246
        ASSERT(m_didStart == m_didEnd);   // if this fires, it means that someone did a push(), but forgot to pop().
251
    }
247
    }
252
248
253
    void push(RenderBox* root, IntSize offset)
249
    void push(RenderBox* root, IntSize offset, int pageHeight = 0, ColumnInfo* colInfo = 0)
254
    {
250
    {
255
        ASSERT(!m_didStart);
251
        ASSERT(!m_didStart);
256
        // We push state even if disabled, because we still need to store layoutDelta
252
        // We push state even if disabled, because we still need to store layoutDelta
257
        m_view->pushLayoutState(root, offset);
253
        m_view->pushLayoutState(root, offset, pageHeight, colInfo);
258
        if (m_disabled)
254
        if (m_disabled)
259
            m_view->disableLayoutState();
255
            m_view->disableLayoutState();
260
        m_didStart = true;
256
        m_didStart = true;
- WebCore/rendering/RootInlineBox.h +6 lines
Lines 40-45 public: WebCore/rendering/RootInlineBox.h_sec1
40
        , m_lineBreakPos(0)
40
        , m_lineBreakPos(0)
41
        , m_lineTop(0)
41
        , m_lineTop(0)
42
        , m_lineBottom(0)
42
        , m_lineBottom(0)
43
        , m_paginationStrut(0)
43
    {
44
    {
44
    }
45
    }
45
46
Lines 57-62 public: WebCore/rendering/RootInlineBox.h_sec2
57
    int lineTop() const { return m_lineTop; }
58
    int lineTop() const { return m_lineTop; }
58
    int lineBottom() const { return m_lineBottom; }
59
    int lineBottom() const { return m_lineBottom; }
59
60
61
    int paginationStrut() const { return m_paginationStrut; }
62
    void setPaginationStrut(int s) { m_paginationStrut = s; }
63
60
    int selectionTop() const;
64
    int selectionTop() const;
61
    int selectionBottom() const { return lineBottom(); }
65
    int selectionBottom() const { return lineBottom(); }
62
    int selectionHeight() const { return max(0, selectionBottom() - selectionTop()); }
66
    int selectionHeight() const { return max(0, selectionBottom() - selectionTop()); }
Lines 141-146 private: WebCore/rendering/RootInlineBox.h_sec3
141
    int m_lineTop;
145
    int m_lineTop;
142
    int m_lineBottom;
146
    int m_lineBottom;
143
147
148
    int m_paginationStrut;
149
144
    // Floats hanging off the line are pushed into this vector during layout. It is only
150
    // Floats hanging off the line are pushed into this vector during layout. It is only
145
    // good for as long as the line has not been marked dirty.
151
    // good for as long as the line has not been marked dirty.
146
    OwnPtr<Vector<RenderBox*> > m_floats;
152
    OwnPtr<Vector<RenderBox*> > m_floats;

Return to Bug 38402