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

📄 bidi.cpp

📁 将konqueror浏览器移植到ARM9 2410中
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/** * This file is part of the html renderer for KDE. * * Copyright (C) 2000 Lars Knoll (knoll@kde.org) * * 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., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * $Id: bidi.cpp,v 1.105.2.1 2001/11/01 18:57:06 mueller Exp $ */#include "bidi.h"#include "break_lines.h"#include "render_flow.h"#include "render_text.h"using namespace khtml;#include "kdebug.h"#include "qdatetime.h"#include "qfontmetrics.h"#define BIDI_DEBUG 0//#define DEBUG_LINEBREAKS// ---------------------------------------------------------------------/* a small helper class used internally to resolve Bidi embedding levels.   Each line of text caches the embedding level at the start of the line for faster   relayouting*/BidiContext::BidiContext(unsigned char l, QChar::Direction e, BidiContext *p, bool o)    : level(l) , override(o), dir(e){    parent = p;    if(p) {        p->ref();        basicDir = p->basicDir;    } else        basicDir = e;    count = 0;}BidiContext::~BidiContext(){    if(parent) parent->deref();}void BidiContext::ref() const{    count++;}void BidiContext::deref() const{    count--;    if(count <= 0) delete this;}// ---------------------------------------------------------------------BidiIterator::BidiIterator(){    par = 0;    obj = 0;    pos = 0;}BidiIterator::BidiIterator(RenderFlow *_par){    par = _par;    obj = par->first();    pos = 0;}BidiIterator::BidiIterator(const BidiIterator &it){    par = it.par;    obj = it.obj;    pos = it.pos;}BidiIterator::BidiIterator(RenderFlow *_par, RenderObject *_obj, int _pos){    par = _par;    obj = _obj;    pos = _pos;}BidiIterator &BidiIterator::operator = (const BidiIterator &it){    obj = it.obj;    pos = it.pos;    par = it.par;    return *this;}inline void BidiIterator::operator ++ (){    if(!obj) return;    if(obj->isText()) {        pos++;        if(pos >= obj->length()) {            obj = par->next(obj);            pos = 0;        }    } else {        obj = par->next(obj);        pos = 0;    }}inline bool BidiIterator::atEnd(){    if(!obj) return true;    return false;}const QChar &BidiIterator::current(){    static const QChar nbsp = QChar(0xA0);    if( !obj || !obj->isText()) return nbsp; // non breaking space    return static_cast<RenderText *>(obj)->text()[pos];}QChar::Direction BidiIterator::direction(){    if(!obj || !obj->isText() || obj->length() <= 0) return QChar::DirON;    RenderText *renderTxt = static_cast<RenderText *>( obj );    if ( pos >= renderTxt->length() )        return QChar::DirON;    return renderTxt->text()[pos].direction();}inline bool operator==( const BidiIterator &it1, const BidiIterator &it2 ){    if(it1.pos != it2.pos) return false;    if(it1.obj != it2.obj) return false;    return true;}inline bool operator!=( const BidiIterator &it1, const BidiIterator &it2 ){    if(it1.pos != it2.pos) return true;    if(it1.obj != it2.obj) return true;    return false;}// -------------------------------------------------------------------------------------------------void RenderFlow::appendRun(QList<BidiRun> &runs, BidiIterator &sor, BidiIterator &eor,                           BidiContext *context, QChar::Direction dir){#if BIDI_DEBUG > 1    kdDebug(6041) << "appendRun: dir="<<(int)dir<<endl;#endif    int start = sor.pos;    RenderObject *obj = sor.obj;    while( obj && obj != eor.obj ) {        if(!obj->isHidden()) {            //kdDebug(6041) << "appendRun: "<< start << "/" << obj->length() <<endl;            runs.append( new BidiRun(start, obj->length(), obj, context, dir) );        }        start = 0;        obj = next(obj);    }    if( obj && !obj->isHidden()) {        //kdDebug(6041) << "appendRun: "<< start << "/" << eor.pos <<endl;        runs.append( new BidiRun(start, eor.pos + 1, obj, context, dir) );    }}// collects one line of the paragraph and transforms it to visual orderBidiContext *RenderFlow::bidiReorderLine(BidiStatus &status, const BidiIterator &start, const BidiIterator &end, BidiContext *startEmbed){    //kdDebug(6041) << "reordering Line from " << start.obj << "/" << start.pos << " to " << end.obj << "/" << end.pos << endl;    QList<BidiRun> runs;    runs.setAutoDelete(true);    BidiContext *context = startEmbed;    //    context->ref();    QChar::Direction dir = QChar::DirON;    BidiIterator sor = start;    BidiIterator eor = start;#ifndef QT_NO_UNICODETABLES    BidiIterator current = start;    BidiIterator last = current;    while(current != end) {        QChar::Direction dirCurrent;        if(current.atEnd()) {            //kdDebug(6041) << "atEnd" << endl;            BidiContext *c = context;            while ( c->parent )                c = c->parent;            dirCurrent = c->dir;        } else            dirCurrent = current.direction();#if BIDI_DEBUG > 1        kdDebug(6041) << "directions: dir=" << (int)dir << " current=" << (int)dirCurrent << " last=" << status.last << " eor=" << status.eor << " lastStrong=" << status.lastStrong << " embedding=" << (int)context->dir << " level =" << (int)context->level << endl;#endif        switch(dirCurrent) {            // embedding and overrides (X1-X9 in the Bidi specs)        case QChar::DirRLE:            {                unsigned char level = context->level;                if(level%2) // we have an odd level                    level += 2;                else                    level++;                if(level < 61) {                    appendRun(runs, sor, eor, context, dir);                    ++eor; sor = eor; dir = QChar::DirON; status.eor = QChar::DirON;                    context = new BidiContext(level, QChar::DirR, context);                    context->ref();                    status.last = QChar::DirR;                    status.lastStrong = QChar::DirR;                }                break;            }        case QChar::DirLRE:            {                unsigned char level = context->level;                if(level%2) // we have an odd level                    level++;                else                    level += 2;                if(level < 61) {                    appendRun(runs, sor, eor, context, dir);                    ++eor; sor = eor; dir = QChar::DirON; status.eor = QChar::DirON;                    context = new BidiContext(level, QChar::DirL, context);                    context->ref();                    status.last = QChar::DirL;                    status.lastStrong = QChar::DirL;                }                break;            }        case QChar::DirRLO:            {                unsigned char level = context->level;                if(level%2) // we have an odd level                    level += 2;                else                    level++;                if(level < 61) {                    appendRun(runs, sor, eor, context, dir);                    ++eor; sor = eor; dir = QChar::DirON; status.eor = QChar::DirON;                    context = new BidiContext(level, QChar::DirR, context, true);                    context->ref();                    dir = QChar::DirR;                    status.last = QChar::DirR;                    status.lastStrong = QChar::DirR;                }                break;            }        case QChar::DirLRO:            {                unsigned char level = context->level;                if(level%2) // we have an odd level                    level++;                else                    level += 2;                if(level < 61) {                    appendRun(runs, sor, eor, context, dir);                    ++eor; sor = eor; dir = QChar::DirON; status.eor = QChar::DirON;                    context = new BidiContext(level, QChar::DirL, context, true);                    context->ref();                    dir = QChar::DirL;                    status.last = QChar::DirL;                    status.lastStrong = QChar::DirL;                }                break;            }        case QChar::DirPDF:            {                BidiContext *c = context->parent;                if(c) {                    appendRun(runs, sor, eor, context, dir);                    ++eor; sor = eor; dir = QChar::DirON; status.eor = QChar::DirON;                    status.last = context->dir;                    context->deref();                    context = c;                    if(context->override)                        dir = context->dir;                    else                        dir = QChar::DirON;                    status.lastStrong = context->dir;                }                break;            }            // strong types        case QChar::DirL:            if(dir == QChar::DirON)                dir = QChar::DirL;            switch(status.last)                {                case QChar::DirL:                    eor = current; status.eor = QChar::DirL; break;                case QChar::DirR:                case QChar::DirAL:                case QChar::DirEN:                case QChar::DirAN:                    appendRun(runs, sor, eor, context, dir);                    ++eor; sor = eor; dir = QChar::DirON; status.eor = QChar::DirON;                    break;                case QChar::DirES:                case QChar::DirET:                case QChar::DirCS:                case QChar::DirBN:                case QChar::DirB:                case QChar::DirS:                case QChar::DirWS:                case QChar::DirON:                    if(dir != QChar::DirL) {                        //last stuff takes embedding dir                        if( context->dir == QChar::DirR ) {                            if(status.eor != QChar::DirR) {                                // AN or EN                                appendRun(runs, sor, eor, context, dir);                                ++eor; sor = eor; dir = QChar::DirON; status.eor = QChar::DirON;                                dir = QChar::DirR;                            }                            else                                eor = last;                            appendRun(runs, sor, eor, context, dir);                            ++eor; sor = eor; dir = QChar::DirON; status.eor = QChar::DirON;                        } else {                            if(status.eor == QChar::DirR) {                                appendRun(runs, sor, eor, context, dir);                                ++eor; sor = eor; dir = QChar::DirON; status.eor = QChar::DirON;                                dir = QChar::DirL;                            } else {                                eor = current; status.eor = QChar::DirL; break;                            }                        }                    } else {                        eor = current; status.eor = QChar::DirL;                    }                default:                    break;                }            status.lastStrong = QChar::DirL;            break;        case QChar::DirAL:        case QChar::DirR:            if(dir == QChar::DirON) dir = QChar::DirR;            switch(status.last)                {                case QChar::DirR:                case QChar::DirAL:                    eor = current; status.eor = QChar::DirR; break;                case QChar::DirL:                case QChar::DirEN:                case QChar::DirAN:                    appendRun(runs, sor, eor, context, dir);                    ++eor; sor = eor; dir = QChar::DirON; status.eor = QChar::DirON;                    break;

⌨️ 快捷键说明

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