⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 render_line.cpp

📁 khtml在gtk上的移植版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
void InlineFlowBox::determineSpacingForFlowBoxes(bool lastLine, RenderObject* endObject){    // All boxes start off open.  They will not apply any margins/border/padding on    // any side.    bool includeLeftEdge = false;    bool includeRightEdge = false;    RenderFlow* flow = static_cast<RenderFlow*>(object());        if (!flow->firstChild())        includeLeftEdge = includeRightEdge = true; // Empty inlines never split across lines.    else if (parent()) { // The root inline box never has borders/margins/padding.        bool ltr = flow->style()->direction() == LTR;                // Check to see if all initial lines are unconstructed.  If so, then        // we know the inline began on this line.        if (!flow->firstLineBox()->isConstructed()) {            if (ltr && flow->firstLineBox() == this)                includeLeftEdge = true;            else if (!ltr && flow->lastLineBox() == this)                includeRightEdge = true;        }            // In order to determine if the inline ends on this line, we check three things:        // (1) If we are the last line and we don't have a continuation(), then we can        // close up.        // (2) If the last line box for the flow has an object following it on the line (ltr,        // reverse for rtl), then the inline has closed.        // (3) The line may end on the inline.  If we are the last child (climbing up        // the end object's chain), then we just closed as well.        if (!flow->lastLineBox()->isConstructed()) {            if (ltr) {                if (!nextLineBox() &&                    ((lastLine && !object()->continuation()) || nextOnLineExists()                     || onEndChain(endObject)))                    includeRightEdge = true;            }            else {                if ((!prevLineBox() || !prevLineBox()->isConstructed()) &&                    ((lastLine && !object()->continuation()) ||                     prevOnLineExists() || onEndChain(endObject)))                    includeLeftEdge = true;            }                    }    }    setEdges(includeLeftEdge, includeRightEdge);    // Recur into our children.    for (InlineBox* currChild = firstChild(); currChild; currChild = currChild->nextOnLine()) {        if (currChild->isInlineFlowBox()) {            InlineFlowBox* currFlow = static_cast<InlineFlowBox*>(currChild);            currFlow->determineSpacingForFlowBoxes(lastLine, endObject);        }    }}int InlineFlowBox::placeBoxesHorizontally(int x){    // Set our x position.    setXPos(x);    int startX = x;    x += borderLeft() + paddingLeft();        for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {        if (curr->object()->isText()) {            InlineTextBox* text = static_cast<InlineTextBox*>(curr);            text->setXPos(x);            x += text->width();        }        else {            if (curr->object()->isPositioned()) {                if (curr->object()->parent()->style()->direction() == LTR)                    curr->setXPos(x);                else {                    // Our offset that we cache needs to be from the edge of the right border box and                    // not the left border box.  We have to subtract |x| from the width of the block                    // (which can be obtained by walking up to the root line box).                    InlineBox* root = this;                    while (!root->isRootInlineBox())                        root = root->parent();                    curr->setXPos(root->object()->width()-x);                }                continue; // The positioned object has no effect on the width.            }            if (curr->object()->isInlineFlow()) {                InlineFlowBox* flow = static_cast<InlineFlowBox*>(curr);                if (curr->object()->isCompact()) {                    int ignoredX = x;                    flow->placeBoxesHorizontally(ignoredX);                }                else {                    x += flow->marginLeft();                    x = flow->placeBoxesHorizontally(x);                    x += flow->marginRight();                }            }            else if (!curr->object()->isCompact()) {                x += curr->object()->marginLeft();                curr->setXPos(x);                x += curr->width() + curr->object()->marginRight();            }        }    }    x += borderRight() + paddingRight();    setWidth(x-startX);    return x;}void InlineFlowBox::verticallyAlignBoxes(int& heightOfBlock){    int maxPositionTop = 0;    int maxPositionBottom = 0;    int maxAscent = 0;    int maxDescent = 0;    // Figure out if we're in strict mode.  Note that we can't simply use !style()->htmlHacks(),    // because that would match almost strict mode as well.    RenderObject* curr = object();    while (curr && !curr->element())        curr = curr->container();    bool strictMode = (curr && curr->element()->getDocument()->inStrictMode());        computeLogicalBoxHeights(maxPositionTop, maxPositionBottom, maxAscent, maxDescent, strictMode);    if (maxAscent + maxDescent < kMax(maxPositionTop, maxPositionBottom))        adjustMaxAscentAndDescent(maxAscent, maxDescent, maxPositionTop, maxPositionBottom);    int maxHeight = maxAscent + maxDescent;    int topPosition = heightOfBlock;    int bottomPosition = heightOfBlock;    placeBoxesVertically(heightOfBlock, maxHeight, maxAscent, strictMode, topPosition, bottomPosition);    setOverflowPositions(topPosition, bottomPosition);    // Shrink boxes with no text children in quirks and almost strict mode.    if (!strictMode)        shrinkBoxesWithNoTextChildren(topPosition, bottomPosition);        heightOfBlock += maxHeight;}void InlineFlowBox::adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent,                                              int maxPositionTop, int maxPositionBottom){    for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {        // The computed lineheight needs to be extended for the        // positioned elements        if (curr->object()->isPositioned())            continue; // Positioned placeholders don't affect calculations.        if (curr->yPos() == PositionTop || curr->yPos() == PositionBottom) {            if (curr->yPos() == PositionTop) {                if (maxAscent + maxDescent < curr->height())                    maxDescent = curr->height() - maxAscent;            }            else {                if (maxAscent + maxDescent < curr->height())                    maxAscent = curr->height() - maxDescent;            }            if (maxAscent + maxDescent >= kMax(maxPositionTop, maxPositionBottom))                break;        }        if (curr->isInlineFlowBox())            static_cast<InlineFlowBox*>(curr)->adjustMaxAscentAndDescent(maxAscent, maxDescent, maxPositionTop, maxPositionBottom);    }}void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositionBottom,                                             int& maxAscent, int& maxDescent, bool strictMode){    if (isRootInlineBox()) {        // Examine our root box.        setHeight(object()->lineHeight(m_firstLine, true));        bool isTableCell = object()->isTableCell();        if (isTableCell) {            RenderTableCell* tableCell = static_cast<RenderTableCell*>(object());            setBaseline(tableCell->RenderBlock::baselinePosition(m_firstLine, true));        }        else            setBaseline(object()->baselinePosition(m_firstLine, true));        if (hasTextChildren() || strictMode) {            int ascent = baseline();            int descent = height() - ascent;            if (maxAscent < ascent)                maxAscent = ascent;            if (maxDescent < descent)                maxDescent = descent;        }    }        for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {        if (curr->object()->isPositioned())            continue; // Positioned placeholders don't affect calculations.                curr->setHeight(curr->object()->lineHeight(m_firstLine));        curr->setBaseline(curr->object()->baselinePosition(m_firstLine));        curr->setYPos(curr->object()->verticalPositionHint(m_firstLine));        if (curr->yPos() == PositionTop) {            if (maxPositionTop < curr->height())                maxPositionTop = curr->height();        }        else if (curr->yPos() == PositionBottom) {            if (maxPositionBottom < curr->height())                maxPositionBottom = curr->height();        }        else if (curr->hasTextChildren() || strictMode) {            int ascent = curr->baseline() - curr->yPos();            int descent = curr->height() - ascent;            if (maxAscent < ascent)                maxAscent = ascent;            if (maxDescent < descent)                maxDescent = descent;        }        if (curr->isInlineFlowBox())            static_cast<InlineFlowBox*>(curr)->computeLogicalBoxHeights(maxPositionTop, maxPositionBottom, maxAscent, maxDescent, strictMode);    }}void InlineFlowBox::placeBoxesVertically(int y, int maxHeight, int maxAscent, bool strictMode,                                         int& topPosition, int& bottomPosition){    if (isRootInlineBox())        setYPos(y + maxAscent - baseline());// Place our root box.        for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {        if (curr->object()->isPositioned())            continue; // Positioned placeholders don't affect calculations.                // Adjust boxes to use their real box y/height and not the logical height (as dictated by        // line-height).        if (curr->isInlineFlowBox())            static_cast<InlineFlowBox*>(curr)->placeBoxesVertically(y, maxHeight, maxAscent, strictMode,                                                                    topPosition, bottomPosition);        bool childAffectsTopBottomPos = true;        if (curr->yPos() == PositionTop)            curr->setYPos(y);        else if (curr->yPos() == PositionBottom)            curr->setYPos(y + maxHeight - curr->height());        else {            if (!curr->hasTextChildren() && !strictMode)                childAffectsTopBottomPos = false;            curr->setYPos(curr->yPos() + y + maxAscent - curr->baseline());        }                int newY = curr->yPos();        int newHeight = curr->height();        int newBaseline = curr->baseline();        if (curr->isInlineTextBox() || curr->isInlineFlowBox()) {            const QFontMetrics &fm = curr->object()->fontMetrics( m_firstLine );            newBaseline = fm.ascent();            newY += curr->baseline() - newBaseline;            newHeight = newBaseline+fm.descent();            if (curr->isInlineFlowBox()) {                newHeight += curr->object()->borderTop() + curr->object()->paddingTop() +                            curr->object()->borderBottom() + curr->object()->paddingBottom();                newY -= curr->object()->borderTop() + curr->object()->paddingTop();                newBaseline += curr->object()->borderTop() + curr->object()->paddingTop();            }	        }        else {            newY += curr->object()->marginTop();            newHeight = curr->height() - (curr->object()->marginTop() + curr->object()->marginBottom());        }        curr->setYPos(newY);        curr->setHeight(newHeight);        curr->setBaseline(newBaseline);        if (childAffectsTopBottomPos) {            if (newY < topPosition)                topPosition = newY;            if (newY + newHeight > bottomPosition)                bottomPosition = newY + newHeight;        }    }    if (isRootInlineBox()) {        const QFontMetrics &fm = object()->fontMetrics( m_firstLine );        setHeight(fm.ascent()+fm.descent());        setYPos(yPos() + baseline() - fm.ascent());        setBaseline(fm.ascent());        if (hasTextChildren() || strictMode) {            if (yPos() < topPosition)                topPosition = yPos();            if (yPos() + height() > bottomPosition)                bottomPosition = yPos() + height();        }    }}void InlineFlowBox::shrinkBoxesWithNoTextChildren(int topPos, int bottomPos){    // First shrink our kids.    for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {        if (curr->object()->isPositioned())            continue; // Positioned placeholders don't affect calculations.                if (curr->isInlineFlowBox())            static_cast<InlineFlowBox*>(curr)->shrinkBoxesWithNoTextChildren(topPos, bottomPos);    }    // See if we have text children. If not, then we need to shrink ourselves to fit on the line.    if (!hasTextChildren()) {        if (yPos() < topPos)            setYPos(topPos);        if (yPos() + height() > bottomPos)            setHeight(bottomPos - yPos());        if (baseline() > height())            setBaseline(height());    }}void InlineFlowBox::paintBackgroundAndBorder(RenderObject::PaintInfo& i, int _tx, int _ty, int xOffsetOnLine){    // Move x/y to our coordinates.    _tx += m_x;    _ty += m_y;        int w = width();    int h = height();    int my = kMax(_ty, i.r.y());    int mh;    if (_ty < i.r.y())        mh= kMax(0, h - (i.r.y() - _ty));    else        mh = kMin(i.r.height(), h);    QPainter* p = i.p;        // You can use p::first-line to specify a background. If so, the root line boxes for    // a line may actually have to paint a background.    RenderStyle* styleToUse = object()->style(m_firstLine);    if ((!parent() && m_firstLine && styleToUse != object()->style()) ||         (parent() && object()->shouldPaintBackgroundOrBorder())) {        CachedImage* bg = styleToUse->backgroundImage();        bool hasBackgroundImage = bg && (bg->pixmap_size() == bg->valid_rect().size()) &&                                  !bg->isTransparent() && !bg->isErrorImage();        if (!hasBackgroundImage || (!prevLineBox() && !nextLineBox()) || !parent())            object()->paintBackgroundExtended(p, styleToUse->backgroundColor(),

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -