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

📄 qtextlayout.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    \value Trailing*//*!    \enum QTextLine::CursorPosition    \value CursorBetweenCharacters    \value CursorOnCharacter*//*!    \fn QTextLine::QTextLine(int line, QTextEngine *e)    \internal    Constructs a new text line using the line at position \a line in    the text engine \a e.*//*!    \fn QTextLine::QTextLine()    Creates an invalid line.*//*!    \fn bool QTextLine::isValid() const    Returns true if this text line is valid; otherwise returns false.*//*!    \fn int QTextLine::lineNumber() const    Returns the position of the line in the text engine.*//*!    Returns the line's bounding rectangle.    \sa x() y() textLength() width()*/QRectF QTextLine::rect() const{    const QScriptLine& sl = eng->lines[i];    return QRectF(sl.x.toReal(), sl.y.toReal(), sl.width.toReal(), sl.height().toReal());}/*!    Returns the rectangle covered by the line.*/QRectF QTextLine::naturalTextRect() const{    const QScriptLine& sl = eng->lines[i];    QFixed x = sl.x + alignLine(eng, sl);    QFixed width = sl.textWidth;    if (sl.justified)        width = sl.width;    return QRectF(x.toReal(), sl.y.toReal(), width.toReal(), sl.height().toReal());}/*!    Returns the line's x position.    \sa rect() y() textLength() width()*/qreal QTextLine::x() const{    return eng->lines[i].x.toReal();}/*!    Returns the line's y position.    \sa x() rect() textLength() width()*/qreal QTextLine::y() const{    return eng->lines[i].y.toReal();}/*!    Returns the line's width as specified by the layout() function.    \sa naturalTextWidth() x() y() textLength() rect()*/qreal QTextLine::width() const{    return eng->lines[i].width.toReal();}/*!    Returns the line's ascent.    \sa descent() height()*/qreal QTextLine::ascent() const{    return eng->lines[i].ascent.toReal();}/*!    Returns the line's descent.    \sa ascent() height()*/qreal QTextLine::descent() const{    return eng->lines[i].descent.toReal();}/*!    Returns the line's height. This is equal to ascent() + descent() + 1.    \sa ascent() descent()*/qreal QTextLine::height() const{    return eng->lines[i].height().toReal();}/*!    Returns the width of the line that is occupied by text. This is    always \<= to width(), and is the minimum width that could be used    by layout() without changing the line break position.*/qreal QTextLine::naturalTextWidth() const{    return eng->lines[i].textWidth.toReal();}/*!    Lays out the line with the given \a width. The line is filled from    its starting position with as many characters as will fit into    the line. In case the text cannot be split at the end of the line,    it will be filled with additional characters to the next whitespace    or end of the text.*/void QTextLine::setLineWidth(qreal width){    QScriptLine &line = eng->lines[i];    line.width = QFixed::fromReal(width);    line.length = 0;    line.textWidth = 0;    layout_helper(INT_MAX);}/*!    Lays out the line. The line is filled from its starting position    with as many characters as are specified by \a numColumns. In case    the text cannot be split until \a numColumns characters, the line    will be filled with as many characters to the next whitespace or    end of the text.*/void QTextLine::setNumColumns(int numColumns){    QScriptLine &line = eng->lines[i];    line.width = INT_MAX/256;    line.length = 0;    line.textWidth = 0;    layout_helper(numColumns);}/*!    Lays out the line. The line is filled from its starting position    with as many characters as are specified by \a numColumns. In case    the text cannot be split until \a numColumns characters, the line    will be filled with as many characters to the next whitespace or    end of the text. The provided \a alignmentWidth is used as reference    width for alignment.*/void QTextLine::setNumColumns(int numColumns, qreal alignmentWidth){    QScriptLine &line = eng->lines[i];    line.width = QFixed::fromReal(alignmentWidth);    line.length = 0;    line.textWidth = 0;    layout_helper(numColumns);}#if 0#define LB_DEBUG qDebug#else#define LB_DEBUG if (0) qDebug#endifstatic inline bool checkFullOtherwiseExtend(QScriptLine &line, QScriptLine &tmpData, QScriptLine &spaceData,                                            int glyphCount, int maxGlyphs, QFixed &minw, bool manualWrap,                                            QFixed softHyphenWidth = QFixed()){    LB_DEBUG("possible break width %f, spacew=%f", tmpData.textWidth.toReal(), spaceData.textWidth.toReal());    if (line.length && !manualWrap &&        (line.textWidth + tmpData.textWidth + spaceData.textWidth + softHyphenWidth > line.width || glyphCount > maxGlyphs))        return true;    minw = qMax(minw, tmpData.textWidth);    line += tmpData;    line.textWidth += spaceData.textWidth;    line.length += spaceData.length;    tmpData.textWidth = 0;    tmpData.length = 0;    spaceData.textWidth = 0;    spaceData.length = 0;    return false;}static inline void addNextCluster(int &pos, int end, QScriptLine &line, int &glyphCount,                                  const QScriptItem &current, const unsigned short *logClusters, const QGlyphLayout *glyphs){    int gp = logClusters[pos];    do {        ++pos;        ++line.length;    } while (pos < end && logClusters[pos] == gp);    do {        line.textWidth += glyphs[gp].advance.x * !glyphs[gp].attributes.dontPrint;        ++gp;    } while (gp < current.num_glyphs && !glyphs[gp].attributes.clusterStart);    Q_ASSERT((pos == end && gp == current.num_glyphs) || logClusters[pos] == gp);    ++glyphCount;}void QTextLine::layout_helper(int maxGlyphs){    QScriptLine &line = eng->lines[i];    line.length = 0;    line.textWidth = 0;    line.hasTrailingSpaces = false;    if (!eng->layoutData->items.size() || line.from >= eng->layoutData->string.length()) {        line.setDefaultHeight(eng);        return;    }    Q_ASSERT(line.from < eng->layoutData->string.length());    QTextOption::WrapMode wrapMode = eng->option.wrapMode();    bool breakany = (wrapMode == QTextOption::WrapAnywhere);    bool manualWrap = (wrapMode == QTextOption::ManualWrap || wrapMode == QTextOption::NoWrap);    // #### binary search!    int item = -1;    int newItem;    for (newItem = eng->layoutData->items.size()-1; newItem > 0; --newItem) {        if (eng->layoutData->items[newItem].position <= line.from)            break;    }    QFixed minw = 0;    int glyphCount = 0;    LB_DEBUG("from: %d: item=%d, total %d width available %f", line.from, newItem, eng->layoutData->items.size(), line.width.toReal());    QScriptLine tmpData;    QScriptLine spaceData;    Qt::Alignment alignment = eng->option.alignment();    const QCharAttributes *attributes = eng->attributes();    int pos = line.from;    int end = 0;    const QGlyphLayout *glyphs = 0;    const unsigned short *logClusters = eng->layoutData->logClustersPtr;    while (newItem < eng->layoutData->items.size()) {        if (newItem != item) {            item = newItem;            const QScriptItem &current = eng->layoutData->items[item];            if (!current.num_glyphs) {                eng->shape(item);                attributes = eng->attributes();                logClusters = eng->layoutData->logClustersPtr;            }            pos = qMax(line.from, current.position);            end = current.position + eng->length(item);            glyphs = eng->glyphs(&current);        }        const QScriptItem &current = eng->layoutData->items[item];        tmpData.ascent = qMax(tmpData.ascent, current.ascent);        tmpData.descent = qMax(tmpData.descent, current.descent);        if (current.isTab && (alignment & Qt::AlignLeft)) {            if (checkFullOtherwiseExtend(line, tmpData, spaceData, glyphCount, maxGlyphs, minw, manualWrap))                goto found;            QFixed x = line.x + line.textWidth + tmpData.textWidth + spaceData.textWidth;            QFixed nx = eng->nextTab(&current, x);            spaceData.textWidth += nx - x;            spaceData.length++;            newItem = item + 1;            ++glyphCount;            if (checkFullOtherwiseExtend(line, tmpData, spaceData, glyphCount, maxGlyphs, minw, manualWrap))                goto found;        } else if (current.isObject) {            tmpData.length++;            // the width of the linesep doesn't count into the textwidth            if (eng->layoutData->string.at(current.position) == QChar::LineSeparator) {                // if the line consists only of the line separator make sure                // we have a sane height                if (!line.length && tmpData.length == 1)                    line.setDefaultHeight(eng);                line += tmpData;                goto found;            }            QTextFormat format = eng->formats()->format(eng->formatIndex(&eng->layoutData->items[item]));            if (eng->block.docHandle())                eng->docLayout()->positionInlineObject(QTextInlineObject(item, eng), eng->block.position() + current.position, format);            tmpData.textWidth += current.width;            newItem = item + 1;            ++glyphCount;            if (checkFullOtherwiseExtend(line, tmpData, spaceData, glyphCount, maxGlyphs, minw, manualWrap))                goto found;        } else if (attributes[pos].whiteSpace) {            while (pos < end && attributes[pos].whiteSpace)                addNextCluster(pos, end, spaceData, glyphCount, current, logClusters, glyphs);        } else {            bool sb_or_ws = false;            do {                addNextCluster(pos, end, tmpData, glyphCount, current, logClusters, glyphs);                if (attributes[pos].whiteSpace || attributes[pos-1].lineBreakType != QCharAttributes::NoBreak) {                    sb_or_ws = true;                    break;                } else if (breakany && attributes[pos].charStop) {                    break;                }            } while (pos < end);            minw = qMax(tmpData.textWidth, minw);            QFixed softHyphenWidth;            if (pos && attributes[pos - 1].lineBreakType == QCharAttributes::SoftHyphen) {                // if we are splitting up a word because of                // a soft hyphen then we ...                //                //  a) have to take the width of the soft hyphen into                //     account to see if the first syllable(s) /and/                //     the soft hyphen fit into the line                //                //  b) if we are so short of available width that the                //     soft hyphen is the first breakable position, then                //     we don't want to show it. However we initially                //     have to take the width for it into accoun so that                //     the text document layout sees the overflow and                //     switch to break-anywhere mode, in which we                //     want the soft-hyphen to slip into the next line                //     and thus become invisible again.                //                if (line.length)                    softHyphenWidth = glyphs[logClusters[pos - 1]].advance.x;                else if (breakany)                    tmpData.textWidth += glyphs[logClusters[pos - 1]].advance.x;            }            if ((sb_or_ws|breakany)                && checkFullOtherwiseExtend(line, tmpData, spaceData, glyphCount, maxGlyphs, minw, manualWrap, softHyphenWidth)) {                if (!breakany) {                    line.textWidth += softHyphenWidth;                }                goto found;            }        }        if (pos == end)            newItem = item + 1;    }    LB_DEBUG("reached end of line");    checkFullOtherwiseExtend(line, tmpData, spaceData, glyphCount, maxGlyphs, minw, manualWrap);found:    if (line.length == 0) {        LB_DEBUG("no break available in line, adding temp: length %d, width %f, space: length %d, width %f",               tmpData.length, tmpData.textWidth.toReal(), spaceData.length, spaceData.textWidth.toReal());        line += tmpData;    }    LB_DEBUG("line length = %d, ascent=%f, descent=%f, textWidth=%f (spacew=%f)", line.length, line.ascent.toReal(),           line.descent.toReal(), line.textWidth.toReal(), spaceData.width.toReal());    LB_DEBUG("        : '%s'", eng->layoutData->string.mid(line.from, line.length).toUtf8().data());    if (manualWrap) {        eng->minWidth = qMax(eng->minWidth, line.textWidth);        eng->maxWidth = qMax(eng->maxWidth, line.textWidth);    } else {        eng->minWidth = qMax(eng->minWidth, minw);        eng->maxWidth += line.textWidth;    }    if (line.textWidth > 0 && item < eng->layoutData->items.size())        eng->maxWidth += spaceData.textWidth;    if (eng->option.flags() & QTextOption::IncludeTrailingSpaces)        line.textWidth += spaceData.textWidth;    line.length += spaceData.length;    if (spaceData.length)        line.hasTrailingSpaces = true;    line.justified = false;    line.gridfitted = false;}/*!    Moves the line to position \a pos.*/void QTextLine::setPosition(const QPointF &pos){    eng->lines[i].x = QFixed::fromReal(pos.x());    eng->lines[i].y = QFixed::fromReal(pos.y());}/*!    Returns the line's position relative to the text layout's position.*/QPointF QTextLine::position() const{    return QPointF(eng->lines[i].x.toReal(), eng->lines[i].y.toReal());}// ### DOC: I have no idea what this means/does.

⌨️ 快捷键说明

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