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

📄 render_line.cpp

📁 khtml在gtk上的移植版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                                              bg, 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->addClip(clipRect);            object()->paintBackgroundExtended(p, object()->style()->backgroundColor(),                                              object()->style()->backgroundImage(), my, mh, startX, _ty,                                              totalWidth, h,                                              borderLeft(), borderRight());            p->restore();        }        // :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(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()->whiteSpace() == PRE ||                 !curr->element() || !curr->element()->containsOnlyWhitespace())) {            shouldDraw = true;            break;        }	    }    return shouldDraw;}void InlineFlowBox::paintDecorations(RenderObject::PaintInfo& i, int _tx, int _ty, bool paintedChildren){    // 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).    QPainter* p = i.p;    _tx += m_x;    _ty += m_y;    RenderStyle* styleToUse = object()->style(m_firstLine);    int deco = parent() ? styleToUse->textDecoration() : styleToUse->textDecorationsInEffect();    if (deco != TDNONE &&         ((!paintedChildren && ((deco & UNDERLINE) || (deco & OVERLINE))) || (paintedChildren && (deco & LINE_THROUGH))) &&        shouldDrawDecoration(object())) {        int x = m_x + borderLeft() + paddingLeft();        int w = m_width - (borderLeft() + paddingLeft() + borderRight() + paddingRight());        RootInlineBox* rootLine = root();        if (rootLine->ellipsisBox()) {            int ellipsisX = rootLine->ellipsisBox()->xPos();            int ellipsisWidth = rootLine->ellipsisBox()->width();                        // FIXME: Will need to work with RTL            if (rootLine == this) {                if (x + w >= ellipsisX + ellipsisWidth)                    w -= (x + w - ellipsisX - ellipsisWidth);            }            else {                if (x >= ellipsisX)                    return;                if (x + w >= ellipsisX)                    w -= (x + w - ellipsisX);            }        }            #if APPLE_CHANGES        // Set up the appropriate text-shadow effect for the decoration.        // FIXME: Support multiple shadow effects.  Need more from the CG API before we can do this.        bool setShadow = false;        if (styleToUse->textShadow()) {            p->setShadow(styleToUse->textShadow()->x, styleToUse->textShadow()->y,                         styleToUse->textShadow()->blur, styleToUse->textShadow()->color);            setShadow = true;        }#endif                // We must have child boxes and have decorations defined.        _tx += borderLeft() + paddingLeft();                QColor underline, overline, linethrough;        underline = overline = linethrough = styleToUse->color();        if (!parent())            object()->getTextDecorationColors(deco, underline, overline, linethrough);        if (styleToUse->font() != p->font())            p->setFont(styleToUse->font());        if (deco & UNDERLINE && !paintedChildren) {            p->setPen(underline);            p->drawLineForText(_tx, _ty, m_baseline, w);        }        if (deco & OVERLINE && !paintedChildren) {            p->setPen(overline);            p->drawLineForText(_tx, _ty, 0, w);        }        if (deco & LINE_THROUGH && paintedChildren) {            p->setPen(linethrough);            p->drawLineForText(_tx, _ty, 2*m_baseline/3, w);        }#if APPLE_CHANGES        if (setShadow)            p->clearShadow();#endif    }}InlineBox* InlineFlowBox::firstLeafChild(){    InlineBox *box = firstChild();    while (box) {        InlineBox* next = 0;        if (!box->isInlineFlowBox())            break;        next = static_cast<InlineFlowBox*>(box)->firstChild();        if (!next)            break;        box = next;    }    return box;}InlineBox* InlineFlowBox::lastLeafChild(){    InlineBox *box = lastChild();    while (box) {        InlineBox* next = 0;        if (!box->isInlineFlowBox())            break;        next = static_cast<InlineFlowBox*>(box)->lastChild();        if (!next)            break;        box = next;    }    return box;}InlineBox* InlineFlowBox::closestChildForXPos(int _x, int _tx){    if (_x < _tx + firstChild()->m_x)        // if the x coordinate is to the left of the first child        return firstChild();     else if (_x >= _tx + lastChild()->m_x + lastChild()->m_width)        // if the x coordinate is to the right of the last child        return lastChild();     else        // look for the closest child;        // check only the right edges, since the left edge of the first        // box has already been checked        for (InlineBox *box = firstChild(); box; box = box->nextOnLine())            if (_x < _tx + box->m_x + box->m_width)                return box;    return 0;}bool InlineFlowBox::canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsisWidth){    for (InlineBox *box = firstChild(); box; box = box->nextOnLine()) {        if (!box->canAccommodateEllipsis(ltr, blockEdge, ellipsisWidth))            return false;    }    return true;}int InlineFlowBox::placeEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth, bool& foundBox){    int result = -1;    for (InlineBox *box = firstChild(); box; box = box->nextOnLine()) {        int currResult = box->placeEllipsisBox(ltr, blockEdge, ellipsisWidth, foundBox);        if (currResult != -1 && result == -1)            result = currResult;    }    return result;}void InlineFlowBox::clearTruncation(){    for (InlineBox *box = firstChild(); box; box = box->nextOnLine())        box->clearTruncation();}void EllipsisBox::paint(RenderObject::PaintInfo& i, int _tx, int _ty){    QPainter* p = i.p;    RenderStyle* _style = m_firstLine ? m_object->style(true) : m_object->style();    if (_style->font() != p->font())        p->setFont(_style->font());    const Font* font = &_style->htmlFont();    QColor textColor = _style->color();    if (textColor != p->pen().color())        p->setPen(textColor);    bool setShadow = false;    if (_style->textShadow()) {        p->setShadow(_style->textShadow()->x, _style->textShadow()->y,                     _style->textShadow()->blur, _style->textShadow()->color);        setShadow = true;    }        const DOMString& str = m_str.string();    font->drawText(p, m_x + _tx,                       m_y + _ty + m_baseline,                      (str.implementation())->s,                      str.length(), 0, str.length(),                      0,                       QPainter::LTR, _style->visuallyOrdered());                          if (setShadow)        p->clearShadow();        if (m_markupBox) {        // Paint the markup box        _tx += m_x + m_width - m_markupBox->xPos();        _ty += m_y + m_baseline - (m_markupBox->yPos() + m_markupBox->baseline());        m_markupBox->object()->paint(i, _tx, _ty);    }}bool EllipsisBox::nodeAtPoint(RenderObject::NodeInfo& info, int _x, int _y, int _tx, int _ty,                              HitTestAction hitTestAction, bool inBox){    if (m_markupBox) {        _tx += m_x + m_width - m_markupBox->xPos();        _ty += m_y + m_baseline - (m_markupBox->yPos() + m_markupBox->baseline());        inBox |= m_markupBox->object()->nodeAtPoint(info, _x, _y, _tx, _ty, hitTestAction, inBox);    }        return inBox;}void RootInlineBox::detach(RenderArena* arena){    detachEllipsisBox(arena);    InlineFlowBox::detach(arena);}void RootInlineBox::detachEllipsisBox(RenderArena* arena){    if (m_ellipsisBox) {        m_ellipsisBox->detach(arena);        m_ellipsisBox = 0;    }}void RootInlineBox::clearTruncation(){    if (m_ellipsisBox) {        detachEllipsisBox(m_object->renderArena());        InlineFlowBox::clearTruncation();    }}bool RootInlineBox::canAccommodateEllipsis(bool ltr, int blockEdge, int lineBoxEdge, int ellipsisWidth){    // First sanity-check the unoverflowed width of the whole line to see if there is sufficient room.    int delta = ltr ? lineBoxEdge - blockEdge : blockEdge - lineBoxEdge;    if (width() - delta < ellipsisWidth)        return false;    // Next iterate over all the line boxes on the line.  If we find a replaced element that intersects    // then we refuse to accommodate the ellipsis.  Otherwise we're ok.    return InlineFlowBox::canAccommodateEllipsis(ltr, blockEdge, ellipsisWidth);}void RootInlineBox::placeEllipsis(const AtomicString& ellipsisStr,  bool ltr, int blockEdge, int ellipsisWidth,                                  InlineBox* markupBox){    // Create an ellipsis box.    m_ellipsisBox = new (m_object->renderArena()) EllipsisBox(m_object, ellipsisStr, this,                                                               ellipsisWidth - (markupBox ? markupBox->width() : 0),                                                              yPos(), height(), baseline(), !prevRootBox(),                                                              markupBox);    if (ltr && (xPos() + width() + ellipsisWidth) <= blockEdge) {        m_ellipsisBox->m_x = xPos() + width();        return;    }    // Now attempt to find the nearest glyph horizontally and place just to the right (or left in RTL)    // of that glyph.  Mark all of the objects that intersect the ellipsis box as not painting (as being    // truncated).    bool foundBox = false;    m_ellipsisBox->m_x = placeEllipsisBox(ltr, blockEdge, ellipsisWidth, foundBox);}int RootInlineBox::placeEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth, bool& foundBox){    int result = InlineFlowBox::placeEllipsisBox(ltr, blockEdge, ellipsisWidth, foundBox);    if (result == -1)        result = ltr ? blockEdge - ellipsisWidth : blockEdge;    return result;}void RootInlineBox::paintEllipsisBox(RenderObject::PaintInfo& i, int _tx, int _ty) const{    if (m_ellipsisBox)        m_ellipsisBox->paint(i, _tx, _ty);}bool RootInlineBox::hitTestEllipsisBox(RenderObject::NodeInfo& info, int _x, int _y, int _tx, int _ty,                                       HitTestAction hitTestAction, bool inBox){    if (m_ellipsisBox)        inBox |= m_ellipsisBox->nodeAtPoint(info, _x, _y, _tx, _ty, hitTestAction, inBox);    return inBox;}void RootInlineBox::adjustPosition(int dx, int dy){    InlineFlowBox::adjustPosition(dx, dy);    m_topOverflow += dy;    m_bottomOverflow += dy;    m_blockHeight += dy;}void RootInlineBox::childRemoved(InlineBox* box){    if (box->object() == m_lineBreakObj)        setLineBreakInfo(0,0);    RootInlineBox* prev = prevRootBox();    if (prev && prev->lineBreakObj() == box->object()) {        prev->setLineBreakInfo(0,0);        prev->markDirty();    }}}

⌨️ 快捷键说明

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