Changeset 21093 in webkit


Ignore:
Timestamp:
Apr 25, 2007 12:10:24 PM (17 years ago)
Author:
hyatt
Message:

Rearchitect calcPrefWidths. The calculation is now done lazily only when minPrefWidth
or maxPrefWidth are asked for. The result of the calculation is cached.

The new invalidation scheme for pref width invalidation follows the
containing block hierarchy and knows to halt at positioned objects, since
they cannot influence the size of their containers.

Reviewed by darin

  • css/cssstyleselector.cpp: (WebCore::CSSStyleSelector::init): (WebCore::CSSStyleSelector::initForStyleResolve):
  • page/FrameView.cpp: (WebCore::FrameView::layout):
  • rendering/RenderApplet.cpp: (WebCore::RenderApplet::layout):
  • rendering/RenderBlock.cpp: (WebCore::RenderBlock::makeChildrenNonInline): (WebCore::RenderBlock::removeChild): (WebCore::RenderBlock::layout): (WebCore::RenderBlock::layoutBlock): (WebCore::RenderBlock::calcPrefWidths): (WebCore::InlineMinMaxIterator::endOfInline): (WebCore::shouldGrowTableCellForImage): (WebCore::RenderBlock::calcInlinePrefWidths): (WebCore::RenderBlock::calcBlockPrefWidths):
  • rendering/RenderBlock.h:
  • rendering/RenderBox.cpp: (WebCore::RenderBox::setStyle): (WebCore::RenderBox::minPrefWidth): (WebCore::RenderBox::maxPrefWidth): (WebCore::RenderBox::calcWidth): (WebCore::RenderBox::calcWidthUsing): (WebCore::RenderBox::calcAbsoluteHorizontal): (WebCore::RenderBox::calcAbsoluteHorizontalValues):
  • rendering/RenderBox.h:
  • rendering/RenderContainer.cpp: (WebCore::RenderContainer::removeChildNode): (WebCore::RenderContainer::appendChildNode): (WebCore::RenderContainer::insertChildNode): (WebCore::RenderContainer::layout):
  • rendering/RenderContainer.h: (WebCore::RenderContainer::moveChildNode):
  • rendering/RenderCounter.cpp: (WebCore::RenderCounter::dirtyLineBoxes): (WebCore::RenderCounter::calcPrefWidths):
  • rendering/RenderCounter.h:
  • rendering/RenderFileUploadControl.cpp: (WebCore::RenderFileUploadControl::calcPrefWidths):
  • rendering/RenderFlexibleBox.cpp: (WebCore::RenderFlexibleBox::calcHorizontalPrefWidths): (WebCore::RenderFlexibleBox::calcVerticalPrefWidths): (WebCore::RenderFlexibleBox::calcPrefWidths): (WebCore::RenderFlexibleBox::layoutBlock):
  • rendering/RenderForeignObject.cpp: (WebCore::RenderForeignObject::layout):
  • rendering/RenderFrameSet.cpp: (WebCore::RenderFrameSet::layout):
  • rendering/RenderHTMLCanvas.cpp: (WebCore::RenderHTMLCanvas::layout):
  • rendering/RenderImage.cpp: (WebCore::RenderImage::layout):
  • rendering/RenderInline.cpp:
  • rendering/RenderInline.h:
  • rendering/RenderListBox.cpp: (WebCore::RenderListBox::updateFromElement): (WebCore::RenderListBox::calcPrefWidths):
  • rendering/RenderListItem.cpp: (WebCore::firstNonMarkerChild): (WebCore::RenderListItem::updateMarkerLocation): (WebCore::RenderListItem::calcPrefWidths): (WebCore::RenderListItem::layout):
  • rendering/RenderListMarker.cpp: (WebCore::RenderListMarker::layout): (WebCore::RenderListMarker::calcPrefWidths): (WebCore::RenderListMarker::updateMargins):
  • rendering/RenderListMarker.h:
  • rendering/RenderObject.cpp: (WebCore::RenderObject::RenderObject): (WebCore::RenderObject::removeChildNode): (WebCore::RenderObject::moveChildNode): (WebCore::RenderObject::appendChildNode): (WebCore::RenderObject::insertChildNode): (WebCore::RenderObject::setPrefWidthsDirty): (WebCore::RenderObject::invalidateContainingBlockPrefWidths): (WebCore::RenderObject::information): (WebCore::RenderObject::setStyle):
  • rendering/RenderObject.h: (WebCore::RenderObject::layer): (WebCore::RenderObject::hasLayer): (WebCore::RenderObject::prefWidthsDirty): (WebCore::RenderObject::setNeedsLayoutAndPrefWidthsRecalc): (WebCore::RenderObject::setHasLayer):
  • rendering/RenderPartObject.cpp: (WebCore::RenderPartObject::layout):
  • rendering/RenderSVGContainer.cpp: (WebCore::RenderSVGContainer::layout):
  • rendering/RenderSVGContainer.h:
  • rendering/RenderSVGHiddenContainer.cpp:
  • rendering/RenderSVGHiddenContainer.h:
  • rendering/RenderSVGText.cpp: (WebCore::RenderSVGText::layout):
  • rendering/RenderTable.cpp: (WebCore::RenderTable::calcWidth): (WebCore::RenderTable::layout): (WebCore::RenderTable::removeChildNode):
  • rendering/RenderTable.h:
  • rendering/RenderTableRow.cpp: (WebCore::RenderTableRow::layout):
  • rendering/RenderTableSection.cpp: (WebCore::RenderTableSection::removeChildNode):
  • rendering/RenderTableSection.h:
  • rendering/RenderText.cpp: (WebCore::RenderText::trimmedPrefWidths): (WebCore::isSpaceAccordingToStyle): (WebCore::RenderText::minPrefWidth): (WebCore::RenderText::maxPrefWidth): (WebCore::RenderText::calcPrefWidths): (WebCore::RenderText::width):
  • rendering/RenderText.h:
  • rendering/RenderView.cpp: (WebCore::RenderView::RenderView): (WebCore::RenderView::calcPrefWidths): (WebCore::RenderView::layout):
  • rendering/RenderWidget.cpp: (WebCore::RenderWidget::layout):
Location:
trunk/WebCore
Files:
40 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r21092 r21093  
     12007-04-25  David Hyatt  <hyatt@apple.com>
     2
     3        Rearchitect calcPrefWidths.  The calculation is now done lazily only when minPrefWidth
     4        or maxPrefWidth are asked for.  The result of the calculation is cached.
     5
     6        The new invalidation scheme for pref width invalidation follows the
     7        containing block hierarchy and knows to halt at positioned objects, since
     8        they cannot influence the size of their containers.
     9
     10        Reviewed by darin
     11
     12        * css/cssstyleselector.cpp:
     13        (WebCore::CSSStyleSelector::init):
     14        (WebCore::CSSStyleSelector::initForStyleResolve):
     15        * page/FrameView.cpp:
     16        (WebCore::FrameView::layout):
     17        * rendering/RenderApplet.cpp:
     18        (WebCore::RenderApplet::layout):
     19        * rendering/RenderBlock.cpp:
     20        (WebCore::RenderBlock::makeChildrenNonInline):
     21        (WebCore::RenderBlock::removeChild):
     22        (WebCore::RenderBlock::layout):
     23        (WebCore::RenderBlock::layoutBlock):
     24        (WebCore::RenderBlock::calcPrefWidths):
     25        (WebCore::InlineMinMaxIterator::endOfInline):
     26        (WebCore::shouldGrowTableCellForImage):
     27        (WebCore::RenderBlock::calcInlinePrefWidths):
     28        (WebCore::RenderBlock::calcBlockPrefWidths):
     29        * rendering/RenderBlock.h:
     30        * rendering/RenderBox.cpp:
     31        (WebCore::RenderBox::setStyle):
     32        (WebCore::RenderBox::minPrefWidth):
     33        (WebCore::RenderBox::maxPrefWidth):
     34        (WebCore::RenderBox::calcWidth):
     35        (WebCore::RenderBox::calcWidthUsing):
     36        (WebCore::RenderBox::calcAbsoluteHorizontal):
     37        (WebCore::RenderBox::calcAbsoluteHorizontalValues):
     38        * rendering/RenderBox.h:
     39        * rendering/RenderContainer.cpp:
     40        (WebCore::RenderContainer::removeChildNode):
     41        (WebCore::RenderContainer::appendChildNode):
     42        (WebCore::RenderContainer::insertChildNode):
     43        (WebCore::RenderContainer::layout):
     44        * rendering/RenderContainer.h:
     45        (WebCore::RenderContainer::moveChildNode):
     46        * rendering/RenderCounter.cpp:
     47        (WebCore::RenderCounter::dirtyLineBoxes):
     48        (WebCore::RenderCounter::calcPrefWidths):
     49        * rendering/RenderCounter.h:
     50        * rendering/RenderFileUploadControl.cpp:
     51        (WebCore::RenderFileUploadControl::calcPrefWidths):
     52        * rendering/RenderFlexibleBox.cpp:
     53        (WebCore::RenderFlexibleBox::calcHorizontalPrefWidths):
     54        (WebCore::RenderFlexibleBox::calcVerticalPrefWidths):
     55        (WebCore::RenderFlexibleBox::calcPrefWidths):
     56        (WebCore::RenderFlexibleBox::layoutBlock):
     57        * rendering/RenderForeignObject.cpp:
     58        (WebCore::RenderForeignObject::layout):
     59        * rendering/RenderFrameSet.cpp:
     60        (WebCore::RenderFrameSet::layout):
     61        * rendering/RenderHTMLCanvas.cpp:
     62        (WebCore::RenderHTMLCanvas::layout):
     63        * rendering/RenderImage.cpp:
     64        (WebCore::RenderImage::layout):
     65        * rendering/RenderInline.cpp:
     66        * rendering/RenderInline.h:
     67        * rendering/RenderListBox.cpp:
     68        (WebCore::RenderListBox::updateFromElement):
     69        (WebCore::RenderListBox::calcPrefWidths):
     70        * rendering/RenderListItem.cpp:
     71        (WebCore::firstNonMarkerChild):
     72        (WebCore::RenderListItem::updateMarkerLocation):
     73        (WebCore::RenderListItem::calcPrefWidths):
     74        (WebCore::RenderListItem::layout):
     75        * rendering/RenderListMarker.cpp:
     76        (WebCore::RenderListMarker::layout):
     77        (WebCore::RenderListMarker::calcPrefWidths):
     78        (WebCore::RenderListMarker::updateMargins):
     79        * rendering/RenderListMarker.h:
     80        * rendering/RenderObject.cpp:
     81        (WebCore::RenderObject::RenderObject):
     82        (WebCore::RenderObject::removeChildNode):
     83        (WebCore::RenderObject::moveChildNode):
     84        (WebCore::RenderObject::appendChildNode):
     85        (WebCore::RenderObject::insertChildNode):
     86        (WebCore::RenderObject::setPrefWidthsDirty):
     87        (WebCore::RenderObject::invalidateContainingBlockPrefWidths):
     88        (WebCore::RenderObject::information):
     89        (WebCore::RenderObject::setStyle):
     90        * rendering/RenderObject.h:
     91        (WebCore::RenderObject::layer):
     92        (WebCore::RenderObject::hasLayer):
     93        (WebCore::RenderObject::prefWidthsDirty):
     94        (WebCore::RenderObject::setNeedsLayoutAndPrefWidthsRecalc):
     95        (WebCore::RenderObject::setHasLayer):
     96        * rendering/RenderPartObject.cpp:
     97        (WebCore::RenderPartObject::layout):
     98        * rendering/RenderSVGContainer.cpp:
     99        (WebCore::RenderSVGContainer::layout):
     100        * rendering/RenderSVGContainer.h:
     101        * rendering/RenderSVGHiddenContainer.cpp:
     102        * rendering/RenderSVGHiddenContainer.h:
     103        * rendering/RenderSVGText.cpp:
     104        (WebCore::RenderSVGText::layout):
     105        * rendering/RenderTable.cpp:
     106        (WebCore::RenderTable::calcWidth):
     107        (WebCore::RenderTable::layout):
     108        (WebCore::RenderTable::removeChildNode):
     109        * rendering/RenderTable.h:
     110        * rendering/RenderTableRow.cpp:
     111        (WebCore::RenderTableRow::layout):
     112        * rendering/RenderTableSection.cpp:
     113        (WebCore::RenderTableSection::removeChildNode):
     114        * rendering/RenderTableSection.h:
     115        * rendering/RenderText.cpp:
     116        (WebCore::RenderText::trimmedPrefWidths):
     117        (WebCore::isSpaceAccordingToStyle):
     118        (WebCore::RenderText::minPrefWidth):
     119        (WebCore::RenderText::maxPrefWidth):
     120        (WebCore::RenderText::calcPrefWidths):
     121        (WebCore::RenderText::width):
     122        * rendering/RenderText.h:
     123        * rendering/RenderView.cpp:
     124        (WebCore::RenderView::RenderView):
     125        (WebCore::RenderView::calcPrefWidths):
     126        (WebCore::RenderView::layout):
     127        * rendering/RenderWidget.cpp:
     128        (WebCore::RenderWidget::layout):
     129
    11302007-04-25  Steve Falkenburg  <sfalken@apple.com>
    2131
     
    494623        <rdar://problem/4966982> 64-bit: In a unordered list, TYPE=DISC and TYPE=CIRCLE attribute values are ignored
    495624
    496         We need to draw our full-circle arcs counter-clockwise, since a clockwise arc from 0 to 2π is no arc at all!
     625        We need to draw our full-circle arcs counter-clockwise, since a clockwise arc from 0 to 2π is no arc at all!
    497626        This only worked on 32-bit due to a rounding error in CoreGraphics, causing it to draw a full circle anyway.
    498627
  • trunk/WebCore/css/cssstyleselector.cpp

    r21061 r21093  
    302302    element = 0;
    303303    settings = 0;
    304     m_matchedRules.clear();
    305304    m_matchedDecls.clear();
    306305    m_ruleList = 0;
     
    565564    style = 0;
    566565   
    567     m_matchedRules.clear();
    568566    m_matchedDecls.clear();
    569567
  • trunk/WebCore/page/FrameView.cpp

    r20964 r21093  
    411411    }
    412412
    413     if (subtree) {
    414         if (root->recalcMinMax())
    415             root->recalcMinMaxWidths();
    416     }
    417413    pauseScheduledEvents();
    418414    root->layout();
  • trunk/WebCore/rendering/RenderApplet.cpp

    r21079 r21093  
    9696{
    9797    ASSERT(needsLayout());
    98     ASSERT(!prefWidthsDirty());
    9998
    10099    calcWidth();
  • trunk/WebCore/rendering/RenderBlock.cpp

    r21082 r21093  
    326326            RenderObject* no = o;
    327327            o = no->nextSibling();
    328             box->appendChildNode(removeChildNode(no));
    329         }
    330         box->appendChildNode(removeChildNode(inlineRunEnd));
     328            box->moveChildNode(no);
     329        }
     330        box->moveChildNode(inlineRunEnd);
    331331    }
    332332
     
    356356            RenderObject* no = o;
    357357            o = no->nextSibling();
    358             prev->appendChildNode(next->removeChildNode(no));
    359             no->setNeedsLayoutAndPrefWidthsRecalc();
     358            prev->moveChildNode(no);
    360359        }
    361360 
     
    381380            RenderObject* no = o;
    382381            o = no->nextSibling();
    383             appendChildNode(anonBlock->removeChildNode(no));
    384             no->setNeedsLayoutAndPrefWidthsRecalc();
     382            moveChildNode(no);
    385383        }
    386384
     
    465463void RenderBlock::layout()
    466464{
     465    // Update our first letter info now.
     466    updateFirstLetter();
     467
    467468    // Table cells call layoutBlock directly, so don't add any logic here.  Put code into
    468469    // layoutBlock().
     
    482483{
    483484    ASSERT(needsLayout());
    484     ASSERT(!prefWidthsDirty());
    485485
    486486    if (isInline() && !isInlineBlockOrInlineTable()) // Inline <form>s inside various table elements can
     
    32523252    ASSERT(prefWidthsDirty());
    32533253
     3254    updateFirstLetter();
     3255
    32543256    if (!isTableCell() && style()->width().isFixed() && style()->width().value() > 0)
    32553257        m_minPrefWidth = m_maxPrefWidth = calcContentBoxWidth(style()->width().value());
     
    32743276
    32753277        if (isTableCell()) {
    3276             Length w = static_cast<RenderTableCell*>(this)->styleOrColWidth();
     3278            Length w = static_cast<const RenderTableCell*>(this)->styleOrColWidth();
    32773279            if (w.isFixed() && w.value() > 0)
    32783280                m_maxPrefWidth = max(m_minPrefWidth, calcContentBoxWidth(w.value()));
     
    33133315    bool endOfInline;
    33143316
    3315     InlineMinMaxIterator(RenderObject* p, RenderObject* o, bool end = false)
    3316         :parent(p), current(o), endOfInline(end) {}
     3317    InlineMinMaxIterator(RenderObject* p, bool end = false)
     3318        :parent(p), current(p), endOfInline(end) {}
    33173319
    33183320    RenderObject* next();
     
    34043406// very specific cirucumstances. Not supporting the quirk has caused us to
    34053407// mis-render some real sites. (See Bugzilla 10517.)
    3406 static bool shouldGrowTableCellForImage(RenderBlock* containingBlock, RenderObject* image, RenderObject* adjacentLeaf)
     3408static bool shouldGrowTableCellForImage(const RenderBlock* containingBlock, const RenderObject* image, const RenderObject* adjacentLeaf)
    34073409{
    34083410    if (!containingBlock->style()->htmlHacks())
     
    34393441    autoWrap = oldAutoWrap = style()->autoWrap();
    34403442
    3441     InlineMinMaxIterator childIterator(this, this);
     3443    InlineMinMaxIterator childIterator(this);
    34423444    bool addedTextIndent = false; // Only gets added in once.
    34433445    RenderObject* prevFloat = 0;
    34443446    RenderObject* previousLeaf = 0;
    3445     while (RenderObject* child = childIterator.next())
    3446     {
     3447    while (RenderObject* child = childIterator.next()) {
    34473448        InlineMinMaxIterator leafIterator = childIterator;
    34483449        RenderObject* nextLeaf = leafIterator.next();
     
    35103511                    Length leftMargin = cstyle->marginLeft();
    35113512                    Length rightMargin = cstyle->marginRight();
    3512                     bool useCalculatedWidths = child->isListMarker();
    3513                     if (leftMargin.isPercent() || rightMargin.isPercent() || useCalculatedWidths)
    3514                         child->calcWidth();
    3515                     if (useCalculatedWidths || leftMargin.isPercent())
    3516                         margins += child->marginLeft();
    3517                     else if (leftMargin.isFixed())
     3513                    if (leftMargin.isFixed())
    35183514                        margins += leftMargin.value();
    3519                     if (useCalculatedWidths || rightMargin.isPercent())
    3520                         margins += child->marginRight();
    3521                     else if (rightMargin.isFixed())
     3515                    if (rightMargin.isFixed())
    35223516                        margins += rightMargin.value();
    35233517                    childMin += margins;
     
    37103704        }
    37113705
     3706        // A margin basically has three types: fixed, percentage, and auto (variable).
     3707        // Auto and percentage margins simply become 0 when computing min/max width.
     3708        // Fixed margins can be added in as is.
    37123709        Length ml = child->style()->marginLeft();
    37133710        Length mr = child->style()->marginRight();
    3714 
    3715         // Call calcWidth on the child to ensure that our margins are
    3716         // up to date.  This method can be called before the child has actually
    3717         // calculated its margins (which are computed inside calcWidth).
    3718         if (ml.isPercent() || mr.isPercent())
    3719             calcWidth();
    3720 
    3721         // A margin basically has three types: fixed, percentage, and auto (variable).
    3722         // Auto margins simply become 0 when computing min/max width.
    3723         // Fixed margins can be added in as is.
    3724         // Percentage margins are computed as a percentage of the width we calculated in
    3725         // the calcWidth call above.  In this case we use the actual cached margin values on
    3726         // the RenderObject itself.
    37273711        int margin = 0, marginLeft = 0, marginRight = 0;
    37283712        if (ml.isFixed())
    37293713            marginLeft += ml.value();
    3730         else if (ml.isPercent())
    3731             marginLeft += child->marginLeft();
    37323714        if (mr.isFixed())
    37333715            marginRight += mr.value();
    3734         else if (mr.isPercent())
    3735             marginRight += child->marginRight();
    37363716        margin = marginLeft + marginRight;
    37373717
  • trunk/WebCore/rendering/RenderBox.cpp

    r21079 r21093  
    117117                setChildNeedsLayout(true);
    118118            m_layer = new (renderArena()) RenderLayer(this);
     119            setHasLayer(true);
    119120            m_layer->insertOnlyThisLayer();
    120121            if (parent() && !needsLayout() && containingBlock())
     
    125126        RenderLayer* layer = m_layer;
    126127        m_layer = 0;
     128        setHasLayer(false);
    127129        layer->removeOnlyThisLayer();
    128130        if (wasFloating && isFloating())
     
    165167    if (layer)
    166168        layer->destroy(arena);
     169}
     170
     171int RenderBox::minPrefWidth() const
     172{
     173    if (prefWidthsDirty())
     174        const_cast<RenderBox*>(this)->calcPrefWidths();
     175       
     176    return m_minPrefWidth;
     177}
     178
     179int RenderBox::maxPrefWidth() const
     180{
     181    if (prefWidthsDirty())
     182        const_cast<RenderBox*>(this)->calcPrefWidths();
     183       
     184    return m_maxPrefWidth;
    167185}
    168186
     
    10581076        m_marginRight = marginRight.calcMinValue(containerWidth);
    10591077        if (treatAsReplaced)
    1060             m_width = max(width.value() + borderLeft() + borderRight() + paddingLeft() + paddingRight(), m_minPrefWidth);
     1078            m_width = max(width.value() + borderLeft() + borderRight() + paddingLeft() + paddingRight(), minPrefWidth());
    10611079
    10621080        return;
     
    10871105    }
    10881106
    1089     if (m_width < m_minPrefWidth && stretchesToMinIntrinsicWidth()) {
    1090         m_width = m_minPrefWidth;
     1107    if (stretchesToMinIntrinsicWidth()) {
     1108        m_width = max(m_width, minPrefWidth());
    10911109        width = Length(m_width, Fixed);
    10921110    }
     
    11291147
    11301148        if (sizesToIntrinsicWidth(widthType)) {
    1131             width = max(width, m_minPrefWidth);
    1132             width = min(width, m_maxPrefWidth);
     1149            width = max(width, minPrefWidth());
     1150            width = min(width, maxPrefWidth());
    11331151        }
    11341152    } else
     
    16651683    }
    16661684
    1667     if (m_width < m_minPrefWidth - bordersPlusPadding && stretchesToMinIntrinsicWidth())
    1668         calcAbsoluteHorizontalValues(Length(m_minPrefWidth - bordersPlusPadding, Fixed), containerBlock, containerDirection,
     1685    if (stretchesToMinIntrinsicWidth() && m_width < minPrefWidth() - bordersPlusPadding)
     1686        calcAbsoluteHorizontalValues(Length(minPrefWidth() - bordersPlusPadding, Fixed), containerBlock, containerDirection,
    16691687                                     containerWidth, bordersPlusPadding,
    16701688                                     left, right, marginLeft, marginRight,
     
    17991817
    18001818            // FIXME: would it be better to have shrink-to-fit in one step?
    1801             int preferredWidth = m_maxPrefWidth - bordersPlusPadding;
    1802             int preferredMinWidth = m_minPrefWidth - bordersPlusPadding;
     1819            int preferredWidth = maxPrefWidth() - bordersPlusPadding;
     1820            int preferredMinWidth = minPrefWidth() - bordersPlusPadding;
    18031821            int availableWidth = availableSpace - rightValue;
    18041822            widthValue = min(max(preferredMinWidth, availableWidth), preferredWidth);
     
    18091827
    18101828            // FIXME: would it be better to have shrink-to-fit in one step?
    1811             int preferredWidth = m_maxPrefWidth - bordersPlusPadding;
    1812             int preferredMinWidth = m_minPrefWidth - bordersPlusPadding;
     1829            int preferredWidth = maxPrefWidth() - bordersPlusPadding;
     1830            int preferredMinWidth = minPrefWidth() - bordersPlusPadding;
    18131831            int availableWidth = availableSpace - leftValue;
    18141832            widthValue = min(max(preferredMinWidth, availableWidth), preferredWidth);
  • trunk/WebCore/rendering/RenderBox.h

    r21079 r21093  
    4343    virtual void destroy();
    4444
    45     virtual int minPrefWidth() const { return m_minPrefWidth; }
    46     virtual int maxPrefWidth() const { return m_maxPrefWidth; }
     45    virtual int minPrefWidth() const;
     46    virtual int maxPrefWidth() const;
    4747
    4848    virtual int overrideSize() const;
     
    183183    void calcAbsoluteHorizontalReplaced();
    184184
     185    // This function calculates the minimum and maximum preferred widths for an object.
     186    // These values are used in shrink-to-fit layout systems.
     187    // These include tables, positioned objects, floats and flexible boxes.
     188    virtual void calcPrefWidths() = 0;
     189
    185190protected:
    186191    // The width/height of the contents + borders + padding.
  • trunk/WebCore/rendering/RenderContainer.cpp

    r21082 r21093  
    157157}
    158158
    159 RenderObject* RenderContainer::removeChildNode(RenderObject* oldChild)
     159RenderObject* RenderContainer::removeChildNode(RenderObject* oldChild, bool fullRemove)
    160160{
    161161    ASSERT(oldChild->parent() == this);
     
    164164    // that a positioned child got yanked).  We also repaint, so that the area exposed when the child
    165165    // disappears gets repainted properly.
    166     if (!documentBeingDestroyed()) {
     166    if (!documentBeingDestroyed() && fullRemove) {
    167167        oldChild->setNeedsLayoutAndPrefWidthsRecalc();
    168168        oldChild->repaint();
     
    172172    oldChild->deleteLineBoxWrapper();
    173173
    174     if (!documentBeingDestroyed()) {
     174    if (!documentBeingDestroyed() && fullRemove) {
    175175        // if we remove visible child from an invisible parent, we don't know the layer visibility any more
    176176        RenderLayer* layer = 0;
     
    376376
    377377
    378 void RenderContainer::appendChildNode(RenderObject* newChild)
     378void RenderContainer::appendChildNode(RenderObject* newChild, bool fullAppend)
    379379{
    380380    ASSERT(newChild->parent() == 0);
     
    392392    m_lastChild = newChild;
    393393   
    394     // Keep our layer hierarchy updated.  Optimize for the common case where we don't have any children
    395     // and don't have a layer attached to ourselves.
    396     RenderLayer* layer = 0;
    397     if (newChild->firstChild() || newChild->hasLayer()) {
    398         layer = enclosingLayer();
    399         newChild->addLayers(layer, newChild);
    400     }
    401 
    402     // if the new child is visible but this object was not, tell the layer it has some visible content
    403     // that needs to be drawn and layer visibility optimization can't be used
    404     if (style()->visibility() != VISIBLE && newChild->style()->visibility() == VISIBLE && !newChild->hasLayer()) {
    405         if (!layer)
     394    if (fullAppend) {
     395        // Keep our layer hierarchy updated.  Optimize for the common case where we don't have any children
     396        // and don't have a layer attached to ourselves.
     397        RenderLayer* layer = 0;
     398        if (newChild->firstChild() || newChild->hasLayer()) {
    406399            layer = enclosingLayer();
    407         if (layer)
    408             layer->setHasVisibleContent(true);
    409     }
    410    
     400            newChild->addLayers(layer, newChild);
     401        }
     402
     403        // if the new child is visible but this object was not, tell the layer it has some visible content
     404        // that needs to be drawn and layer visibility optimization can't be used
     405        if (style()->visibility() != VISIBLE && newChild->style()->visibility() == VISIBLE && !newChild->hasLayer()) {
     406            if (!layer)
     407                layer = enclosingLayer();
     408            if (layer)
     409                layer->setHasVisibleContent(true);
     410        }
     411       
     412        if (!newChild->isFloatingOrPositioned() && childrenInline())
     413            dirtyLinesFromChangedChild(newChild);
     414    }
     415
    411416    newChild->setNeedsLayoutAndPrefWidthsRecalc(); // Goes up the containing block hierarchy.
    412417    if (!normalChildNeedsLayout())
    413418        setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child.
    414419   
    415     if (!newChild->isFloatingOrPositioned() && childrenInline())
    416         dirtyLinesFromChangedChild(newChild);
    417    
    418420    if (AXObjectCache::accessibilityEnabled())
    419421        document()->axObjectCache()->childrenChanged(this);
    420422}
    421423
    422 void RenderContainer::insertChildNode(RenderObject* child, RenderObject* beforeChild)
     424void RenderContainer::insertChildNode(RenderObject* child, RenderObject* beforeChild, bool fullInsert)
    423425{
    424426    if (!beforeChild) {
     
    445447    child->setParent(this);
    446448   
    447     // Keep our layer hierarchy updated.  Optimize for the common case where we don't have any children
    448     // and don't have a layer attached to ourselves.
    449     RenderLayer* layer = 0;
    450     if (child->firstChild() || child->hasLayer()) {
    451         layer = enclosingLayer();
    452         child->addLayers(layer, child);
    453     }
    454 
    455     // if the new child is visible but this object was not, tell the layer it has some visible content
    456     // that needs to be drawn and layer visibility optimization can't be used
    457     if (style()->visibility() != VISIBLE && child->style()->visibility() == VISIBLE && !child->hasLayer()) {
    458         if (!layer)
     449    if (fullInsert) {
     450        // Keep our layer hierarchy updated.  Optimize for the common case where we don't have any children
     451        // and don't have a layer attached to ourselves.
     452        RenderLayer* layer = 0;
     453        if (child->firstChild() || child->hasLayer()) {
    459454            layer = enclosingLayer();
    460         if (layer)
    461             layer->setHasVisibleContent(true);
     455            child->addLayers(layer, child);
     456        }
     457
     458        // if the new child is visible but this object was not, tell the layer it has some visible content
     459        // that needs to be drawn and layer visibility optimization can't be used
     460        if (style()->visibility() != VISIBLE && child->style()->visibility() == VISIBLE && !child->hasLayer()) {
     461            if (!layer)
     462                layer = enclosingLayer();
     463            if (layer)
     464                layer->setHasVisibleContent(true);
     465        }
     466
     467       
     468        if (!child->isFloating() && childrenInline())
     469            dirtyLinesFromChangedChild(child);
    462470    }
    463471
     
    466474        setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child.
    467475   
    468     if (!child->isFloating() && childrenInline())
    469         dirtyLinesFromChangedChild(child);
    470    
    471476    if (AXObjectCache::accessibilityEnabled())
    472477        document()->axObjectCache()->childrenChanged(this);
     
    476481{
    477482    ASSERT(needsLayout());
    478     ASSERT(!prefWidthsDirty());
    479483
    480484    RenderObject* child = m_firstChild;
  • trunk/WebCore/rendering/RenderContainer.h

    r21079 r21093  
    4242    void destroyLeftoverChildren();
    4343
    44     virtual RenderObject* removeChildNode(RenderObject*);
    45     virtual void appendChildNode(RenderObject*);
    46     virtual void insertChildNode(RenderObject* child, RenderObject* before);
    47 
     44    virtual RenderObject* removeChildNode(RenderObject*, bool fullRemove = true);
     45    virtual void appendChildNode(RenderObject*, bool fullAppend = true);
     46    virtual void insertChildNode(RenderObject* child, RenderObject* before, bool fullInsert = true);
     47   
     48    // Designed for speed.  Don't waste time doing a bunch of work like layer updating and repainting when we know that our
     49    // change in parentage is not going to affect anything.
     50    virtual void moveChildNode(RenderObject* child) { appendChildNode(child->parent()->removeChildNode(child, false), false); }
     51   
    4852    virtual void layout();
    4953    virtual void calcPrefWidths() { setPrefWidthsDirty(false); }
  • trunk/WebCore/rendering/RenderCounter.cpp

    r21079 r21093  
    245245}
    246246
    247 void RenderCounter::calcPrefWidths()
     247void RenderCounter::dirtyLineBoxes(bool fullLayout, bool dummy)
     248{
     249    if (prefWidthsDirty())
     250        calcPrefWidths(0);
     251    RenderText::dirtyLineBoxes(fullLayout, dummy);
     252}
     253
     254void RenderCounter::calcPrefWidths(int lead)
    248255{
    249256    setTextInternal(originalText());
    250     RenderText::calcPrefWidths();
     257    RenderText::calcPrefWidths(lead);
    251258}
    252259
  • trunk/WebCore/rendering/RenderCounter.h

    r21079 r21093  
    3636    virtual bool isRenderCounter() const;
    3737    virtual PassRefPtr<StringImpl> originalText() const;
    38     virtual void calcPrefWidths();
     38   
     39    virtual void dirtyLineBoxes(bool, bool);
     40    virtual void calcPrefWidths(int leadWidth);
    3941
    4042    static void destroyCounterNodes(RenderObject*);
  • trunk/WebCore/rendering/RenderFileUploadControl.cpp

    r21079 r21093  
    232232void RenderFileUploadControl::calcPrefWidths()
    233233{
     234    ASSERT(prefWidthsDirty());
     235
    234236    m_minPrefWidth = 0;
    235237    m_maxPrefWidth = 0;
  • trunk/WebCore/rendering/RenderFlexibleBox.cpp

    r21082 r21093  
    120120        }
    121121
    122         int margin=0;
    123         //  auto margins don't affect minwidth
    124 
     122        // A margin basically has three types: fixed, percentage, and auto (variable).
     123        // Auto and percentage margins simply become 0 when computing min/max width.
     124        // Fixed margins can be added in as is.
    125125        Length ml = child->style()->marginLeft();
    126126        Length mr = child->style()->marginRight();
    127 
    128         // Call calcWidth on the child to ensure that our margins are
    129         // up to date.  This method can be called before the child has actually
    130         // calculated its margins (which are computed inside calcWidth).
    131         child->calcWidth();
    132 
    133         if (!ml.isAuto() && !mr.isAuto()) {
    134             if (!child->style()->width().isAuto()) {
    135                 if (child->style()->direction()==LTR)
    136                     margin = child->marginLeft();
    137                 else
    138                     margin = child->marginRight();
    139             } else
    140                 margin = child->marginLeft()+child->marginRight();
    141         } else if (!ml.isAuto())
    142             margin = child->marginLeft();
    143         else if (!mr.isAuto())
    144             margin = child->marginRight();
    145 
    146         margin = max(margin, 0);
     127        int margin = 0, marginLeft = 0, marginRight = 0;
     128        if (ml.isFixed())
     129            marginLeft += ml.value();
     130        if (mr.isFixed())
     131            marginRight += mr.value();
     132        margin = marginLeft + marginRight;
    147133
    148134        m_minPrefWidth += child->minPrefWidth() + margin;
     
    164150        }
    165151
     152        // A margin basically has three types: fixed, percentage, and auto (variable).
     153        // Auto/percentage margins simply become 0 when computing min/max width.
     154        // Fixed margins can be added in as is.
    166155        Length ml = child->style()->marginLeft();
    167156        Length mr = child->style()->marginRight();
    168 
    169         // Call calcWidth on the child to ensure that our margins are
    170         // up to date.  This method can be called before the child has actually
    171         // calculated its margins (which are computed inside calcWidth).
    172         if (ml.isPercent() || mr.isPercent())
    173             calcWidth();
    174 
    175         // A margin basically has three types: fixed, percentage, and auto (variable).
    176         // Auto margins simply become 0 when computing min/max width.
    177         // Fixed margins can be added in as is.
    178         // Percentage margins are computed as a percentage of the width we calculated in
    179         // the calcWidth call above.  In this case we use the actual cached margin values on
    180         // the RenderObject itself.
    181157        int margin = 0;
    182158        if (ml.isFixed())
    183159            margin += ml.value();
    184         else if (ml.isPercent())
    185             margin += child->marginLeft();
    186 
    187160        if (mr.isFixed())
    188161            margin += mr.value();
    189         else if (mr.isAuto())
    190             margin += child->marginRight();
    191 
    192         margin = max(margin, 0);
    193162       
    194163        int w = child->minPrefWidth() + margin;
     
    206175    ASSERT(prefWidthsDirty());
    207176
    208     m_minPrefWidth = 0;
    209     m_maxPrefWidth = 0;
    210 
    211     if (hasMultipleLines() || isVertical())
    212         calcVerticalPrefWidths();
    213     else
    214         calcHorizontalPrefWidths();
    215 
    216     m_maxPrefWidth = max(m_maxPrefWidth, m_minPrefWidth);
    217 
    218177    if (style()->width().isFixed() && style()->width().value() > 0)
    219178        m_minPrefWidth = m_maxPrefWidth = calcContentBoxWidth(style()->width().value());
    220    
     179    else {
     180        m_minPrefWidth = m_maxPrefWidth = 0;
     181
     182        if (hasMultipleLines() || isVertical())
     183            calcVerticalPrefWidths();
     184        else
     185            calcHorizontalPrefWidths();
     186
     187        m_maxPrefWidth = max(m_minPrefWidth, m_maxPrefWidth);
     188    }
     189
    221190    if (style()->minWidth().isFixed() && style()->minWidth().value() > 0) {
    222191        m_maxPrefWidth = max(m_maxPrefWidth, calcContentBoxWidth(style()->minWidth().value()));
     
    239208{
    240209    ASSERT(needsLayout());
    241     ASSERT(!prefWidthsDirty());
    242210
    243211    if (!relayoutChildren && posChildNeedsLayout() && !normalChildNeedsLayout() && !selfNeedsLayout()) {
  • trunk/WebCore/rendering/RenderForeignObject.cpp

    r21079 r21093  
    8686{
    8787    ASSERT(needsLayout());
    88     ASSERT(!prefWidthsDirty());
    8988
    9089    IntRect oldBounds;
  • trunk/WebCore/rendering/RenderFrameSet.cpp

    r21079 r21093  
    454454{
    455455    ASSERT(needsLayout());
    456     ASSERT(!prefWidthsDirty());
    457456
    458457    if (!parent()->isFrameSet()) {
  • trunk/WebCore/rendering/RenderHTMLCanvas.cpp

    r21079 r21093  
    8080{
    8181    ASSERT(needsLayout());
    82     ASSERT(!prefWidthsDirty());
    8382
    8483    IntRect oldBounds;
  • trunk/WebCore/rendering/RenderImage.cpp

    r21079 r21093  
    304304{
    305305    ASSERT(needsLayout());
    306     ASSERT(!prefWidthsDirty());
    307306
    308307    IntRect oldBounds;
  • trunk/WebCore/rendering/RenderInline.cpp

    r21079 r21093  
    293293}
    294294
    295 void RenderInline::calcPrefWidths()
    296 {
    297     ASSERT(prefWidthsDirty());
    298 
    299     // Irrelevant, since some enclosing block will actually measure us and our children.
    300     m_minPrefWidth = 0;
    301     m_maxPrefWidth = 0;
    302 
    303     setPrefWidthsDirty(false);
    304 }
    305 
    306295bool RenderInline::requiresLayer()
    307296{
  • trunk/WebCore/rendering/RenderInline.h

    r21079 r21093  
    5959    virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
    6060
    61     virtual void calcPrefWidths();
    62 
    6361    // overrides RenderObject
    6462    virtual bool requiresLayer();
  • trunk/WebCore/rendering/RenderListBox.cpp

    r21079 r21093  
    119119        m_optionsWidth = static_cast<int>(ceilf(width));
    120120        m_optionsChanged = false;
     121       
     122        if (!m_vBar && Scrollbar::hasPlatformScrollbars())
     123            if (FrameView* view = node()->document()->view()) {
     124                RefPtr<PlatformScrollbar> widget = new PlatformScrollbar(this, VerticalScrollbar, SmallScrollbar);
     125                view->addChild(widget.get());
     126                m_vBar = widget.release();
     127            }
     128       
    121129        setNeedsLayoutAndPrefWidthsRecalc();
    122130    }
     
    154162void RenderListBox::calcPrefWidths()
    155163{
    156     if (!m_vBar && Scrollbar::hasPlatformScrollbars())
    157         if (FrameView* view = node()->document()->view()) {
    158             RefPtr<PlatformScrollbar> widget = new PlatformScrollbar(this, VerticalScrollbar, SmallScrollbar);
    159             view->addChild(widget.get());
    160             m_vBar = widget.release();
    161         }
    162 
    163     if (m_optionsChanged)
    164         updateFromElement();
     164    ASSERT(!m_optionsChanged);
    165165
    166166    m_minPrefWidth = 0;
  • trunk/WebCore/rendering/RenderListItem.cpp

    r21079 r21093  
    175175}
    176176
     177static RenderObject* firstNonMarkerChild(RenderObject* parent)
     178{
     179    RenderObject* result = parent->firstChild();
     180    while (result && result->isListMarker())
     181        result = result->nextSibling();
     182    return result;
     183}
     184
    177185void RenderListItem::updateMarkerLocation()
    178186{
     
    193201
    194202        if (markerPar != lineBoxParent || m_marker->prefWidthsDirty()) {
     203            updateFirstLetter();
    195204            m_marker->remove();
    196205            if (!lineBoxParent)
    197206                lineBoxParent = this;
    198             lineBoxParent->addChild(m_marker, lineBoxParent->firstChild());
     207            lineBoxParent->addChild(m_marker, firstNonMarkerChild(lineBoxParent));
    199208            if (m_marker->prefWidthsDirty())
    200209                m_marker->calcPrefWidths();
    201             recalcMinMaxWidths();
    202210        }
    203211    }
     
    206214void RenderListItem::calcPrefWidths()
    207215{
    208     // Make sure our marker is in the correct location.
     216    ASSERT(prefWidthsDirty());
     217   
    209218    updateMarkerLocation();
    210     if (prefWidthsDirty())
    211         RenderBlock::calcPrefWidths();
     219
     220    RenderBlock::calcPrefWidths();
    212221}
    213222
    214223void RenderListItem::layout()
    215224{
    216     ASSERT(needsLayout());
    217     ASSERT(!prefWidthsDirty());
    218    
     225    ASSERT(needsLayout());
     226
    219227    updateMarkerLocation();   
    220228    RenderBlock::layout();
  • trunk/WebCore/rendering/RenderListMarker.cpp

    r21079 r21093  
    627627{
    628628    ASSERT(needsLayout());
    629     if (prefWidthsDirty())
    630         calcPrefWidths();
     629    ASSERT(!prefWidthsDirty());
     630
     631    if (isImage()) {
     632        m_width = m_image->image()->width();
     633        m_height = m_image->image()->height();
     634    } else {
     635        m_width = minPrefWidth();
     636        m_height = style()->font().height();
     637    }
     638
     639    m_marginLeft = m_marginRight = 0;
     640
     641    Length leftMargin = style()->marginLeft();
     642    Length rightMargin = style()->marginRight();
     643    if (leftMargin.isFixed())
     644        m_marginLeft = leftMargin.value();
     645    if (rightMargin.isFixed())
     646        m_marginRight = rightMargin.value();
     647
    631648    setNeedsLayout(false);
    632649}
     
    651668
    652669    if (isImage()) {
    653         m_width = m_image->image()->width();
    654         m_height = m_image->image()->height();
    655         m_minPrefWidth = m_maxPrefWidth = m_width;
     670        m_minPrefWidth = m_maxPrefWidth = m_image->image()->width();
    656671        setPrefWidthsDirty(false);
     672        updateMargins();
    657673        return;
    658674    }
     
    700716    }
    701717
    702     m_width = width;
    703718    m_minPrefWidth = width;
    704719    m_maxPrefWidth = width;
    705720
    706     // FIXME: A little strange to set the height in calcPrefWidths.
    707     m_height = font.height();
    708 
    709721    setPrefWidthsDirty(false);
    710 }
    711 
    712 void RenderListMarker::calcWidth()
    713 {
    714     // m_width is set in calcPrefWidths()
     722   
     723    updateMargins();
     724}
     725
     726void RenderListMarker::updateMargins()
     727{
    715728    const Font& font = style()->font();
     729
     730    int marginLeft = 0;
     731    int marginRight = 0;
    716732
    717733    if (isInside()) {
    718734        if (isImage()) {
    719             if (style()->direction() == LTR) {
    720                 m_marginLeft = 0;
    721                 m_marginRight = cMarkerPadding;
    722             } else {
    723                 m_marginLeft = cMarkerPadding;
    724                 m_marginRight = 0;
    725             }
     735            if (style()->direction() == LTR)
     736                marginRight = cMarkerPadding;
     737            else
     738                marginLeft = cMarkerPadding;
    726739        } else switch (style()->listStyleType()) {
    727740            case DISC:
     
    729742            case SQUARE:
    730743                if (style()->direction() == LTR) {
    731                     m_marginLeft = -1;
    732                     m_marginRight = font.ascent() - m_width + 1;
     744                    marginLeft = -1;
     745                    marginRight = font.ascent() - minPrefWidth() + 1;
    733746                } else {
    734                     m_marginLeft = font.ascent() - m_width + 1;
    735                     m_marginRight = -1;
     747                    marginLeft = font.ascent() - minPrefWidth() + 1;
     748                    marginRight = -1;
    736749                }
    737750                break;
    738751            default:
    739                 m_marginLeft = 0;
    740                 m_marginRight = 0;
     752                break;
    741753        }
    742754    } else {
    743755        if (style()->direction() == LTR) {
    744756            if (isImage())
    745                 m_marginLeft = -m_width - cMarkerPadding;
     757                marginLeft = -minPrefWidth() - cMarkerPadding;
    746758            else {
    747759                int offset = font.ascent() * 2 / 3;
     
    750762                    case CIRCLE:
    751763                    case SQUARE:
    752                         m_marginLeft = -offset - cMarkerPadding - 1;
     764                        marginLeft = -offset - cMarkerPadding - 1;
    753765                        break;
    754766                    case LNONE:
    755                         m_marginLeft = 0;
    756767                        break;
    757768                    default:
    758                         m_marginLeft = m_text.isEmpty() ? 0 : -m_width - offset / 2;
     769                        marginLeft = m_text.isEmpty() ? 0 : -minPrefWidth() - offset / 2;
    759770                }
    760771            }
    761772        } else {
    762773            if (isImage())
    763                 m_marginLeft = cMarkerPadding;
     774                marginLeft = cMarkerPadding;
    764775            else {
    765776                int offset = font.ascent() * 2 / 3;
     
    768779                    case CIRCLE:
    769780                    case SQUARE:
    770                         m_marginLeft = offset + cMarkerPadding + 1 - m_width;
     781                        marginLeft = offset + cMarkerPadding + 1 - minPrefWidth();
    771782                        break;
    772783                    case LNONE:
    773                         m_marginLeft = 0;
    774784                        break;
    775785                    default:
    776                         m_marginLeft = m_text.isEmpty() ? 0 : offset / 2;
     786                        marginLeft = m_text.isEmpty() ? 0 : offset / 2;
    777787                }
    778788            }
    779789        }
    780         m_marginRight = -m_marginLeft - m_width;
    781     }
     790        marginRight = -marginLeft - minPrefWidth();
     791    }
     792
     793    style()->setMarginLeft(Length(marginLeft, Fixed));
     794    style()->setMarginRight(Length(marginRight, Fixed));
    782795}
    783796
  • trunk/WebCore/rendering/RenderListMarker.h

    r21079 r21093  
    5252    virtual void imageChanged(CachedImage*);
    5353
    54     virtual void calcWidth();
    55 
    5654    virtual InlineBox* createInlineBox(bool, bool, bool);
    5755
     
    7068    virtual bool canBeSelectionLeaf() const { return true; }
    7169
     70    void updateMargins();
     71
    7272private:
    7373    IntRect getRelativeMarkerRect();
    7474
    75     String m_text;
    7675    CachedImage* m_image;
    7776    RenderListItem* m_listItem;
  • trunk/WebCore/rendering/RenderObject.cpp

    r21082 r21093  
    177177    , m_normalChildNeedsLayout(false)
    178178    , m_posChildNeedsLayout(false)
    179     , m_prefWidthsDirty(true)
     179    , m_prefWidthsDirty(false)
    180180    , m_floating(false)
    181181    , m_positioned(false)
     
    183183    , m_paintBackground(false)
    184184    , m_isAnonymous(node == node->document())
    185     , m_recalcMinMax(false)
    186185    , m_isText(false)
    187186    , m_inline(true)
    188187    , m_replaced(false)
    189188    , m_isDragging(false)
     189    , m_hasLayer(false)
    190190    , m_hasOverflowClip(false)
    191191    , m_hasOverrideSize(false)
     
    253253}
    254254
    255 RenderObject* RenderObject::removeChildNode(RenderObject*)
     255RenderObject* RenderObject::removeChildNode(RenderObject*, bool)
    256256{
    257257    ASSERT_NOT_REACHED();
     
    264264}
    265265
    266 void RenderObject::appendChildNode(RenderObject*)
     266void RenderObject::moveChildNode(RenderObject*)
    267267{
    268268    ASSERT_NOT_REACHED();
    269269}
    270270
    271 void RenderObject::insertChildNode(RenderObject*, RenderObject*)
     271void RenderObject::appendChildNode(RenderObject*, bool)
     272{
     273    ASSERT_NOT_REACHED();
     274}
     275
     276void RenderObject::insertChildNode(RenderObject*, RenderObject*, bool)
    272277{
    273278    ASSERT_NOT_REACHED();
     
    498503{
    499504    return 0;
    500 }
    501 
    502 void RenderObject::updateFirstLetter()
    503 {
    504505}
    505506
     
    653654void RenderObject::markAllDescendantsWithFloatsForLayout(RenderObject*)
    654655{
     656}
     657
     658void RenderObject::setPrefWidthsDirty(bool b, bool markParents)
     659{
     660    bool alreadyDirty = m_prefWidthsDirty;
     661    m_prefWidthsDirty = b;
     662    if (b && !alreadyDirty && markParents && (style()->position() != FixedPosition && style()->position() != AbsolutePosition))
     663        invalidateContainingBlockPrefWidths();
     664}
     665
     666void RenderObject::invalidateContainingBlockPrefWidths()
     667{
     668    RenderObject* o = containingBlock();
     669    while (o && !o->m_prefWidthsDirty) {
     670        o->m_prefWidthsDirty = true;
     671        if (o->style()->position() == FixedPosition || o->style()->position() == AbsolutePosition)
     672            // A positioned object has no effect on the min/max width of its containing block ever.
     673            // We can optimize this case and not go up any further.
     674            break;
     675        o = o->containingBlock();
     676    }
    655677}
    656678
     
    19181940    if (needsLayout())
    19191941        ts << "nl ";
    1920     if (m_recalcMinMax)
    1921         ts << "rmm ";
    19221942    if (style() && style()->zIndex())
    19231943        ts << "zI: " << style()->zIndex();
     
    27072727}
    27082728
    2709 void RenderObject::recalcMinMaxWidths()
    2710 {
    2711     ASSERT(m_recalcMinMax);
    2712 
    2713     m_recalcMinMax = false;
    2714     updateFirstLetter();
    2715 
    2716     RenderObject* child = firstChild();
    2717     while (child) {
    2718         int cmin = 0;
    2719         int cmax = 0;
    2720         bool test = false;
    2721         if ((!m_prefWidthsDirty && child->m_recalcMinMax) || child->m_prefWidthsDirty) {
    2722             cmin = child->minPrefWidth();
    2723             cmax = child->maxPrefWidth();
    2724             test = true;
    2725         }
    2726         if (child->m_recalcMinMax)
    2727             child->recalcMinMaxWidths();
    2728         if (child->m_prefWidthsDirty)
    2729             child->calcPrefWidths();
    2730         if (!m_prefWidthsDirty && test && (cmin != child->minPrefWidth() || cmax != child->maxPrefWidth()))
    2731             m_prefWidthsDirty = true;
    2732         child = child->nextSibling();
    2733     }
    2734 
    2735     // we need to recalculate, if the contains inline children, as the change could have
    2736     // happened somewhere deep inside the child tree. Also do this for blocks or tables that
    2737     // are inline (i.e., inline-block and inline-table).
    2738     if ((!isInline() || isInlineBlockOrInlineTable()) && childrenInline())
    2739         m_prefWidthsDirty = true;
    2740 
    2741     if (m_prefWidthsDirty)
    2742         calcPrefWidths();
    2743 }
    2744 
    27452729void RenderObject::scheduleRelayout()
    27462730{
  • trunk/WebCore/rendering/RenderObject.h

    r21079 r21093  
    154154
    155155    virtual RenderLayer* layer() const { return 0; }
    156     bool hasLayer() const { return !!layer(); }
    157156    RenderLayer* enclosingLayer() const;
    158157    void addLayers(RenderLayer* parentLayer, RenderObject* newObject);
     
    178177    // children.
    179178    virtual RenderBlock* firstLineBlock() const;
    180     virtual void updateFirstLetter();
    181179
    182180    // Called when an object that was floating or positioned becomes a normal flow object
     
    207205
    208206    // raw tree manipulation
    209     virtual RenderObject* removeChildNode(RenderObject*);
    210     virtual void appendChildNode(RenderObject*);
    211     virtual void insertChildNode(RenderObject* child, RenderObject* before);
     207    virtual RenderObject* removeChildNode(RenderObject*, bool fullRemove = true);
     208    virtual void appendChildNode(RenderObject*, bool fullAppend = true);
     209    virtual void insertChildNode(RenderObject* child, RenderObject* before, bool fullInsert = true);
     210    // Designed for speed.  Don't waste time doing a bunch of work like layer updating and repainting when we know that our
     211    // change in parentage is not going to affect anything.
     212    virtual void moveChildNode(RenderObject*);
    212213    //////////////////////////////////////////
    213214
     
    311312    bool isDragging() const { return m_isDragging; }
    312313    bool isReplaced() const { return m_replaced; } // a "replaced" element (see CSS)
    313 
     314   
     315    bool hasLayer() const { return m_hasLayer; }
     316   
    314317    bool hasBoxDecorations() const { return m_paintBackground; }
    315318    bool mustRepaintBackgroundOrBorder() const;
     
    321324
    322325    bool prefWidthsDirty() const { return m_prefWidthsDirty; }
    323     bool recalcMinMax() const { return m_recalcMinMax; }
    324326
    325327    bool isSelectionBorder() const;
     
    370372    void setChildNeedsLayout(bool b, bool markParents = true);
    371373
    372     void setPrefWidthsDirty(bool b)
    373     {
    374         m_prefWidthsDirty = b;
    375         if (b) {
    376             RenderObject* o = this;
    377             RenderObject* root = this;
    378             while(o) { // FIXME: && !o->m_recalcMinMax ) {
    379                 o->m_recalcMinMax = true;
    380                 root = o;
    381                 o = o->m_parent;
    382             }
    383         }
    384     }
    385 
     374    void setPrefWidthsDirty(bool, bool markParents = true);
     375    void invalidateContainingBlockPrefWidths();
     376   
    386377    void setNeedsLayoutAndPrefWidthsRecalc()
    387378    {
     379        setNeedsLayout(true);
    388380        setPrefWidthsDirty(true);
    389         setNeedsLayout(true);
    390381    }
    391382
     
    398389    void setReplaced(bool b = true) { m_replaced = b; }
    399390    void setHasOverflowClip(bool b = true) { m_hasOverflowClip = b; }
     391    void setHasLayer(bool b = true) { m_hasLayer = b; }
    400392
    401393    void scheduleRelayout();
     
    460452                                         bool includeLeftEdge = true, bool includeRightEdge = true) { }
    461453
    462     /*
    463      * This function calculates the minimum & maximum width that the object
    464      * can be set to.
    465      *
    466      * when the Element calls setPrefWidthsDirty(false), calcPrefWidths() will
    467      * be no longer called.
    468      *
    469      * when a element has a fixed size, m_minPrefWidth and m_maxPrefWidth should be
    470      * set to the same value. This has the special meaning that m_width,
    471      * contains the actual value.
    472      *
    473      * assumes calcPrefWidths has already been called for all children.
    474      */
    475     virtual void calcPrefWidths() { }
    476 
    477     /*
    478      * Does the min max width recalculations after changes.
    479      */
    480     void recalcMinMaxWidths();
    481 
     454   
    482455    /*
    483456     * Calculates the actual width of the object (only for non inline
     
    923896
    924897    bool m_isAnonymous               : 1;
    925     bool m_recalcMinMax              : 1;
    926898    bool m_isText                    : 1;
    927899    bool m_inline                    : 1;
     
    929901    bool m_isDragging                : 1;
    930902
     903    bool m_hasLayer                  : 1;
    931904    bool m_hasOverflowClip           : 1;
    932905
  • trunk/WebCore/rendering/RenderPartObject.cpp

    r21079 r21093  
    246246{
    247247    ASSERT(needsLayout());
    248     ASSERT(!prefWidthsDirty());
    249248
    250249    calcWidth();
  • trunk/WebCore/rendering/RenderSVGContainer.cpp

    r21087 r21093  
    8686}
    8787
    88 void RenderSVGContainer::calcPrefWidths()
    89 {
    90     ASSERT(prefWidthsDirty());
    91     m_minPrefWidth = m_maxPrefWidth = 0;
    92     setPrefWidthsDirty(false);
    93 }
    94 
    9588void RenderSVGContainer::layout()
    9689{
    9790    ASSERT(needsLayout());
    98     ASSERT(!prefWidthsDirty());
    9991
    10092    calcViewport();
  • trunk/WebCore/rendering/RenderSVGContainer.h

    r21079 r21093  
    6464    virtual short baselinePosition(bool b, bool isRootLineBox = false) const;
    6565   
    66     virtual void calcPrefWidths();
    6766    virtual void layout();
    6867    virtual void paint(PaintInfo&, int parentX, int parentY);
  • trunk/WebCore/rendering/RenderSVGHiddenContainer.cpp

    r21079 r21093  
    5555}
    5656
    57 void RenderSVGHiddenContainer::calcPrefWidths()
    58 {
    59     ASSERT(prefWidthsDirty());
    60     m_minPrefWidth = m_maxPrefWidth = 0;
    61     setPrefWidthsDirty(false);
    62 }
    63 
    6457void RenderSVGHiddenContainer::layout()
    6558{
  • trunk/WebCore/rendering/RenderSVGHiddenContainer.h

    r21079 r21093  
    4747        virtual short baselinePosition(bool b, bool isRootLineBox = false) const;
    4848       
    49         virtual void calcPrefWidths();
    5049        virtual void layout();
    5150        virtual void paint(PaintInfo&, int parentX, int parentY);
  • trunk/WebCore/rendering/RenderSVGText.cpp

    r21079 r21093  
    5959{
    6060    ASSERT(needsLayout());
    61     ASSERT(!prefWidthsDirty());
    6261
    6362    IntRect oldBounds;
  • trunk/WebCore/rendering/RenderTable.cpp

    r21082 r21093  
    234234        // Percent or fixed table
    235235        m_width = style()->width().calcMinValue(availableWidth);
    236         m_width = max(m_minPrefWidth, m_width);
     236        m_width = max(minPrefWidth(), m_width);
    237237    } else {
    238238        // An auto width table should shrink to fit within the line width if necessary in order to
     
    251251       
    252252        // Ensure we aren't bigger than our max width or smaller than our min width.
    253         m_width = min(availContentWidth, m_maxPrefWidth);
     253        m_width = min(availContentWidth, maxPrefWidth());
    254254    }
    255255   
    256     m_width = max(m_width, m_minPrefWidth);
     256    m_width = max(m_width, minPrefWidth());
    257257
    258258    // Finally, with our true width determined, compute our margins for real.
     
    265265{
    266266    ASSERT(needsLayout());
    267     ASSERT(!prefWidthsDirty());
    268     ASSERT(!m_needsSectionRecalc);
    269267
    270268    if (posChildNeedsLayout() && !normalChildNeedsLayout() && !selfNeedsLayout()) {
     
    275273    }
    276274
     275    recalcSectionsIfNeeded();
     276       
    277277    IntRect oldBounds;
    278278    IntRect oldOutlineBox;
     
    686686}
    687687
    688 RenderObject* RenderTable::removeChildNode(RenderObject* child)
     688RenderObject* RenderTable::removeChildNode(RenderObject* child, bool fullRemove)
    689689{
    690690    setNeedsSectionRecalc();
    691     return RenderContainer::removeChildNode(child);
     691    return RenderContainer::removeChildNode(child, fullRemove);
    692692}
    693693
  • trunk/WebCore/rendering/RenderTable.h

    r21079 r21093  
    166166    void setNeedsSectionRecalc() { m_needsSectionRecalc = true; }
    167167
    168     virtual RenderObject* removeChildNode(RenderObject*);
     168    virtual RenderObject* removeChildNode(RenderObject*, bool fullRemove = true);
    169169
    170170    RenderTableSection* sectionAbove(const RenderTableSection*, bool skipEmptySections = false) const;
  • trunk/WebCore/rendering/RenderTableRow.cpp

    r21082 r21093  
    113113{
    114114    ASSERT(needsLayout());
    115     ASSERT(!prefWidthsDirty());
    116115
    117116    for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
  • trunk/WebCore/rendering/RenderTableSection.cpp

    r21082 r21093  
    10051005}
    10061006
    1007 RenderObject* RenderTableSection::removeChildNode(RenderObject* child)
     1007RenderObject* RenderTableSection::removeChildNode(RenderObject* child, bool fullRemove)
    10081008{
    10091009    setNeedsCellRecalc();
    1010     return RenderContainer::removeChildNode(child);
     1010    return RenderContainer::removeChildNode(child, fullRemove);
    10111011}
    10121012
  • trunk/WebCore/rendering/RenderTableSection.h

    r19696 r21093  
    122122    int getBaseline(int row) { return m_grid[row].baseLine; }
    123123
    124     virtual RenderObject* removeChildNode(RenderObject*);
     124    virtual RenderObject* removeChildNode(RenderObject*, bool fullRemove = true);
    125125
    126126    virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
  • trunk/WebCore/rendering/RenderText.cpp

    r21079 r21093  
    436436    }
    437437
    438     if (m_hasTab)
    439         calcPrefWidthsInternal(leadWidth);
     438    if (m_hasTab || prefWidthsDirty())
     439        calcPrefWidths(leadWidth);
    440440
    441441    minW = m_minWidth;
     
    495495}
    496496
    497 void RenderText::calcPrefWidths()
    498 {
    499     // Use 0 for the leadWidth. If the text contains a variable width tab, the real width
    500     // will get measured when trimmedMinMaxWidth calls again with the real leadWidth.
    501     ASSERT(prefWidthsDirty());
    502     calcPrefWidthsInternal(0);
    503 }
    504 
    505497inline bool isSpaceAccordingToStyle(UChar c, RenderStyle* style)
    506498{
     
    508500}
    509501
    510 void RenderText::calcPrefWidthsInternal(int leadWidth)
    511 {
     502int RenderText::minPrefWidth() const
     503{
     504    if (prefWidthsDirty())
     505        const_cast<RenderText*>(this)->calcPrefWidths(0);
     506       
     507    return m_minWidth;
     508}
     509
     510int RenderText::maxPrefWidth() const
     511{
     512    if (prefWidthsDirty())
     513        const_cast<RenderText*>(this)->calcPrefWidths(0);
     514       
     515    return m_maxWidth;
     516}
     517
     518void RenderText::calcPrefWidths(int leadWidth)
     519{
     520    ASSERT(m_hasTab || prefWidthsDirty());
     521
    512522    m_minWidth = 0;
    513523    m_beginMinWidth = 0;
     
    9921002    if (&f == &style()->font()) {
    9931003        if (!style()->preserveNewline() && !from && len == textLength())
    994             w = m_maxWidth;
     1004            w = maxPrefWidth();
    9951005        else
    9961006            w = widthFromCache(f, from, len, xPos);
  • trunk/WebCore/rendering/RenderText.h

    r21079 r21093  
    7676    virtual short lineHeight(bool firstLine, bool isRootLineBox = false) const;
    7777
    78     virtual void calcPrefWidths();
    79     virtual int minPrefWidth() const { return m_minWidth; }
    80     virtual int maxPrefWidth() const { return m_maxWidth; }
     78    virtual int minPrefWidth() const;
     79    virtual int maxPrefWidth() const;
    8180
    8281    void trimmedPrefWidths(int leadWidth,
     
    130129protected:
    131130    void setTextInternal(PassRefPtr<StringImpl>);
     131    virtual void calcPrefWidths(int leadWidth);
    132132
    133133private:
     
    139139    void deleteTextBoxes();
    140140    bool containsOnlyWhitespace(unsigned from, unsigned len) const;
    141     void calcPrefWidthsInternal(int leadWidth);
    142 
    143141    int widthFromCache(const Font&, int start, int len, int xPos) const;
    144142    bool isAllASCII() const { return m_isAllASCII; }
  • trunk/WebCore/rendering/RenderView.cpp

    r21079 r21093  
    5555    m_maxPrefWidth = 0;
    5656
    57     setPrefWidthsDirty(true);
     57    setPrefWidthsDirty(true, false);
    5858   
    5959    setPositioned(true); // to 0,0 :)
     
    6161    // Create a new root layer for our layer hierarchy.
    6262    m_layer = new (node->document()->renderArena()) RenderLayer(this);
     63    setHasLayer(true);
    6364}
    6465
     
    8889
    8990    m_maxPrefWidth = m_minPrefWidth;
    90 
    91     setPrefWidthsDirty(false);
    9291}
    9392
     
    9594{
    9695    if (printing())
    97         m_minPrefWidth = m_width;
     96        m_minPrefWidth = m_maxPrefWidth = m_width;
    9897
    9998    bool relayoutChildren = !printing() && (!m_frameView || m_width != m_frameView->visibleWidth() || m_height != m_frameView->visibleHeight());
    10099    if (relayoutChildren)
    101100        setChildNeedsLayout(true, false);
    102 
    103     if (recalcMinMax())
    104         recalcMinMaxWidths();
    105101   
    106102    if (needsLayout())
  • trunk/WebCore/rendering/RenderWidget.cpp

    r21079 r21093  
    151151{
    152152    ASSERT(needsLayout());
    153     ASSERT(!prefWidthsDirty());
    154153
    155154    setNeedsLayout(false);
Note: See TracChangeset for help on using the changeset viewer.