Changeset 69082 in webkit


Ignore:
Timestamp:
Oct 4, 2010 11:13:38 PM (14 years ago)
Author:
hyatt@apple.com
Message:

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

Reviewed by Dan Bernstein.

Convert addOverhangingFloats and addIntrudingFloats to be block-flow-aware.

Also clean up how floats are placed to use a bit instead of the magic -1 value on top().

  • rendering/RenderBlock.cpp:

(WebCore::RenderBlock::layoutBlock):
(WebCore::RenderBlock::layoutBlockChild):
(WebCore::RenderBlock::insertFloatingObject):
(WebCore::RenderBlock::removeFloatingObject):
(WebCore::RenderBlock::removeFloatingObjectsBelow):
(WebCore::RenderBlock::positionNewFloats):
(WebCore::RenderBlock::markLinesDirtyInBlockRange):
(WebCore::RenderBlock::clearFloats):
(WebCore::RenderBlock::addOverhangingFloats):
(WebCore::RenderBlock::addIntrudingFloats):

  • rendering/RenderBlock.h:

(WebCore::RenderBlock::FloatingObject::FloatingObject):
(WebCore::RenderBlock::FloatingObject::isPlaced):
(WebCore::RenderBlock::FloatingObject::setIsPlaced):

  • rendering/RenderBlockLineLayout.cpp:

(WebCore::RenderBlock::determineStartPosition):

Location:
trunk/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r69081 r69082  
     12010-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
    1292010-10-04  Nico Weber  <thakis@chromium.org>
    230
  • trunk/WebCore/rendering/RenderBlock.cpp

    r69025 r69082  
    12261226                    RenderBlock* block = toRenderBlock(child);
    12271227                    if (block->lowestFloatLogicalBottom() + block->logicalTop() > newHeight)
    1228                         addOverhangingFloats(block, -block->x(), -block->y(), false);
     1228                        addOverhangingFloats(block, -block->logicalLeft(), -block->logicalTop(), false);
    12291229                }
    12301230            }
     
    19511951    // of this block), then the parent gets notified of the floats now.
    19521952    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));
    19541954
    19551955    IntSize childOffset(child->x() - oldRect.x(), child->y() - oldRect.y());
     
    29282928
    29292929    FloatingObject* newObj = new FloatingObject(o->style()->floating() == FLEFT ? FloatingObject::FloatLeft : FloatingObject::FloatRight);
    2930 
    2931     newObj->setTop(-1);
    29322930   
    29332931    // Our location is irrelevant if we're unsplittable or no pagination is in effect.
     
    29582956            if (it.current()->m_renderer == o) {
    29592957                if (childrenInline()) {
    2960                     int bottom = it.current()->bottom();
     2958                    int logicalTop = logicalTopForFloat(it.current());
     2959                    int logicalBottom = logicalBottomForFloat(it.current());
     2960                   
    29612961                    // Special-case zero- and less-than-zero-height floats: those don't touch
    29622962                    // the line that they're on, but it still needs to be dirtied. This is
    29632963                    // accomplished by pretending they have a height of 1.
    2964                     bottom = max(bottom, it.current()->top() + 1);
    2965                     markLinesDirtyInVerticalRange(0, bottom);
     2964                    logicalBottom = max(logicalBottom, logicalTop + 1);
     2965                    markLinesDirtyInBlockRange(0, logicalBottom);
    29662966                }
    29672967                m_floatingObjects->removeRef(it.current());
     
    29782978   
    29792979    FloatingObject* curr = m_floatingObjects->last();
    2980     while (curr != lastFloat && (curr->top() == -1 || curr->top() >= y)) {
     2980    while (curr != lastFloat && (!curr->isPlaced() || curr->top() >= y)) {
    29812981        m_floatingObjects->removeLast();
    29822982        curr = m_floatingObjects->last();
     
    29922992
    29932993    // 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())
    29952995        return false;
    29962996
     
    29992999    // the new floats that need it.
    30003000    FloatingObject* lastFloat = m_floatingObjects->getPrev();
    3001     while (lastFloat && lastFloat->top() == -1) {
     3001    while (lastFloat && !lastFloat->isPlaced()) {
    30023002        f = m_floatingObjects->prev();
    30033003        lastFloat = m_floatingObjects->getPrev();
     
    30883088        f->setTop(y);
    30893089        f->setHeight(o->marginTop() + o->height() + o->marginBottom());
     3090
     3091        f->setIsPlaced();
    30903092
    30913093        // If the child moved, we have to repaint it.
     
    32173219    int left = fixedOffset;
    32183220    if (m_floatingObjects) {
    3219         if ( heightRemaining ) *heightRemaining = 1;
     3221        if (heightRemaining)
     3222            *heightRemaining = 1;
    32203223        FloatingObject* r;
    32213224        DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
    32223225        for ( ; (r = it.current()); ++it) {
    3223             if (r->top() <= y && r->bottom() > y
     3226            if (r->isPlaced() && r->top() <= y && r->bottom() > y
    32243227                && r->type() == FloatingObject::FloatLeft
    32253228                && r->right() > left) {
     
    32463249
    32473250    if (m_floatingObjects) {
    3248         if (heightRemaining) *heightRemaining = 1;
     3251        if (heightRemaining)
     3252            *heightRemaining = 1;
    32493253        FloatingObject* r;
    32503254        DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
    32513255        for ( ; (r = it.current()); ++it) {
    3252             if (r->top() <= y && r->bottom() > y
     3256            if (r->isPlaced() && r->top() <= y && r->bottom() > y
    32533257                && r->type() == FloatingObject::FloatRight
    32543258                && r->left() < right) {
     
    33023306    DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
    33033307    for ( ; (r = it.current()); ++it) {
    3304         if (r->type() & floatType)
     3308        if (r->isPlaced() && r->type() & floatType)
    33053309            lowestFloatBottom = max(lowestFloatBottom, logicalBottomForFloat(r));
    33063310    }
     
    35863590}
    35873591
    3588 void RenderBlock::markLinesDirtyInVerticalRange(int top, int bottom, RootInlineBox* highest)
    3589 {
    3590     if (top >= bottom)
     3592void RenderBlock::markLinesDirtyInBlockRange(int logicalTop, int logicalBottom, RootInlineBox* highest)
     3593{
     3594    if (logicalTop >= logicalBottom)
    35913595        return;
    35923596
    35933597    RootInlineBox* lowestDirtyLine = lastRootBox();
    35943598    RootInlineBox* afterLowest = lowestDirtyLine;
    3595     while (lowestDirtyLine && lowestDirtyLine->blockHeight() >= bottom) {
     3599    while (lowestDirtyLine && lowestDirtyLine->blockHeight() >= logicalBottom) {
    35963600        afterLowest = lowestDirtyLine;
    35973601        lowestDirtyLine = lowestDirtyLine->prevRootBox();
    35983602    }
    35993603
    3600     while (afterLowest && afterLowest != highest && afterLowest->blockHeight() >= top) {
     3604    while (afterLowest && afterLowest != highest && afterLowest->blockHeight() >= logicalTop) {
    36013605        afterLowest->markDirty();
    36023606        afterLowest = afterLowest->prevRootBox();
     
    37003704        deleteAllValues(floatMap);
    37013705
    3702         markLinesDirtyInVerticalRange(changeLogicalTop, changeLogicalBottom);
    3703     }
    3704 }
    3705 
    3706 int RenderBlock::addOverhangingFloats(RenderBlock* child, int xoff, int yoff, bool makeChildPaintOtherFloats)
     3706        markLinesDirtyInBlockRange(changeLogicalTop, changeLogicalBottom);
     3707    }
     3708}
     3709
     3710int RenderBlock::addOverhangingFloats(RenderBlock* child, int logicalLeftOffset, int logicalTopOffset, bool makeChildPaintOtherFloats)
    37073711{
    37083712    // Prevent floats from being added to the canvas by the root element, e.g., <html>.
     
    37163720    DeprecatedPtrListIterator<FloatingObject> it(*child->m_floatingObjects);
    37173721    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()) {
    37223726            // If the object is not in the list, we add it now.
    37233727            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()));
    37253731                floatingObj->m_renderer = r->m_renderer;
    37263732
     
    37563762}
    37573763
    3758 void RenderBlock::addIntrudingFloats(RenderBlock* prev, int xoff, int yoff)
     3764void RenderBlock::addIntrudingFloats(RenderBlock* prev, int logicalLeftOffset, int logicalTopOffset)
    37593765{
    37603766    // If the parent or previous sibling doesn't have any floats to add, don't bother.
     
    37623768        return;
    37633769
     3770    logicalLeftOffset += (style()->isVerticalBlockFlow() ? marginLeft() : marginTop());
     3771               
    37643772    DeprecatedPtrListIterator<FloatingObject> it(*prev->m_floatingObjects);
    37653773    for (FloatingObject *r; (r = it.current()); ++it) {
    3766         if (r->bottom() > yoff) {
     3774        if (logicalBottomForFloat(r) > logicalTopOffset) {
    37673775            // The object may already be in our list. Check for it up front to avoid
    37683776            // creating duplicate entries.
     
    37713779                DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
    37723780                while ((f = it.current())) {
    3773                     if (f->m_renderer == r->m_renderer) break;
     3781                    if (f->m_renderer == r->m_renderer)
     3782                        break;
    37743783                    ++it;
    37753784                }
    37763785            }
    37773786            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()));
    37793791
    37803792                // 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| variable
    3782                 // above.  |xoff| will equal -flow->marginLeft() in this case, so it's already been taken
    3783                 // into account.  Only apply this code if |child| is false, since otherwise the left margin
     3793                // 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
    37843796                // will get applied twice.
    37853797                if (prev != parent())
    3786                     floatingObj->setLeft(floatingObj->left() + prev->marginLeft());
    3787                 
     3798                    floatingObj->setLeft(floatingObj->left() + (style()->isVerticalBlockFlow() ? prev->marginLeft() : prev->marginTop()));
     3799               
    37883800                floatingObj->m_shouldPaint = false;  // We are not in the direct inheritance chain for this float. We will never paint it.
    37893801                floatingObj->m_renderer = r->m_renderer;
  • trunk/WebCore/rendering/RenderBlock.h

    r69025 r69082  
    362362        // Note that Type uses bits so you can use FloatBoth as a mask to query for both left and right.
    363363        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)
    366376            : m_renderer(0)
    367377            , m_frameRect(frameRect)
     
    370380            , m_shouldPaint(true)
    371381            , m_isDescendant(false)
     382            , m_isPlaced(true)
    372383        {
    373384        }
     
    375386        Type type() { return static_cast<Type>(m_type); }
    376387
    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(); }
    381395        int width() const { return m_frameRect.width(); }
    382396        int height() const { return m_frameRect.height(); }
     
    387401        void setHeight(int height) { m_frameRect.setHeight(height); }
    388402
    389         const IntRect& frameRect() const { return m_frameRect; }
     403        const IntRect& frameRect() const { ASSERT(isPlaced()); return m_frameRect; }
    390404        void setFrameRect(const IntRect& frameRect) { m_frameRect = frameRect; }
    391405
     
    396410        bool m_shouldPaint : 1;
    397411        bool m_isDescendant : 1;
     412        bool m_isPlaced : 1;
    398413    };
    399414
     
    515530    void adjustForBorderFit(int x, int& left, int& right) const; // Helper function for borderFitAdjust
    516531
    517     void markLinesDirtyInVerticalRange(int top, int bottom, RootInlineBox* highest = 0);
     532    void markLinesDirtyInBlockRange(int logicalTop, int logicalTop, RootInlineBox* highest = 0);
    518533
    519534    void newLine(EClear);
  • trunk/WebCore/rendering/RenderBlockLineLayout.cpp

    r68957 r69082  
    960960                        int floatTop = floats[floatIndex].rect.y();
    961961                        curr->markDirty();
    962                         markLinesDirtyInVerticalRange(curr->blockHeight(), floatTop + max(floats[floatIndex].rect.height(), newSize.height()), curr);
     962                        markLinesDirtyInBlockRange(curr->blockHeight(), floatTop + max(floats[floatIndex].rect.height(), newSize.height()), curr);
    963963                        floats[floatIndex].rect.setSize(newSize);
    964964                        dirtiedByFloat = true;
Note: See TracChangeset for help on using the changeset viewer.