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

📄 qtextengine.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                        eor = current;                        status.eor = dirCurrent;                        break;                    case QChar::DirR:                    case QChar::DirAL:                    case QChar::DirAN:                        if (!first)                            appendItems(engine, sor, eor, control, dir);                        status.eor = QChar::DirEN;                        dir = QChar::DirAN; break;                    case QChar::DirES:                    case QChar::DirCS:                        if(status.eor == QChar::DirEN || dir == QChar::DirAN) {                            eor = current; break;                        }                    case QChar::DirBN:                    case QChar::DirB:                    case QChar::DirS:                    case QChar::DirWS:                    case QChar::DirON:                        if(status.eor == QChar::DirR) {                            // neutrals go to R                            eor = current - 1;                            appendItems(engine, sor, eor, control, dir);                            dir = QChar::DirON; status.eor = QChar::DirEN;                            dir = QChar::DirAN;                        }                        else if(status.eor == QChar::DirL ||                                 (status.eor == QChar::DirEN && status.lastStrong == QChar::DirL)) {                            eor = current; status.eor = dirCurrent;                        } else {                            // numbers on both sides, neutrals get right to left direction                            if(dir != QChar::DirL) {                                appendItems(engine, sor, eor, control, dir);                                dir = QChar::DirON; status.eor = QChar::DirON;                                eor = current - 1;                                dir = QChar::DirR;                                appendItems(engine, sor, eor, control, dir);                                dir = QChar::DirON; status.eor = QChar::DirON;                                dir = QChar::DirAN;                            } else {                                eor = current; status.eor = dirCurrent;                            }                        }                    default:                        break;                    }                break;            }        case QChar::DirAN:            hasBidi = true;            dirCurrent = QChar::DirAN;            if(dir == QChar::DirON) dir = QChar::DirAN;            switch(status.last)                {                case QChar::DirL:                case QChar::DirAN:                    eor = current; status.eor = QChar::DirAN; break;                case QChar::DirR:                case QChar::DirAL:                case QChar::DirEN:                    if (!first)                        appendItems(engine, sor, eor, control, dir);                    dir = QChar::DirON; status.eor = QChar::DirAN;                    break;                case QChar::DirCS:                    if(status.eor == QChar::DirAN) {                        eor = current; break;                    }                case QChar::DirES:                case QChar::DirET:                case QChar::DirBN:                case QChar::DirB:                case QChar::DirS:                case QChar::DirWS:                case QChar::DirON:                    if(status.eor == QChar::DirR) {                        // neutrals go to R                        eor = current - 1;                        appendItems(engine, sor, eor, control, dir);                        status.eor = QChar::DirAN;                        dir = QChar::DirAN;                    } else if(status.eor == QChar::DirL ||                               (status.eor == QChar::DirEN && status.lastStrong == QChar::DirL)) {                        eor = current; status.eor = dirCurrent;                    } else {                        // numbers on both sides, neutrals get right to left direction                        if(dir != QChar::DirL) {                            appendItems(engine, sor, eor, control, dir);                            status.eor = QChar::DirON;                            eor = current - 1;                            dir = QChar::DirR;                            appendItems(engine, sor, eor, control, dir);                            status.eor = QChar::DirAN;                            dir = QChar::DirAN;                        } else {                            eor = current; status.eor = dirCurrent;                        }                    }                default:                    break;                }            break;        case QChar::DirES:        case QChar::DirCS:            break;        case QChar::DirET:            if(status.last == QChar::DirEN) {                dirCurrent = QChar::DirEN;                eor = current; status.eor = dirCurrent;            }            break;            // boundary neutrals should be ignored        case QChar::DirBN:            break;            // neutrals        case QChar::DirB:            // ### what do we do with newline and paragraph separators that come to here?            break;        case QChar::DirS:            // ### implement rule L1            break;        case QChar::DirWS:        case QChar::DirON:            break;        default:            break;        }        //cout << "     after: dir=" << //        dir << " current=" << dirCurrent << " last=" << status.last << " eor=" << status.eor << " lastStrong=" << status.lastStrong << " embedding=" << control.direction() << endl;        if(current >= (int)length) break;        // set status.last as needed.        switch(dirCurrent) {        case QChar::DirET:        case QChar::DirES:        case QChar::DirCS:        case QChar::DirS:        case QChar::DirWS:        case QChar::DirON:            switch(status.last)            {            case QChar::DirL:            case QChar::DirR:            case QChar::DirAL:            case QChar::DirEN:            case QChar::DirAN:                status.last = dirCurrent;                break;            default:                status.last = QChar::DirON;            }            break;        case QChar::DirNSM:        case QChar::DirBN:            // ignore these            break;        case QChar::DirLRO:        case QChar::DirLRE:            status.last = QChar::DirL;            break;        case QChar::DirRLO:        case QChar::DirRLE:            status.last = QChar::DirR;            break;        case QChar::DirEN:            if (status.last == QChar::DirL) {                status.last = QChar::DirL;                break;            }            // fall through        default:            status.last = dirCurrent;        }        first = false;        ++current;    }#if (BIDI_DEBUG >= 1)    cout << "reached end of line current=" << current << ", eor=" << eor << endl;#endif    eor = current - 1; // remove dummy char    if (sor <= eor)        appendItems(engine, sor, eor, control, dir);    return hasBidi;}void QTextEngine::bidiReorder(int numItems, const quint8 *levels, int *visualOrder){    // first find highest and lowest levels    uchar levelLow = 128;    uchar levelHigh = 0;    int i = 0;    while (i < numItems) {        //printf("level = %d\n", r->level);        if (levels[i] > levelHigh)            levelHigh = levels[i];        if (levels[i] < levelLow)            levelLow = levels[i];        i++;    }    // implements reordering of the line (L2 according to BiDi spec):    // L2. From the highest level found in the text to the lowest odd level on each line,    // reverse any contiguous sequence of characters that are at that level or higher.    // reversing is only done up to the lowest odd level    if(!(levelLow%2)) levelLow++;#if (BIDI_DEBUG >= 1)    cout << "reorderLine: lineLow = " << (uint)levelLow << ", lineHigh = " << (uint)levelHigh << endl;#endif    int count = numItems - 1;    for (i = 0; i < numItems; i++)        visualOrder[i] = i;    while(levelHigh >= levelLow) {        int i = 0;        while (i < count) {            while(i < count && levels[i] < levelHigh) i++;            int start = i;            while(i <= count && levels[i] >= levelHigh) i++;            int end = i-1;            if(start != end) {                //cout << "reversing from " << start << " to " << end << endl;                for(int j = 0; j < (end-start+1)/2; j++) {                    int tmp = visualOrder[start+j];                    visualOrder[start+j] = visualOrder[end-j];                    visualOrder[end-j] = tmp;                }            }            i++;        }        levelHigh--;    }#if (BIDI_DEBUG >= 1)    cout << "visual order is:" << endl;    for (i = 0; i < numItems; i++)        cout << visualOrder[i] << endl;#endif}// -----------------------------------------------------------------------------------------------------//// The line break algorithm. See http://www.unicode.org/reports/tr14/tr14-13.html//// -----------------------------------------------------------------------------------------------------/* The Unicode algorithm does in our opinion allow line breaks at some   places they shouldn't be allowed. The following changes were thus   made in comparison to the Unicode reference:   CL->AL from Dbk to Ibk   CL->PR from Dbk to Ibk   EX->AL from Dbk to Ibk   IS->AL from Dbk to Ibk   PO->AL from Dbk to Ibk   SY->AL from Dbk to Ibk   SY->PO from Dbk to Ibk   SY->PR from Dbk to Ibk   SY->OP from Dbk to Ibk   Al->OP from Dbk to Ibk   AL->HY from Dbk to Ibk   AL->PR from Dbk to Ibk   AL->PO from Dbk to Ibk   PR->PR from Dbk to Ibk   PO->PO from Dbk to Ibk   PR->PO from Dbk to Ibk   PO->PR from Dbk to Ibk   HY->PO from Dbk to Ibk   HY->PR from Dbk to Ibk   HY->OP from Dbk to Ibk   PO->OP from Dbk to Ibk   NU->EX from Dbk to Ibk   NU->PR from Dbk to Ibk   PO->NU from Dbk to Ibk   EX->PO from Dbk to Ibk*/enum break_action {    Dbk, // Direct break    Ibk, // Indirect break; only allowed if space between the two chars    Pbk // Prohibited break; no break allowed even if space between chars};// The following line break classes are not treated by the table:// SA, BK, CR, LF, SG, CB, SPstatic const quint8 breakTable[QUnicodeTables::LineBreak_CM+1][QUnicodeTables::LineBreak_CM+1] ={    // OP,  CL,  QU,  GL, NS,  EX,  SY,  IS,  PR,  PO,  NU,  AL,  ID,  IN,  HY,  BA,  BB,  B2,  ZW,  CM    { Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk }, // OP    { Dbk, Pbk, Ibk, Pbk, Pbk, Pbk, Pbk, Pbk, Ibk, Ibk, Dbk, Ibk, Dbk, Dbk, Ibk, Ibk, Pbk, Pbk, Pbk, Pbk }, // CL    { Pbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Pbk, Pbk }, // QU    { Ibk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Pbk, Pbk }, // GL    { Dbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Ibk, Ibk, Dbk, Dbk, Pbk, Ibk }, // NS    { Dbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Dbk, Ibk, Ibk, Ibk, Dbk, Dbk, Ibk, Ibk, Dbk, Dbk, Pbk, Ibk }, // EX    { Ibk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Ibk, Ibk, Ibk, Ibk, Dbk, Dbk, Ibk, Ibk, Dbk, Dbk, Pbk, Ibk }, // SY    { Dbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Dbk, Dbk, Ibk, Ibk, Dbk, Dbk, Ibk, Ibk, Dbk, Dbk, Pbk, Ibk }, // IS    { Ibk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Ibk, Ibk, Ibk, Ibk, Ibk, Dbk, Ibk, Ibk, Dbk, Dbk, Pbk, Pbk }, // PR    { Ibk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Ibk, Ibk, Ibk, Ibk, Dbk, Dbk, Ibk, Ibk, Dbk, Dbk, Pbk, Ibk }, // PO    { Dbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Ibk, Ibk, Ibk, Ibk, Dbk, Ibk, Ibk, Ibk, Dbk, Dbk, Pbk, Pbk }, // NU    { Ibk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Ibk, Ibk, Ibk, Ibk, Dbk, Ibk, Ibk, Ibk, Dbk, Dbk, Pbk, Pbk }, // AL    { Dbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Dbk, Ibk, Dbk, Dbk, Dbk, Ibk, Ibk, Ibk, Dbk, Dbk, Pbk, Ibk }, // ID    { Dbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Dbk, Dbk, Dbk, Dbk, Dbk, Ibk, Ibk, Ibk, Dbk, Dbk, Pbk, Ibk }, // IN    { Ibk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Ibk, Ibk, Ibk, Ibk, Dbk, Dbk, Ibk, Ibk, Dbk, Dbk, Pbk, Ibk }, // HY    { Dbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Ibk, Ibk, Dbk, Dbk, Pbk, Ibk }, // BA    { Ibk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Pbk, Ibk }, // BB    { Dbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Ibk, Ibk, Dbk, Pbk, Pbk, Ibk }, // B2    { Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Pbk, Ibk }, // ZW    { Dbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Dbk, Ibk, Dbk, Dbk, Dbk, Ibk, Ibk, Ibk, Dbk, Dbk, Pbk, Pbk }  // CM};// set the soft break flag at every possible line breaking point. This needs correct clustering information.static void calcLineBreaks(const QString &str, QCharAttributes *charAttributes){    int len = str.length();    if (!len)        return;    const QChar *uc = str.unicode();    const QUnicodeTables::Properties *prop = QUnicodeTables::properties(uc->unicode());    int cls = prop->line_break_class;    if (cls >= QUnicodeTables::LineBreak_CM)        cls = QUnicodeTables::LineBreak_ID;    charAttributes[0].softBreak = false;    charAttributes[0].whiteSpace = (cls == QUnicodeTables::LineBreak_SP || cls == QUnicodeTables::LineBreak_BK);    charAttributes[0].charStop = true;    charAttributes[0].category = prop->category;    for (int i = 1; i < len; ++i) {        prop = QUnicodeTables::properties(uc[i].unicode());        int ncls = prop->line_break_class;        int category = prop->category;        if (category == QChar::Mark_NonSpacing)            goto nsm;                if (category == QChar::Other_Surrogate) {            // char stop only on first pair            if (uc[i].unicode() >= 0xd800 && uc[i].unicode() < 0xdc00 && i < len-1                && uc[i+1].unicode() >= 0xdc00 && uc[i+1].unicode() < 0xe000)                goto nsm;            // ### correctly handle second surrogate        }        if (ncls == QUnicodeTables::LineBreak_SP || ncls == QUnicodeTables::LineBreak_BK) {            charAttributes[i].softBreak = false;            charAttributes[i].whiteSpace = true;            charAttributes[i].charStop = true;            charAttributes[i].category = QChar::Separator_Space;            cls = ncls;            continue;        }	if (cls == QUnicodeTables::LineBreak_SA && ncls == QUnicodeTables::LineBreak_SA) {            // two complex chars (thai or lao), thai_attributes might override, but here            // we do a best guess            charAttributes[i].softBreak = true;            charAttributes[i].whiteSpace = false;            charAttributes[i].charStop = true;            charAttributes[i].category = QChar::Separator_Space;            cls = ncls;            continue;        }        {	    int tcls = ncls;	    if (tcls >= QUnicodeTables::LineBreak_SA)		tcls = QUnicodeTables::LineBreak_ID;	    if (cls >= QUnicodeTables::LineBreak_SA)		cls = QUnicodeTables::LineBreak_ID;	    bool softBreak;	    int brk = breakTable[cls][tcls];	    if (brk == Ibk)		softBreak = (cls == QUnicodeTables::LineBreak_SP);	    else		softBreak = (brk == Dbk);//        qDebug("char = %c %04x, cls=%d, ncls=%d, brk=%d soft=%d", uc[i].cell(), uc[i].unicode(), cls, ncls, brk, charAttributes[i].softBreak);	    charAttributes[i].softBreak = softBreak;	    charAttributes[i].whiteSpace = false;	    charAttributes[i].charStop = true;	    charAttributes[i].category = category;	    cls = ncls;	}        continue;    nsm:        charAttributes[i].softBreak = false;        charAttributes[i].whiteSpace = false;        charAttributes[i].charStop = false;        charAttributes[i].category = QChar::Mark_NonSpacing;    }}#if defined(Q_WS_X11) || defined (Q_WS_QWS)# include "qtextengine_unix.cpp"#elif defined(Q_WS_WIN)# include "qtextengine_win.cpp"#elif defined(Q_WS_MAC)# include "qtextengine_mac.cpp"#endifstatic void init(QTextEngine *e){#ifdef Q_WS_WIN    if(!resolvedUsp10)        resolveUsp10();#endif    e->ignoreBidi = false;    e->cacheGlyphs = false;    e->layoutData = 0;    e->minWidth = 0;    e->maxWidth = 0;    e->underlinePositions = 0;

⌨️ 快捷键说明

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