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

📄 qtextengine.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qdebug.h"#include "qtextformat.h"#include "qtextformat_p.h"#include "qtextengine_p.h"#include "qabstracttextdocumentlayout.h"#include "qtextlayout.h"#include "qvarlengtharray.h"#include "qscriptengine_p.h"#include "qfont.h"#include "qfont_p.h"#include "qfontengine_p.h"#include "qstring.h"#include <private/qunicodetables_p.h>#include "qtextdocument_p.h"#include <qapplication.h>#include <stdlib.h>// -----------------------------------------------------------------------------------------------------//// The BiDi algorithm//// -----------------------------------------------------------------------------------------------------#define BIDI_DEBUG 0//2#if (BIDI_DEBUG >= 1)#include <iostream>using namespace std;static const char *directions[] = {    "DirL", "DirR", "DirEN", "DirES", "DirET", "DirAN", "DirCS", "DirB", "DirS", "DirWS", "DirON",    "DirLRE", "DirLRO", "DirAL", "DirRLE", "DirRLO", "DirPDF", "DirNSM", "DirBN"};#endifstruct QBidiStatus {    QBidiStatus() {        eor = QChar::DirON;        lastStrong = QChar::DirON;        last = QChar:: DirON;        dir = QChar::DirON;    }    QChar::Direction eor;    QChar::Direction lastStrong;    QChar::Direction last;    QChar::Direction dir;};// The Unicode standard says this should be 61, setting it to 29 would save quite some space here.enum { MaxBidiLevel = 61 };struct QBidiControl {    inline QBidiControl(bool rtl)        : cCtx(0), base(rtl), override(false), level(rtl) {}    inline void embed(bool rtl, bool o = false) {        uchar plus2 = 0;        if((level%2 != 0) == rtl ) {            level++;            plus2 = 2;        }        level++;        if (level <= MaxBidiLevel) {            override = o;            unsigned char control = (plus2 + (override ? 1 : 0)) << (cCtx % 4)*2;            unsigned char mask = ~(0x3 << (cCtx % 4)*2);            ctx[cCtx>>2] &= mask;            ctx[cCtx>>2] |= control;            cCtx++;        }    }    inline bool canPop() const { return cCtx != 0; }    inline void pdf() {        Q_ASSERT(cCtx);        (void) --cCtx;        unsigned char control = (ctx[cCtx>>2] >> ((cCtx % 4)*2)) & 0x3;        override = control & 0x1;        level--;        if (control & 0x2)            level--;    }    inline QChar::Direction basicDirection() const {        return (base ? QChar::DirR : QChar:: DirL);    }    inline uchar baseLevel() const {        return base;    }    inline QChar::Direction direction() const {        return ((level%2) ? QChar::DirR : QChar:: DirL);    }    unsigned char ctx[(MaxBidiLevel+3)/4];    unsigned char cCtx : 6;    unsigned char base : 1;    unsigned char override : 1;    unsigned char unused : 2;    unsigned char level : 6;};static void qAppendItems(QTextEngine *engine, int &start, int &stop, QBidiControl &control, QChar::Direction dir){    QScriptItemArray &items = engine->layoutData->items;    const QChar *text = engine->layoutData->string.unicode();    if (start > stop) {        // #### the algorithm is currently not really safe against this. Still needs fixing.//         qWarning("QTextEngine: BiDi internal error in qAppendItems()");        return;    }    int level = control.level;    if(dir != QChar::DirON && !control.override) {        // add level of run (cases I1 & I2)        if(level % 2) {            if(dir == QChar::DirL || dir == QChar::DirAN || dir == QChar::DirEN)                level++;        } else {            if(dir == QChar::DirR)                level++;            else if(dir == QChar::DirAN || dir == QChar::DirEN)                level += 2;        }    }#if (BIDI_DEBUG >= 1)    qDebug("new run: dir=%s from %d, to %d level = %d\n", directions[dir], start, stop, level);#endif    int script = -1;    QScriptItem item;    item.position = start;    item.analysis.script = script;    item.analysis.bidiLevel = level;    item.analysis.override = control.override;    item.analysis.reserved = 0;    for (int i = start; i <= stop; i++) {        unsigned short uc = text[i].unicode();        int s = QUnicodeTables::script(text[i]);        if (uc == QChar::ObjectReplacementCharacter || uc == QChar::LineSeparator) {            item.analysis.bidiLevel = level % 2 ? level-1 : level;            item.analysis.script = QUnicodeTables::Common;            item.isObject = true;            s = -1;        } else if (uc == 9) {            item.analysis.script = QUnicodeTables::Common;            item.isSpace = true;            item.isTab = true;            item.analysis.bidiLevel = control.baseLevel();            s = -1;        } else if (s != script && (s != QUnicodeTables::Inherited || script == -1)) {            item.analysis.script = s == QUnicodeTables::Inherited ? QUnicodeTables::Common : s;            item.analysis.bidiLevel = level;        } else {            if (i - start < 32000)                continue;            start = i;        }        item.position = i;        items.append(item);        script = s;        item.isSpace = item.isTab = item.isObject = false;    }    ++stop;    start = stop;}typedef void (* fAppendItems)(QTextEngine *, int &start, int &stop, QBidiControl &control, QChar::Direction dir);static fAppendItems appendItems = qAppendItems;// creates the next QScript items.static bool bidiItemize(QTextEngine *engine, bool rightToLeft){#if BIDI_DEBUG >= 2    cout << "bidiItemize: rightToLeft=" << rightToLeft << endl;#endif    QBidiControl control(rightToLeft);    bool hasBidi = rightToLeft;    int sor = 0;    int eor = -1;    int length = engine->layoutData->string.length();    if (!length)        return hasBidi;    const ushort *unicode = (const ushort *)engine->layoutData->string.unicode();    int current = 0;    QChar::Direction dir = rightToLeft ? QChar::DirR : QChar::DirL;    QBidiStatus status;    QChar::Direction sdir = QChar::direction(*unicode);    if (sdir != QChar::DirL && sdir != QChar::DirR && sdir != QChar::DirEN && sdir != QChar::DirAN)	sdir = QChar::DirON;    else        dir = QChar::DirON;    status.eor = sdir;    status.lastStrong = rightToLeft ? QChar::DirR : QChar::DirL;    status.last = status.lastStrong;    status.dir = sdir;    while (current <= length) {        QChar::Direction dirCurrent;        if (current == (int)length)            dirCurrent = control.basicDirection();        else            dirCurrent = QChar::direction(unicode[current]);#if (BIDI_DEBUG >= 2)        cout << "pos=" << current << " dir=" << directions[dir]             << " current=" << directions[dirCurrent] << " last=" << directions[status.last]             << " eor=" << eor << "/" << directions[status.eor]             << " sor=" << sor << " lastStrong="             << directions[status.lastStrong]             << " level=" << (int)control.level << " override=" << (bool)control.override << endl;#endif        switch(dirCurrent) {            // embedding and overrides (X1-X9 in the BiDi specs)        case QChar::DirRLE:        case QChar::DirRLO:        case QChar::DirLRE:        case QChar::DirLRO:            {                bool rtl = (dirCurrent == QChar::DirRLE || dirCurrent == QChar::DirRLO);                hasBidi |= rtl;                bool override = (dirCurrent == QChar::DirLRO || dirCurrent == QChar::DirRLO);                uchar level = control.level+1;                if ((level%2 != 0) == rtl) ++level;                if(level < MaxBidiLevel) {                    eor = current-1;                    appendItems(engine, sor, eor, control, dir);                    eor = current;                    control.embed(rtl, override);                    QChar::Direction edir = (rtl ? QChar::DirR : QChar::DirL);                    dir = status.eor = edir;                    status.lastStrong = edir;                }                break;            }        case QChar::DirPDF:            {                if (control.canPop()) {                    if (dir != control.direction()) {                        eor = current-1;                        appendItems(engine, sor, eor, control, dir);                        dir = control.direction();                    }                    eor = current;                    appendItems(engine, sor, eor, control, dir);                    control.pdf();                    dir = QChar::DirON; status.eor = QChar::DirON;                    status.last = control.direction();                    if (control.override)                        dir = control.direction();                    else                        dir = QChar::DirON;                    status.lastStrong = control.direction();                }                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:                    if (eor >= 0) {                        appendItems(engine, sor, eor, control, dir);                        dir = eor < length ? QChar::direction(unicode[eor]) : control.basicDirection();                        status.eor = dir;                    } else {                        eor = current; status.eor = dir;                    }                    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(control.direction() == QChar::DirR) {                            if(status.eor != QChar::DirR) {                                // AN or EN                                appendItems(engine, sor, eor, control, dir);                                status.eor = QChar::DirON;                                dir = QChar::DirR;                            }                            eor = current - 1;                            appendItems(engine, sor, eor, control, dir);                            dir = eor < length ? QChar::direction(unicode[eor]) : control.basicDirection();                            status.eor = dir;                        } else {                            if(status.eor != QChar::DirL) {                                appendItems(engine, sor, eor, control, dir);                                status.eor = QChar::DirON;                                dir = QChar::DirL;                            } else {                                eor = current; status.eor = QChar::DirL; break;                            }                        }                    } else {

⌨️ 快捷键说明

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