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

📄 qtextengine.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    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;    if (!ignoreBidi) {        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);    }    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++)//                 fprintf(stderr, " %d", logClusters[k]);//             fprintf(stderr, "\n");            // do the simple thing for now and give the first glyph in a cluster the full width, all other ones 0.            int charFrom = from - pos;            if (charFrom < 0)                charFrom = 0;            int glyphStart = logClusters[charFrom];            if (charFrom > 0 && logClusters[charFrom-1] == glyphStart)                while (charFrom < ilen && logClusters[charFrom] == glyphStart)                    charFrom++;            if (charFrom < ilen) {                glyphStart = logClusters[charFrom];                int charEnd = from + len - 1 - pos;                if (charEnd >= ilen)                    charEnd = ilen-1;                int glyphEnd = logClusters[charEnd];                while (charEnd < ilen && logClusters[charEnd] == glyphEnd)                    charEnd++;                glyphEnd = (charEnd == ilen) ? si->num_glyphs : logClusters[charEnd];//                 qDebug("char: start=%d end=%d / glyph: start = %d, end = %d", charFrom, charEnd, glyphStart, glyphEnd);                for (int i = glyphStart; i < glyphEnd; i++)                    w += glyphs[i].advance.x;            }        }    }//     qDebug("   --> w= %d ", w);    return w;}glyph_metrics_t QTextEngine::boundingBox(int from,  int len) const{    itemize();    glyph_metrics_t gm;    for (int i = 0; i < layoutData->items.size(); i++) {        const QScriptItem *si = layoutData->items.constData() + i;        int pos = si->position;        int ilen = length(i);        if (pos > from + len)            break;        if (pos + len > from) {            if (!si->num_glyphs)                shape(i);            unsigned short *logClusters = this->logClusters(si);            QGlyphLayout *glyphs = this->glyphs(si);            // do the simple thing for now and give the first glyph in a cluster the full width, all other ones 0.            int charFrom = from - pos;            if (charFrom < 0)                charFrom = 0;            int glyphStart = logClusters[charFrom];            if (charFrom > 0 && logClusters[charFrom-1] == glyphStart)                while (charFrom < ilen && logClusters[charFrom] == glyphStart)                    charFrom++;            if (charFrom < ilen) {                glyphStart = logClusters[charFrom];                int charEnd = from + len - 1 - pos;                if (charEnd >= ilen)                    charEnd = ilen-1;                int glyphEnd = logClusters[charEnd];                while (charEnd < ilen && logClusters[charEnd] == glyphEnd)                    charEnd++;                glyphEnd = (charEnd == ilen) ? si->num_glyphs : logClusters[charEnd];                if (glyphStart <= glyphEnd ) {                    QFontEngine *fe = fontEngine(*si);                    glyph_metrics_t m = fe->boundingBox(glyphs+glyphStart, glyphEnd-glyphStart);                    gm.x = qMin(gm.x, m.x + gm.xoff);                    gm.y = qMin(gm.y, m.y + gm.yoff);                    gm.width = qMax(gm.width, m.width+gm.xoff);                    gm.height = qMax(gm.height, m.height+gm.yoff);                    gm.xoff += m.xoff;                    gm.yoff += m.yoff;                }            }        }    }    return gm;}QFont QTextEngine::font(const QScriptItem &si) const{    if (!hasFormats())        return fnt;    QTextCharFormat f = format(&si);    QFont font = f.font();    if (block.docHandle()) {        // Make sure we get the right dpi on printers        QPaintDevice *pdev = block.docHandle()->layout()->paintDevice();        if (pdev)            font = QFont(font, pdev);    } else {        font = font.resolve(fnt);    }    if (f.verticalAlignment() != QTextCharFormat::AlignNormal)        font.setPointSize((font.pointSize() * 2) / 3);    return font;}QFontEngine *QTextEngine::fontEngine(const QScriptItem &si, QFixed *ascent, QFixed *descent) const{    QFontEngine *engine;    QFontEngine *scaledEngine = 0;    int script = si.analysis.script;#if defined(Q_WS_WIN)    if (hasUsp10) {        const SCRIPT_PROPERTIES *script_prop = script_properties[si.analysis.script];        script = scriptForWinLanguage(script_prop->langid);    }#endif        if (!hasFormats()) {        engine = fnt.d->engineForScript(script);#if defined(Q_WS_WIN)        if (engine->type() == QFontEngine::Box)            engine = fnt.d->engineForScript(QUnicodeTables::Common);#endif    } else {        QTextCharFormat f = format(&si);        QFont font = f.font();        if (block.docHandle()) {            // Make sure we get the right dpi on printers            QPaintDevice *pdev = block.docHandle()->layout()->paintDevice();            if (pdev)                font = QFont(font, pdev);        } else {            font = font.resolve(fnt);        }        engine = font.d->engineForScript(script);#if defined(Q_WS_WIN)        if (engine->type() == QFontEngine::Box)            engine = font.d->engineForScript(QUnicodeTables::Common);#endif        if (f.verticalAlignment() != QTextCharFormat::AlignNormal) {            font.setPointSize((font.pointSize() * 2) / 3);            scaledEngine = font.d->engineForScript(script);#if defined(Q_WS_WIN)            if (scaledEngine->type() == QFontEngine::Box)                scaledEngine = font.d->engineForScript(QUnicodeTables::Common);#endif        }    }    if (ascent) {        *ascent = engine->ascent();        *descent = engine->descent();    }        if (scaledEngine)        return scaledEngine;    return engine;}struct QJustificationPoint {    int type;    QFixed kashidaWidth;    QGlyphLayout *glyph;    QFontEngine *fontEngine;};Q_DECLARE_TYPEINFO(QJustificationPoint, Q_PRIMITIVE_TYPE);static void set(QJustificationPoint *point, int type, QGlyphLayout *glyph, QFontEngine *fe){    point->type = type;    point->glyph = glyph;    point->fontEngine = fe;    if (type >= QGlyphLayout::Arabic_Normal) {        QChar ch(0x640); // Kashida character        QGlyphLayout glyphs[8];        int nglyphs = 7;        fe->stringToCMap(&ch, 1, glyphs, &nglyphs, 0);        if (glyphs[0].glyph && glyphs[0].advance.x != 0) {            point->kashidaWidth = glyphs[0].advance.x;        } else {            point->type = QGlyphLayout::NoJustification;            point->kashidaWidth = 0;        }    }}void QTextEngine::justify(const QScriptLine &line){//     qDebug("justify: line.gridfitted = %d, line.justified=%d", line.gridfitted, line.justified);    if (line.gridfitted && line.justified)        return;    if (!line.gridfitted) {        // redo layout in device metrics, then adjust        const_cast<QScriptLine &>(line).gridfitted = true;    }    if ((option.alignment() & Qt::AlignHorizontal_Mask) != Qt::AlignJustify)        return;    itemize();    if (line.from + (int)line.length == layoutData->string.length()        || layoutData->string.at(line.from + line.length - 1) == QChar::LineSeparator)        return;    // justify line    int maxJustify = 0;    // don't include trailing white spaces when doing justification    int line_length = line.length;    const QCharAttributes *a = attributes()+line.from;    while (line_length && a[line_length-1].whiteSpace)        --line_length;    // subtract one char more, as we can't justfy after the last character    --line_length;    if (!line_length)        return;    int firstItem = findItem(line.from);    int nItems = findItem(line.from + line_length - 1) - firstItem + 1;    QVarLengthArray<QJustificationPoint> justificationPoints;    int nPoints = 0;//     qDebug("justifying from %d len %d, firstItem=%d, nItems=%d", line.from, line_length, firstItem, nItems);    QFixed minKashida = 0x100000;    // we need to do all shaping before we go into the next loop, as we there    // store pointers to the glyph data that could get reallocated by the shaping    // process.    for (int i = 0; i < nItems; ++i) {        QScriptItem &si = layoutData->items[firstItem + i];        if (!si.num_glyphs)            shape(firstItem + i);    }    for (int i = 0; i < nItems; ++i) {        QScriptItem &si = layoutData->items[firstItem + i];        int kashida_type = QGlyphLayout::Arabic_Normal;        int kashida_pos = -1;        int start = qMax(line.from - si.position, 0);        int end = qMin(line.from + line_length - (int)si.position, length(firstItem+i));        unsigned short *log_clusters = logClusters(&si);        int gs = log_clusters[start];        int ge = (end == length(firstItem+i) ? si.num_glyphs : log_clusters[end]);        QGlyphLayout *g = glyphs(&si);        for (int i = gs; i < ge; ++i) {            g[i].justificationType = QGlyphLayout::JustifyNone;            g[i].nKashidas = 0;            g[i].space_18d6 = 0;            justificationPoints.resize(nPoints+3);            int justification = g[i].attributes.justification;            switch(justification) {            case QGlyphLayout::NoJustification:                break;            case QGlyphLayout::Space          :                // fall through

⌨️ 快捷键说明

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