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

📄 bidiresolver.h

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 H
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 2000 Lars Knoll (knoll@kde.org) * Copyright (C) 2003, 2004, 2006, 2007, 2008 Apple Inc.  All right reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB.  If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */#ifndef BidiResolver_h#define BidiResolver_h#include "BidiContext.h"#include <wtf/Noncopyable.h>#include <wtf/PassRefPtr.h>#include <wtf/Vector.h>namespace WebCore {// The BidiStatus at a given position (typically the end of a line) can// be cached and then used to restart bidi resolution at that position.struct BidiStatus {    BidiStatus()        : eor(WTF::Unicode::OtherNeutral)        , lastStrong(WTF::Unicode::OtherNeutral)        , last(WTF::Unicode::OtherNeutral)    {    }    BidiStatus(WTF::Unicode::Direction eorDir, WTF::Unicode::Direction lastStrongDir, WTF::Unicode::Direction lastDir, PassRefPtr<BidiContext> bidiContext)        : eor(eorDir)        , lastStrong(lastStrongDir)        , last(lastDir)        , context(bidiContext)    {    }    WTF::Unicode::Direction eor;    WTF::Unicode::Direction lastStrong;    WTF::Unicode::Direction last;    RefPtr<BidiContext> context;};inline bool operator==(const BidiStatus& status1, const BidiStatus& status2){    return status1.eor == status2.eor && status1.last == status2.last && status1.lastStrong == status2.lastStrong && *(status1.context) == *(status2.context);}inline bool operator!=(const BidiStatus& status1, const BidiStatus& status2){    return !(status1 == status2);}struct BidiCharacterRun {    BidiCharacterRun(int start, int stop, BidiContext* context, WTF::Unicode::Direction dir)        : m_start(start)        , m_stop(stop)        , m_override(context->override())        , m_next(0)    {        if (dir == WTF::Unicode::OtherNeutral)            dir = context->dir();        m_level = context->level();        // add level of run (cases I1 & I2)        if (m_level % 2) {            if (dir == WTF::Unicode::LeftToRight || dir == WTF::Unicode::ArabicNumber || dir == WTF::Unicode::EuropeanNumber)                m_level++;        } else {            if (dir == WTF::Unicode::RightToLeft)                m_level++;            else if (dir == WTF::Unicode::ArabicNumber || dir == WTF::Unicode::EuropeanNumber)                m_level += 2;        }    }    void destroy() { delete this; }    int start() const { return m_start; }    int stop() const { return m_stop; }    unsigned char level() const { return m_level; }    bool reversed(bool visuallyOrdered) { return m_level % 2 && !visuallyOrdered; }    bool dirOverride(bool visuallyOrdered) { return m_override || visuallyOrdered; }    BidiCharacterRun* next() const { return m_next; }    unsigned char m_level;    int m_start;    int m_stop;    bool m_override;    BidiCharacterRun* m_next;};template <class Iterator, class Run> class BidiResolver : public Noncopyable {public :    BidiResolver()        : m_direction(WTF::Unicode::OtherNeutral)        , reachedEndOfLine(false)        , emptyRun(true)        , m_firstRun(0)        , m_lastRun(0)        , m_logicallyLastRun(0)        , m_runCount(0)    {    }    const Iterator& position() const { return current; }    void setPosition(const Iterator& position) { current = position; }    void increment() { current.increment(); }    BidiContext* context() const { return m_status.context.get(); }    void setContext(PassRefPtr<BidiContext> c) { m_status.context = c; }    void setLastDir(WTF::Unicode::Direction lastDir) { m_status.last = lastDir; }    void setLastStrongDir(WTF::Unicode::Direction lastStrongDir) { m_status.lastStrong = lastStrongDir; }    void setEorDir(WTF::Unicode::Direction eorDir) { m_status.eor = eorDir; }    WTF::Unicode::Direction dir() const { return m_direction; }    void setDir(WTF::Unicode::Direction d) { m_direction = d; }    const BidiStatus& status() const { return m_status; }    void setStatus(const BidiStatus s) { m_status = s; }    void embed(WTF::Unicode::Direction);    void commitExplicitEmbedding();    void createBidiRunsForLine(const Iterator& end, bool visualOrder = false, bool hardLineBreak = false);    Run* firstRun() const { return m_firstRun; }    Run* lastRun() const { return m_lastRun; }    Run* logicallyLastRun() const { return m_logicallyLastRun; }    unsigned runCount() const { return m_runCount; }    void addRun(Run*);    void prependRun(Run*);    void moveRunToEnd(Run*);    void moveRunToBeginning(Run*);    void deleteRuns();protected:    void appendRun();    void reverseRuns(unsigned start, unsigned end);    Iterator current;    Iterator sor;    Iterator eor;    Iterator last;    BidiStatus m_status;    WTF::Unicode::Direction m_direction;    Iterator endOfLine;    bool reachedEndOfLine;    Iterator lastBeforeET;    bool emptyRun;    Run* m_firstRun;    Run* m_lastRun;    Run* m_logicallyLastRun;    unsigned m_runCount;private:    void raiseExplicitEmbeddingLevel(WTF::Unicode::Direction from, WTF::Unicode::Direction to);    void lowerExplicitEmbeddingLevel(WTF::Unicode::Direction from);    Vector<WTF::Unicode::Direction, 8> m_currentExplicitEmbeddingSequence;};template <class Iterator, class Run>inline void BidiResolver<Iterator, Run>::addRun(Run* run){    if (!m_firstRun)        m_firstRun = run;    else        m_lastRun->m_next = run;    m_lastRun = run;    m_runCount++;}template <class Iterator, class Run>inline void BidiResolver<Iterator, Run>::prependRun(Run* run){    ASSERT(!run->m_next);    if (!m_lastRun)        m_lastRun = run;    else        run->m_next = m_firstRun;    m_firstRun = run;    m_runCount++;}template <class Iterator, class Run>inline void BidiResolver<Iterator, Run>::moveRunToEnd(Run* run){    ASSERT(m_firstRun);    ASSERT(m_lastRun);    ASSERT(run->m_next);    Run* current = 0;    Run* next = m_firstRun;    while (next != run) {        current = next;        next = current->next();    }    if (!current)        m_firstRun = run->next();    else        current->m_next = run->m_next;    run->m_next = 0;    m_lastRun->m_next = run;    m_lastRun = run;}template <class Iterator, class Run>inline void BidiResolver<Iterator, Run>::moveRunToBeginning(Run* run){    ASSERT(m_firstRun);    ASSERT(m_lastRun);    ASSERT(run != m_firstRun);    Run* current = m_firstRun;    Run* next = current->next();    while (next != run) {        current = next;        next = current->next();    }    current->m_next = run->m_next;    if (run == m_lastRun)        m_lastRun = current;    run->m_next = m_firstRun;    m_firstRun = run;}template <class Iterator, class Run>void BidiResolver<Iterator, Run>::appendRun(){    if (!emptyRun && !eor.atEnd()) {        addRun(new Run(sor.offset(), eor.offset() + 1, context(), m_direction));        eor.increment();        sor = eor;    }    m_direction = WTF::Unicode::OtherNeutral;    m_status.eor = WTF::Unicode::OtherNeutral;}template <class Iterator, class Run>void BidiResolver<Iterator, Run>::embed(WTF::Unicode::Direction d){    using namespace WTF::Unicode;    ASSERT(d == PopDirectionalFormat || d == LeftToRightEmbedding || d == LeftToRightOverride || d == RightToLeftEmbedding || d == RightToLeftOverride);    m_currentExplicitEmbeddingSequence.append(d);}template <class Iterator, class Run>void BidiResolver<Iterator, Run>::lowerExplicitEmbeddingLevel(WTF::Unicode::Direction from){    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 (from == 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) {                appendRun();                m_direction = LeftToRight;            }        } else if (m_status.eor == EuropeanNumber || m_status.eor == ArabicNumber || m_status.lastStrong == LeftToRight) {            appendRun();            m_direction = RightToLeft;        }        eor = last;    }

⌨️ 快捷键说明

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