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

📄 qtextengine.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//                 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 * !glyphs[i].attributes.dontPrint;            }        }    }//     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;}glyph_metrics_t QTextEngine::tightBoundingBox(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->tightBoundingBox(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() && block.docHandle()->layout()) {        // 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);    }    QTextCharFormat::VerticalAlignment valign = f.verticalAlignment();    if (valign == QTextCharFormat::AlignSuperScript || valign == QTextCharFormat::AlignSubScript) {        if (font.pointSize() != -1)            font.setPointSize((font.pointSize() * 2) / 3);        else            font.setPixelSize((font.pixelSize() * 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() && block.docHandle()->layout()) {            // 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        QTextCharFormat::VerticalAlignment valign = f.verticalAlignment();        if (valign == QTextCharFormat::AlignSuperScript || valign == QTextCharFormat::AlignSubScript) {            if (font.pointSize() != -1)                font.setPointSize((font.pointSize() * 2) / 3);            else                font.setPixelSize((font.pixelSize() * 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 (!forceJustification && (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            case QGlyphLayout::Arabic_Space   :                if (kashida_pos >= 0) {//                     qDebug("kashida position at %d in word", kashida_pos);                    set(&justificationPoints[nPoints], kashida_type, g+kashida_pos, fontEngine(si));                    minKashida = qMin(minKashida, justificationPoints[nPoints].kashidaWidth);                    maxJustify = qMax(maxJustify, justificationPoints[nPoints].type);                    ++nPoints;                }                kashida_pos = -1;                kashida_type = QGlyphLayout::Arabic_Normal;                // fall through            case QGlyphLayout::Character      :                set(&justificationPoints[nPoints++], justification, g+i, fontEngine(si));                maxJustify = qMax(maxJustify, justification);                break;            case QGlyphLayout::Arabic_Normal  :            case QGlyphLayout::Arabic_Waw     :            case QGlyphLayout::Arabic_BaRa    :            case QGlyphLayout::Arabic_Alef    :            case QGlyphLayout::Arabic_HaaDal  :            case QGlyphLayout::Arabic_Seen    :            case QGlyphLayout::Arabic_Kashida :                if (justification >= kashida_type) {                    kashida_pos = i;                    kashida_type = justification;                }            }        }        if (kashida_pos >= 0) {            set(&justificationPoints[nPoints], kashida_type, g+kashida_pos, fontEngine(si));            minKashida = qMin(minKashida, justificationPoints[nPoints].kashidaWidth);            maxJustify = qMax(maxJustify, justificationPoints[nPoints].type);            ++nPoints;

⌨️ 快捷键说明

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