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

📄 khtml_text_operations.cpp

📁 khtml在gtk上的移植版本
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                m_positionEndOffset = subrunEnd;                m_textCharacters = str.unicode() + runStart;                m_textLength = subrunEnd - runStart;                m_lastCharacter = str[subrunEnd - 1];            }            // If we are doing a subrun that doesn't go to the end of the text box,            // come back again to finish handling this text box; don't advance to the next one.            if (m_positionEndOffset < runEnd) {                return;            }            // Advance to the next text box.            InlineTextBox *nextTextBox = m_textBox->nextTextBox();            long nextRunStart = nextTextBox ? nextTextBox->m_start : str.length();            if (nextRunStart > runEnd) {                m_lastTextNodeEndedWithCollapsedSpace = true; // collapsed space between runs or at the end            }            m_textBox = nextTextBox;            return;        }    }}bool TextIterator::handleReplacedElement(){    if (m_lastTextNodeEndedWithCollapsedSpace) {        long offset = m_lastTextNode->nodeIndex();        emitCharacter(' ', m_lastTextNode->parentNode(), offset + 1, offset + 1);        return false;    }    long offset = m_node->nodeIndex();    m_positionNode = m_node->parentNode();    m_positionStartOffset = offset;    m_positionEndOffset = offset + 1;    m_textCharacters = 0;    m_textLength = 0;    m_lastCharacter = 0;    return true;}bool TextIterator::handleNonTextNode(){    switch (m_node->id()) {        case ID_BR: {            long offset = m_node->nodeIndex();            emitCharacter('\n', m_node->parentNode(), offset, offset + 1);            break;        }        case ID_TD:        case ID_TH:            if (m_lastCharacter != '\n' && m_lastTextNode) {                long offset = m_lastTextNode->nodeIndex();                emitCharacter('\t', m_lastTextNode->parentNode(), offset, offset + 1);            }            break;        case ID_BLOCKQUOTE:        case ID_DD:        case ID_DIV:        case ID_DL:        case ID_DT:        case ID_H1:        case ID_H2:        case ID_H3:        case ID_H4:        case ID_H5:        case ID_H6:        case ID_HR:        case ID_LI:        case ID_OL:        case ID_P:        case ID_PRE:        case ID_TR:        case ID_UL:            if (m_lastCharacter != '\n' && m_lastTextNode) {                long offset = m_lastTextNode->nodeIndex();                emitCharacter('\n', m_lastTextNode->parentNode(), offset, offset + 1);            }            break;    }    return true;}void TextIterator::exitNode(){    bool endLine = false;    bool addNewline = false;    switch (m_node->id()) {        case ID_BLOCKQUOTE:        case ID_DD:        case ID_DIV:        case ID_DL:        case ID_DT:        case ID_HR:        case ID_LI:        case ID_OL:        case ID_PRE:        case ID_TR:        case ID_UL:            endLine = true;            break;        case ID_H1:        case ID_H2:        case ID_H3:        case ID_H4:        case ID_H5:        case ID_H6:        case ID_P:            endLine = true;            addNewline = true;            break;    }    if (endLine && m_lastCharacter != '\n' && m_lastTextNode) {        long offset = m_lastTextNode->nodeIndex();        emitCharacter('\n', m_lastTextNode->parentNode(), offset, offset + 1);        m_needAnotherNewline = addNewline;    } else if (addNewline && m_lastTextNode) {        long offset = m_node->childNodeCount();        emitCharacter('\n', m_node, offset, offset);    }}void TextIterator::emitCharacter(QChar c, NodeImpl *textNode, long textStartOffset, long textEndOffset){    m_singleCharacterBuffer = c;    m_positionNode = textNode;    m_positionStartOffset = textStartOffset;    m_positionEndOffset = textEndOffset;    m_textCharacters = &m_singleCharacterBuffer;    m_textLength = 1;    m_lastTextNodeEndedWithCollapsedSpace = false;    m_lastCharacter = c;}Range TextIterator::position() const{    assert(m_positionNode);    return Range(m_positionNode, m_positionStartOffset, m_positionNode, m_positionEndOffset);}CharacterIterator::CharacterIterator()    : m_offset(0), m_runOffset(0), m_atBreak(true){}CharacterIterator::CharacterIterator(const Range &r)    : m_offset(0), m_runOffset(0), m_atBreak(true), m_textIterator(r){    while (!atEnd() && m_textIterator.textLength() == 0) {        m_textIterator.advance();    }}Range CharacterIterator::position() const{    Range r = m_textIterator.position();    if (m_textIterator.textLength() <= 1) {        assert(m_runOffset == 0);    } else {        Node n = r.startContainer();        assert(n == r.endContainer());        long offset = r.startOffset() + m_runOffset;        r.setStart(n, offset);        r.setEnd(n, offset + 1);    }    return r;}void CharacterIterator::advance(long count){    assert(!atEnd());    m_atBreak = false;    long remaining = m_textIterator.textLength() - m_runOffset;    if (count < remaining) {        m_runOffset += count;        m_offset += count;        return;    }    count -= remaining;    m_offset += remaining;    for (m_textIterator.advance(); !atEnd(); m_textIterator.advance()) {        long runLength = m_textIterator.textLength();        if (runLength == 0) {            m_atBreak = true;        } else {            if (count < runLength) {                m_runOffset = count;                m_offset += count;                return;            }            count -= runLength;            m_offset += runLength;        }    }    m_atBreak = true;    m_runOffset = 0;}CircularSearchBuffer::CircularSearchBuffer(const QString &s, bool isCaseSensitive)    : m_target(s){    assert(!s.isEmpty());    if (!isCaseSensitive) {        m_target = s.lower();    }    m_target.replace(nonBreakingSpace, ' ');    m_isCaseSensitive = isCaseSensitive;    m_buffer = static_cast<QChar *>(malloc(s.length() * sizeof(QChar)));    m_cursor = m_buffer;    m_bufferFull = false;}void CircularSearchBuffer::append(const QChar &c){    if (m_isCaseSensitive) {        *m_cursor++ = c.unicode() == nonBreakingSpace ? ' ' : c.unicode();    } else {        *m_cursor++ = c.unicode() == nonBreakingSpace ? ' ' : c.lower().unicode();    }    if (m_cursor == m_buffer + length()) {        m_cursor = m_buffer;        m_bufferFull = true;    }}// This function can only be used when the buffer is not yet full,// and when then count is small enough to fit in the buffer.// No need for a more general version for the search algorithm.void CircularSearchBuffer::append(long count, const QChar *characters){    long tailSpace = m_buffer + length() - m_cursor;    assert(!m_bufferFull);    assert(count <= tailSpace);    if (m_isCaseSensitive) {        for (long i = 0; i != count; ++i) {            QChar c = characters[i];            m_cursor[i] = c.unicode() == nonBreakingSpace ? ' ' : c.unicode();        }    } else {        for (long i = 0; i != count; ++i) {            QChar c = characters[i];            m_cursor[i] = c.unicode() == nonBreakingSpace ? ' ' : c.lower().unicode();        }    }    if (count < tailSpace) {        m_cursor += count;    } else {        m_bufferFull = true;        m_cursor = m_buffer;    }}long CircularSearchBuffer::neededCharacters() const{    return m_bufferFull ? 0 : m_buffer + length() - m_cursor;}bool CircularSearchBuffer::isMatch() const{    assert(m_bufferFull);    long headSpace = m_cursor - m_buffer;    long tailSpace = length() - headSpace;    return memcmp(m_cursor, m_target.unicode(), tailSpace * sizeof(QChar)) == 0        && memcmp(m_buffer, m_target.unicode() + tailSpace, headSpace * sizeof(QChar)) == 0;}QString plainText(const Range &r){    // Allocate string at the right size, rather than building it up by successive append calls.    long length = 0;    for (TextIterator it(r); !it.atEnd(); it.advance()) {        length += it.textLength();    }#if KWIQ    QString result("", length);#else     QString result("");    result.reserve(length);#endif    for (TextIterator it(r); !it.atEnd(); it.advance()) {        result.append(it.textCharacters(), it.textLength());    }    return result;}Range findPlainText(const Range &r, const QString &s, bool forward, bool caseSensitive){    // FIXME: Can we do Boyer-Moore or equivalent instead for speed?    // FIXME: This code does not allow \n at the moment because of issues with <br>.    // Once we fix those, we can remove this check.    if (s.isEmpty() || s.find('\n') != -1) {        Range result = r;        result.collapse(forward);        return result;    }    CircularSearchBuffer buffer(s, caseSensitive);    bool found = false;    CharacterIterator rangeEnd;    {        CharacterIterator it(r);        while (!it.atEnd()) {            // Fill the buffer.            while (long needed = buffer.neededCharacters()) {                long available = it.numCharacters();                long runLength = kMin(needed, available);                buffer.append(runLength, it.characters());                it.advance(runLength);                if (it.atBreak()) {                    if (it.atEnd()) {                        goto done;                    }                    buffer.clear();                }            }            // Do the search.            do {                if (buffer.isMatch()) {                    // Compute the range for the result.                    found = true;                    rangeEnd = it;                    // If searching forward, stop on the first match.                    // If searching backward, don't stop, so we end up with the last match.                    if (forward) {                        goto done;                    }                }                buffer.append(it.characters()[0]);                it.advance(1);            } while (!it.atBreak());            buffer.clear();        }    }done:    Range result = r;    if (!found) {        result.collapse(!forward);    } else {        CharacterIterator it(r);        it.advance(rangeEnd.characterOffset() - buffer.length());        result.setStart(it.position().startContainer(), it.position().startOffset());        it.advance(buffer.length() - 1);        result.setEnd(it.position().endContainer(), it.position().endOffset());    }    return result;}}

⌨️ 快捷键说明

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