????// Always ensure ourstyleinfo is up-to-date. This can happen in situations where the layout beats any sort ofstyle recalc update that needs to occur.
????????if (!m_postLayoutTasksTimer.isActive()&& needsLayout()){ ????????????// Post-layout widget updates or an event handler made us need layout again. Lay out again, but this timedefer widget updates and event dispatch until after we return. ????????????m_postLayoutTasksTimer.startOneShot(0); ????????????pauseScheduledEvents(); ????????????layout(); ????????} ????} else { ????????resumeScheduledEvents(); ????} }
???? // Use calcWidth/Height to get the newwidth/height, since this will take the fullpage zoom factor into account. ???? bool relayoutChildren = !printing()&&(!m_frameView || m_width != viewWidth()|| m_height != viewHeight()); ???? if (relayoutChildren) {
???? ASSERT(!m_layoutState); ???? LayoutState state; ???? // FIXME: May be better to pusha clip and avoid issuing offscreen repaints. ???? state.m_clipped = false; ???? m_layoutState = &state;
???? if (needsLayout()) ???????? RenderBlock::layout();//類繼承的好處,直接調(diào)用父類的layout
??? // Reset overflow and then replace it with docWidth and docHeight. ??? m_overflow.clear(); ??? addLayoutOverflow(IntRect(0, 0, docWidth(), docHeight()));
void RenderBlock::layout() { ???? // Update our first letterinfo now. ???? updateFirstLetter(); ???? // Table cells call layoutBlock directly, so don't add any logic here. Put code into layoutBlock(). ???? layoutBlock(false);
???? // It's safe to check for control clip here, since controls can never betable cells. If we have a lightweight clip, there can never be any overflow from children. ??? if (hasControlClip() && m_overflow) ??????? clearLayoutOverflow(); }
???? // Expand our intrinsicheight to 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 intrinsicheight, since they can slightly affect the intrinsicheight as we adjust for clean column breaks. ???? int singleColumnBottom = layoutColumns();
???? // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if we overflow or not. ??? updateScrollInfoAfterLayout();
??? // Repaint with our new bounds if they are different from our old bounds. ??? bool didFullRepaint = repainter.repaintAfterLayout(); ??? if (!didFullRepaint && repaintTop != repaintBottom && (style()->visibility() == VISIBLE || enclosingLayer()->hasVisibleContent())) { ??????? // 設(shè)置repaintRect
?????? // Make sure the rect is still non-empty after intersecting for overflow above ??????? if (!repaintRect.isEmpty()) { ??????????? repaintRectangle(repaintRect); // We need to do a partial repaint of our content. ??????????? if (hasReflection()) ??????????????? repaintRectangle(reflectedRect(repaintRect)); ??????? } ??? } ??? setNeedsLayout(false); }
四、RenderBlock::layoutBlockChildren方法
void RenderBlock::layoutBlockChildren(bool relayoutChildren, int& maxFloatBottom) { int top = borderTop()+ paddingTop(); int bottom = borderBottom()+ paddingBottom()+ horizontalScrollbarHeight();
??? // Fieldsets need to find their legend and position it inside the border of the object. ??? // The legend then gets skipped during normal layout. ??? RenderObject* legend = layoutLegend(relayoutChildren);
//遍歷子節(jié)點
RenderBox* next = firstChildBox(); ??? while (next) { ??????? RenderBox* child = next; ??????? next = child->nextSiblingBox();
??????? if (legend == child) ??????????? continue; // Skip the legend, since it has already been positioned up in the fieldset's border. ?????? // Make sure we layout children if they need it. ??????? // FIXME: Technically percentage height objects only need a relayout if their percentage isn't going to be turned into ??????? // an auto value.? Add a method to determine this, so that we can 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, we also 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.? These include 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;
??????? // Lay out the child. ??????? layoutBlockChild(child, marginInfo, previousFloatBottom, maxFloatBottom); ??? }
??? // Now do the handling of the bottom of the block, adding in our bottom border/padding and ??? // determining the correct collapsed bottom margin information. ??? handleBottomOfBlock(top, bottom, marginInfo); }