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

📄 qtextlayout.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        QFont f = eng->font(si);        gf.fontEngine = f.d->engineForScript(si.analysis.script);        gf.f = &f;        QTextCharFormat chf;        if (eng->hasFormats() || selection) {            chf = eng->format(&si);            if (selection)                chf.merge(selection->format);            setPenAndDrawBackground(p, pen, chf, QRectF(x.toReal(), (y - line.ascent).toReal(),                                                        gf.width.toReal(), line.height().toReal()));            QTextCharFormat::VerticalAlignment valign = chf.verticalAlignment();            if (valign != QTextCharFormat::AlignNormal) {                QFixed height = gf.fontEngine->ascent() + gf.fontEngine->descent();                if (valign == QTextCharFormat::AlignSubScript)                    itemBaseLine += height / 6;                else if (valign == QTextCharFormat::AlignSuperScript)                    itemBaseLine -= height / 2;            }        }        if (f.d->underline)            gf.flags |= QTextItem::Underline;        if (f.d->overline)            gf.flags |= QTextItem::Overline;        if (f.d->strikeOut)            gf.flags |= QTextItem::StrikeOut;        gf.underlineColor = chf.underlineColor();        Q_ASSERT(gf.fontEngine);        if (eng->underlinePositions) {            // can't have selections in this case            drawMenuText(p, x, itemBaseLine, si, gf, eng, start, gs);        } else {            QPointF pos(x.toReal(), itemBaseLine.toReal());            if (chf.hasProperty(QTextFormat::TextOutline)) {                QPainterPath path;                path.setFillRule(Qt::WindingFill);                if (gf.num_glyphs)                    gf.fontEngine->addOutlineToPath(pos.x(), pos.y(), gf.glyphs, gf.num_glyphs, &path, gf.flags);                if (gf.flags) {                    const QFontEngine *fe = gf.fontEngine;                    const qreal lw = fe->lineThickness().toReal();                    if (gf.flags & QTextItem::Underline) {                        qreal offs = fe->underlinePosition().toReal();                        path.addRect(pos.x(), pos.y() + offs, gf.width.toReal(), lw);                    }                    if (gf.flags & QTextItem::Overline) {                        qreal offs = fe->ascent().toReal() + 1;                        path.addRect(pos.x(), pos.y() - offs, gf.width.toReal(), lw);                    }                    if (gf.flags & QTextItem::StrikeOut) {                        qreal offs = fe->ascent().toReal() / 3;                        path.addRect(pos.x(), pos.y() - offs, gf.width.toReal(), lw);                    }                }                p->save();                p->setRenderHint(QPainter::Antialiasing);                //Currently QPen with a Qt::NoPen style still returns a default                //QBrush which != Qt::NoBrush so we need this specialcase to reset it                if (p->pen().style() == Qt::NoPen)                    p->setBrush(Qt::NoBrush);                else                    p->setBrush(p->pen().brush());                p->setPen(chf.textOutline());                p->drawPath(path);                p->restore();            } else {                p->drawTextItem(pos, gf);            }        }        if (selection)            p->restore();        x += gf.width;    }    if (selection && outlineRect.isValid()) {        QVariant outline = selection->format.property(QTextFormat::OutlinePen);        if (outline.type() == QVariant::Pen) {            p->setPen(qVariantValue<QPen>(outline));            p->drawRect(outlineRect);        }    }    if (eng->hasFormats())        p->setPen(pen);}/*!  \fn int QTextLine::cursorToX(int cursorPos, Edge edge) const  \overload*//*!  Converts the cursor position \a cursorPos to the corresponding x position  inside the line, taking account of the \a edge.  If \a cursorPos is not a valid cursor position, the nearest valid  cursor position will be used instead, and cpos will be modified to  point to this valid cursor position.  \sa xToCursor()*/qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const{    if (!eng->layoutData)        eng->itemize();    const QScriptLine &line = eng->lines[i];    QFixed x = line.x;    x += alignLine(eng, line);    if (!i && !eng->layoutData->items.size()) {        *cursorPos = 0;        return x.toReal();    }    int pos = *cursorPos;    int itm = eng->findItem(pos);    if (pos == line.from + (int)line.length) {        // end of line ensure we have the last item on the line        itm = eng->findItem(pos-1);    }    const QScriptItem *si = &eng->layoutData->items[itm];    if (!si->num_glyphs)        eng->shape(itm);    pos -= si->position;    QGlyphLayout *glyphs = eng->glyphs(si);    unsigned short *logClusters = eng->logClusters(si);    int l = eng->length(itm);    if (pos > l)        pos = l;    if (pos < 0)        pos = 0;    int glyph_pos = pos == l ? si->num_glyphs : logClusters[pos];    if (edge == Trailing) {        // trailing edge is leading edge of next cluster        while (glyph_pos < si->num_glyphs && !glyphs[glyph_pos].attributes.clusterStart)            glyph_pos++;    }    bool reverse = eng->layoutData->items[itm].analysis.bidiLevel % 2;    int lineEnd = line.from + line.length;    // add the items left of the cursor    int firstItem = eng->findItem(line.from);    int lastItem = eng->findItem(lineEnd - 1);    int nItems = lastItem-firstItem+1;    QVarLengthArray<int> visualOrder(nItems);    QVarLengthArray<uchar> levels(nItems);    for (int i = 0; i < nItems; ++i)        levels[i] = eng->layoutData->items[i+firstItem].analysis.bidiLevel;    QTextEngine::bidiReorder(nItems, levels.data(), visualOrder.data());    for (int i = 0; i < nItems; ++i) {        int item = visualOrder[i]+firstItem;        if (item == itm)            break;        QScriptItem &si = eng->layoutData->items[item];        if (!si.num_glyphs)            eng->shape(item);        if (si.isTab) {            x = eng->nextTab(&si, x);            continue;        } else if (si.isObject) {            x += si.width;            continue;        }        int start = qMax(line.from, si.position);        int end = qMin(lineEnd, si.position + eng->length(item));        logClusters = eng->logClusters(&si);        int gs = logClusters[start-si.position];        int ge = (end == si.position + eng->length(item)) ? si.num_glyphs-1 : logClusters[end-si.position-1];        QGlyphLayout *glyphs = eng->glyphs(&si);        while (gs <= ge) {            x += (glyphs[gs].advance.x + QFixed::fromFixed(glyphs[gs].space_18d6)) * !glyphs[gs].attributes.dontPrint;            ++gs;        }    }    logClusters = eng->logClusters(si);    glyphs = eng->glyphs(si);    if (si->isTab) {        if(pos == l)            x = eng->nextTab(si, x);    } else if (si->isObject) {        if(pos == l)            x += si->width;    } else {        if (reverse) {            int end = qMin(lineEnd, si->position + l) - si->position;            int glyph_end = end == l ? si->num_glyphs : logClusters[end];            for (int i = glyph_end - 1; i >= glyph_pos; i--)                x += (glyphs[i].advance.x + QFixed::fromFixed(glyphs[i].space_18d6)) * !glyphs[i].attributes.dontPrint;        } else {            int start = qMax(line.from - si->position, 0);            int glyph_start = logClusters[start];            for (int i = glyph_start; i < glyph_pos; i++)                x += (glyphs[i].advance.x + QFixed::fromFixed(glyphs[i].space_18d6)) *!glyphs[i].attributes.dontPrint;        }    }    *cursorPos = pos + si->position;    return x.toReal();}/*!  \fn int QTextLine::xToCursor(qreal x, CursorPosition cpos) const  Converts the x-coordinate \a x, to the nearest matching cursor  position, depending on the cursor position type, \a cpos.  \sa cursorToX()*/int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const{    QFixed x = QFixed::fromReal(_x);    const QScriptLine &line = eng->lines[i];    if (!eng->layoutData)        eng->itemize();    int line_length = line.length;    if (line_length > 0 && eng->layoutData->string.at(line.from + line_length - 1) == QChar::LineSeparator)        --line_length;    if (!line_length)        return line.from;    int firstItem = eng->findItem(line.from);    int lastItem = eng->findItem(line.from + line_length - 1);    int nItems = lastItem-firstItem+1;    x -= line.x;    x -= alignLine(eng, line);//     qDebug("xToCursor: x=%f, cpos=%d", x, cpos);    QVarLengthArray<int> visualOrder(nItems);    QVarLengthArray<unsigned char> levels(nItems);    for (int i = 0; i < nItems; ++i)        levels[i] = eng->layoutData->items[i+firstItem].analysis.bidiLevel;    QTextEngine::bidiReorder(nItems, levels.data(), visualOrder.data());    if (x <= 0) {        // left of first item        int item = visualOrder[0]+firstItem;        QScriptItem &si = eng->layoutData->items[item];        if (!si.num_glyphs)            eng->shape(item);        int pos = si.position;        if (si.analysis.bidiLevel % 2)            pos += eng->length(item);        pos = qMax(line.from, pos);        pos = qMin(line.from + line_length, pos);        return pos;    } else if (x < line.textWidth               || (line.justified && x < line.width)) {        // has to be in one of the runs        QFixed pos;        for (int i = 0; i < nItems; ++i) {            int item = visualOrder[i]+firstItem;            QScriptItem &si = eng->layoutData->items[item];            if (!si.num_glyphs)                eng->shape(item);            int item_length = eng->length(item);//             qDebug("    item %d, visual %d x_remain=%f", i, item, x);            int start = qMax(line.from - si.position, 0);            int end = qMin(line.from + line_length - si.position, item_length);            unsigned short *logClusters = eng->logClusters(&si);            int gs = logClusters[start];            int ge = (end == item_length ? si.num_glyphs : logClusters[end]) - 1;            QGlyphLayout *glyphs = eng->glyphs(&si);            QFixed item_width = 0;            if (si.isTab) {                item_width = eng->nextTab(&si, pos) - pos;            } else if (si.isObject) {                item_width = si.width;            } else {                int g = gs;                while (g <= ge) {                    item_width += (glyphs[g].advance.x + QFixed::fromFixed(glyphs[g].space_18d6)) * !glyphs[g].attributes.dontPrint;                    ++g;                }            }//             qDebug("      start=%d, end=%d, gs=%d, ge=%d item_width=%f", start, end, gs, ge, item_width);            if (pos + item_width < x) {                pos += item_width;                continue;            }//             qDebug("      inside run");            if (si.isTab || si.isObject) {                if (cpos == QTextLine::CursorOnCharacter)                    return si.position;                bool left_half = (x - pos) < item_width/2;                if (bool(si.analysis.bidiLevel % 2) != left_half)                    return si.position;                return si.position + 1;            }            int glyph_pos = -1;            // has to be inside run            if (cpos == QTextLine::CursorOnCharacter) {                if (si.analysis.bidiLevel % 2) {                    pos += item_width;                    int last_glyph = gs;                    while (gs <= ge) {                        if (glyphs[gs].attributes.clusterStart && pos < x) {                            glyph_pos = last_glyph;                            break;                        }                        pos -= (glyphs[gs].advance.x + QFixed::fromFixed(glyphs[gs].space_18d6)) * !glyphs[gs].attributes.dontPrint;                        ++gs;                    }                } else {                    glyph_pos = gs;                    while (gs <= ge) {                        if (glyphs[gs].attributes.clusterStart) {                            if (pos > x)                                break;                            glyph_pos = gs;                        }                        pos += (glyphs[gs].advance.x + QFixed::fromFixed(glyphs[gs].space_18d6)) * !glyphs[gs].attributes.dontPrint;                        ++gs;                    }                }            } else {                QFixed dist = INT_MAX/256;                if (si.analysis.bidiLevel % 2) {                    pos += item_width;                    while (gs <= ge) {                        if (glyphs[gs].attributes.clusterStart && qAbs(x-pos) < dist) {                            glyph_pos = gs;                            dist = qAbs(x-pos);                        }                        pos -= (glyphs[gs].advance.x + QFixed::fromFixed(glyphs[gs].space_18d6)) * !glyphs[gs].attributes.dontPrint;                        ++gs;                    }                } else {                    while (gs <= ge) {                        if (glyphs[gs].attributes.clusterStart && qAbs(x-pos) < dist) {                            glyph_pos = gs;                            dist = qAbs(x-pos);                        }                        pos += (glyphs[gs].advance.x + QFixed::fromFixed(glyphs[gs].space_18d6)) * !glyphs[gs].attributes.dontPrint;                        ++gs;                    }                }                if (qAbs(x-pos) < dist)                    return si.position + end;            }            Q_ASSERT(glyph_pos != -1);            int j;            for (j = 0; j < eng->length(item); ++j)                if (logClusters[j] == glyph_pos)                    break;//             qDebug("at pos %d (in run: %d)", si.position + j, j);            return si.position + j;        }    }    // right of last item    int item = visualOrder[nItems-1]+firstItem;    QScriptItem &si = eng->layoutData->items[item];    if (!si.num_glyphs)        eng->shape(item);    int pos = si.position;    if (!(si.analysis.bidiLevel % 2))        pos += eng->length(item);    pos = qMax(line.from, pos);    int maxPos = line.from + line_length;    // except for the last line we assume that the    // character between lines is a space and we want    // to position the cursor to the left of that    // character.    // ###### breaks with japanese for example, fix > 4.1    if (this->i < eng->lines.count() - 1)        --maxPos;    pos = qMin(pos, maxPos);    return pos;}

⌨️ 快捷键说明

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