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

📄 render_line.cpp

📁 konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版本源码包.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        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        // see khtmltests/rendering/html_align.html        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));        bool isTableCell = object()->isTableCell();        if (isTableCell) {            RenderTableCell* tableCell = static_cast<RenderTableCell*>(object());            setBaseline(tableCell->RenderBlock::baselinePosition(m_firstLine));        }        else            setBaseline(object()->baselinePosition(m_firstLine));        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.        // CSS2: 10.8.1 - line-height on the block level element specifies the *minimum*        // height of the generated line box        if (hasTextChildren() && maxHeight < object()->lineHeight(m_firstLine))            maxHeight = object()->lineHeight(m_firstLine);    }    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 );#ifdef APPLE_CHANGES            newBaseline = fm.ascent();            newY += curr->baseline() - newBaseline;            newHeight = newBaseline+fm.descent();#else            // only adjust if the leading delta is superior to the font's natural leading            if ( kAbs(fm.ascent() - curr->baseline()) > fm.leading()/2 ) {                int ascent = fm.ascent()+fm.leading()/2;                newBaseline = ascent;                newY += curr->baseline() - newBaseline;                newHeight = fm.lineSpacing();            }#endif            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 );#ifdef APPLE_CHANGES        setHeight(fm.ascent()+fm.descent());        setYPos(yPos() + baseline() - fm.ascent());        setBaseline(fm.ascent());#else        if ( kAbs(fm.ascent() - baseline()) > fm.leading()/2 ) {            int ascent = fm.ascent()+fm.leading()/2;            setHeight(fm.lineSpacing());            setYPos(yPos() + baseline() - ascent);            setBaseline(ascent);        }#endif        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::paintBackgrounds(QPainter* p, const QColor& c, const BackgroundLayer* bgLayer,                                     int my, int mh, int _tx, int _ty, int w, int h, int xoff){    if (!bgLayer)        return;    paintBackgrounds(p, c, bgLayer->next(), my, mh, _tx, _ty, w, h, xoff);    paintBackground(p, c, bgLayer, my, mh, _tx, _ty, w, h, xoff);}void InlineFlowBox::paintBackground(QPainter* p, const QColor& c, const BackgroundLayer* bgLayer,                                    int my, int mh, int _tx, int _ty, int w, int h, int xOffsetOnLine){    CachedImage* bg = bgLayer->backgroundImage();    bool hasBackgroundImage = bg && (bg->pixmap_size() == bg->valid_rect().size()) &&                              !bg->isTransparent() && !bg->isErrorImage();    if (!hasBackgroundImage || (!prevLineBox() && !nextLineBox()) || !parent())        object()->paintBackgroundExtended(p, c, bgLayer, my, mh, _tx, _ty, w, h, borderLeft(), borderRight());    else {        // We have a background image that spans multiple lines.        // We need to adjust _tx and _ty by the width of all previous lines.        // Think of background painting on inlines as though you had one long line, a single continuous        // strip.  Even though that strip has been broken up across multiple lines, you still paint it        // as though you had one single line.  This means each line has to pick up the background where        // the previous line left off.        int startX = _tx - xOffsetOnLine;        int totalWidth = xOffsetOnLine;        for (InlineRunBox* curr = this; curr; curr = curr->nextLineBox())            totalWidth += curr->width();        QRect clipRect(_tx, _ty, width(), height());        clipRect = p->xForm(clipRect);        p->save();        p->setClipRect( clipRect );        object()->paintBackgroundExtended(p, c, bgLayer, my, mh, startX, _ty,                                          totalWidth, h, borderLeft(), borderRight());        p->restore();    }}void InlineFlowBox::paintBackgroundAndBorder(RenderObject::PaintInfo& pI, 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, pI.r.y());    int mh;    if (_ty<pI.r.y())        mh= kMax(0,h-(pI.r.y()-_ty));    else        mh = kMin(pI.r.height(),h);    // 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())) {        QColor c = styleToUse->backgroundColor();        paintBackgrounds(pI.p, c, styleToUse->backgroundLayers(), my, mh, _tx, _ty, w, h, xOffsetOnLine);        // :first-line cannot be used to put borders on a line. Always paint borders with our        // non-first-line style.        if (parent() && object()->style()->hasBorder())            object()->paintBorder(pI.p, _tx, _ty, w, h, object()->style(), includeLeftEdge(), includeRightEdge());    }}static bool shouldDrawDecoration(RenderObject* obj){    bool shouldDraw = false;    for (RenderObject* curr = obj->firstChild();         curr; curr = curr->nextSibling()) {        if (curr->isInlineFlow()) {            shouldDraw = true;            break;        }        else if (curr->isText() && !curr->isBR() && (curr->style()->preserveWS() ||                 !curr->element() || !curr->element()->containsOnlyWhitespace())) {            shouldDraw = true;            break;        }    }    return shouldDraw;}void InlineFlowBox::paintDecorations(RenderObject::PaintInfo& pI, int _tx, int _ty){    // Now paint our text decorations. We only do this if we aren't in quirks mode (i.e., in    // almost-strict mode or strict mode).    _tx += m_x;    _ty += m_y;    RenderStyle* styleToUse = object()->style(m_firstLine);    int deco = parent() ? styleToUse->textDecoration() : styleToUse->textDecorationsInEffect();    if (deco != TDNONE && shouldDrawDecoration(object())) {        // We must have child boxes and have decorations defined.        _tx += borderLeft() + paddingLeft();        int w = m_width - (borderLeft() + paddingLeft() + borderRight() + paddingRight());//    kdDebug() << k_funcinfo << "w: " << w << " deco: " << deco << endl;        if ( !w )            return;        const QFontMetrics &fm = object()->fontMetrics( m_firstLine );        // thick lines on small fonts look ugly        int thickness = fm.height() > 20 ? fm.lineWidth() : 1;        QColor underline, overline, linethrough;        underline = overline = linethrough = styleToUse->color();        if (!parent())            object()->getTextDecorationColors(deco, underline, overline, linethrough);        if (deco & UNDERLINE) {            int underlineOffset = ( fm.height() + m_baseline ) / 2;            if (underlineOffset <= m_baseline) underlineOffset = m_baseline+1;            pI.p->fillRect(_tx, _ty + underlineOffset, w, thickness, underline );        }        if (deco & OVERLINE) {            pI.p->fillRect(_tx, _ty, w, thickness, overline );        }        if (deco & LINE_THROUGH) {            pI.p->fillRect(_tx, _ty + 2*m_baseline/3, w, thickness, linethrough );        }    }}

⌨️ 快捷键说明

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