📄 render_box.cpp
字号:
return width;}void RenderBox::calcHorizontalMargins(const Length& ml, const Length& mr, int cw){ if (isFloating() || isInline()) // Inline blocks/tables and floats don't have their margins increased. { m_marginLeft = ml.minWidth(cw); m_marginRight = mr.minWidth(cw); } else { if ( (ml.isVariable() && mr.isVariable()) || (!ml.isVariable() && !mr.isVariable() && containingBlock()->style()->textAlign() == KHTML_CENTER) ) { m_marginLeft = (cw - m_width)/2; if (m_marginLeft<0) m_marginLeft=0; m_marginRight = cw - m_width - m_marginLeft; } else if (mr.isVariable() || (!ml.isVariable() && containingBlock()->style()->direction() == RTL && containingBlock()->style()->textAlign() == KHTML_LEFT)) { m_marginLeft = ml.width(cw); m_marginRight = cw - m_width - m_marginLeft; } else if (ml.isVariable() || (!mr.isVariable() && containingBlock()->style()->direction() == LTR && containingBlock()->style()->textAlign() == KHTML_RIGHT)) { m_marginRight = mr.width(cw); m_marginLeft = cw - m_width - m_marginRight; } else { m_marginLeft = ml.minWidth(cw); m_marginRight = mr.minWidth(cw); } }}void RenderBox::calcHeight(){#ifdef DEBUG_LAYOUT kdDebug( 6040 ) << "RenderBox::calcHeight()" << endl;#endif //cell height is managed by table, inline elements do not have a height property. if ( isTableCell() || (isInline() && !isReplaced()) ) return; if (isPositioned()) calcAbsoluteVertical(); else { calcVerticalMargins(); // For tables, calculate margins only if (isTable()) return; Length h; bool treatAsReplaced = isReplaced() && !isInlineBlockOrInlineTable(); bool checkMinMaxHeight = false; if ( treatAsReplaced ) h = Length( calcReplacedHeight(), Fixed ); else { h = style()->height(); checkMinMaxHeight = true; } int height; if (checkMinMaxHeight) { height = calcHeightUsing(style()->height()); if (height == -1) height = m_height; int minH = calcHeightUsing(style()->minHeight()); // Leave as -1 if unset. int maxH = style()->maxHeight().value() == UNDEFINED ? height : calcHeightUsing(style()->maxHeight()); if (maxH == -1) maxH = height; height = kMin(maxH, height); height = kMax(minH, height); } else { // The only times we don't check min/max height are when a fixed length has // been given as an override. Just use that. height = calcBoxHeight(h.value()); } if (height<m_height && !overhangingContents() && style()->overflow()==OVISIBLE) setOverhangingContents(); m_height = height; } // Unfurling marquees override with the furled height. if (style()->overflow() == OMARQUEE && m_layer && m_layer->marquee() && m_layer->marquee()->isUnfurlMarquee() && !m_layer->marquee()->isHorizontal()) { m_layer->marquee()->setEnd(m_height); m_height = kMin(m_height, m_layer->marquee()->unfurlPos()); }}int RenderBox::calcHeightUsing(const Length& h){ int height = -1; if (!h.isVariable()) { if (h.isFixed()) height = h.value(); else if (h.isPercent()) height = calcPercentageHeight(h); if (height != -1) { height = calcBoxHeight(height); return height; } } return height;}int RenderBox::calcPercentageHeight(const Length& height, bool treatAsReplaced) const{ int result = -1; RenderBlock* cb = containingBlock(); // In quirk mode, table cells violate what the CSS spec says to do with heights. if (cb->isTableCell() && style()->htmlHacks()) { result = static_cast<RenderTableCell*>(cb)->cellPercentageHeight(); } // Otherwise we only use our percentage height if our containing block had a specified // height. else if (cb->style()->height().isFixed()) result = cb->calcContentHeight(cb->style()->height().value()); else if (cb->style()->height().isPercent()) { // We need to recur and compute the percentage height for our containing block. result = cb->calcPercentageHeight(cb->style()->height(), treatAsReplaced); if (result != -1) result = cb->calcContentHeight(result); } else if (cb->isCanvas()) { if (!canvas()->pagedMode()) result = static_cast<RenderCanvas*>(cb)->viewportHeight(); else result = static_cast<RenderCanvas*>(cb)->height(); result -= cb->style()->borderTopWidth() - cb->style()->borderBottomWidth(); result -= cb->paddingTop() + cb->paddingBottom(); } else if (cb->isBody() && style()->htmlHacks() && cb->style()->height().isVariable() && !cb->isFloatingOrPositioned()) { int margins = cb->collapsedMarginTop() + cb->collapsedMarginBottom(); int visHeight = canvas()->viewportHeight(); RenderObject* p = cb->parent(); result = visHeight - (margins + p->marginTop() + p->marginBottom() + p->borderTop() + p->borderBottom() + p->paddingTop() + p->paddingBottom()); } else if (cb->isAnonymousBlock() || treatAsReplaced && style()->htmlHacks()) { // IE quirk. result = cb->calcPercentageHeight(cb->style()->height(), treatAsReplaced); } if (result != -1) { result = height.width(result); if (cb->isTableCell() && !isTable() && style()->boxSizing() != BORDER_BOX) { result -= (borderTop() + paddingTop() + borderBottom() + paddingBottom()); result = kMax(0, result); } } return result;}short RenderBox::calcReplacedWidth() const{ int width = calcReplacedWidthUsing(Width); int minW = calcReplacedWidthUsing(MinWidth); int maxW = style()->maxWidth().value() == UNDEFINED ? width : calcReplacedWidthUsing(MaxWidth); if (width > maxW) width = maxW; if (width < minW) width = minW; return width;}int RenderBox::calcReplacedWidthUsing(WidthType widthType) const{ Length w; if (widthType == Width) w = style()->width(); else if (widthType == MinWidth) w = style()->minWidth(); else w = style()->maxWidth(); switch (w.type()) { case Fixed: return w.value(); case Percent: { const int cw = containingBlockWidth(); if (cw > 0) { int result = w.minWidth(cw); return result; } } // fall through default: return intrinsicWidth(); }}int RenderBox::calcReplacedHeight() const{ int height = calcReplacedHeightUsing(Height); int minH = calcReplacedHeightUsing(MinHeight); int maxH = style()->maxHeight().value() == UNDEFINED ? height : calcReplacedHeightUsing(MaxHeight); if (height > maxH) height = maxH; if (height < minH) height = minH; return height;}int RenderBox::calcReplacedHeightUsing(HeightType heightType) const{ Length h; if (heightType == Height) h = style()->height(); else if (heightType == MinHeight) h = style()->minHeight(); else h = style()->maxHeight(); switch( h.type() ) { case Fixed: return h.value(); case Percent: { int th = calcPercentageHeight(h, true); if (th != -1) return th; // fall through } default: return intrinsicHeight(); };}int RenderBox::availableHeight() const{ return availableHeightUsing(style()->height());}int RenderBox::availableHeightUsing(const Length& h) const{ if (h.isFixed()) return calcContentHeight(h.value()); if (isCanvas()) if (static_cast<const RenderCanvas*>(this)->pagedMode()) return static_cast<const RenderCanvas*>(this)->pageHeight(); else return static_cast<const RenderCanvas*>(this)->viewportHeight(); // We need to stop here, since we don't want to increase the height of the table // artificially. We're going to rely on this cell getting expanded to some new // height, and then when we lay out again we'll use the calculation below. if (isTableCell() && (h.isVariable() || h.isPercent())) { const RenderTableCell* tableCell = static_cast<const RenderTableCell*>(this); return tableCell->cellPercentageHeight() - (borderTop()+borderBottom()+paddingTop()+paddingBottom()); } if (h.isPercent()) return calcContentHeight(h.width(containingBlock()->availableHeight())); return containingBlock()->availableHeight();}void RenderBox::calcVerticalMargins(){ if( isTableCell() ) { // table margins are basically infinite m_marginTop = TABLECELLMARGIN; m_marginBottom = TABLECELLMARGIN; return; } Length tm = style()->marginTop(); Length bm = style()->marginBottom(); // margins are calculated with respect to the _width_ of // the containing block (8.3) int cw = containingBlock()->contentWidth(); m_marginTop = tm.minWidth(cw); m_marginBottom = bm.minWidth(cw);}void RenderBox::setStaticX(short staticX){ m_staticX = staticX;}void RenderBox::setStaticY(int staticY){ m_staticY = staticY;}void RenderBox::calcAbsoluteHorizontal(){ const int AUTO = -666666; int l, r, cw; RenderObject* cb = container(); int pab = (style()->boxSizing() == BORDER_BOX) ? 0 : borderLeft()+ borderRight()+ paddingLeft()+ paddingRight(); l = r = AUTO; cw = containingBlockWidth() + cb->paddingLeft() + cb->paddingRight(); if (!style()->left().isVariable()) l = style()->left().width(cw); if (!style()->right().isVariable()) r = style()->right().width(cw); int static_distance=0; if ((parent()->style()->direction()==LTR && (l==AUTO && r==AUTO )) || style()->left().isStatic()) { // calc hypothetical location in the normal flow // used for 1) left=static-position // 2) left, right, width are all auto -> calc top -> 3. // 3) precalc for case 2 below // all positioned elements are blocks, so that // would be at the left edge static_distance = m_staticX - cb->borderLeft(); // Should already have been set through layout of the parent(). for (RenderObject* po = parent(); po && po != cb; po = po->parent()) static_distance += po->xPos(); if (l==AUTO || style()->left().isStatic()) l = static_distance; } else if ((parent()->style()->direction()==RTL && (l==AUTO && r==AUTO )) || style()->right().isStatic()) { static_distance = m_staticX - cb->borderLeft(); // Should already have been set through layout of the parent(). for (RenderObject* po = parent(); po && po != cb; po = po->parent()) static_distance += po->xPos(); if (r==AUTO || style()->right().isStatic()) r = static_distance; } int w = m_width, ml, mr, x; calcAbsoluteHorizontalValues(Width, cb, cw, pab, static_distance, l, r, w, ml, mr, x); m_width = w; m_marginLeft = ml; m_marginRight = mr; m_x = x; // Avoid doing any work in the common case (where the values of min-width and max-width are their defaults). int minW = m_width, minML, minMR, minX; calcAbsoluteHorizontalValues(MinWidth, cb, cw, pab, static_distance, l, r, minW, minML, minMR, minX); int maxW = m_width, maxML, maxMR, maxX; if (style()->maxWidth().value() != UNDEFINED) calcAbsoluteHorizontalValues(MaxWidth, cb, cw, static_distance, pab, l, r, maxW, maxML, maxMR, maxX); if (m_width > maxW) { m_width = maxW; m_marginLeft = maxML; m_marginRight = maxMR; m_x = maxX; } if (m_width < minW) { m_width = minW; m_marginLeft = minML; m_marginRight = minMR; m_x = minX; }}void RenderBox::calcAbsoluteHorizontalValues(WidthType widthType, RenderObject* cb, int cw, int pab, int static_distance, int l, int r, int& w, int& ml, int& mr, int& x){ const int AUTO = -666666; w = ml = mr = AUTO; if (!style()->marginLeft().isVariable()) ml = style()->marginLeft().width(cw); if (!style()->marginRight().isVariable()) mr = style()->marginRight().width(cw); Length width; if (widthType == Width) width = style()->width(); else if (widthType == MinWidth) width = style()->minWidth(); else width = style()->maxWidth(); if (!width.isVariable()) w = width.width(cw); else if (isReplaced()) w = intrinsicWidth(); if (l != AUTO && w != AUTO && r != AUTO) { // left, width, right all given, play with margins int ot = l + w + r + pab; if (ml==AUTO && mr==AUTO) { // both margins auto, solve for equality ml = (cw - ot)/2; mr = cw - ot - ml; } else if (ml==AUTO) // solve for left margin ml = cw - ot - mr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -