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

📄 render_text.cpp

📁 khtml在gtk上的移植版本
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        curr->setExtracted(false);        last = curr;    }    m_lastTextBox = last;}void RenderText::removeTextBox(InlineTextBox* box){    if (box == m_firstTextBox)        m_firstTextBox = box->nextTextBox();    if (box == m_lastTextBox)        m_lastTextBox = box->prevTextBox();    if (box->nextTextBox())        box->nextTextBox()->setPreviousLineBox(box->prevTextBox());    if (box->prevTextBox())        box->prevTextBox()->setNextLineBox(box->nextTextBox());}void RenderText::deleteTextBoxes(){    if (firstTextBox()) {        RenderArena* arena = renderArena();        InlineTextBox *curr = firstTextBox(), *next = 0;        while (curr) {            next = curr->nextTextBox();            curr->detach(arena);            curr = next;        }        m_firstTextBox = m_lastTextBox = 0;    }}bool RenderText::isTextFragment() const{    return false;}DOM::DOMStringImpl* RenderText::originalString() const{    return element() ? element()->string() : 0;}void RenderText::absoluteRects(QValueList<QRect>& rects, int _tx, int _ty){    for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())        rects.append(QRect(_tx + box->xPos(),                            _ty + box->yPos(),                            box->width(),                            box->height()));}InlineTextBox* RenderText::findNextInlineTextBox(int offset, int &pos){    // The text runs point to parts of the rendertext's str string    // (they don't include '\n')    // Find the text run that includes the character at @p offset    // and return pos, which is the position of the char in the run.    if (!m_firstTextBox)        return 0;        InlineTextBox* s = m_firstTextBox;    int off = s->m_len;    while (offset > off && s->nextTextBox())    {        s = s->nextTextBox();        off = s->m_start + s->m_len;    }    // we are now in the correct text run    pos = (offset > off ? s->m_len : s->m_len - (off - offset) );    return s;}bool RenderText::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty,                             HitTestAction hitTestAction, bool inside){    assert(parent());    for (InlineTextBox *s = m_firstTextBox; s; s = s->nextTextBox()) {        if((_y >=_ty + s->m_y) && (_y < _ty + s->m_y + s->height()) &&           (_x >= _tx + s->m_x) && (_x <_tx + s->m_x + s->m_width) ) {            inside = true;            break;        }    }    if (inside && element()) {        if (info.innerNode() && info.innerNode()->renderer() &&             !info.innerNode()->renderer()->isInline()) {            // Within the same layer, inlines are ALWAYS fully above blocks.  Change inner node.            info.setInnerNode(element());                        // Clear everything else.            info.setInnerNonSharedNode(0);            info.setURLElement(0);        }                if (!info.innerNode())            info.setInnerNode(element());        if (!info.innerNonSharedNode())            info.setInnerNonSharedNode(element());    }    return inside;}Position RenderText::positionForCoordinates(int _x, int _y){    if (!firstTextBox() || stringLength() == 0)        return Position(element(), 0);    int absx, absy;    containingBlock()->absolutePosition(absx, absy);    if (firstTextBox() && _y < absy + firstTextBox()->root()->bottomOverflow() && _x < absx + firstTextBox()->m_x) {        // at the y coordinate of the first line or above        // and the x coordinate is to the left than the first text box left edge        return Position(element(), firstTextBox()->m_start);    }    if (lastTextBox() && _y >= absy + lastTextBox()->root()->topOverflow() && _x >= absx + lastTextBox()->m_x + lastTextBox()->m_width) {        // at the y coordinate of the last line or below        // and the x coordinate is to the right than the last text box right edge        return Position(element(), lastTextBox()->m_start + lastTextBox()->m_len);    }    for (InlineTextBox *box = firstTextBox(); box; box = box->nextTextBox()) {        if (_y >= absy + box->root()->topOverflow() && _y < absy + box->root()->bottomOverflow()) {            if (_x < absx + box->m_x + box->m_width) {                // and the x coordinate is to the left of the right edge of this box                // check to see if position goes in this box                int offset = box->offsetForPosition(_x - absx);                if (offset != -1) {                    return Position(element(), offset + box->m_start);                }            }            else if (!box->prevOnLine() && _x < absx + box->m_x)                // box is first on line                // and the x coordinate is to the left than the first text box left edge                return Position(element(), box->m_start);            else if (!box->nextOnLine() && _x >= absx + box->m_x + box->m_width)                // box is last on line                // and the x coordinate is to the right than the last text box right edge                return Position(element(), box->m_start + box->m_len);        }    }        return Position(element(), 0);}void RenderText::caretPos(int offset, bool override, int &_x, int &_y, int &width, int &height){    if (!firstTextBox() || stringLength() == 0) {        _x = _y = height = -1;        return;    }    // Find the text box for the given offset    InlineTextBox *box = 0;    for (box = firstTextBox(); box; box = box->nextTextBox()) {        if (offset <= box->m_start + box->m_len)            break;    }        if (!box) {        _x = _y = height = -1;        return;    }    height = box->root()->bottomOverflow() - box->root()->topOverflow();    _y = box->root()->topOverflow();    const QFontMetrics &fm = metrics(box->isFirstLineStyle());    QString string(str->s + box->m_start, box->m_len);    long pos = offset - box->m_start; // the number of characters we are into the string    _x = box->m_x + (fm.boundingRect(string, pos)).right();#if 0    // EDIT FIXME    if (pos)        _x += fm.rightBearing(*(str->s + box->m_start + offset));#endif    int absx, absy;    absolutePosition(absx,absy);    _x += absx;    _y += absy;}void RenderText::posOfChar(int chr, int &x, int &y){    absolutePosition( x, y, false );    //if( chr > (int) str->l )    //chr = str->l;    int pos;    InlineTextBox * s = findNextInlineTextBox( chr, pos );    if ( s )    {        // s is the line containing the character        x += s->m_x; // this is the x of the beginning of the line, but it's good enough for now        y += s->m_y;    }}static intsimpleDifferenceBetweenColors(QColor c1, QColor c2){    // a distance could be computed by squaring the differences between components, but    // this is faster and so far seems good enough for our purposes.    return abs(c1.red() - c2.red()) + abs(c1.green() - c2.green()) + abs(c1.blue() - c2.blue());}static QColor correctedTextColor(QColor textColor, QColor backgroundColor) {    // Adjust the text color if it is too close to the background color,    // by darkening or lightening it to move it further away.        int d = simpleDifferenceBetweenColors(textColor, backgroundColor);    // semi-arbitrarily chose 255 value here after a few tests;     if (d > 255) {        return textColor;    }        int distanceFromWhite = simpleDifferenceBetweenColors(textColor, Qt::white);    int distanceFromBlack = simpleDifferenceBetweenColors(textColor, Qt::black);    if (distanceFromWhite < distanceFromBlack) {        return textColor.dark();    }        return textColor.light();}void RenderText::paint(PaintInfo& i, int tx, int ty){    if (i.phase != PaintActionForeground && i.phase != PaintActionSelection)        return;        if (!shouldPaintWithinRoot(i))        return;            if (style()->visibility() != VISIBLE || !firstTextBox())        return;        if (ty + firstTextBox()->yPos() > i.r.y() + i.r.height()) return;    if (ty + lastTextBox()->yPos() + lastTextBox()->height() < i.r.y()) return;        QPainter* p = i.p;    RenderStyle* pseudoStyle = style(true);    if (pseudoStyle == style()) pseudoStyle = 0;    int d = style()->textDecorationsInEffect();    bool isPrinting = (p->device()->devType() == QInternal::Printer);        // Walk forward until we hit the first line that needs to be painted.    InlineTextBox* s = firstTextBox();    for (; s && !s->checkVerticalPoint(i.r.y(), ty, i.r.height()); s = s->nextTextBox());    if (!s) return;        // Now calculate startPos and endPos, for painting selection.    // We paint selection while endPos > 0    int endPos = 0, startPos = 0;    if (!isPrinting && (selectionState() != SelectionNone)) {        if (selectionState() == SelectionInside) {            //kdDebug(6040) << this << " SelectionInside -> 0 to end" << endl;            startPos = 0;            endPos = str->l;        } else {            selectionStartEnd(startPos, endPos);            if(selectionState() == SelectionStart)                endPos = str->l;            else if(selectionState() == SelectionEnd)                startPos = 0;        }        //kdDebug(6040) << this << " Selection from " << startPos << " to " << endPos << endl;    }    const Font *font = &style()->htmlFont();#if APPLE_CHANGES    // Do one pass for the selection, then another for the rest.    bool haveSelection = startPos != endPos && !isPrinting && selectionState() != SelectionNone;    if (!haveSelection && i.phase == PaintActionSelection) {        // When only painting the selection, don't bother to paint if there is none.        return;    }    InlineTextBox* startBox = s;    for (int pass = 0; pass < (haveSelection ? 2 : 1); pass++) {        s = startBox;        bool drawSelectionBackground = haveSelection && pass == 0 && i.phase != PaintActionSelection;        bool drawText = !haveSelection || pass == 1;#endif    // run until we find one that is outside the range, then we    // know we can stop    do {        if (isPrinting)        {            if (ty+s->m_y+s->height() > i.r.y() + i.r.height())            {               RenderCanvas* canvasObj = canvas();               if (ty+s->m_y < canvasObj->truncatedAt())#if APPLE_CHANGES && !KWIQ                   canvasObj->setBestTruncatedAt(ty+s->m_y, this);#else                   canvasObj->setTruncatedAt(ty+s->m_y);#endif               // Let's stop here.               break;            }        }        if (s->m_truncation == cFullTruncation)            continue;                RenderStyle* _style = pseudoStyle && s->m_firstLine ? pseudoStyle : style();        if (_style->font() != p->font())            p->setFont(_style->font());        font = &_style->htmlFont(); // Always update, since smallCaps is not stored in the QFont.#if APPLE_CHANGES        if (drawText) {#endif                QColor textColor = _style->color();        if (_style->shouldCorrectTextColor()) {            textColor = correctedTextColor(textColor, _style->backgroundColor());        }        if(textColor != p->pen().color())            p->setPen(textColor);#if APPLE_CHANGES        // Set a text shadow if we have one.        // FIXME: Support multiple shadow effects.  Need more from the CG API before        // we can do this.        bool setShadow = false;        if (_style->textShadow()) {            p->setShadow(_style->textShadow()->x, _style->textShadow()->y,                         _style->textShadow()->blur, _style->textShadow()->color);            setShadow = true;        }#endif                if (s->m_len > 0) {            bool paintSelectedTextOnly = (i.phase == PaintActionSelection);            bool paintSelectedTextSeparately = false; // Whether or not we have to do multiple paints.  Only                                           // necessary when a custom ::selection foreground color is applied.            QColor selectionColor = p->pen().color();            ShadowData* selectionTextShadow = 0;            if (haveSelection) {                RenderStyle* pseudoStyle = getPseudoStyle(RenderStyle::SELECTION);                if (pseudoStyle) {                    if (pseudoStyle->color() != selectionColor || pseudoStyle->textShadow()) {                        if (!paintSelectedTextOnly)                            paintSelectedTextSeparately = true;                        if (pseudoStyle->color() != selectionColor)                            selectionColor = pseudoStyle->color();                        if (pseudoStyle->textShadow())                            selectionTextShadow = pseudoStyle->textShadow();                    }                }            }                        if (!paintSelectedTextOnly && !paintSelectedTextSeparately) {                // FIXME: Handle RTL direction, handle reversed strings.  For now truncation can only be turned on                // for non-reversed LTR strings.                int endPoint = s->m_len;                if (s->m_truncation != cNoTruncation)                    endPoint = s->m_truncation - s->m_start;                font->drawText(p, s->m_x + tx, s->m_y + ty + s->m_baseline,                               str->s, str->l, s->m_start, endPoint,                               s->m_toAdd, s->m_reversed ? QPainter::RTL : QPainter::LTR, style()->visuallyOrdered());            }            else {                int offset = s->m_start;

⌨️ 快捷键说明

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