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

📄 qtextlayout.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            bool sb_or_ws = false;            do {                int gp = logClusters[pos];                do {                    ++pos;                    ++tmpData.length;                } while (pos < end && logClusters[pos] == gp);                do {                    tmpData.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;                if (attributes[pos].whiteSpace || attributes[pos].softBreak) {                    sb_or_ws = true;                    break;                } else if (breakany && attributes[pos].charStop) {                    break;                }            } while (pos < end);            minw = qMax(tmpData.textWidth, minw);                        QFixed softHyphenWidth;            if (pos && eng->layoutData->string.at(pos - 1) == 0x00ad) {                // 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)                && check_full_otherwise_extend(line, tmpData, spaceData,                                               glyphCount, maxGlyphs, minw,                                               manualWrap, softHyphenWidth)) {                if (!breakany) {                    line.textWidth += softHyphenWidth;                }                goto found;            }            if (sb_or_ws)                breakany = false;        } else {            while (pos < end && attributes[pos].whiteSpace) {                int gp = logClusters[pos];                do {                    ++pos;                    ++spaceData.length;                } while (pos < end && logClusters[pos] == gp);                do {                    spaceData.textWidth += glyphs[gp].advance.x * !glyphs[gp].attributes.dontPrint;                    ++gp;                } while (gp < current.num_glyphs && !glyphs[gp].attributes.clusterStart);                ++glyphCount;                Q_ASSERT((pos == end && gp == current.num_glyphs) || logClusters[pos] == gp);            }        }        if (pos == end)            newItem = item + 1;    }    LB_DEBUG("reached end of line");    check_full_otherwise_extend(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 (eng->option.wrapMode() == QTextOption::ManualWrap || eng->option.wrapMode() == QTextOption::NoWrap) {        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;    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());}// ### DOC: I have no idea what this means/does.// You create a text layout with a string of text. Once you layouted// it, it contains a number of QTextLines. from() returns the position// inside the text string where this line starts. If you e.g. has a// text of "This is a string", layouted into two lines (the second// starting at the word 'a'), layout.lineAt(0).from() == 0 and// layout.lineAt(1).from() == 8./*!    Returns the start of the line from the beginning of the string    passed to the QTextLayout.*/int QTextLine::textStart() const{    return eng->lines[i].from;}/*!    Returns the length of the text in the line.    \sa naturalTextWidth()*/int QTextLine::textLength() const{    return eng->lines[i].length;}static void drawMenuText(QPainter *p, QFixed x, QFixed y, const QScriptItem &si, QTextItemInt &gf, QTextEngine *eng,                         int start, int glyph_start){    int ge = glyph_start + gf.num_glyphs;    int gs = glyph_start;    int end = start + gf.num_chars;    unsigned short *logClusters = eng->logClusters(&si);    QGlyphLayout *glyphs = eng->glyphs(&si);    QFixed orig_width = gf.width;    int *ul = eng->underlinePositions;    if (ul)        while (*ul != -1 && *ul < start)            ++ul;    bool rtl = si.analysis.bidiLevel % 2;    if (rtl)        x += si.width;    do {        int gtmp = ge;        int stmp = end;        if (ul && *ul != -1 && *ul < end) {            stmp = *ul;            gtmp = logClusters[*ul-si.position];        }        gf.num_glyphs = gtmp - gs;        gf.glyphs = glyphs + gs;        gf.num_chars = stmp - start;        gf.chars = eng->layoutData->string.unicode() + start;        QFixed w = 0;        while (gs < gtmp) {            w += (glyphs[gs].advance.x + QFixed::fromFixed(glyphs[gs].space_18d6)) * !glyphs[gs].attributes.dontPrint;            ++gs;        }        start = stmp;        gf.width = w;        if (rtl)            x -= w;        if (gf.num_chars)            p->drawTextItem(QPointF(x.toReal(), y.toReal()), gf);        if (!rtl)            x += w;        if (ul && *ul != -1 && *ul < end) {            // draw underline            gtmp = (*ul == end-1) ? ge : logClusters[*ul+1-si.position];            ++stmp;            gf.num_glyphs = gtmp - gs;            gf.glyphs = glyphs + gs;            gf.num_chars = stmp - start;            gf.chars = eng->layoutData->string.unicode() + start;            gf.logClusters = logClusters + start - si.position;            w = 0;            while (gs < gtmp) {                w += (glyphs[gs].advance.x + QFixed::fromFixed(glyphs[gs].space_18d6)) * !glyphs[gs].attributes.dontPrint;                ++gs;            }            ++start;            gf.width = w;            gf.flags |= QTextItem::Underline;            if (rtl)                x -= w;            p->drawTextItem(QPointF(x.toReal(), y.toReal()), gf);            if (!rtl)                x += w;            gf.flags &= ~QTextItem::Underline;            ++gf.chars;            ++ul;        }    } while (gs < ge);    gf.width = orig_width;}static void setPenAndDrawBackground(QPainter *p, const QPen &defaultPen, const QTextCharFormat &chf, const QRectF &r){    QBrush c = chf.foreground();    if (c.style() == Qt::NoBrush)        p->setPen(defaultPen);    QBrush bg = chf.background();    if (bg.style() != Qt::NoBrush)        p->fillRect(r, bg);    if (c.style() != Qt::NoBrush)        p->setPen(QPen(c, 0));}/*!    \fn void QTextLine::draw(QPainter *painter, const QPointF &position, const QTextLayout::FormatRange *selection) const    Draws a line on the given \a painter at the specified \a position.    The \a selection is reserved for internal use.*/void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatRange *selection) const{    const QScriptLine &line = eng->lines[i];    if (!line.length)        return;    QPen pen = p->pen();    int lineEnd = line.from + line.length;    int firstItem = eng->findItem(line.from);    int lastItem = eng->findItem(lineEnd - 1);    int nItems = lastItem-firstItem+1;    QFixed x = QFixed::fromReal(pos.x());    QFixed y = QFixed::fromReal(pos.y());    QFixed pos_x = x;    QFixed pos_y = y;    x += line.x;    y += line.y + line.ascent;    x += alignLine(eng, line);    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());    QRectF outlineRect;    for (int i = 0; i < nItems; ++i) {        int item = visualOrder[i]+firstItem;        QScriptItem &si = eng->layoutData->items[item];        int si_len = eng->length(item);        if (!si.num_glyphs)            eng->shape(item);        if (si.isObject || si.isTab) {            if (eng->hasFormats() &&                (!selection || (si.position < selection->start + selection->length                                && si.position + si_len > selection->start))) {                p->save();                QTextCharFormat format = eng->format(&si);                if (selection)                    format.merge(selection->format);                QFixed width = si.width;                if (si.isTab) {                    width = eng->nextTab(&si, x - pos_x) - (x - pos_x);                }                setPenAndDrawBackground(p, pen, format, QRectF(x.toReal(), (y - line.ascent).toReal(), width.toReal(), line.height().toReal()));                if (si.isObject && eng->block.docHandle()) {                    QRectF itemRect(x.toReal(), (y-si.ascent).toReal(), width.toReal(), si.height().toReal());                    eng->docLayout()->drawInlineObject(p, itemRect,                                                       QTextInlineObject(item, eng),                                                       si.position + eng->block.position(),                                                       format);                    if (selection) {                        QBrush bg = format.background();                        if (bg.style() != Qt::NoBrush) {                            QColor c = bg.color();                            c.setAlpha(128);                            p->fillRect(itemRect, c);                        }                        if (selection)                            outlineRect = outlineRect.unite(itemRect);                    }                } else { // si.isTab                    QTextItemInt gf;                    QFont f = eng->font(si);                    if (f.d->underline)                        gf.flags |= QTextItem::Underline;                    if (f.d->overline)                        gf.flags |= QTextItem::Overline;                    if (f.d->strikeOut)                        gf.flags |= QTextItem::StrikeOut;                    if (gf.flags) {                        if (si.analysis.bidiLevel %2)                            gf.flags |= QTextItem::RightToLeft;                        gf.ascent = si.ascent;                        gf.descent = si.descent;                        gf.num_glyphs = 0;                        gf.chars = 0;                        gf.num_chars = 0;                        gf.width = width;                        gf.fontEngine = f.d->engineForScript(si.analysis.script);                        gf.f = &f;                        gf.underlineColor = format.underlineColor();                        p->drawTextItem(QPointF(x.toReal(), y.toReal()), gf);                    }                }                p->restore();            }            if (si.isTab)                x = eng->nextTab(&si, x - pos_x) + pos_x;            else                x += si.width;            continue;        }        unsigned short *logClusters = eng->logClusters(&si);        QGlyphLayout *glyphs = eng->glyphs(&si);        int start = qMax(line.from, si.position);        int gs = logClusters[start-si.position];        int end;        int ge;        if (lineEnd < si.position + eng->length(item)) {            end = lineEnd;            ge = logClusters[end-si.position];        } else {            end = si.position + si_len;            ge = si.num_glyphs;        }        // show soft-hyphen at line-break        if (si.position + si_len >= lineEnd            && eng->layoutData->string.at(lineEnd - 1) == 0x00ad)            glyphs[ge - 1].attributes.dontPrint = false;        QFixed itemBaseLine = y;        QTextItemInt gf;        if (si.analysis.bidiLevel %2)            gf.flags |= QTextItem::RightToLeft;        gf.ascent = si.ascent;        gf.descent = si.descent;        gf.num_glyphs = ge - gs;        gf.glyphs = glyphs + gs;        gf.chars = eng->layoutData->string.unicode() + start;        gf.logClusters = logClusters + start - si.position;        gf.num_chars = end - start;        gf.width = 0;        int g = gs;        while (g < ge) {            gf.width += (glyphs[g].advance.x + QFixed::fromFixed(glyphs[g].space_18d6)) * !glyphs[g].attributes.dontPrint;            ++g;        }        if (selection) {            int from = qMax(start, selection->start) - si.position;            int to = qMin(end, selection->start + selection->length) - si.position;            if (from >= to) {                x += gf.width;                continue;            }            int start_glyph = logClusters[from];            int end_glyph = (to == eng->length(item)) ? si.num_glyphs : logClusters[to];            QFixed soff;            QFixed swidth;            if (si.analysis.bidiLevel %2) {                for (int g = ge - 1; g >= end_glyph; --g)                    soff += (glyphs[g].advance.x + QFixed::fromFixed(glyphs[g].space_18d6)) * !glyphs[g].attributes.dontPrint;                for (int g = end_glyph - 1; g >= start_glyph; --g)                    swidth += (glyphs[g].advance.x + QFixed::fromFixed(glyphs[g].space_18d6)) * !glyphs[g].attributes.dontPrint;            } else {                for (int g = gs; g < start_glyph; ++g)                    soff += (glyphs[g].advance.x + QFixed::fromFixed(glyphs[g].space_18d6)) * !glyphs[g].attributes.dontPrint;                for (int g = start_glyph; g < end_glyph; ++g)                    swidth += (glyphs[g].advance.x + QFixed::fromFixed(glyphs[g].space_18d6)) * !glyphs[g].attributes.dontPrint;            }            QRectF rect((x + soff).toReal(), (y - line.ascent).toReal(), swidth.toReal(), line.height().toReal());            if (selection)                outlineRect = outlineRect.unite(rect);            p->save();            p->setClipRect(rect, Qt::IntersectClip);        }

⌨️ 快捷键说明

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