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

📄 bidiresolver.h

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 H
📖 第 1 页 / 共 3 页
字号:
    appendRun();    emptyRun = true;    // sor for the new run is determined by the higher level (rule X10)    setLastDir(from);    setLastStrongDir(from);    eor = Iterator();}template <class Iterator, class Run>void BidiResolver<Iterator, Run>::raiseExplicitEmbeddingLevel(WTF::Unicode::Direction from, WTF::Unicode::Direction to){    using namespace WTF::Unicode;    if (!emptyRun && eor != last) {        ASSERT(m_status.eor != OtherNeutral || eor.atEnd());        // bidi.sor ... bidi.eor ... bidi.last eor; need to append the bidi.sor-bidi.eor run or extend it through bidi.last        ASSERT(m_status.last == EuropeanNumberSeparator            || m_status.last == EuropeanNumberTerminator            || m_status.last == CommonNumberSeparator            || m_status.last == BoundaryNeutral            || m_status.last == BlockSeparator            || m_status.last == SegmentSeparator            || m_status.last == WhiteSpaceNeutral            || m_status.last == OtherNeutral);        if (m_direction == OtherNeutral)            m_direction = m_status.lastStrong == LeftToRight ? LeftToRight : RightToLeft;        if (to == LeftToRight) {            // bidi.sor ... bidi.eor ... bidi.last L            if (m_status.eor == EuropeanNumber) {                if (m_status.lastStrong != LeftToRight) {                    m_direction = EuropeanNumber;                    appendRun();                }            } else if (m_status.eor == ArabicNumber) {                m_direction = ArabicNumber;                appendRun();            } else if (m_status.lastStrong != LeftToRight && from == LeftToRight) {                appendRun();                m_direction = LeftToRight;            }        } else if (m_status.eor == ArabicNumber            || m_status.eor == EuropeanNumber && (m_status.lastStrong != LeftToRight || from == RightToLeft)            || m_status.eor != EuropeanNumber && m_status.lastStrong == LeftToRight && from == RightToLeft) {            appendRun();            m_direction = RightToLeft;        }        eor = last;    }    appendRun();    emptyRun = true;    setLastDir(to);    setLastStrongDir(to);    eor = Iterator();}template <class Iterator, class Run>void BidiResolver<Iterator, Run>::commitExplicitEmbedding(){    using namespace WTF::Unicode;    unsigned char fromLevel = context()->level();    RefPtr<BidiContext> toContext = context();    for (size_t i = 0; i < m_currentExplicitEmbeddingSequence.size(); ++i) {        Direction embedding = m_currentExplicitEmbeddingSequence[i];        if (embedding == PopDirectionalFormat) {            if (BidiContext* parentContext = toContext->parent())                toContext = parentContext;        } else {            Direction direction = (embedding == RightToLeftEmbedding || embedding == RightToLeftOverride) ? RightToLeft : LeftToRight;            bool override = embedding == LeftToRightOverride || embedding == RightToLeftOverride;            unsigned char level = toContext->level();            if (direction == RightToLeft) {                // Go to the least greater odd integer                level += 1;                level |= 1;            } else {                // Go to the least greater even integer                level += 2;                level &= ~1;            }            if (level < 61)                toContext = new BidiContext(level, direction, override, toContext.get());        }    }    unsigned char toLevel = toContext->level();    if (toLevel > fromLevel)        raiseExplicitEmbeddingLevel(fromLevel % 2 ? RightToLeft : LeftToRight, toLevel % 2 ? RightToLeft : LeftToRight);    else if (toLevel < fromLevel)        lowerExplicitEmbeddingLevel(fromLevel % 2 ? RightToLeft : LeftToRight);    setContext(toContext);    m_currentExplicitEmbeddingSequence.clear();}template <class Iterator, class Run>void BidiResolver<Iterator, Run>::deleteRuns(){    emptyRun = true;    if (!m_firstRun)        return;    Run* curr = m_firstRun;    while (curr) {        Run* s = curr->next();        curr->destroy();        curr = s;    }    m_firstRun = 0;    m_lastRun = 0;    m_runCount = 0;}template <class Iterator, class Run>void BidiResolver<Iterator, Run>::reverseRuns(unsigned start, unsigned end){    if (start >= end)        return;    ASSERT(end < m_runCount);        // Get the item before the start of the runs to reverse and put it in    // |beforeStart|.  |curr| should point to the first run to reverse.    Run* curr = m_firstRun;    Run* beforeStart = 0;    unsigned i = 0;    while (i < start) {        i++;        beforeStart = curr;        curr = curr->next();    }    Run* startRun = curr;    while (i < end) {        i++;        curr = curr->next();    }    Run* endRun = curr;    Run* afterEnd = curr->next();    i = start;    curr = startRun;    Run* newNext = afterEnd;    while (i <= end) {        // Do the reversal.        Run* next = curr->next();        curr->m_next = newNext;        newNext = curr;        curr = next;        i++;    }    // Now hook up beforeStart and afterEnd to the startRun and endRun.    if (beforeStart)        beforeStart->m_next = endRun;    else        m_firstRun = endRun;    startRun->m_next = afterEnd;    if (!afterEnd)        m_lastRun = startRun;}template <class Iterator, class Run>void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, bool visualOrder, bool hardLineBreak){    using namespace WTF::Unicode;    ASSERT(m_direction == OtherNeutral);    emptyRun = true;    eor = Iterator();    last = current;    bool pastEnd = false;    BidiResolver<Iterator, Run> stateAtEnd;    while (true) {        Direction dirCurrent;        if (pastEnd && (hardLineBreak || current.atEnd())) {            BidiContext* c = context();            while (c->parent())                c = c->parent();            dirCurrent = c->dir();            if (hardLineBreak) {                // A deviation from the Unicode Bidi Algorithm in order to match                // Mac OS X text and WinIE: a hard line break resets bidi state.                stateAtEnd.setContext(c);                stateAtEnd.setEorDir(dirCurrent);                stateAtEnd.setLastDir(dirCurrent);                stateAtEnd.setLastStrongDir(dirCurrent);            }        } else {            dirCurrent = current.direction();            if (context()->override()                    && dirCurrent != RightToLeftEmbedding                    && dirCurrent != LeftToRightEmbedding                    && dirCurrent != RightToLeftOverride                    && dirCurrent != LeftToRightOverride                    && dirCurrent != PopDirectionalFormat)                dirCurrent = context()->dir();            else if (dirCurrent == NonSpacingMark)                dirCurrent = m_status.last;        }        ASSERT(m_status.eor != OtherNeutral || eor.atEnd());        switch (dirCurrent) {        // embedding and overrides (X1-X9 in the Bidi specs)        case RightToLeftEmbedding:        case LeftToRightEmbedding:        case RightToLeftOverride:        case LeftToRightOverride:        case PopDirectionalFormat:            embed(dirCurrent);            commitExplicitEmbedding();            break;            // strong types        case LeftToRight:            switch(m_status.last) {                case RightToLeft:                case RightToLeftArabic:                case EuropeanNumber:                case ArabicNumber:                    if (m_status.last != EuropeanNumber || m_status.lastStrong != LeftToRight)                        appendRun();                    break;                case LeftToRight:                    break;                case EuropeanNumberSeparator:                case EuropeanNumberTerminator:                case CommonNumberSeparator:                case BoundaryNeutral:                case BlockSeparator:                case SegmentSeparator:                case WhiteSpaceNeutral:                case OtherNeutral:                    if (m_status.eor == EuropeanNumber) {                        if (m_status.lastStrong != LeftToRight) {                            // the numbers need to be on a higher embedding level, so let's close that run                            m_direction = EuropeanNumber;                            appendRun();                            if (context()->dir() != LeftToRight) {                                // the neutrals take the embedding direction, which is R                                eor = last;                                m_direction = RightToLeft;                                appendRun();                            }                        }                    } else if (m_status.eor == ArabicNumber) {                        // Arabic numbers are always on a higher embedding level, so let's close that run                        m_direction = ArabicNumber;                        appendRun();                        if (context()->dir() != LeftToRight) {                            // the neutrals take the embedding direction, which is R                            eor = last;                            m_direction = RightToLeft;                            appendRun();                        }                    } else if (m_status.lastStrong != LeftToRight) {                        //last stuff takes embedding dir                        if (context()->dir() == RightToLeft) {                            eor = last;                             m_direction = RightToLeft;                        }                        appendRun();                    }                default:                    break;            }            eor = current;            m_status.eor = LeftToRight;            m_status.lastStrong = LeftToRight;            m_direction = LeftToRight;            break;        case RightToLeftArabic:        case RightToLeft:            switch (m_status.last) {                case LeftToRight:                case EuropeanNumber:                case ArabicNumber:                    appendRun();                case RightToLeft:                case RightToLeftArabic:                    break;                case EuropeanNumberSeparator:                case EuropeanNumberTerminator:                case CommonNumberSeparator:                case BoundaryNeutral:                case BlockSeparator:                case SegmentSeparator:                case WhiteSpaceNeutral:                case OtherNeutral:                    if (m_status.eor == EuropeanNumber) {                        if (m_status.lastStrong == LeftToRight && context()->dir() == LeftToRight)                            eor = last;                        appendRun();                    } else if (m_status.eor == ArabicNumber)                        appendRun();                    else if (m_status.lastStrong == LeftToRight) {                        if (context()->dir() == LeftToRight)                            eor = last;                        appendRun();                    }                default:                    break;            }

⌨️ 快捷键说明

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