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

📄 bidi.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (C) 2000 Lars Knoll (knoll@kde.org) * Copyright (C) 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. * */#include "config.h"#include "bidi.h"#include "CharacterNames.h"#include "Document.h"#include "Element.h"#include "FrameView.h"#include "InlineTextBox.h"#include "Logging.h"#include "RenderArena.h"#include "RenderInline.h"#include "RenderLayer.h"#include "RenderListMarker.h"#include "RenderView.h"#include "break_lines.h"#include <wtf/AlwaysInline.h>#include <wtf/RefCountedLeakCounter.h>#include <wtf/StdLibExtras.h>#include <wtf/Vector.h>using namespace std;using namespace WTF;using namespace Unicode;namespace WebCore {// We don't let our line box tree for a single line get any deeper than this.const unsigned cMaxLineDepth = 200;class InlineIterator {public:    InlineIterator()        : block(0)        , obj(0)        , pos(0)        , nextBreakablePosition(-1)    {    }    InlineIterator(RenderBlock* b, RenderObject* o, unsigned p)        : block(b)        , obj(o)        , pos(p)        , nextBreakablePosition(-1)    {    }    void increment(InlineBidiResolver* resolver = 0);    bool atEnd() const;    UChar current() const;    WTF::Unicode::Direction direction() const;    RenderBlock* block;    RenderObject* obj;    unsigned pos;    int nextBreakablePosition;};// Midpoint globals.  The goal is not to do any allocation when dealing with// these midpoints, so we just keep an array around and never clear it.  We track// the number of items and position using the two other variables.static Vector<InlineIterator>* smidpoints;static unsigned sNumMidpoints;static unsigned sCurrMidpoint;static bool betweenMidpoints;static bool isLineEmpty = true;static bool previousLineBrokeCleanly = true;static int getBorderPaddingMargin(RenderBoxModelObject* child, bool endOfInline){    bool leftSide = (child->style()->direction() == LTR) ? !endOfInline : endOfInline;    if (leftSide)        return child->marginLeft() + child->paddingLeft() + child->borderLeft();    return child->marginRight() + child->paddingRight() + child->borderRight();}static int inlineWidth(RenderObject* child, bool start = true, bool end = true){    unsigned lineDepth = 1;    int extraWidth = 0;    RenderObject* parent = child->parent();    while (parent->isInline() && !parent->isInlineBlockOrInlineTable() && lineDepth++ < cMaxLineDepth) {        if (start && !child->previousSibling())            extraWidth += getBorderPaddingMargin(toRenderBoxModelObject(parent), false);        if (end && !child->nextSibling())            extraWidth += getBorderPaddingMargin(toRenderBoxModelObject(parent), true);        child = parent;        parent = child->parent();    }    return extraWidth;}#ifndef NDEBUGstatic WTF::RefCountedLeakCounter bidiRunCounter("BidiRun");static bool inBidiRunDestroy;#endifvoid BidiRun::destroy(){#ifndef NDEBUG    inBidiRunDestroy = true;#endif    RenderArena* renderArena = m_object->renderArena();    delete this;#ifndef NDEBUG    inBidiRunDestroy = false;#endif    // Recover the size left there for us by operator delete and free the memory.    renderArena->free(*reinterpret_cast<size_t*>(this), this);}void* BidiRun::operator new(size_t sz, RenderArena* renderArena) throw(){#ifndef NDEBUG    bidiRunCounter.increment();#endif    return renderArena->allocate(sz);}void BidiRun::operator delete(void* ptr, size_t sz){#ifndef NDEBUG    bidiRunCounter.decrement();#endif    ASSERT(inBidiRunDestroy);    // Stash size where destroy() can find it.    *(size_t*)ptr = sz;}// ---------------------------------------------------------------------inline bool operator==(const InlineIterator& it1, const InlineIterator& it2){    return it1.pos == it2.pos && it1.obj == it2.obj;}inline bool operator!=(const InlineIterator& it1, const InlineIterator& it2){    return it1.pos != it2.pos || it1.obj != it2.obj;}static inline RenderObject* bidiNext(RenderBlock* block, RenderObject* current, InlineBidiResolver* resolver = 0, bool skipInlines = true, bool* endOfInlinePtr = 0){    RenderObject* next = 0;    bool oldEndOfInline = endOfInlinePtr ? *endOfInlinePtr : false;    bool endOfInline = false;    while (current) {        next = 0;        if (!oldEndOfInline && !current->isFloating() && !current->isReplaced() && !current->isPositioned() && !current->isText()) {            next = current->firstChild();            if (next && resolver && next->isRenderInline()) {                EUnicodeBidi ub = next->style()->unicodeBidi();                if (ub != UBNormal) {                    TextDirection dir = next->style()->direction();                    Direction d = (ub == Embed                        ? (dir == RTL ? RightToLeftEmbedding : LeftToRightEmbedding)                        : (dir == RTL ? RightToLeftOverride : LeftToRightOverride));                    resolver->embed(d);                }            }        }        if (!next) {            if (!skipInlines && !oldEndOfInline && current->isRenderInline()) {                next = current;                endOfInline = true;                break;            }            while (current && current != block) {                if (resolver && current->isRenderInline() && current->style()->unicodeBidi() != UBNormal)                    resolver->embed(PopDirectionalFormat);                next = current->nextSibling();                if (next) {                    if (resolver && next->isRenderInline()) {                        EUnicodeBidi ub = next->style()->unicodeBidi();                        if (ub != UBNormal) {                            TextDirection dir = next->style()->direction();                            Direction d = (ub == Embed                                ? (dir == RTL ? RightToLeftEmbedding: LeftToRightEmbedding)                                : (dir == RTL ? RightToLeftOverride : LeftToRightOverride));                            resolver->embed(d);                        }                    }                    break;                }                                current = current->parent();                if (!skipInlines && current && current != block && current->isRenderInline()) {                    next = current;                    endOfInline = true;                    break;                }            }        }        if (!next)            break;        if (next->isText() || next->isFloating() || next->isReplaced() || next->isPositioned()            || ((!skipInlines || !next->firstChild()) // Always return EMPTY inlines.                && next->isRenderInline()))            break;        current = next;    }    if (endOfInlinePtr)        *endOfInlinePtr = endOfInline;    return next;}static RenderObject* bidiFirst(RenderBlock* block, InlineBidiResolver* resolver, bool skipInlines = true){    if (!block->firstChild())        return 0;        RenderObject* o = block->firstChild();    if (o->isRenderInline()) {        if (resolver) {            EUnicodeBidi ub = o->style()->unicodeBidi();            if (ub != UBNormal) {                TextDirection dir = o->style()->direction();                Direction d = (ub == Embed                    ? (dir == RTL ? RightToLeftEmbedding : LeftToRightEmbedding)                    : (dir == RTL ? RightToLeftOverride : LeftToRightOverride));                resolver->embed(d);            }        }        if (skipInlines && o->firstChild())            o = bidiNext(block, o, resolver, skipInlines);        else {            // Never skip empty inlines.            if (resolver)                resolver->commitExplicitEmbedding();            return o;         }    }    if (o && !o->isText() && !o->isReplaced() && !o->isFloating() && !o->isPositioned())        o = bidiNext(block, o, resolver, skipInlines);    if (resolver)        resolver->commitExplicitEmbedding();    return o;}inline void InlineIterator::increment(InlineBidiResolver* resolver){    if (!obj)        return;    if (obj->isText()) {        pos++;        if (pos >= toRenderText(obj)->textLength()) {            obj = bidiNext(block, obj, resolver);            pos = 0;            nextBreakablePosition = -1;        }    } else {        obj = bidiNext(block, obj, resolver);        pos = 0;        nextBreakablePosition = -1;    }}template<>inline void InlineBidiResolver::increment(){    current.increment(this);}inline bool InlineIterator::atEnd() const{    return !obj;}inline UChar InlineIterator::current() const{    if (!obj || !obj->isText())        return 0;    RenderText* text = toRenderText(obj);    if (pos >= text->textLength())        return 0;    return text->characters()[pos];}ALWAYS_INLINE Direction InlineIterator::direction() const{    if (UChar c = current())        return Unicode::direction(c);

⌨️ 快捷键说明

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