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

📄 rendertext.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    return prev;}void RenderText::setTextInternal(PassRefPtr<StringImpl> text){    m_text = text;    ASSERT(m_text);    m_text = document()->displayStringModifiedByEncoding(PassRefPtr<StringImpl>(m_text));#if ENABLE(SVG)    if (isSVGText()) {        if (style() && style()->whiteSpace() == PRE) {            // Spec: When xml:space="preserve", the SVG user agent will do the following using a            // copy of the original character data content. It will convert all newline and tab            // characters into space characters. Then, it will draw all space characters, including            // leading, trailing and multiple contiguous space characters.            m_text = m_text->replace('\n', ' ');            // If xml:space="preserve" is set, white-space is set to "pre", which            // preserves leading, trailing & contiguous space character for us.       } else {            // Spec: When xml:space="default", the SVG user agent will do the following using a            // copy of the original character data content. First, it will remove all newline            // characters. Then it will convert all tab characters into space characters.            // Then, it will strip off all leading and trailing space characters.            // Then, all contiguous space characters will be consolidated.               m_text = m_text->replace('\n', StringImpl::empty());           // If xml:space="default" is set, white-space is set to "nowrap", which handles           // leading, trailing & contiguous space character removal for us.        }        m_text = m_text->replace('\t', ' ');    }#endif    if (style()) {        switch (style()->textTransform()) {            case TTNONE:                break;            case CAPITALIZE: {                m_text = m_text->capitalize(previousCharacter());                break;            }            case UPPERCASE:                m_text = m_text->upper();                break;            case LOWERCASE:                m_text = m_text->lower();                break;        }        // We use the same characters here as for list markers.        // See the listMarkerText function in RenderListMarker.cpp.        switch (style()->textSecurity()) {            case TSNONE:                break;            case TSCIRCLE:                m_text = m_text->secure(whiteBullet);                break;            case TSDISC:                m_text = m_text->secure(bullet);                break;            case TSSQUARE:                m_text = m_text->secure(blackSquare);        }    }    ASSERT(m_text);    ASSERT(!isBR() || (textLength() == 1 && (*m_text)[0] == '\n'));    m_isAllASCII = charactersAreAllASCII(m_text.get());}void RenderText::setText(PassRefPtr<StringImpl> text, bool force){    ASSERT(text);    if (!force && equal(m_text.get(), text.get()))        return;    setTextInternal(text);    setNeedsLayoutAndPrefWidthsRecalc();}int RenderText::lineHeight(bool firstLine, bool) const{    // Always use the interior line height of the parent (e.g., if our parent is an inline block).    return parent()->lineHeight(firstLine, true);}void RenderText::dirtyLineBoxes(bool fullLayout){    if (fullLayout)        deleteTextBoxes();    else if (!m_linesDirty) {        for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())            box->dirtyLineBoxes();    }    m_linesDirty = false;}InlineTextBox* RenderText::createTextBox(){    return new (renderArena()) InlineTextBox(this);}InlineTextBox* RenderText::createInlineTextBox(){    InlineTextBox* textBox = createTextBox();    if (!m_firstTextBox)        m_firstTextBox = m_lastTextBox = textBox;    else {        m_lastTextBox->setNextLineBox(textBox);        textBox->setPreviousLineBox(m_lastTextBox);        m_lastTextBox = textBox;    }    return textBox;}void RenderText::positionLineBox(InlineBox* box){    InlineTextBox* s = static_cast<InlineTextBox*>(box);    // FIXME: should not be needed!!!    if (!s->len()) {        // We want the box to be destroyed.        s->remove();        s->destroy(renderArena());        m_firstTextBox = m_lastTextBox = 0;        return;    }    m_containsReversedText |= s->direction() == RTL;}unsigned RenderText::width(unsigned from, unsigned len, int xPos, bool firstLine) const{    if (from >= textLength())        return 0;    if (from + len > textLength())        len = textLength() - from;    return width(from, len, style(firstLine)->font(), xPos);}unsigned RenderText::width(unsigned from, unsigned len, const Font& f, int xPos) const{    ASSERT(from + len <= textLength());    if (!characters())        return 0;    int w;    if (&f == &style()->font()) {        if (!style()->preserveNewline() && !from && len == textLength())            w = maxPrefWidth();        else            w = widthFromCache(f, from, len, xPos);    } else        w = f.width(TextRun(text()->characters() + from, len, allowTabs(), xPos));    return w;}IntRect RenderText::linesBoundingBox() const{    IntRect result;        ASSERT(!firstTextBox() == !lastTextBox());  // Either both are null or both exist.    if (firstTextBox() && lastTextBox()) {        // Return the width of the minimal left side and the maximal right side.        int leftSide = 0;        int rightSide = 0;        for (InlineTextBox* curr = firstTextBox(); curr; curr = curr->nextTextBox()) {            if (curr == firstTextBox() || curr->x() < leftSide)                leftSide = curr->x();            if (curr == firstTextBox() || curr->x() + curr->width() > rightSide)                rightSide = curr->x() + curr->width();        }        result.setWidth(rightSide - leftSide);        result.setX(leftSide);        result.setHeight(lastTextBox()->y() + lastTextBox()->height() - firstTextBox()->y());        result.setY(firstTextBox()->y());    }    return result;}IntRect RenderText::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer){    RenderObject* cb = containingBlock();    return cb->clippedOverflowRectForRepaint(repaintContainer);}IntRect RenderText::selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool clipToVisibleContent){    ASSERT(!needsLayout());    if (selectionState() == SelectionNone)        return IntRect();    RenderBlock* cb =  containingBlock();    if (!cb)        return IntRect();    // Now calculate startPos and endPos for painting selection.    // We include a selection while endPos > 0    int startPos, endPos;    if (selectionState() == SelectionInside) {        // We are fully selected.        startPos = 0;        endPos = textLength();    } else {        selectionStartEnd(startPos, endPos);        if (selectionState() == SelectionStart)            endPos = textLength();        else if (selectionState() == SelectionEnd)            startPos = 0;    }    if (startPos == endPos)        return IntRect();    IntRect rect;    for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())        rect.unite(box->selectionRect(0, 0, startPos, endPos));    if (clipToVisibleContent)        computeRectForRepaint(repaintContainer, rect);    else {        if (cb->hasColumns())            cb->adjustRectForColumns(rect);        rect = localToContainerQuad(FloatRect(rect), repaintContainer).enclosingBoundingBox();    }    return rect;}int RenderText::caretMinOffset() const{    InlineTextBox* box = firstTextBox();    if (!box)        return 0;    int minOffset = box->start();    for (box = box->nextTextBox(); box; box = box->nextTextBox())        minOffset = min<int>(minOffset, box->start());    return minOffset;}int RenderText::caretMaxOffset() const{    InlineTextBox* box = lastTextBox();    if (!box)        return textLength();    int maxOffset = box->start() + box->len();    for (box = box->prevTextBox(); box; box = box->prevTextBox())        maxOffset = max<int>(maxOffset, box->start() + box->len());    return maxOffset;}unsigned RenderText::caretMaxRenderedOffset() const{    int l = 0;    for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())        l += box->len();    return l;}int RenderText::previousOffset(int current) const{    StringImpl* si = m_text.get();    TextBreakIterator* iterator = cursorMovementIterator(si->characters(), si->length());    if (!iterator)        return current - 1;    long result = textBreakPreceding(iterator, current);    if (result == TextBreakDone)        result = current - 1;#ifdef BUILDING_ON_TIGER    // ICU 3.2 allows character breaks before a half-width Katakana voiced mark.    if (static_cast<unsigned>(result) < si->length()) {        UChar character = (*si)[result];        if (character == 0xFF9E || character == 0xFF9F)            --result;    }#endif    return result;}#define HANGUL_CHOSEONG_START (0x1100)#define HANGUL_CHOSEONG_END (0x115F)#define HANGUL_JUNGSEONG_START (0x1160)#define HANGUL_JUNGSEONG_END (0x11A2)#define HANGUL_JONGSEONG_START (0x11A8)#define HANGUL_JONGSEONG_END (0x11F9)#define HANGUL_SYLLABLE_START (0xAC00)#define HANGUL_SYLLABLE_END (0xD7AF)#define HANGUL_JONGSEONG_COUNT (28)enum HangulState {    HangulStateL,    HangulStateV,    HangulStateT,    HangulStateLV,    HangulStateLVT,    HangulStateBreak};inline bool isHangulLVT(UChar32 character){    return (character - HANGUL_SYLLABLE_START) % HANGUL_JONGSEONG_COUNT;}int RenderText::previousOffsetForBackwardDeletion(int current) const{#if PLATFORM(MAC)    UChar32 character;    while (current > 0) {        if (U16_IS_TRAIL((*m_text)[--current]))            --current;        if (current < 0)            break;        UChar32 character = m_text->characterStartingAt(current);        // We don't combine characters in Armenian ... Limbu range for backward deletion.        if ((character >= 0x0530) && (character < 0x1950))            break;        if (u_isbase(character) && (character != 0xFF9E) && (character != 0xFF9F))            break;    }    if (current <= 0)        return current;    // Hangul    character = m_text->characterStartingAt(current);    if (((character >= HANGUL_CHOSEONG_START) && (character <= HANGUL_JONGSEONG_END)) || ((character >= HANGUL_SYLLABLE_START) && (character <= HANGUL_SYLLABLE_END))) {        HangulState state;        HangulState initialState;        if (character < HANGUL_JUNGSEONG_START)            state = HangulStateL;        else if (character < HANGUL_JONGSEONG_START)            state = HangulStateV;        else if (character < HANGUL_SYLLABLE_START)            state = HangulStateT;        else            state = isHangulLVT(character) ? HangulStateLVT : HangulStateLV;        initialState = state;        while (current > 0 && ((character = m_text->characterStartingAt(current - 1)) >= HANGUL_CHOSEONG_START) && (character <= HANGUL_SYLLABLE_END) && ((character <= HANGUL_JONGSEONG_END) || (character >= HANGUL_SYLLABLE_START))) {            switch (state) {            case HangulStateV:                if (character <= HANGUL_CHOSEONG_END)                    state = HangulStateL;                else if ((character >= HANGUL_SYLLABLE_START) && (character <= HANGUL_SYLLABLE_END) && !isHangulLVT(character))                    state = HangulStateLV;                else if (character > HANGUL_JUNGSEONG_END)                    state = HangulStateBreak;                break;            case HangulStateT:                if ((character >= HANGUL_JUNGSEONG_START) && (character <= HANGUL_JUNGSEONG_END))                    state = HangulStateV;                else if ((character >= HANGUL_SYLLABLE_START) && (character <= HANGUL_SYLLABLE_END))                    state = (isHangulLVT(character) ? HangulStateLVT : HangulStateLV);                else if (character < HANGUL_JUNGSEONG_START)                    state = HangulStateBreak;                break;            default:                state = (character < HANGUL_JUNGSEONG_START) ? HangulStateL : HangulStateBreak;                break;            }            if (state == HangulStateBreak)                break;            --current;        }    }    return current;#else    // Platforms other than Mac delete by one code point.    return current - 1;#endif}int RenderText::nextOffset(int current) const{    StringImpl* si = m_text.get();    TextBreakIterator* iterator = cursorMovementIterator(si->characters(), si->length());    if (!iterator)        return current + 1;    long result = textBreakFollowing(iterator, current);    if (result == TextBreakDone)        result = current + 1;#ifdef BUILDING_ON_TIGER    // ICU 3.2 allows character breaks before a half-width Katakana voiced mark.    if (static_cast<unsigned>(result) < si->length()) {        UChar character = (*si)[result];        if (character == 0xFF9E || character == 0xFF9F)            ++result;    }#endif    return result;}#ifndef NDEBUGvoid RenderText::checkConsistency() const{#ifdef CHECK_CONSISTENCY    const InlineTextBox* prev = 0;    for (const InlineTextBox* child = m_firstTextBox; child != 0; child = child->nextTextBox()) {        ASSERT(child->object() == this);        ASSERT(child->prevTextBox() == prev);        prev = child;    }    ASSERT(prev == m_lastTextBox);#endif}#endif} // namespace WebCore

⌨️ 快捷键说明

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