📄 render_block.cpp
字号:
// Now check for clear. int heightIncrease = getClearDelta(child); if (heightIncrease) { // The child needs to be lowered. Move the child so that it just clears the float. child->setPos(child->xPos(), child->yPos()+heightIncrease); clearOccurred = true; // Increase our height by the amount we had to clear. if (!child->isSelfCollapsingBlock()) m_height += heightIncrease; else { // For self-collapsing blocks that clear, they may end up collapsing // into the bottom of the parent block. We simulate this behavior by // setting our positive margin value to compensate for the clear. prevPosMargin = QMAX(0, child->yPos() - m_height); prevNegMargin = 0; selfCollapsingBlockClearedFloat = true; } if (topMarginContributor && canCollapseTopWithChildren) { // We can no longer collapse with the top of the block since a clear // occurred. The empty blocks collapse into the cleared block. // XXX This isn't quite correct. Need clarification for what to do // if the height the cleared block is offset by is smaller than the // margins involved. -dwh m_maxTopPosMargin = oldTopPosMargin; m_maxTopNegMargin = oldTopNegMargin; topMarginContributor = false; } // If our value of clear caused us to be repositioned vertically to be // underneath a float, we might have to do another layout to take into account // the extra space we now have available. if (child->style()->width().isPercent() && child->usesLineWidth()) // The child's width is a percentage of the line width. // When the child shifts to clear an item, its width can // change (because it has more available line width). // So go ahead and mark the item as dirty. child->setChildNeedsLayout(true); if (child->containsFloats()) child->markAllDescendantsWithFloatsForLayout(); child->layoutIfNeeded(); } // Reset the top margin contributor to false if we encountered // a non-empty child. This has to be done after checking for clear, // so that margins can be reset if a clear occurred. if (topMarginContributor && !child->isSelfCollapsingBlock()) topMarginContributor = false; int chPos = xPos; if (style()->direction() == LTR) { // Add in our left margin. chPos += child->marginLeft(); // Some objects (e.g., tables, horizontal rules, overflow:auto blocks) avoid floats. They need // to shift over as necessary to dodge any floats that might get in the way. if (child->avoidsFloats()) { int leftOff = leftOffset(m_height); if (style()->textAlign() != KHTML_CENTER && child->style()->marginLeft().type != Variable) { if (child->marginLeft() < 0) leftOff += child->marginLeft(); chPos = kMax(chPos, leftOff); // Let the float sit in the child's margin if it can fit. } else if (leftOff != xPos) { // The object is shifting right. The object might be centered, so we need to // recalculate our horizontal margins. Note that the containing block content // width computation will take into account the delta between |leftOff| and |xPos| // so that we can just pass the content width in directly to the |calcHorizontalMargins| // function. // -dwh int cw = lineWidth( child->yPos() ); static_cast<RenderBox*>(child)->calcHorizontalMargins ( child->style()->marginLeft(), child->style()->marginRight(), cw); chPos = leftOff + child->marginLeft(); } } } else { chPos -= child->width() + child->marginRight(); if (child->avoidsFloats()) { int rightOff = rightOffset(m_height); if (style()->textAlign() != KHTML_CENTER && child->style()->marginRight().type != Variable) { if (child->marginRight() < 0) rightOff -= child->marginRight(); chPos = kMin(chPos, rightOff - child->width()); // Let the float sit in the child's margin if it can fit. } else if (rightOff != xPos) { // The object is shifting left. The object might be centered, so we need to // recalculate our horizontal margins. Note that the containing block content // width computation will take into account the delta between |rightOff| and |xPos| // so that we can just pass the content width in directly to the |calcHorizontalMargins| // function. // -dwh int cw = lineWidth( child->yPos() ); static_cast<RenderBox*>(child)->calcHorizontalMargins ( child->style()->marginLeft(), child->style()->marginRight(), cw); chPos = rightOff - child->marginRight() - child->width(); } } } child->setPos(chPos, child->yPos()); m_height += child->height(); int overflowDelta = child->overflowHeight(false) - child->height(); if (m_height + overflowDelta > m_overflowHeight) m_overflowHeight = m_height + overflowDelta; prevBlock = child; if (child->isRenderBlock() && !child->avoidsFloats()) prevFlow = static_cast<RenderBlock*>(child); if (child->hasOverhangingFloats() && !child->hasOverflowClip()) { // need to add the child's floats to our floating objects list, but not in the case where // overflow is auto/scroll addOverHangingFloats( static_cast<RenderBlock *>(child), -child->xPos(), -child->yPos(), true ); } // See if this child has made our overflow need to grow. // XXXdwh Work with left overflow as well as right overflow. int rightChildPos = child->xPos() + QMAX(child->overflowWidth(false), child->width()); if (rightChildPos > m_overflowWidth) m_overflowWidth = rightChildPos; if (child == blockForCompactChild) { blockForCompactChild = 0; if (compactChild) { // We have a compact child to squeeze in. int compactXPos = xPos+compactChild->marginLeft(); if (style()->direction() == RTL) { compactChild->calcWidth(); // have to do this because of the capped maxwidth compactXPos = width() - borderRight() - paddingRight() - marginRight() - compactChild->width() - compactChild->marginRight(); } compactXPos -= child->xPos(); // Put compactXPos into the child's coordinate space. compactChild->setPos(compactXPos, compactChild->yPos()); // Set the x position. compactChild = 0; } } // We did a layout as though the compact child was a block. Set it back to compact now. if (treatCompactAsBlock) { child->style()->setDisplay(COMPACT); treatCompactAsBlock = false; } // If the child moved, we have to repaint it as well as any floating/positioned // descendants. An exception is if we need a layout. In this case, we know we're going to // repaint ourselves (and the child) anyway. if (!selfNeedsLayout() && child->checkForRepaintDuringLayout()) child->repaintDuringLayoutIfMoved(oldChildX, oldChildY); child = child->nextSibling(); } // If our last flow was a self-collapsing block that cleared a float, then we don't // collapse it with the bottom of the block. if (selfCollapsingBlockClearedFloat) canCollapseBottomWithChildren = false; // If we can't collapse with children then go ahead and add in the bottom margins. if (!canCollapseBottomWithChildren && (!topMarginContributor || !canCollapseTopWithChildren) && (strictMode || !quirkContainer || !bottomChildQuirk)) m_height += prevPosMargin - prevNegMargin; m_height += toAdd; // Negative margins can cause our height to shrink below our minimal height (border/padding). // If this happens, ensure that the computed height is increased to the minimal height. if (m_height < minHeight) m_height = minHeight; // Always make sure our overflowheight is at least our height. if (m_overflowHeight < m_height) m_overflowHeight = m_height; if (canCollapseBottomWithChildren && (!topMarginContributor || !canCollapseTopWithChildren)) { // Update our max pos/neg bottom margins, since we collapsed our bottom margins // with our children. if (prevPosMargin > m_maxBottomPosMargin) m_maxBottomPosMargin = prevPosMargin; if (prevNegMargin > m_maxBottomNegMargin) m_maxBottomNegMargin = prevNegMargin; if (!bottomChildQuirk) m_bottomMarginQuirk = false; if (bottomChildQuirk && marginBottom() == 0) // We have no bottom margin and our last child has a quirky margin. // We will pick up this quirky margin and pass it through. // This deals with the <td><div><p> case. m_bottomMarginQuirk = true; } setNeedsLayout(false); // kdDebug( 6040 ) << "needsLayout = " << needsLayout_ << endl;}void RenderBlock::layoutPositionedObjects(bool relayoutChildren){ if (m_positionedObjects) { //kdDebug( 6040 ) << renderName() << " " << this << "::layoutPositionedObjects() start" << endl; RenderObject* r; QPtrListIterator<RenderObject> it(*m_positionedObjects); for ( ; (r = it.current()); ++it ) { //kdDebug(6040) << " have a positioned object" << endl; if ( relayoutChildren ) r->setChildNeedsLayout(true); r->layoutIfNeeded(); } }}void RenderBlock::markPositionedObjectsForLayout(){ if (m_positionedObjects) { RenderObject* r; QPtrListIterator<RenderObject> it(*m_positionedObjects); for (; (r = it.current()); ++it) r->setChildNeedsLayout(true); }}void RenderBlock::getAbsoluteRepaintRectIncludingFloats(QRect& bounds, QRect& fullBounds){ bounds = fullBounds = getAbsoluteRepaintRect(); // Include any overhanging floats (if we know we're the one to paint them). // We null-check m_floatingObjects here to catch any cases where m_height ends up negative // for some reason. I think I've caught all those cases, but this way we stay robust and don't // crash. -dwh if (hasOverhangingFloats() && m_floatingObjects) { FloatingObject* r; QPtrListIterator<FloatingObject> it(*m_floatingObjects); for ( ; (r = it.current()); ++it) { // Only repaint the object if our noPaint flag isn't set and if it isn't in // its own layer. if (!r->noPaint && !r->node->layer()) { QRect childRect, childFullRect; r->node->getAbsoluteRepaintRectIncludingFloats(childRect, childFullRect); fullBounds = fullBounds.unite(childFullRect); } } }}void RenderBlock::repaintFloatingDescendants(){ // Repaint any overhanging floats (if we know we're the one to paint them). if (hasOverhangingFloats()) { FloatingObject* r; QPtrListIterator<FloatingObject> it(*m_floatingObjects); for ( ; (r = it.current()); ++it) { // Only repaint the object if our noPaint flag isn't set and if it isn't in // its own layer. if (!r->noPaint && !r->node->layer()) { r->node->repaint(); r->node->repaintFloatingDescendants(); } } }}void RenderBlock::repaintObjectsBeforeLayout(){ RenderFlow::repaintObjectsBeforeLayout(); if (!needsLayout()) return; // Walk our positioned objects. if (m_positionedObjects) { RenderObject* r; QPtrListIterator<RenderObject> it(*m_positionedObjects); for ( ; (r = it.current()); ++it ) r->repaintObjectsBeforeLayout(); }}void RenderBlock::paint(PaintInfo& i, int _tx, int _ty){ _tx += m_x; _ty += m_y; // check if we need to do anything at all... if (!isRoot() && !isInlineFlow() && !isRelPositioned() && !isPositioned()) { int h = m_overflowHeight; int yPos = _ty; if (m_floatingObjects && floatBottom() > h) h = floatBottom(); // Sanity check the first line // to see if it extended a little above our box. Overflow out the bottom is already handled via // overflowHeight(), so we don't need to check that. if (m_firstLineBox && m_firstLineBox->topOverflow() < 0) yPos += m_firstLineBox->topOverflow(); int os = 2*maximalOutlineSize(i.phase); if( (yPos >= i.r.y() + i.r.height() + os) || (_ty + h <= i.r.y() - os)) return; } return RenderBlock::paintObject(i, _tx, _ty);}void RenderBlock::paintObject(PaintInfo& i, int _tx, int _ty){ PaintAction paintAction = i.phase; // If we're a repositioned run-in, don't paint background/borders.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -