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

📄 qtextengine.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// The following line break classes are not treated by the table://  AI, BK, CB, CR, LF, NL, SA, SG, SP, XXenum break_class {    // the first 4 values have to agree with the enum in QCharAttributes    ProhibitedBreak,            // PB in table    DirectBreak,                // DB in table    IndirectBreak,              // IB in table    CombiningIndirectBreak,     // CI in table    CombiningProhibitedBreak,   // CP in table};#define DB DirectBreak#define IB IndirectBreak#define CI CombiningIndirectBreak#define CP CombiningProhibitedBreak#define PB ProhibitedBreakstatic const quint8 breakTable[QUnicodeTables::LineBreak_JT+1][QUnicodeTables::LineBreak_JT+1] ={/*          OP  CL  QU  GL  NS  EX  SY  IS  PR  PO  NU  AL  ID  IN  HY  BA  BB  B2  ZW  CM  WJ  H2  H3  JL  JV  JT *//* OP */ { PB, PB, PB, PB, PB, PB, PB, PB, PB, PB, PB, PB, PB, PB, PB, PB, PB, PB, PB, CP, PB, PB, PB, PB, PB, PB },/* CL */ { DB, PB, IB, IB, PB, PB, PB, PB, IB, IB, IB, IB, DB, DB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, DB },/* QU */ { PB, PB, IB, IB, IB, PB, PB, PB, IB, IB, IB, IB, IB, IB, IB, IB, IB, IB, PB, CI, PB, IB, IB, IB, IB, IB },/* GL */ { IB, PB, IB, IB, IB, PB, PB, PB, IB, IB, IB, IB, IB, IB, IB, IB, IB, IB, PB, CI, PB, IB, IB, IB, IB, IB },/* NS */ { DB, PB, IB, IB, IB, PB, PB, PB, DB, DB, DB, DB, DB, DB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, DB },/* EX */ { DB, PB, IB, IB, IB, PB, PB, PB, DB, IB, DB, IB, DB, DB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, DB },/* SY */ { IB, PB, IB, IB, IB, PB, PB, PB, IB, IB, IB, IB, DB, DB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, DB },/* IS */ { DB, PB, IB, IB, IB, PB, PB, PB, DB, DB, IB, IB, DB, DB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, DB },/* PR */ { IB, PB, IB, IB, IB, PB, PB, PB, IB, IB, IB, IB, IB, DB, IB, IB, DB, DB, PB, CI, PB, IB, IB, IB, IB, IB },/* PO */ { IB, PB, IB, IB, IB, PB, PB, PB, IB, IB, IB, IB, DB, DB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, DB },/* NU */ { IB, PB, IB, IB, IB, IB, PB, PB, IB, IB, IB, IB, DB, IB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, DB },/* AL */ { IB, PB, IB, IB, IB, PB, PB, PB, IB, IB, IB, IB, DB, IB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, DB },/* ID */ { DB, PB, IB, IB, IB, PB, PB, PB, DB, IB, DB, DB, DB, IB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, DB },/* IN */ { DB, PB, IB, IB, IB, PB, PB, PB, DB, DB, DB, DB, DB, IB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, DB },/* HY */ { IB, PB, IB, IB, IB, PB, PB, PB, IB, IB, IB, DB, DB, DB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, DB },/* BA */ { DB, PB, IB, IB, IB, PB, PB, PB, DB, DB, DB, DB, DB, DB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, DB },/* BB */ { IB, PB, IB, IB, IB, PB, PB, PB, IB, IB, IB, IB, IB, IB, IB, IB, IB, IB, PB, CI, PB, IB, IB, IB, IB, IB },/* B2 */ { DB, PB, IB, IB, IB, PB, PB, PB, DB, DB, DB, DB, DB, DB, IB, IB, DB, PB, PB, CI, PB, DB, DB, DB, DB, DB },/* ZW */ { DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, DB, PB, DB, DB, DB, DB, DB, DB, DB },/* CM */ { DB, PB, IB, IB, IB, PB, PB, PB, DB, DB, IB, IB, DB, IB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, DB },/* WJ */ { IB, PB, IB, IB, IB, PB, PB, PB, IB, IB, IB, IB, IB, IB, IB, IB, IB, IB, PB, CI, PB, IB, IB, IB, IB, IB },/* H2 */ { DB, PB, IB, IB, IB, PB, PB, PB, DB, IB, DB, DB, DB, IB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, IB, IB },/* H3 */ { DB, PB, IB, IB, IB, PB, PB, PB, DB, IB, DB, DB, DB, IB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, IB },/* JL */ { DB, PB, IB, IB, IB, PB, PB, PB, DB, IB, DB, DB, DB, IB, IB, IB, DB, DB, PB, CI, PB, IB, IB, IB, IB, DB },/* JV */ { DB, PB, IB, IB, IB, PB, PB, PB, DB, IB, DB, DB, DB, IB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, IB, IB },/* JT */ { DB, PB, IB, IB, IB, PB, PB, PB, DB, IB, DB, DB, DB, IB, IB, IB, DB, DB, PB, CI, PB, DB, DB, DB, DB, IB }};#undef DB#undef IB#undef CI#undef CP#undef PBstatic void calcLineBreaks(const QString &string, QCharAttributes *charAttributes){    int len = string.length();    if (!len)        return;    const QChar *uc = string.unicode();    // ##### can this fail if the first char is a surrogate?    const QUnicodeTables::Properties *prop = QUnicodeTables::properties(uc->unicode());    int cls = prop->line_break_class;    // handle case where input starts with an LF    if (cls == QUnicodeTables::LineBreak_LF)        cls = QUnicodeTables::LineBreak_BK;    charAttributes[0].whiteSpace = (cls == QUnicodeTables::LineBreak_SP || cls == QUnicodeTables::LineBreak_BK);    charAttributes[0].charStop = true;    int lcls = cls;    for (int i = 1; i < len; ++i) {        charAttributes[i].whiteSpace = false;        charAttributes[i].charStop = true;        prop = QUnicodeTables::properties(uc[i].unicode());        int ncls = prop->line_break_class;        // handle surrogates        if (ncls == QUnicodeTables::LineBreak_SG) {            if (uc[i].isHighSurrogate() && i < len - 1 && uc[i+1].isLowSurrogate()) {                continue;            } else if (uc[i].isLowSurrogate() && uc[i-1].isHighSurrogate()) {                uint code = QChar::surrogateToUcs4(uc[i-1].unicode(), uc[i].unicode());                prop = QUnicodeTables::properties(code);                ncls = prop->line_break_class;                charAttributes[i].charStop = false;            } else {                ncls = QUnicodeTables::LineBreak_AL;            }        }        // set white space and char stop flag        if (ncls >= QUnicodeTables::LineBreak_SP)            charAttributes[i].whiteSpace = true;        if (ncls == QUnicodeTables::LineBreak_CM)            charAttributes[i].charStop = false;        QCharAttributes::LineBreakType lineBreakType = QCharAttributes::NoBreak;        if (cls >= QUnicodeTables::LineBreak_LF) {            lineBreakType = QCharAttributes::ForcedBreak;        } else if(cls == QUnicodeTables::LineBreak_CR) {            lineBreakType = (ncls == QUnicodeTables::LineBreak_LF) ? QCharAttributes::NoBreak : QCharAttributes::ForcedBreak;        }        if (ncls == QUnicodeTables::LineBreak_SP)            goto next_no_cls_update;        if (ncls >= QUnicodeTables::LineBreak_CR)            goto next;        // two complex chars (thai or lao), thai_attributes might override, but here we do a best guess	if (cls == QUnicodeTables::LineBreak_SA && ncls == QUnicodeTables::LineBreak_SA) {            lineBreakType = QCharAttributes::Break;            goto next;        }        {            int tcls = ncls;            if (tcls >= QUnicodeTables::LineBreak_SA)                tcls = QUnicodeTables::LineBreak_ID;            if (cls >= QUnicodeTables::LineBreak_SA)                cls = QUnicodeTables::LineBreak_ID;            int brk = breakTable[cls][tcls];            switch (brk) {            case DirectBreak:                lineBreakType = QCharAttributes::Break;                if (uc[i-1].unicode() == 0xad) // soft hyphen                    lineBreakType = QCharAttributes::SoftHyphen;                break;            case IndirectBreak:                lineBreakType = (lcls == QUnicodeTables::LineBreak_SP) ? QCharAttributes::Break : QCharAttributes::NoBreak;                break;            case CombiningIndirectBreak:                lineBreakType = QCharAttributes::NoBreak;                if (lcls == QUnicodeTables::LineBreak_SP){                    if (i > 1)                        charAttributes[i-2].lineBreakType = QCharAttributes::Break;                } else {                    goto next_no_cls_update;                }                break;            case CombiningProhibitedBreak:                lineBreakType = QCharAttributes::NoBreak;                if (lcls != QUnicodeTables::LineBreak_SP)                    goto next_no_cls_update;            case ProhibitedBreak:            default:                break;            }        }    next:        cls = ncls;    next_no_cls_update:        lcls = ncls;        charAttributes[i-1].lineBreakType = lineBreakType;    }    charAttributes[len-1].lineBreakType = QCharAttributes::ForcedBreak;}#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->forceJustification = false;    e->layoutData = 0;    e->minWidth = 0;    e->maxWidth = 0;    e->underlinePositions = 0;    e->specialData = 0;    e->stackEngine = false;}QTextEngine::QTextEngine(){    init(this);}QTextEngine::QTextEngine(const QString &str, const QFont &f)    : fnt(f){    init(this);    text = str;}QTextEngine::~QTextEngine(){    if (!stackEngine)        delete layoutData;    delete specialData;}const QCharAttributes *QTextEngine::attributes() const{    if (layoutData && layoutData->haveCharAttributes)        return (QCharAttributes *) layoutData->memory;    itemize();    ensureSpace(layoutData->string.length());    calcLineBreaks(layoutData->string, (QCharAttributes *) layoutData->memory);    for (int i = 0; i < layoutData->items.size(); i++) {        const QScriptItem &si = layoutData->items[i];        int script = si.analysis.script;#ifdef Q_WS_WIN        if(hasUsp10) {            script = QUnicodeTables::script(layoutData->string.at(si.position));        }#endif        if (script == QUnicodeTables::Inherited)            script = QUnicodeTables::Common;        AttributeFunction attributes = qt_scriptEngines[script].charAttributes;        if (!attributes)            continue;        int from = si.position;        int len = length(i);        attributes(script, layoutData->string, from, len, (QCharAttributes *) layoutData->memory);    }    layoutData->haveCharAttributes = true;    return (QCharAttributes *) layoutData->memory;}void QTextEngine::shape(int item) const{    if (layoutData->items[item].isObject) {        ensureSpace(1);        if (block.docHandle()) {            QTextFormat format = formats()->format(formatIndex(&layoutData->items[item]));            docLayout()->resizeInlineObject(QTextInlineObject(item, const_cast<QTextEngine *>(this)),                                            layoutData->items[item].position + block.position(), format);        }    } else {        shapeText(item);    }}void QTextEngine::invalidate(){    freeMemory();    lines.clear();    minWidth = 0;    maxWidth = 0;    if (specialData)        specialData->resolvedFormatIndices.clear();}void QTextEngine::validate() const{    if (layoutData)        return;    layoutData = new LayoutData();    if (block.docHandle())        layoutData->string = block.text();    else        layoutData->string = text;    if (specialData && specialData->preeditPosition != -1)        layoutData->string.insert(specialData->preeditPosition, specialData->preeditText);}void QTextEngine::itemize() const{    validate();    if (layoutData->items.size())        return;    if (layoutData->string.length() == 0)        return;    bool ignore = ignoreBidi;    if (!ignore && option.textDirection() == Qt::LeftToRight) {        ignore = true;        const QChar *start = layoutData->string.unicode();        const QChar * const end = start + layoutData->string.length();        while (start < end) {            if (start->unicode() >= 0x590) {                ignore = false;                break;            }            ++start;        }    }        if (!ignore) {        layoutData->hasBidi = bidiItemize(const_cast<QTextEngine *>(this), (option.textDirection() == Qt::RightToLeft));    } else {        QBidiControl control(false);        int start = 0;        int stop = layoutData->string.length() - 1;        appendItems(const_cast<QTextEngine *>(this), start, stop, control, QChar::DirL);        layoutData->hasBidi = false;    }    addRequiredBoundaries();    resolveAdditionalFormats();}int QTextEngine::findItem(int strPos) const{    itemize();    // ##### use binary search    int item;    for (item = layoutData->items.size()-1; item > 0; --item) {        if (layoutData->items[item].position <= strPos)            break;    }    return item;}QFixed QTextEngine::width(int from, int len) const{    itemize();    QFixed w = 0;//     qDebug("QTextEngine::width(from = %d, len = %d), numItems=%d, strleng=%d", from,  len, items.size(), string.length());    for (int i = 0; i < layoutData->items.size(); i++) {        const QScriptItem *si = layoutData->items.constData() + i;        int pos = si->position;        int ilen = length(i);//          qDebug("item %d: from %d len %d", i, pos, ilen);        if (pos >= from + len)            break;        if (pos + ilen > from) {            if (!si->num_glyphs)                shape(i);            if (si->isObject) {                w += si->width;                continue;            } else if (si->isTab) {                w = nextTab(si, w);                continue;            }            QGlyphLayout *glyphs = this->glyphs(si);            unsigned short *logClusters = this->logClusters(si);//             fprintf(stderr, "  logclusters:");//             for (int k = 0; k < ilen; k++)

⌨️ 快捷键说明

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