Changeset 69628 in webkit
- Timestamp:
- Oct 12, 2010 6:36:33 PM (13 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r69626 r69628 1 2010-10-12 David Hyatt <hyatt@apple.com> 2 3 Reviewed by Dan Bernstein 4 5 <rdar://problem/8488444> REGRESSION (r67771) 6 https://bugs.webkit.org/show_bug.cgi?id=47434 7 Crash when printing in RenderBlock::markDescendantBlocksAndLinesForLayout 8 9 Added printing/simultaneous-position-float-change.html 10 11 Remove the markDescendantBlocksAndLinesForLayout method since it can walk m_floatingObjects lists with deleted 12 objects in them. Make the mechanism for relayout when the page height changes the same as the one when pageY 13 changes and just tie a concept of pageHeightChanged to the layout state. If that is set, blocks will just 14 automatically mark themselves as needing layout. 15 16 * platform/mac/printing/simultaneous-position-float-change-expected.checksum: Added. 17 * platform/mac/printing/simultaneous-position-float-change-expected.png: Added. 18 * platform/mac/printing/simultaneous-position-float-change-expected.txt: Added. 19 * printing/simultaneous-position-float-change.html: Added. 20 1 21 2010-09-30 Dumitru Daniliuc <dumi@chromium.org> 2 22 -
trunk/WebCore/ChangeLog
r69625 r69628 1 2010-10-12 David Hyatt <hyatt@apple.com> 2 3 Reviewed by Dan Bernstein 4 5 <rdar://problem/8488444> REGRESSION (r67771) 6 https://bugs.webkit.org/show_bug.cgi?id=47434 7 Crash when printing in RenderBlock::markDescendantBlocksAndLinesForLayout 8 9 Added printing/simultaneous-position-float-change.html 10 11 Remove the markDescendantBlocksAndLinesForLayout method since it can walk m_floatingObjects lists with deleted 12 objects in them. Make the mechanism for relayout when the page height changes the same as the one when pageY 13 changes and just tie a concept of pageHeightChanged to the layout state. If that is set, blocks will just 14 automatically mark themselves as needing layout. 15 16 * rendering/LayoutState.cpp: 17 (WebCore::LayoutState::LayoutState): 18 * rendering/LayoutState.h: 19 (WebCore::LayoutState::LayoutState): 20 (WebCore::LayoutState::pageHeight): 21 (WebCore::LayoutState::pageHeightChanged): 22 * rendering/RenderBlock.cpp: 23 (WebCore::RenderBlock::layoutBlock): 24 (WebCore::RenderBlock::layoutBlockChild): 25 (WebCore::RenderBlock::layoutPositionedObjects): 26 (WebCore::RenderBlock::markForPaginationRelayoutIfNeeded): 27 (WebCore::RenderBlock::insertFloatingObject): 28 (WebCore::RenderBlock::positionNewFloats): 29 * rendering/RenderBlock.h: 30 * rendering/RenderBox.cpp: 31 * rendering/RenderBox.h: 32 (WebCore::RenderBox::markForPaginationRelayoutIfNeeded): 33 * rendering/RenderFlexibleBox.cpp: 34 (WebCore::RenderFlexibleBox::layoutHorizontalBox): 35 (WebCore::RenderFlexibleBox::layoutVerticalBox): 36 * rendering/RenderView.cpp: 37 (WebCore::RenderView::RenderView): 38 (WebCore::RenderView::layout): 39 * rendering/RenderView.h: 40 (WebCore::RenderView::setPageHeight): 41 (WebCore::RenderView::pushLayoutState): 42 (WebCore::LayoutStateMaintainer::LayoutStateMaintainer): 43 (WebCore::LayoutStateMaintainer::push): 44 1 45 2010-10-12 Anders Carlsson <andersca@apple.com> 2 46 -
trunk/WebCore/rendering/LayoutState.cpp
r67660 r69628 35 35 namespace WebCore { 36 36 37 LayoutState::LayoutState(LayoutState* prev, RenderBox* renderer, const IntSize& offset, int pageHeight, ColumnInfo* columnInfo)37 LayoutState::LayoutState(LayoutState* prev, RenderBox* renderer, const IntSize& offset, int pageHeight, bool pageHeightChanged, ColumnInfo* columnInfo) 38 38 : m_columnInfo(columnInfo) 39 39 , m_next(prev) … … 87 87 m_pageOffset = IntSize(m_layoutOffset.width() + renderer->borderLeft() + renderer->paddingLeft(), 88 88 m_layoutOffset.height() + renderer->borderTop() + renderer->paddingTop()); 89 m_pageHeightChanged = pageHeightChanged; 89 90 } else { 90 91 // If we don't establish a new page height, then propagate the old page height and offset down. 91 92 m_pageHeight = m_next->m_pageHeight; 93 m_pageHeightChanged = m_next->m_pageHeightChanged; 92 94 m_pageOffset = m_next->m_pageOffset; 93 95 … … 108 110 : m_clipped(false) 109 111 , m_pageHeight(0) 112 , m_pageHeightChanged(false) 110 113 , m_columnInfo(0) 111 114 , m_next(0) -
trunk/WebCore/rendering/LayoutState.h
r67660 r69628 43 43 : m_clipped(false) 44 44 , m_pageHeight(0) 45 , m_pageHeightChanged(false) 45 46 , m_columnInfo(0) 46 47 , m_next(0) … … 51 52 } 52 53 53 LayoutState(LayoutState*, RenderBox*, const IntSize& offset, int pageHeight, ColumnInfo*);54 LayoutState(LayoutState*, RenderBox*, const IntSize& offset, int pageHeight, bool pageHeightChanged, ColumnInfo*); 54 55 LayoutState(RenderObject*); 55 56 … … 68 69 void addForcedColumnBreak(int childY); 69 70 71 bool pageHeight() const { return m_pageHeight; } 72 bool pageHeightChanged() const { return m_pageHeightChanged; } 73 70 74 private: 71 75 // The normal operator new is disallowed. … … 82 86 83 87 int m_pageHeight; // The current page height for the pagination model that encloses us. 88 bool m_pageHeightChanged; // If our page height has changed, this will force all blocks to relayout. 84 89 IntSize m_pageOffset; // The offset of the start of the first page in the nearest enclosing pagination model. 85 90 ColumnInfo* m_columnInfo; // If the enclosing pagination model is a column model, then this will store column information for easy retrieval/manipulation. -
trunk/WebCore/rendering/RenderBlock.cpp
r69319 r69628 1139 1139 setLogicalHeight(0); 1140 1140 bool hasSpecifiedPageHeight = false; 1141 bool pageHeightChanged = false; 1141 1142 ColumnInfo* colInfo = columnInfo(); 1142 1143 if (hasColumns()) { … … 1154 1155 if (colInfo->columnHeight() != pageHeight && m_everHadLayout) { 1155 1156 colInfo->setColumnHeight(pageHeight); 1156 markDescendantBlocksAndLinesForLayout(); // We need to dirty all descendant blocks and lines, since the column height is different now.1157 pageHeightChanged = true; 1157 1158 } 1158 1159 … … 1161 1162 } 1162 1163 1163 LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection(), pageHeight, colInfo);1164 LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection(), pageHeight, pageHeightChanged, colInfo); 1164 1165 1165 1166 // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, to track … … 1868 1869 } 1869 1870 1870 bool paginated = view()->layoutState()->isPaginated(); 1871 if (!child->needsLayout() && paginated && view()->layoutState()->m_pageHeight && childRenderBlock && view()->layoutState()->pageY(child->y()) != childRenderBlock->pageY()) 1872 childRenderBlock->markForPaginationRelayout(); 1871 if (!child->needsLayout()) 1872 child->markForPaginationRelayoutIfNeeded(); 1873 1873 1874 1874 bool childHadLayout = child->m_everHadLayout; … … 1887 1887 int logicalTopAfterClear = clearFloatsIfNeeded(child, marginInfo, oldPosMarginBefore, oldNegMarginBefore, logicalTopBeforeClear); 1888 1888 1889 bool paginated = view()->layoutState()->isPaginated(); 1889 1890 if (paginated) { 1890 1891 int oldTop = logicalTopAfterClear; … … 1936 1937 if (!child->avoidsFloats() && childRenderBlock->containsFloats()) 1937 1938 childRenderBlock->markAllDescendantsWithFloatsForLayout(); 1938 if ( paginated && !child->needsLayout() && view()->layoutState()->m_pageHeight && view()->layoutState()->pageY(child->y()) != childRenderBlock->pageY())1939 child RenderBlock->markForPaginationRelayout();1939 if (!child->needsLayout()) 1940 child->markForPaginationRelayoutIfNeeded(); 1940 1941 } 1941 1942 … … 2018 2019 if (hasColumns()) 2019 2020 view()->layoutState()->clearPaginationInformation(); // Positioned objects are not part of the column flow, so they don't paginate with the columns. 2020 2021 bool paginated = view()->layoutState()->isPaginated();2022 2021 2023 2022 RenderBox* r; … … 2036 2035 r->setPreferredLogicalWidthsDirty(true, false); 2037 2036 2038 if (!r->needsLayout() && paginated && view()->layoutState()->m_pageHeight) { 2039 RenderBlock* childRenderBlock = r->isRenderBlock() ? toRenderBlock(r) : 0; 2040 if (childRenderBlock && view()->layoutState()->pageY(childRenderBlock->y()) != childRenderBlock->pageY()) 2041 childRenderBlock->markForPaginationRelayout(); 2042 } 2037 if (!r->needsLayout()) 2038 r->markForPaginationRelayoutIfNeeded(); 2043 2039 2044 2040 // We don't have to do a full layout. We just have to update our position. Try that first. If we have shrink-to-fit width … … 2064 2060 } 2065 2061 } 2062 } 2063 2064 void RenderBlock::markForPaginationRelayoutIfNeeded() 2065 { 2066 ASSERT(!needsLayout()); 2067 if (needsLayout()) 2068 return; 2069 2070 if (view()->layoutState()->pageHeightChanged() || (view()->layoutState()->pageHeight() && view()->layoutState()->pageY(y()) != pageY())) 2071 setChildNeedsLayout(true, false); 2066 2072 } 2067 2073 … … 2941 2947 // Our location is irrelevant if we're unsplittable or no pagination is in effect. 2942 2948 // Just go ahead and lay out the float. 2943 bool affectedByPagination = o->isRenderBlock() && view()->layoutState()->m_pageHeight; 2949 bool isChildRenderBlock = o->isRenderBlock(); 2950 if (isChildRenderBlock && !o->needsLayout() && view()->layoutState()->pageHeightChanged()) 2951 o->setChildNeedsLayout(true, false); 2952 2953 bool affectedByPagination = isChildRenderBlock && view()->layoutState()->m_pageHeight; 2944 2954 if (!affectedByPagination || isWritingModeRoot()) // We are unsplittable if we're a block flow root. 2945 2955 o->layoutIfNeeded(); … … 3075 3085 RenderBlock* childBlock = childBox->isRenderBlock() ? toRenderBlock(childBox) : 0; 3076 3086 3077 if ( childBlock && view()->layoutState()->m_pageHeight && view()->layoutState()->pageY(childBox->y()) != childBlock->pageY())3078 childB lock->markForPaginationRelayout();3087 if (!childBox->needsLayout()) 3088 childBox->markForPaginationRelayoutIfNeeded();; 3079 3089 childBox->layoutIfNeeded(); 3080 3090 … … 3865 3875 childBlock->markAllDescendantsWithFloatsForLayout(floatToRemove, inLayout); 3866 3876 } 3867 }3868 }3869 3870 void RenderBlock::markDescendantBlocksAndLinesForLayout(bool inLayout)3871 {3872 if (!m_everHadLayout)3873 return;3874 3875 setChildNeedsLayout(true, !inLayout);3876 3877 // Iterate over our children and mark them as needed.3878 if (!childrenInline()) {3879 for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {3880 if (child->isFloatingOrPositioned())3881 continue;3882 child->markDescendantBlocksAndLinesForLayout(inLayout);3883 }3884 }3885 3886 // Walk our floating objects and mark them too.3887 if (m_floatingObjects) {3888 DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);3889 while (it.current()) {3890 if (it.current()->m_renderer->isRenderBlock())3891 it.current()->m_renderer->markDescendantBlocksAndLinesForLayout(inLayout);3892 ++it;3893 }3894 }3895 3896 if (m_positionedObjects) {3897 // FIXME: Technically we don't have to mark the positioned objects if we're the block3898 // that established the columns, but we don't really have that information here.3899 Iterator end = m_positionedObjects->end();3900 for (Iterator it = m_positionedObjects->begin(); it != end; ++it)3901 (*it)->markDescendantBlocksAndLinesForLayout();3902 3877 } 3903 3878 } -
trunk/WebCore/rendering/RenderBlock.h
r69235 r69628 91 91 void markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove = 0, bool inLayout = true); 92 92 void markPositionedObjectsForLayout(); 93 void markForPaginationRelayout() 94 { 95 if (isTable()) 96 markDescendantBlocksAndLinesForLayout(); 97 else 98 setChildNeedsLayout(true, false); 99 } 100 virtual void markDescendantBlocksAndLinesForLayout(bool inLayout = true); 93 virtual void markForPaginationRelayoutIfNeeded(); 101 94 102 95 bool containsFloats() { return m_floatingObjects && !m_floatingObjects->isEmpty(); } -
trunk/WebCore/rendering/RenderBox.cpp
r69476 r69628 3127 3127 } 3128 3128 3129 void RenderBox::markDescendantBlocksAndLinesForLayout(bool inLayout)3130 {3131 if (!m_everHadLayout || isReplaced())3132 return;3133 3134 setChildNeedsLayout(true, !inLayout);3135 3136 // Iterate over our children and mark them as needed.3137 for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {3138 if (child->isFloatingOrPositioned())3139 continue;3140 child->markDescendantBlocksAndLinesForLayout(inLayout);3141 }3142 }3143 3144 3129 } // namespace WebCore -
trunk/WebCore/rendering/RenderBox.h
r69235 r69628 363 363 virtual bool avoidsFloats() const; 364 364 365 virtual void mark DescendantBlocksAndLinesForLayout(bool inLayout = true);366 365 virtual void markForPaginationRelayoutIfNeeded() { } 366 367 367 bool isWritingModeRoot() const { return !parent() || parent()->style()->writingMode() != style()->writingMode(); } 368 368 -
trunk/WebCore/rendering/RenderFlexibleBox.cpp
r68842 r69628 335 335 gatherFlexChildrenInfo(iterator, relayoutChildren, highestFlexGroup, lowestFlexGroup, haveFlex); 336 336 337 bool paginated = view()->layoutState()->isPaginated();338 339 337 RenderBox* child; 340 338 … … 367 365 child->computeBlockDirectionMargins(this); 368 366 369 if (!child->needsLayout() && paginated && view()->layoutState()->m_pageHeight) { 370 RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0; 371 if (childRenderBlock && view()->layoutState()->pageY(child->y()) != childRenderBlock->pageY()) 372 childRenderBlock->markForPaginationRelayout(); 373 } 367 if (!child->needsLayout()) 368 child->markForPaginationRelayoutIfNeeded(); 374 369 375 370 // Now do the layout. … … 441 436 child->setChildNeedsLayout(true, false); 442 437 443 if (!child->needsLayout() && paginated && view()->layoutState()->m_pageHeight) { 444 RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0; 445 if (childRenderBlock && view()->layoutState()->pageY(child->y()) != childRenderBlock->pageY()) 446 childRenderBlock->markForPaginationRelayout(); 447 } 438 if (!child->needsLayout()) 439 child->markForPaginationRelayoutIfNeeded(); 448 440 449 441 child->layoutIfNeeded(); … … 660 652 gatherFlexChildrenInfo(iterator, relayoutChildren, highestFlexGroup, lowestFlexGroup, haveFlex); 661 653 662 bool paginated = view()->layoutState()->isPaginated();663 664 654 RenderBox* child; 665 655 … … 711 701 setHeight(height() + child->marginTop()); 712 702 713 if (!child->needsLayout() && paginated && view()->layoutState()->m_pageHeight) { 714 RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0; 715 if (childRenderBlock && view()->layoutState()->pageY(child->y()) != childRenderBlock->pageY()) 716 childRenderBlock->markForPaginationRelayout(); 717 } 703 if (!child->needsLayout()) 704 child->markForPaginationRelayoutIfNeeded(); 718 705 719 706 // Now do a layout. -
trunk/WebCore/rendering/RenderView.cpp
r68436 r69628 51 51 , m_maximalOutlineSize(0) 52 52 , m_pageHeight(0) 53 , m_pageHeightChanged(false) 53 54 , m_layoutState(0) 54 55 , m_layoutStateDisableCount(0) … … 117 118 state.m_clipped = false; 118 119 state.m_pageHeight = m_pageHeight; 120 state.m_pageHeightChanged = m_pageHeightChanged; 121 m_pageHeightChanged = false; 119 122 m_layoutState = &state; 120 123 -
trunk/WebCore/rendering/RenderView.h
r69220 r69628 136 136 if (m_pageHeight != height) { 137 137 m_pageHeight = height; 138 m arkDescendantBlocksAndLinesForLayout();138 m_pageHeightChanged = true; 139 139 } 140 140 } … … 176 176 177 177 // These functions may only be accessed by LayoutStateMaintainer. 178 bool pushLayoutState(RenderBox* renderer, const IntSize& offset, int pageHeight = 0, ColumnInfo* colInfo = 0)178 bool pushLayoutState(RenderBox* renderer, const IntSize& offset, int pageHeight = 0, bool pageHeightChanged = false, ColumnInfo* colInfo = 0) 179 179 { 180 180 // We push LayoutState even if layoutState is disabled because it stores layoutDelta too. 181 181 if (!doingFullRepaint() || renderer->hasColumns() || m_layoutState->isPaginated()) { 182 m_layoutState = new (renderArena()) LayoutState(m_layoutState, renderer, offset, pageHeight, colInfo);182 m_layoutState = new (renderArena()) LayoutState(m_layoutState, renderer, offset, pageHeight, pageHeightChanged, colInfo); 183 183 return true; 184 184 } … … 228 228 private: 229 229 unsigned m_pageHeight; 230 bool m_pageHeightChanged; 230 231 LayoutState* m_layoutState; 231 232 unsigned m_layoutStateDisableCount; … … 255 256 public: 256 257 // ctor to push now 257 LayoutStateMaintainer(RenderView* view, RenderBox* root, IntSize offset, bool disableState = false, int pageHeight = 0, ColumnInfo* colInfo = 0)258 LayoutStateMaintainer(RenderView* view, RenderBox* root, IntSize offset, bool disableState = false, int pageHeight = 0, bool pageHeightChanged = false, ColumnInfo* colInfo = 0) 258 259 : m_view(view) 259 260 , m_disabled(disableState) … … 262 263 , m_didCreateLayoutState(false) 263 264 { 264 push(root, offset, pageHeight, colInfo);265 push(root, offset, pageHeight, pageHeightChanged, colInfo); 265 266 } 266 267 … … 280 281 } 281 282 282 void push(RenderBox* root, IntSize offset, int pageHeight = 0, ColumnInfo* colInfo = 0)283 void push(RenderBox* root, IntSize offset, int pageHeight = 0, bool pageHeightChanged = false, ColumnInfo* colInfo = 0) 283 284 { 284 285 ASSERT(!m_didStart); 285 286 // We push state even if disabled, because we still need to store layoutDelta 286 m_didCreateLayoutState = m_view->pushLayoutState(root, offset, pageHeight, colInfo);287 m_didCreateLayoutState = m_view->pushLayoutState(root, offset, pageHeight, pageHeightChanged, colInfo); 287 288 if (m_disabled && m_didCreateLayoutState) 288 289 m_view->disableLayoutState();
Note: See TracChangeset
for help on using the changeset viewer.