📄 render_flow.cpp
字号:
return lh.minWidth(s->font().pixelSize()); return lh.value; } if (m_lineHeight == -1) m_lineHeight = RenderObject::lineHeight(false); return m_lineHeight;}void RenderFlow::dirtyLineBoxes(bool fullLayout, bool isRootLineBox){ if (!isRootLineBox && isReplaced()) return RenderBox::dirtyLineBoxes(isRootLineBox); if (fullLayout) deleteLineBoxes(); else { for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) curr->dirtyLineBoxes(); }}InlineBox* RenderFlow::createInlineBox(bool makePlaceHolderBox, bool isRootLineBox, bool isOnlyRun){ if (!isRootLineBox && (isReplaced() || makePlaceHolderBox)) // Inline tables and inline blocks return RenderBox::createInlineBox(false, isRootLineBox); // (or positioned element placeholders). InlineFlowBox* flowBox = 0; if (isInlineFlow()) flowBox = new (renderArena()) InlineFlowBox(this); else flowBox = new (renderArena()) RootInlineBox(this); if (!m_firstLineBox) m_firstLineBox = m_lastLineBox = flowBox; else { m_lastLineBox->setNextLineBox(flowBox); flowBox->setPreviousLineBox(m_lastLineBox); m_lastLineBox = flowBox; } return flowBox;}void RenderFlow::paintLineBoxBackgroundBorder(PaintInfo& i, int _tx, int _ty){ if (!shouldPaintWithinRoot(i)) return; if (!firstLineBox()) return; if (style()->visibility() == VISIBLE && i.phase == PaintActionForeground) { // We can check the first box and last box and avoid painting if we don't // intersect. int yPos = _ty + firstLineBox()->yPos(); int h = lastLineBox()->yPos() + lastLineBox()->height() - firstLineBox()->yPos(); if( (yPos >= i.r.y() + i.r.height()) || (yPos + h <= i.r.y())) return; // See if our boxes intersect with the dirty rect. If so, then we paint // them. Note that boxes can easily overlap, so we can't make any assumptions // based off positions of our first line box or our last line box. int xOffsetWithinLineBoxes = 0; for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) { yPos = _ty + curr->yPos(); h = curr->height(); if ((yPos < i.r.y() + i.r.height()) && (yPos + h > i.r.y())) curr->paintBackgroundAndBorder(i, _tx, _ty, xOffsetWithinLineBoxes); xOffsetWithinLineBoxes += curr->width(); } }}void RenderFlow::paintLineBoxDecorations(PaintInfo& i, int _tx, int _ty, bool paintedChildren){ if (!shouldPaintWithinRoot(i)) return; // We only paint line box decorations in strict or almost strict mode. // Otherwise we let the InlineTextBoxes paint their own decorations. if (style()->htmlHacks() || !firstLineBox()) return; if (style()->visibility() == VISIBLE && i.phase == PaintActionForeground) { // We can check the first box and last box and avoid painting if we don't // intersect. int yPos = _ty + firstLineBox()->yPos();; int h = lastLineBox()->yPos() + lastLineBox()->height() - firstLineBox()->yPos(); if( (yPos >= i.r.y() + i.r.height()) || (yPos + h <= i.r.y())) return; // See if our boxes intersect with the dirty rect. If so, then we paint // them. Note that boxes can easily overlap, so we can't make any assumptions // based off positions of our first line box or our last line box. for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) { yPos = _ty + curr->yPos(); h = curr->height(); if ((yPos < i.r.y() + i.r.height()) && (yPos + h > i.r.y())) curr->paintDecorations(i, _tx, _ty, paintedChildren); } }}QRect RenderFlow::getAbsoluteRepaintRect(){ if (isInlineFlow()) { // Find our leftmost position. int left = 0; int top = firstLineBox() ? firstLineBox()->yPos() : 0; for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) if (curr == firstLineBox() || curr->xPos() < left) left = curr->xPos(); // Now invalidate a rectangle. int ow = style() ? style()->outlineSize() : 0; if (isCompact()) left -= m_x; if (style()->position() == RELATIVE && m_layer) m_layer->relativePositionOffset(left, top); QRect r(-ow+left, -ow+top, width()+ow*2, height()+ow*2); containingBlock()->computeAbsoluteRepaintRect(r); if (ow) { for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) { if (!curr->isText()) { QRect childRect = curr->getAbsoluteRepaintRectWithOutline(ow); r = r.unite(childRect); } } if (continuation() && !continuation()->isInline()) { QRect contRect = continuation()->getAbsoluteRepaintRectWithOutline(ow); r = r.unite(contRect); } } return r; } else { if (firstLineBox() && firstLineBox()->topOverflow() < 0) { int ow = style() ? style()->outlineSize() : 0; QRect r(-ow, -ow+firstLineBox()->topOverflow(), overflowWidth(false)+ow*2, overflowHeight(false)+ow*2-firstLineBox()->topOverflow()); computeAbsoluteRepaintRect(r); return r; } } return RenderBox::getAbsoluteRepaintRect();}intRenderFlow::lowestPosition(bool includeOverflowInterior, bool includeSelf) const{ int bottom = RenderBox::lowestPosition(includeOverflowInterior, includeSelf); if (!includeOverflowInterior && hasOverflowClip()) return bottom; // FIXME: Come up with a way to use the layer tree to avoid visiting all the kids. // For now, we have to descend into all the children, since we may have a huge abs div inside // a tiny rel div buried somewhere deep in our child tree. In this case we have to get to // the abs div. for (RenderObject *c = firstChild(); c; c = c->nextSibling()) { if (!c->isFloatingOrPositioned() && !c->isText()) { int lp = c->yPos() + c->lowestPosition(false); bottom = kMax(bottom, lp); } } return bottom;}int RenderFlow::rightmostPosition(bool includeOverflowInterior, bool includeSelf) const{ int right = RenderBox::rightmostPosition(includeOverflowInterior, includeSelf); if (!includeOverflowInterior && hasOverflowClip()) return right; // FIXME: Come up with a way to use the layer tree to avoid visiting all the kids. // For now, we have to descend into all the children, since we may have a huge abs div inside // a tiny rel div buried somewhere deep in our child tree. In this case we have to get to // the abs div. for (RenderObject *c = firstChild(); c; c = c->nextSibling()) { if (!c->isFloatingOrPositioned() && !c->isText()) { int rp = c->xPos() + c->rightmostPosition(false); right = kMax(right, rp); } } return right;}int RenderFlow::leftmostPosition(bool includeOverflowInterior, bool includeSelf) const{ int left = RenderBox::leftmostPosition(includeOverflowInterior, includeSelf); if (!includeOverflowInterior && hasOverflowClip()) return left; // FIXME: Come up with a way to use the layer tree to avoid visiting all the kids. // For now, we have to descend into all the children, since we may have a huge abs div inside // a tiny rel div buried somewhere deep in our child tree. In this case we have to get to // the abs div. for (RenderObject *c = firstChild(); c; c = c->nextSibling()) { if (!c->isFloatingOrPositioned() && !c->isText()) { int lp = c->xPos() + c->leftmostPosition(false); left = kMin(left, lp); } } return left;}void RenderFlow::caretPos(int offset, bool override, int &_x, int &_y, int &width, int &height){ if (firstChild() || style()->display() == INLINE) { // Do the normal calculation RenderBox::caretPos(offset, override, _x, _y, width, height); return; } // This is a special case: // The element is not an inline element, and it's empty. So we have to // calculate a fake position to indicate where objects are to be inserted. // EDIT FIXME: this does neither take into regard :first-line nor :first-letter // However, as soon as some content is entered, the line boxes will be // constructed properly and this kludge is not called any more. So only // the caret size of an empty :first-line'd block is wrong, but I think we // can live with that. RenderStyle *currentStyle = style(true); //height = currentStyle->fontMetrics().height(); height = lineHeight(true); width = 1; // EDIT FIXME: This needs to account for text direction int w = this->width(); switch (currentStyle->textAlign()) { case LEFT: case KHTML_LEFT: case TAAUTO: case JUSTIFY: _x = 0; break; case CENTER: case KHTML_CENTER: _x = w / 2; break; case RIGHT: case KHTML_RIGHT: _x = w; break; } _y = 0; int absx, absy; absolutePosition(absx, absy, false); _x += absx + paddingLeft() + borderLeft(); _y += absy + paddingTop() + borderTop();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -