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

📄 qtextengine.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
            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;        }    }    QFixed need = line.width - line.textWidth;    if (need < 0) {        // line overflows already!        const_cast<QScriptLine &>(line).justified = true;        return;    }//     qDebug("doing justification: textWidth=%x, requested=%x, maxJustify=%d", line.textWidth.value(), line.width.value(), maxJustify);//     qDebug("     minKashida=%f, need=%f", minKashida, need);    // distribute in priority order    if (maxJustify >= QGlyphLayout::Arabic_Normal) {        while (need >= minKashida) {            for (int type = maxJustify; need >= minKashida && type >= QGlyphLayout::Arabic_Normal; --type) {                for (int i = 0; need >= minKashida && i < nPoints; ++i) {                    if (justificationPoints[i].type == type && justificationPoints[i].kashidaWidth <= need) {                        justificationPoints[i].glyph->nKashidas++;                        // ############                        justificationPoints[i].glyph->space_18d6 += justificationPoints[i].kashidaWidth.value();                        need -= justificationPoints[i].kashidaWidth;//                         qDebug("adding kashida type %d with width %x, neednow %x", type, justificationPoints[i].kashidaWidth, need.value());                    }                }            }        }    }    Q_ASSERT(need >= 0);    if (!need)        goto end;    maxJustify = qMin(maxJustify, (int)QGlyphLayout::Space);    for (int type = maxJustify; need != 0 && type > 0; --type) {        int n = 0;        for (int i = 0; i < nPoints; ++i) {            if (justificationPoints[i].type == type)                ++n;        }//          qDebug("number of points for justification type %d: %d", type, n);        if (!n)            continue;        for (int i = 0; i < nPoints; ++i) {            if (justificationPoints[i].type == type) {                QFixed add = need/n;//                  qDebug("adding %x to glyph %x", add.value(), justificationPoints[i].glyph->glyph);                justificationPoints[i].glyph->space_18d6 = add.value();                need -= add;                --n;            }        }        Q_ASSERT(!need);    } end:    const_cast<QScriptLine &>(line).justified = true;}void QScriptLine::setDefaultHeight(QTextEngine *eng){    QFont f;    QFontEngine *e;    if (eng->block.docHandle()) {        f = eng->block.charFormat().font();        // Make sure we get the right dpi on printers        QPaintDevice *pdev = eng->block.docHandle()->layout()->paintDevice();        if (pdev)            f = QFont(f, pdev);        e = f.d->engineForScript(QUnicodeTables::Common);    } else {        e = eng->fnt.d->engineForScript(QUnicodeTables::Common);    }    ascent = qMax(ascent, e->ascent());    descent = qMax(descent, e->descent());}QTextEngine::LayoutData::LayoutData(){    memory = 0;    allocated = 0;    num_glyphs = 0;    memory_on_stack = false;    used = 0;    hasBidi = false;    inLayout = false;    haveCharAttributes = false;    logClustersPtr = 0;    glyphPtr = 0;}QTextEngine::LayoutData::LayoutData(const QString &str, void **stack_memory, int _allocated)    : string(str){    allocated = _allocated;        int space_charAttributes = sizeof(QCharAttributes)*string.length()/sizeof(void*) + 1;    int space_logClusters = sizeof(unsigned short)*string.length()/sizeof(void*) + 1;    available_glyphs = ((int)allocated - space_charAttributes - space_logClusters)*(int)sizeof(void*)/(int)sizeof(QGlyphLayout) - 2;    if (available_glyphs < str.length()) {        // need to allocate on the heap        num_glyphs = 0;        allocated = 0;        memory_on_stack = false;        memory = 0;        logClustersPtr = 0;        glyphPtr = 0;    } else {        num_glyphs = str.length();        allocated = str.length();                memory_on_stack = true;        memory = stack_memory;        logClustersPtr = (unsigned short *)(memory + space_charAttributes);        glyphPtr = (QGlyphLayout *)(memory + space_charAttributes + space_logClusters);        memset(memory, 0, space_charAttributes*sizeof(void *));        memset(glyphPtr, 0, num_glyphs*sizeof(QGlyphLayout));    }    used = 0;    hasBidi = false;    inLayout = false;    haveCharAttributes = false;}QTextEngine::LayoutData::~LayoutData(){    if (!memory_on_stack)        free(memory);    memory = 0;}void QTextEngine::LayoutData::reallocate(int totalGlyphs){    Q_ASSERT(totalGlyphs >= num_glyphs);    if (memory_on_stack && available_glyphs >= totalGlyphs) {        memset(glyphPtr + num_glyphs, 0, (totalGlyphs - num_glyphs)*sizeof(QGlyphLayout));        num_glyphs = totalGlyphs;        return;    }        int space_charAttributes = sizeof(QCharAttributes)*string.length()/sizeof(void*) + 1;    int space_logClusters = sizeof(unsigned short)*string.length()/sizeof(void*) + 1;    int space_glyphs = sizeof(QGlyphLayout)*totalGlyphs/sizeof(void*) + 2;    int newAllocated = space_charAttributes + space_glyphs + space_logClusters;    void **old_mem = memory;    memory = (void **)::realloc(memory_on_stack ? 0 : old_mem, newAllocated*sizeof(void *));    if (memory_on_stack && memory)        memcpy(memory, old_mem, allocated*sizeof(void *));    memory_on_stack = false;    void **m = memory;    m += space_charAttributes;    logClustersPtr = (unsigned short *) m;    m += space_logClusters;    glyphPtr = (QGlyphLayout *) m;    memset(((char *)memory) + allocated*sizeof(void *), 0,           (newAllocated - allocated)*sizeof(void *));    allocated = newAllocated;    num_glyphs = totalGlyphs;}void QTextEngine::freeMemory(){    if (!stackEngine) {        delete layoutData;        layoutData = 0;    } else {        layoutData->used = 0;        layoutData->hasBidi = false;        layoutData->inLayout = false;        layoutData->haveCharAttributes = false;    }    for (int i = 0; i < lines.size(); ++i) {        lines[i].justified = 0;        lines[i].gridfitted = 0;    }}int QTextEngine::formatIndex(const QScriptItem *si) const{    if (specialData && !specialData->resolvedFormatIndices.isEmpty())        return specialData->resolvedFormatIndices.at(si - &layoutData->items[0]);    QTextDocumentPrivate *p = block.docHandle();    if (!p)        return -1;    int pos = si->position;    if (specialData && si->position >= specialData->preeditPosition) {        if (si->position < specialData->preeditPosition + specialData->preeditText.length())            pos = qMax(specialData->preeditPosition - 1, 0);        else            pos -= specialData->preeditText.length();    }    QTextDocumentPrivate::FragmentIterator it = p->find(block.position() + pos);    return it.value()->format;}QTextCharFormat QTextEngine::format(const QScriptItem *si) const{    QTextCharFormat format;    const QTextFormatCollection *formats = 0;    if (block.docHandle()) {        formats = this->formats();        format = formats->charFormat(formatIndex(si));    }    if (specialData && specialData->resolvedFormatIndices.isEmpty()) {        int end = si->position + length(si);        for (int i = 0; i < specialData->addFormats.size(); ++i) {            const QTextLayout::FormatRange &r = specialData->addFormats.at(i);            if (r.start <= si->position && r.start + r.length >= end) {                if (!specialData->addFormatIndices.isEmpty())                    format.merge(formats->format(specialData->addFormatIndices.at(i)));                else                    format.merge(r.format);            }        }    }    return format;}void QTextEngine::addRequiredBoundaries() const{    int position = 0;    SpecialData *s = specialData;    const QTextDocumentPrivate *p = block.docHandle();    if (p) {        QTextDocumentPrivate::FragmentIterator it = p->find(block.position());        QTextDocumentPrivate::FragmentIterator end = p->find(block.position() + block.length() - 1); // -1 to omit the block separator char        int format = it.value()->format;        for (; it != end; ++it) {            if (s && position >= s->preeditPosition) {                position += s->preeditText.length();                s = 0;            }            const QTextFragmentData * const frag = it.value();            if (format != frag->format)                setBoundary(position);            format = frag->format;            position += frag->size;        }    }    if (specialData) {        for (int i = 0; i < specialData->addFormats.size(); ++i) {            const QTextLayout::FormatRange &r = specialData->addFormats.at(i);            setBoundary(r.start);            setBoundary(r.start + r.length);            //qDebug("adding boundaries %d %d", r.start, r.start+r.length);        }    }}bool QTextEngine::atWordSeparator(int position) const{    const QChar c = layoutData->string.at(position);    return c == '.'        || c == ','        || c == ':'        || c == ';'        || c == '-'        || c == '<'        || c == '>'        || c == '['        || c == ']'        || c == '('        || c == ')'        || c == '{'        || c == '}'        || c == QChar::Nbsp        ;}void QTextEngine::indexAdditionalFormats(){    if (!block.docHandle())        return;    specialData->addFormatIndices.resize(specialData->addFormats.count());    QTextFormatCollection * const formats = this->formats();    for (int i = 0; i < specialData->addFormats.count(); ++i) {        specialData->addFormatIndices[i] = formats->indexForFormat(specialData->addFormats.at(i).format);        specialData->addFormats[i].format = QTextCharFormat();    }}void QTextEngine::setBoundary(int strPos) const{    if (strPos <= 0 || strPos >= layoutData->string.length())        return;    int itemToSplit = 0;    while (itemToSplit < layoutData->items.size() && layoutData->items[itemToSplit].position <= strPos)        itemToSplit++;    itemToSplit--;    if (layoutData->items[itemToSplit].position == strPos) {        // already a split at the requested position        return;    }    splitItem(itemToSplit, strPos - layoutData->items[itemToSplit].position);}void QTextEngine::splitItem(int item, int pos) const{    if (pos <= 0)        return;    layoutData->items.insert(item + 1, QScriptItem(layoutData->items[item]));    QScriptItem &oldItem = layoutData->items[item];    QScriptItem &newItem = layoutData->items[item+1];    newItem.position += pos;    if (oldItem.num_glyphs) {        // already shaped, break glyphs aswell        int breakGlyph = logClusters(&oldItem)[pos];        newItem.num_glyphs = oldItem.num_glyphs - breakGlyph;        oldItem.num_glyphs = breakGlyph;        newItem.glyph_data_offset = oldItem.glyph_data_offset + breakGlyph;        for (int i = 0; i < newItem.num_glyphs; i++)            logClusters(&newItem)[i] -= breakGlyph;        QFixed w = 0;        const QGlyphLayout *g = glyphs(&oldItem);        for(int j = 0; j < breakGlyph; ++j)            w += (g++)->advance.x;        newItem.width = oldItem.width - w;        oldItem.width = w;    }//     qDebug("split at position %d itempos=%d", pos, item);}QFixed QTextEngine::nextTab(const QScriptItem *si, QFixed x) const{    // #### should work for alignright and righttoleft    if (!(option.alignment() & Qt::AlignLeft) ||        option.textDirection() != Qt::LeftToRight)        return x + si->width;    QList<qreal> tabArray = option.tabArray();    if (!tabArray.isEmpty()) {        for (int i = 0; i < tabArray.size(); ++i) {            if (tabArray.at(i) > x.toReal())                return QFixed::fromReal(tabArray.at(i));        }    }    QFixed tab = QFixed::fromReal(option.tabStop());    if (tab <= 0)        tab = 80; // default    return ((x / tab).truncate() + 1) * tab;}void QTextEngine::resolveAdditionalFormats() const{    if (!specialData || specialData->addFormats.isEmpty()        || !block.docHandle())        return;    QTextFormatCollection *collection = this->formats();    specialData->resolvedFormatIndices.clear();    QVector<int> indices(layoutData->items.count());    for (int i = 0; i < layoutData->items.count(); ++i) {        QTextCharFormat f = format(&layoutData->items.at(i));        indices[i] = collection->indexForFormat(f);    }    specialData->resolvedFormatIndices = indices;}QStackTextEngine::QStackTextEngine(const QString &string, const QFont &f)    : _layoutData(string, _memory, MemSize){    fnt = f;    text = string;    stackEngine = true;    layoutData = &_layoutData;}

⌨️ 快捷键说明

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