Changeset 69082 in webkit
- Timestamp:
- Oct 4, 2010 11:13:38 PM (14 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r69081 r69082 1 2010-10-04 David Hyatt <hyatt@apple.com> 2 3 Reviewed by Dan Bernstein. 4 5 https://bugs.webkit.org/show_bug.cgi?id=47112 6 7 Convert addOverhangingFloats and addIntrudingFloats to be block-flow-aware. 8 9 Also clean up how floats are placed to use a bit instead of the magic -1 value on top(). 10 11 * rendering/RenderBlock.cpp: 12 (WebCore::RenderBlock::layoutBlock): 13 (WebCore::RenderBlock::layoutBlockChild): 14 (WebCore::RenderBlock::insertFloatingObject): 15 (WebCore::RenderBlock::removeFloatingObject): 16 (WebCore::RenderBlock::removeFloatingObjectsBelow): 17 (WebCore::RenderBlock::positionNewFloats): 18 (WebCore::RenderBlock::markLinesDirtyInBlockRange): 19 (WebCore::RenderBlock::clearFloats): 20 (WebCore::RenderBlock::addOverhangingFloats): 21 (WebCore::RenderBlock::addIntrudingFloats): 22 * rendering/RenderBlock.h: 23 (WebCore::RenderBlock::FloatingObject::FloatingObject): 24 (WebCore::RenderBlock::FloatingObject::isPlaced): 25 (WebCore::RenderBlock::FloatingObject::setIsPlaced): 26 * rendering/RenderBlockLineLayout.cpp: 27 (WebCore::RenderBlock::determineStartPosition): 28 1 29 2010-10-04 Nico Weber <thakis@chromium.org> 2 30 -
trunk/WebCore/rendering/RenderBlock.cpp
r69025 r69082 1226 1226 RenderBlock* block = toRenderBlock(child); 1227 1227 if (block->lowestFloatLogicalBottom() + block->logicalTop() > newHeight) 1228 addOverhangingFloats(block, -block-> x(), -block->y(), false);1228 addOverhangingFloats(block, -block->logicalLeft(), -block->logicalTop(), false); 1229 1229 } 1230 1230 } … … 1951 1951 // of this block), then the parent gets notified of the floats now. 1952 1952 if (childRenderBlock && childRenderBlock->containsFloats()) 1953 maxFloatLogicalBottom = max(maxFloatLogicalBottom, addOverhangingFloats(toRenderBlock(child), -child-> x(), -child->y(), !childNeededLayout));1953 maxFloatLogicalBottom = max(maxFloatLogicalBottom, addOverhangingFloats(toRenderBlock(child), -child->logicalLeft(), -child->logicalTop(), !childNeededLayout)); 1954 1954 1955 1955 IntSize childOffset(child->x() - oldRect.x(), child->y() - oldRect.y()); … … 2928 2928 2929 2929 FloatingObject* newObj = new FloatingObject(o->style()->floating() == FLEFT ? FloatingObject::FloatLeft : FloatingObject::FloatRight); 2930 2931 newObj->setTop(-1);2932 2930 2933 2931 // Our location is irrelevant if we're unsplittable or no pagination is in effect. … … 2958 2956 if (it.current()->m_renderer == o) { 2959 2957 if (childrenInline()) { 2960 int bottom = it.current()->bottom(); 2958 int logicalTop = logicalTopForFloat(it.current()); 2959 int logicalBottom = logicalBottomForFloat(it.current()); 2960 2961 2961 // Special-case zero- and less-than-zero-height floats: those don't touch 2962 2962 // the line that they're on, but it still needs to be dirtied. This is 2963 2963 // accomplished by pretending they have a height of 1. 2964 bottom = max(bottom, it.current()->top()+ 1);2965 markLinesDirtyIn VerticalRange(0, bottom);2964 logicalBottom = max(logicalBottom, logicalTop + 1); 2965 markLinesDirtyInBlockRange(0, logicalBottom); 2966 2966 } 2967 2967 m_floatingObjects->removeRef(it.current()); … … 2978 2978 2979 2979 FloatingObject* curr = m_floatingObjects->last(); 2980 while (curr != lastFloat && ( curr->top() == -1|| curr->top() >= y)) {2980 while (curr != lastFloat && (!curr->isPlaced() || curr->top() >= y)) { 2981 2981 m_floatingObjects->removeLast(); 2982 2982 curr = m_floatingObjects->last(); … … 2992 2992 2993 2993 // If all floats have already been positioned, then we have no work to do. 2994 if (!f || f-> top() != -1)2994 if (!f || f->isPlaced()) 2995 2995 return false; 2996 2996 … … 2999 2999 // the new floats that need it. 3000 3000 FloatingObject* lastFloat = m_floatingObjects->getPrev(); 3001 while (lastFloat && lastFloat->top() == -1) {3001 while (lastFloat && !lastFloat->isPlaced()) { 3002 3002 f = m_floatingObjects->prev(); 3003 3003 lastFloat = m_floatingObjects->getPrev(); … … 3088 3088 f->setTop(y); 3089 3089 f->setHeight(o->marginTop() + o->height() + o->marginBottom()); 3090 3091 f->setIsPlaced(); 3090 3092 3091 3093 // If the child moved, we have to repaint it. … … 3217 3219 int left = fixedOffset; 3218 3220 if (m_floatingObjects) { 3219 if ( heightRemaining ) *heightRemaining = 1; 3221 if (heightRemaining) 3222 *heightRemaining = 1; 3220 3223 FloatingObject* r; 3221 3224 DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects); 3222 3225 for ( ; (r = it.current()); ++it) { 3223 if (r-> top() <= y && r->bottom() > y3226 if (r->isPlaced() && r->top() <= y && r->bottom() > y 3224 3227 && r->type() == FloatingObject::FloatLeft 3225 3228 && r->right() > left) { … … 3246 3249 3247 3250 if (m_floatingObjects) { 3248 if (heightRemaining) *heightRemaining = 1; 3251 if (heightRemaining) 3252 *heightRemaining = 1; 3249 3253 FloatingObject* r; 3250 3254 DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects); 3251 3255 for ( ; (r = it.current()); ++it) { 3252 if (r-> top() <= y && r->bottom() > y3256 if (r->isPlaced() && r->top() <= y && r->bottom() > y 3253 3257 && r->type() == FloatingObject::FloatRight 3254 3258 && r->left() < right) { … … 3302 3306 DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects); 3303 3307 for ( ; (r = it.current()); ++it) { 3304 if (r-> type() & floatType)3308 if (r->isPlaced() && r->type() & floatType) 3305 3309 lowestFloatBottom = max(lowestFloatBottom, logicalBottomForFloat(r)); 3306 3310 } … … 3586 3590 } 3587 3591 3588 void RenderBlock::markLinesDirtyIn VerticalRange(int top, int bottom, RootInlineBox* highest)3589 { 3590 if ( top >= bottom)3592 void RenderBlock::markLinesDirtyInBlockRange(int logicalTop, int logicalBottom, RootInlineBox* highest) 3593 { 3594 if (logicalTop >= logicalBottom) 3591 3595 return; 3592 3596 3593 3597 RootInlineBox* lowestDirtyLine = lastRootBox(); 3594 3598 RootInlineBox* afterLowest = lowestDirtyLine; 3595 while (lowestDirtyLine && lowestDirtyLine->blockHeight() >= bottom) {3599 while (lowestDirtyLine && lowestDirtyLine->blockHeight() >= logicalBottom) { 3596 3600 afterLowest = lowestDirtyLine; 3597 3601 lowestDirtyLine = lowestDirtyLine->prevRootBox(); 3598 3602 } 3599 3603 3600 while (afterLowest && afterLowest != highest && afterLowest->blockHeight() >= top) {3604 while (afterLowest && afterLowest != highest && afterLowest->blockHeight() >= logicalTop) { 3601 3605 afterLowest->markDirty(); 3602 3606 afterLowest = afterLowest->prevRootBox(); … … 3700 3704 deleteAllValues(floatMap); 3701 3705 3702 markLinesDirtyIn VerticalRange(changeLogicalTop, changeLogicalBottom);3703 } 3704 } 3705 3706 int RenderBlock::addOverhangingFloats(RenderBlock* child, int xoff, int yoff, bool makeChildPaintOtherFloats)3706 markLinesDirtyInBlockRange(changeLogicalTop, changeLogicalBottom); 3707 } 3708 } 3709 3710 int RenderBlock::addOverhangingFloats(RenderBlock* child, int logicalLeftOffset, int logicalTopOffset, bool makeChildPaintOtherFloats) 3707 3711 { 3708 3712 // Prevent floats from being added to the canvas by the root element, e.g., <html>. … … 3716 3720 DeprecatedPtrListIterator<FloatingObject> it(*child->m_floatingObjects); 3717 3721 for (FloatingObject* r; (r = it.current()); ++it) { 3718 int bottom = child->y() + r->bottom();3719 lowestFloatLogicalBottom = max(lowestFloatLogicalBottom, bottom);3720 3721 if ( bottom > height()) {3722 int logicalBottom = child->logicalTop() + logicalBottomForFloat(r); 3723 lowestFloatLogicalBottom = max(lowestFloatLogicalBottom, logicalBottom); 3724 3725 if (logicalBottom > logicalHeight()) { 3722 3726 // If the object is not in the list, we add it now. 3723 3727 if (!containsFloat(r->m_renderer)) { 3724 FloatingObject* floatingObj = new FloatingObject(r->type(), IntRect(r->left() - xoff, r->top() - yoff, r->width(), r->height())); 3728 int leftOffset = style()->isVerticalBlockFlow() ? logicalLeftOffset : logicalTopOffset; 3729 int topOffset = style()->isVerticalBlockFlow() ? logicalTopOffset : logicalLeftOffset; 3730 FloatingObject* floatingObj = new FloatingObject(r->type(), IntRect(r->left() - leftOffset, r->top() - topOffset, r->width(), r->height())); 3725 3731 floatingObj->m_renderer = r->m_renderer; 3726 3732 … … 3756 3762 } 3757 3763 3758 void RenderBlock::addIntrudingFloats(RenderBlock* prev, int xoff, int yoff)3764 void RenderBlock::addIntrudingFloats(RenderBlock* prev, int logicalLeftOffset, int logicalTopOffset) 3759 3765 { 3760 3766 // If the parent or previous sibling doesn't have any floats to add, don't bother. … … 3762 3768 return; 3763 3769 3770 logicalLeftOffset += (style()->isVerticalBlockFlow() ? marginLeft() : marginTop()); 3771 3764 3772 DeprecatedPtrListIterator<FloatingObject> it(*prev->m_floatingObjects); 3765 3773 for (FloatingObject *r; (r = it.current()); ++it) { 3766 if ( r->bottom() > yoff) {3774 if (logicalBottomForFloat(r) > logicalTopOffset) { 3767 3775 // The object may already be in our list. Check for it up front to avoid 3768 3776 // creating duplicate entries. … … 3771 3779 DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects); 3772 3780 while ((f = it.current())) { 3773 if (f->m_renderer == r->m_renderer) break; 3781 if (f->m_renderer == r->m_renderer) 3782 break; 3774 3783 ++it; 3775 3784 } 3776 3785 } 3777 3786 if (!f) { 3778 FloatingObject* floatingObj = new FloatingObject(r->type(), IntRect(r->left() - xoff - marginLeft(), r->top() - yoff, r->width(), r->height())); 3787 int leftOffset = style()->isVerticalBlockFlow() ? logicalLeftOffset : logicalTopOffset; 3788 int topOffset = style()->isVerticalBlockFlow() ? logicalTopOffset : logicalLeftOffset; 3789 3790 FloatingObject* floatingObj = new FloatingObject(r->type(), IntRect(r->left() - leftOffset, r->top() - topOffset, r->width(), r->height())); 3779 3791 3780 3792 // Applying the child's margin makes no sense in the case where the child was passed in. 3781 // since his own margin was added already through the subtraction of the |xoff| variable3782 // above. | xoff| will equal -flow->marginLeft()in this case, so it's already been taken3783 // into account. Only apply this code if |child| is false, since otherwise the left margin3793 // since this margin was added already through the modification of the |logicalLeftOffset| variable 3794 // above. |logicalLeftOffset| will equal the margin in this case, so it's already been taken 3795 // into account. Only apply this code if prev is the parent, since otherwise the left margin 3784 3796 // will get applied twice. 3785 3797 if (prev != parent()) 3786 floatingObj->setLeft(floatingObj->left() + prev->marginLeft());3787 3798 floatingObj->setLeft(floatingObj->left() + (style()->isVerticalBlockFlow() ? prev->marginLeft() : prev->marginTop())); 3799 3788 3800 floatingObj->m_shouldPaint = false; // We are not in the direct inheritance chain for this float. We will never paint it. 3789 3801 floatingObj->m_renderer = r->m_renderer; -
trunk/WebCore/rendering/RenderBlock.h
r69025 r69082 362 362 // Note that Type uses bits so you can use FloatBoth as a mask to query for both left and right. 363 363 enum Type { FloatLeft = 1, FloatRight = 2, FloatBoth = 3 }; 364 365 FloatingObject(Type type, const IntRect& frameRect = IntRect()) 364 365 FloatingObject(Type type) 366 : m_renderer(0) 367 , m_paginationStrut(0) 368 , m_type(type) 369 , m_shouldPaint(true) 370 , m_isDescendant(false) 371 , m_isPlaced(false) 372 { 373 } 374 375 FloatingObject(Type type, const IntRect& frameRect) 366 376 : m_renderer(0) 367 377 , m_frameRect(frameRect) … … 370 380 , m_shouldPaint(true) 371 381 , m_isDescendant(false) 382 , m_isPlaced(true) 372 383 { 373 384 } … … 375 386 Type type() { return static_cast<Type>(m_type); } 376 387 377 int left() const { return m_frameRect.x(); } 378 int right() const { return m_frameRect.right(); } 379 int top() const { return m_frameRect.y(); } 380 int bottom() const { return m_frameRect.bottom(); } 388 bool isPlaced() const { return m_isPlaced; } 389 void setIsPlaced(bool placed = true) { m_isPlaced = placed; } 390 391 int left() const { ASSERT(isPlaced()); return m_frameRect.x(); } 392 int right() const { ASSERT(isPlaced()); return m_frameRect.right(); } 393 int top() const { ASSERT(isPlaced()); return m_frameRect.y(); } 394 int bottom() const { ASSERT(isPlaced()); return m_frameRect.bottom(); } 381 395 int width() const { return m_frameRect.width(); } 382 396 int height() const { return m_frameRect.height(); } … … 387 401 void setHeight(int height) { m_frameRect.setHeight(height); } 388 402 389 const IntRect& frameRect() const { return m_frameRect; }403 const IntRect& frameRect() const { ASSERT(isPlaced()); return m_frameRect; } 390 404 void setFrameRect(const IntRect& frameRect) { m_frameRect = frameRect; } 391 405 … … 396 410 bool m_shouldPaint : 1; 397 411 bool m_isDescendant : 1; 412 bool m_isPlaced : 1; 398 413 }; 399 414 … … 515 530 void adjustForBorderFit(int x, int& left, int& right) const; // Helper function for borderFitAdjust 516 531 517 void markLinesDirtyIn VerticalRange(int top, int bottom, RootInlineBox* highest = 0);532 void markLinesDirtyInBlockRange(int logicalTop, int logicalTop, RootInlineBox* highest = 0); 518 533 519 534 void newLine(EClear); -
trunk/WebCore/rendering/RenderBlockLineLayout.cpp
r68957 r69082 960 960 int floatTop = floats[floatIndex].rect.y(); 961 961 curr->markDirty(); 962 markLinesDirtyIn VerticalRange(curr->blockHeight(), floatTop + max(floats[floatIndex].rect.height(), newSize.height()), curr);962 markLinesDirtyInBlockRange(curr->blockHeight(), floatTop + max(floats[floatIndex].rect.height(), newSize.height()), curr); 963 963 floats[floatIndex].rect.setSize(newSize); 964 964 dirtiedByFloat = true;
Note: See TracChangeset
for help on using the changeset viewer.