📄 render_box.cpp
字号:
else if (mr==AUTO) // solve for right margin mr = cw - ot - ml; else { // overconstrained, solve according to dir if (style()->direction()==LTR) r = cw - ( l + w + ml + mr + pab); else l = cw - ( r + w + ml + mr + pab); } } else { // one or two of (left, width, right) missing, solve // auto margins are ignored if (ml==AUTO) ml = 0; if (mr==AUTO) mr = 0; //1. solve left & width. if (l==AUTO && w==AUTO && r!=AUTO) { w = kMin(kMax(m_minWidth - pab, cw - (r + ml + mr + pab)), m_maxWidth - pab); l = cw - ( r + w + ml + mr + pab); } else //2. solve left & right. use static positioning. if (l==AUTO && w!=AUTO && r==AUTO) { if (style()->direction()==RTL) { r = static_distance; l = cw - ( r + w + ml + mr + pab); } else { l = static_distance; r = cw - ( l + w + ml + mr + pab); } } else //3. solve width & right. if (l!=AUTO && w==AUTO && r==AUTO) { w = kMin(kMax(m_minWidth - pab, cw - (l + ml + mr + pab)), m_maxWidth - pab); r = cw - ( l + w + ml + mr + pab); } else //4. solve left if (l==AUTO && w!=AUTO && r!=AUTO) l = cw - ( r + w + ml + mr + pab); else //5. solve width if (l!=AUTO && w==AUTO && r!=AUTO) w = cw - ( r + l + ml + mr + pab); else //6. solve right if (l!=AUTO && w!=AUTO && r==AUTO) r = cw - ( l + w + ml + mr + pab); } w += pab; x = l + ml + cb->borderLeft();}void RenderBox::calcAbsoluteVertical(){ // css2 spec 10.6.4 & 10.6.5 // based on // http://www.w3.org/Style/css2-updates/REC-CSS2-19980512-errata // (actually updated 2000-10-24) // that introduces static-position value for top, left & right const int AUTO = -666666; int t, b, ch; t = b = AUTO; int pab = (style()->boxSizing() == BORDER_BOX) ? 0 : borderTop()+borderBottom()+paddingTop()+paddingBottom(); RenderObject* cb = container(); Length hl = cb->style()->height(); if (hl.isFixed()) { if (cb->style()->boxSizing() == BORDER_BOX) ch = kMax(0, hl.value() - cb->borderTop() - cb->borderBottom()); else ch = hl.value() + cb->paddingTop() + cb->paddingBottom(); } else if (cb->isCanvas() || cb->isRoot()) ch = cb->availableHeight(); else ch = cb->height() - cb->borderTop() - cb->borderBottom(); if(!style()->top().isVariable()) t = style()->top().width(ch); if(!style()->bottom().isVariable()) b = style()->bottom().width(ch); int h, mt, mb, y; calcAbsoluteVerticalValues(Height, cb, ch, pab, t, b, h, mt, mb, y); // Avoid doing any work in the common case (where the values of min-height and max-height are their defaults). int minH = h, minMT, minMB, minY; calcAbsoluteVerticalValues(MinHeight, cb, ch, pab, t, b, minH, minMT, minMB, minY); int maxH = h, maxMT, maxMB, maxY; if (style()->maxHeight().value() != UNDEFINED) calcAbsoluteVerticalValues(MaxHeight, cb, ch, pab, t, b, maxH, maxMT, maxMB, maxY); if (h > maxH) { h = maxH; mt = maxMT; mb = maxMB; y = maxY; } if (h < minH) { h = minH; mt = minMT; mb = minMB; y = minY; }#ifdef APPLE_CHANGES // If our natural height exceeds the new height once we've set it, then we need to make sure to update // overflow to track the spillout. if (m_height > h) setOverflowHeight(m_height);#endif // Set our final values. m_height = h; m_marginTop = mt; m_marginBottom = mb; m_y = y;}void RenderBox::calcAbsoluteVerticalValues(HeightType heightType, RenderObject* cb, int ch, int pab, int t, int b, int& h, int& mt, int& mb, int& y){ const int AUTO = -666666; h = mt = mb = AUTO; if (!style()->marginTop().isVariable()) mt = style()->marginTop().width(ch); if (!style()->marginBottom().isVariable()) mb = style()->marginBottom().width(ch); Length height; if (heightType == Height) height = style()->height(); else if (heightType == MinHeight) height = style()->minHeight(); else height = style()->maxHeight(); int ourHeight = m_height; if (isTable() && height.isVariable()) // Height is never unsolved for tables. "auto" means shrink to fit. Use our // height instead. h = ourHeight - pab; else if (!height.isVariable()) { h = height.width(ch); if (ourHeight - pab > h) ourHeight = h + pab; } else if (isReplaced()) h = intrinsicHeight(); int static_top=0; if ((t==AUTO && b==AUTO ) || style()->top().isStatic()) { // calc hypothetical location in the normal flow // used for 1) top=static-position // 2) top, bottom, height are all auto -> calc top -> 3. // 3) precalc for case 2 below static_top = m_staticY -cb->borderTop(); // Should already have been set through layout of the parent(). RenderObject* po = parent(); for (; po && po != cb; po = po->parent()) static_top += po->yPos(); if (h==AUTO || style()->top().isStatic()) t = static_top; } if (t!=AUTO && h!=AUTO && b!=AUTO) { // top, height, bottom all given, play with margins int ot = h + t + b + pab; if (mt==AUTO && mb==AUTO) { // both margins auto, solve for equality mt = (ch - ot)/2; mb = ch - ot - mt; } else if (mt==AUTO) // solve for top margin mt = ch - ot - mb; else if (mb==AUTO) // solve for bottom margin mb = ch - ot - mt; else // overconstrained, solve for bottom b = ch - ( h+t+mt+mb+pab); } else { // one or two of (top, height, bottom) missing, solve // auto margins are ignored if (mt==AUTO) mt = 0; if (mb==AUTO) mb = 0; //1. solve top & height. use content height. if (t==AUTO && h==AUTO && b!=AUTO) { h = ourHeight - pab; t = ch - ( h+b+mt+mb+pab); } else //2. solve top & bottom. use static positioning. if (t==AUTO && h!=AUTO && b==AUTO) { t = static_top; b = ch - ( h+t+mt+mb+pab); } else //3. solve height & bottom. use content height. if (t!=AUTO && h==AUTO && b==AUTO) { h = ourHeight - pab; b = ch - ( h+t+mt+mb+pab); } else //4. solve top if (t==AUTO && h!=AUTO && b!=AUTO) t = ch - ( h+b+mt+mb+pab); else //5. solve height if (t!=AUTO && h==AUTO && b!=AUTO) h = ch - ( t+b+mt+mb+pab); else //6. solve bottom if (t!=AUTO && h!=AUTO && b==AUTO) b = ch - ( h+t+mt+mb+pab); } if (ourHeight < h + pab) //content must still fit ourHeight = h + pab; if (hasOverflowClip() && ourHeight > h + pab) ourHeight = h + pab; // Do not allow the height to be negative. This can happen when someone specifies both top and bottom // but the containing block height is less than top, e.g., top:20px, bottom:0, containing block height 16. ourHeight = kMax(0, ourHeight); h = ourHeight; y = t + mt + cb->borderTop();}int RenderBox::lowestPosition(bool /*includeOverflowInterior*/, bool includeSelf) const{ return includeSelf ? m_height : 0;}int RenderBox::rightmostPosition(bool /*includeOverflowInterior*/, bool includeSelf) const{ return includeSelf ? m_width : 0;}int RenderBox::leftmostPosition(bool /*includeOverflowInterior*/, bool includeSelf) const{ return includeSelf ? 0 : m_width;}int RenderBox::pageTopAfter(int y) const{ RenderObject* cb = container(); if (cb) return cb->pageTopAfter(y+yPos()) - yPos(); else return 0;}int RenderBox::crossesPageBreak(int t, int b) const{ RenderObject* cb = container(); if (cb) return cb->crossesPageBreak(yPos()+t, yPos()+b); else return false;}void RenderBox::caretPos(int /*offset*/, int flags, int &_x, int &_y, int &width, int &height){#if 0 _x = -1; // propagate it downwards to its children, someone will feel responsible RenderObject *child = firstChild();// if (child) kdDebug(6040) << "delegating caretPos to " << child->renderName() << endl; if (child) child->caretPos(offset, override, _x, _y, width, height); // if not, use the extents of this box. offset 0 means left, offset 1 means // right if (_x == -1) { //kdDebug(6040) << "no delegation" << endl; _x = xPos() + (offset == 0 ? 0 : m_width); _y = yPos(); height = m_height; width = override && offset == 0 ? m_width : 1; // If height of box is smaller than font height, use the latter one, // otherwise the caret might become invisible. // FIXME: ignoring :first-line, missing good reason to take care of int fontHeight = style()->fontMetrics().height(); if (fontHeight > height) height = fontHeight; int absx, absy; RenderObject *cb = containingBlock(); if (cb && cb != this && cb->absolutePosition(absx,absy)) { //kdDebug(6040) << "absx=" << absx << " absy=" << absy << endl; _x += absx; _y += absy; } else { // we don't know our absolute position, and there is no point returning // just a relative one _x = _y = -1; } }#endif _x = xPos(); _y = yPos();// kdDebug(6040) << "_x " << _x << " _y " << _y << endl; width = 1; // no override is indicated in boxes RenderBlock *cb = containingBlock(); // Place caret outside the border if (flags & CFOutside) { RenderStyle *s = element() && element()->parent() && element()->parent()->renderer() ? element()->parent()->renderer()->style() : cb->style(); const QFontMetrics &fm = s->fontMetrics(); height = fm.height(); bool rtl = s->direction() == RTL; bool outsideEnd = flags & CFOutsideEnd; if (outsideEnd) { _x += this->width(); } else { _x--; } int hl = fm.leading() / 2; if (!isReplaced() || style()->display() == BLOCK) { if (!outsideEnd ^ rtl) _y -= hl; else _y += kMax(this->height() - fm.ascent() - hl, 0); } else { _y += baselinePosition(false) - fm.ascent() - hl; } // Place caret inside the element } else { const QFontMetrics &fm = style()->fontMetrics(); height = fm.height(); RenderStyle *s = style(); _x += borderLeft() + paddingLeft(); _y += borderTop() + paddingTop(); // ### regard direction switch (s->textAlign()) { case LEFT: case KHTML_LEFT: case TAAUTO: // ### find out what this does case JUSTIFY: break; case CENTER: case KHTML_CENTER: _x += contentWidth() / 2; break; case KHTML_RIGHT: case RIGHT: _x += contentWidth(); break; } } int absx, absy; if (cb && cb != this && cb->absolutePosition(absx,absy)) {// kdDebug(6040) << "absx=" << absx << " absy=" << absy << endl; _x += absx; _y += absy; } else { // we don't know our absolute position, and there is no point returning // just a relative one _x = _y = -1; }}#undef DEBUG_LAYOUT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -