boolsubtree =m_layoutRoot; RenderObject*root =subtree ? m_layoutRoot : document->renderer(); if(!root){ //FIXME: Do we need to set m_sizehere? m_layoutSchedulingEnabled=true; return; }
if(!m_postLayoutTasksTimer.isActive()&&needsLayout()){ //Post-layout widget updates or an event handler made us need layoutagain.Lay out again,but this time deferwidget updates and event dispatch until after wereturn. m_postLayoutTasksTimer.startOneShot(0); pauseScheduledEvents(); layout(); } }else { resumeScheduledEvents(); } }
void RenderView::layout() { if (printing()) m_minPrefWidth =m_maxPrefWidth =m_width;
//Use calcWidth/Heightto get the new width/height,since this will take the full pagezoom factor into account. bool relayoutChildren =!printing()&&(!m_frameView||m_width !=viewWidth()||m_height !=viewHeight()); if (relayoutChildren){
setChildNeedsLayout(true, false); for (RenderObject* child = firstChild(); child; child =child->nextSibling()) { if (child->style()->height().isPercent() ||child->style()->minHeight().isPercent() ||child->style()->maxHeight().isPercent()) child->setChildNeedsLayout(true, false); }
}
ASSERT(!m_layoutState); LayoutState state; //FIXME: May be better to push aclip and avoid issuing offscreen repaints. state.m_clipped=false; m_layoutState =&state;
if (needsLayout()) RenderBlock::layout();//类继承的好处,直接调用父类的layout
// Reset overflow and then replace it with docWidth anddocHeight. m_overflow.clear(); addLayoutOverflow(IntRect(0, 0, docWidth(), docHeight()));
voidRenderBlock::layout() { //Update our first letter infonow. updateFirstLetter(); //Tablecells call layoutBlock directly,so don't add any logichere. Put code into layoutBlock(). layoutBlock(false);
// It'ssafe to check forcontrol clip here,since controls can never be tablecells.If we have a lightweight clip, there can never be any overflowfrom children. if (hasControlClip() &&m_overflow) clearLayoutOverflow(); }
if (oldWidth!=width() ||oldColumnWidth !=desiredColumnWidth()) relayoutChildren =true; clearFloats();
int previousHeight =height(); setHeight(0);
//这就是在布局基本概念中提到的Block-level元素的子节点要么是Block-level元素要么为Inline-level元素。 if (childrenInline()) layoutInlineChildren(relayoutChildren,repaintTop,repaintBottom); else layoutBlockChildren(relayoutChildren,maxFloatBottom);
//Expand our intrinsic heightto encompass floats. int toAdd =borderBottom()+paddingBottom()+horizontalScrollbarHeight(); if (floatBottom()>(m_height- toAdd)&&(isInlineBlockOrInlineTable()||isFloatingOrPositioned()||hasOverflowClip()|| (parent()&&parent()->isFlexibleBox()||m_hasColumns))) setHeight(floatBottom()+toAdd);
//Now lay out our columns within this intrinsic height,since they can slightly affect the intrinsic heightas we adjust forclean column breaks. int singleColumnBottom =layoutColumns();
//Calculate our new height.//布局完子节点后确定父节点高度 int oldHeight =height(); calcHeight();
if (previousHeight!=height()) relayoutChildren =true;
// Update ourscroll information if we're overflow:auto/scroll/hidden now thatwe know if we overflow or not. updateScrollInfoAfterLayout();
// Repaint with ournew bounds if they are different from our old bounds. bool didFullRepaint = repainter.repaintAfterLayout(); if (!didFullRepaint && repaintTop != repaintBottom &&(style()->visibility() == VISIBLE ||enclosingLayer()->hasVisibleContent())) { // 设置repaintRect
// Make sure the rect isstill non-empty after intersecting for overflow above if (!repaintRect.isEmpty()) { repaintRectangle(repaintRect); // We need to do a partialrepaint of our content. if (hasReflection()) repaintRectangle(reflectedRect(repaintRect)); } } setNeedsLayout(false); }
// Fieldsets needto find their legend and position it inside the border of theobject. // The legend then gets skippedduring normal layout. RenderObject* legend =layoutLegend(relayoutChildren);
//遍历子节点
RenderBox* next = firstChildBox(); while (next) { RenderBox* child = next; next = child->nextSiblingBox();
if (legend == child) continue; // Skip the legend, since it has already been positionedup in the fieldset's border. // Make sure we layout children if they need it. // FIXME: Technically percentage height objects only need arelayout if their percentage isn't going to be turned into // an auto value. Add a method to determine this, so that wecan avoid the relayout. if (relayoutChildren || ((child->style()->height().isPercent()|| child->style()->minHeight().isPercent() ||child->style()->maxHeight().isPercent()) &&!isRenderView())) child->setChildNeedsLayout(true, false);
// If relayoutChildren is set and we have percentage padding, wealso need to invalidate the child's pref widths. if (relayoutChildren &&(child->style()->paddingLeft().isPercent() ||child->style()->paddingRight().isPercent())) child->setPrefWidthsDirty(true, false);
// Handle the four types of special elements first. Theseinclude positioned content, floating content, compacts and // run-ins. When we encounter these four types of objects,we don't actually lay them out as normal flow blocks. if (handleSpecialChild(child, marginInfo)) continue;
// Layout the child. layoutBlockChild(child,marginInfo, previousFloatBottom, maxFloatBottom); }
// Now do the handling of the bottomof the block, adding in our bottom border/padding and // determining the correct collapsed bottom margininformation. handleBottomOfBlock(top,bottom, marginInfo); }