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

📄 qtextdocumentlayout.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    int rspan = cell.rowSpan();    int cspan = cell.columnSpan();    if (rspan != 1) {        int cr = cell.row();        if (cr != r)            return;    }    if (cspan != 1) {        int cc = cell.column();        if (cc != c)            return;    }    if (td->border != 0) {        const QBrush oldBrush = painter->brush();        const QPen oldPen = painter->pen();        const qreal border = td->border.toReal();        QRectF borderRect(cellRect.left() - border, cellRect.top() - border, cellRect.width() + border, cellRect.height() + border);        // invert the border style for cells        QTextFrameFormat::BorderStyle cellBorder = table->format().borderStyle();        switch (cellBorder) {        case QTextFrameFormat::BorderStyle_Inset:            cellBorder = QTextFrameFormat::BorderStyle_Outset;            break;        case QTextFrameFormat::BorderStyle_Outset:            cellBorder = QTextFrameFormat::BorderStyle_Inset;            break;        case QTextFrameFormat::BorderStyle_Groove:            cellBorder = QTextFrameFormat::BorderStyle_Ridge;            break;        case QTextFrameFormat::BorderStyle_Ridge:            cellBorder = QTextFrameFormat::BorderStyle_Groove;            break;        default:            break;        }        qreal topMargin = (td->effectiveTopMargin + td->cellSpacing + td->border).toReal();        qreal bottomMargin = (td->effectiveBottomMargin + td->cellSpacing + td->border).toReal();        const int headerRowCount = qMin(table->format().headerRowCount(), table->rows() - 1);        if (r >= headerRowCount)            topMargin += td->headerHeight.toReal();        drawBorder(painter, borderRect, topMargin, bottomMargin,                   border, table->format().borderBrush(), cellBorder);        painter->setBrush(oldBrush);        painter->setPen(oldPen);    }    {        const QBrush bg = cell.format().background();        if (bg != Qt::NoBrush)            fillBackground(painter, cellRect, bg);    }    const QFixed verticalOffset = td->cellVerticalOffsets.at(c + r * table->columns());    const QPointF cellPos = QPointF(cellRect.left() + td->cellPadding.toReal(),                                    cellRect.top() + (td->cellPadding + verticalOffset).toReal());    QTextBlock repaintBlock;    drawFlow(cellPos, painter, cell_context, cell.begin(),             td->childFrameMap.values(r + c * table->rows()),             &repaintBlock);    if (repaintBlock.isValid()) {        *cursorBlockNeedingRepaint = repaintBlock;        *cursorBlockOffset = cellPos;    }}void QTextDocumentLayoutPrivate::drawFlow(const QPointF &offset, QPainter *painter, const QAbstractTextDocumentLayout::PaintContext &context,                                          QTextFrame::Iterator it, const QList<QTextFrame *> &floats, QTextBlock *cursorBlockNeedingRepaint) const{    Q_Q(const QTextDocumentLayout);    const bool inRootFrame = (!it.atEnd() && it.parentFrame() && it.parentFrame()->parentFrame() == 0);    QVector<QCheckPoint>::ConstIterator lastVisibleCheckPoint = checkPoints.end();    if (inRootFrame && context.clip.isValid()) {        lastVisibleCheckPoint = qLowerBound(checkPoints.begin(), checkPoints.end(), QFixed::fromReal(context.clip.bottom()));    }    QTextBlock lastBlock;    for (; !it.atEnd(); ++it) {        QTextFrame *c = it.currentFrame();        if (inRootFrame && !checkPoints.isEmpty()) {            int currentPosInDoc;            if (c)                currentPosInDoc = c->firstPosition();            else                currentPosInDoc = it.currentBlock().position();            // if we're past what is already laid out then we're better off            // not trying to draw things that may not be positioned correctly yet            if (currentPosInDoc >= checkPoints.last().positionInFrame)                break;            if (lastVisibleCheckPoint != checkPoints.end()                && context.clip.isValid()                && currentPosInDoc >= lastVisibleCheckPoint->positionInFrame               )                break;        }        if (c)            drawFrame(offset, painter, context, c);        else            drawBlock(offset, painter, context, it.currentBlock());        // when entering a table and the previous block is empty        // then layoutFlow 'hides' the block that just causes a        // new line by positioning it /on/ the table border. as we        // draw that block before the table itself the decoration        // 'overpaints' the cursor and we need to paint it afterwards        // again        if (isEmptyBlockBeforeTable(lastBlock, it)            && lastBlock.contains(context.cursorPosition)           ) {            *cursorBlockNeedingRepaint = lastBlock;        }        lastBlock = it.currentBlock();    }    QTextDocument *document = q->document();    for (int i = 0; i < floats.count(); ++i) {        QTextFrame *frame = floats.at(i);        if (!isFrameFromInlineObject(frame)            || frame->frameFormat().position() == QTextFrameFormat::InFlow)            continue;        const int pos = frame->firstPosition() - 1;        QTextCharFormat format = const_cast<QTextDocumentLayout *>(q)->format(pos);        QTextObjectInterface *handler = q->handlerForObject(format.objectType());        if (handler) {            QRectF rect = frameBoundingRectInternal(frame);            handler->drawObject(painter, rect, document, pos, format);        }    }}void QTextDocumentLayoutPrivate::drawBlock(const QPointF &offset, QPainter *painter,                                           const QAbstractTextDocumentLayout::PaintContext &context,                                           QTextBlock bl) const{    Q_Q(const QTextDocumentLayout);    const QTextLayout *tl = bl.layout();    QRectF r = tl->boundingRect();    r.translate(offset + tl->position());    if (context.clip.isValid() && (r.bottom() < context.clip.y() || r.top() > context.clip.bottom()))        return;//      LDEBUG << debug_indent << "drawBlock" << bl.position() << "at" << offset << "br" << tl->boundingRect();    QTextBlockFormat blockFormat = bl.blockFormat();    QBrush bg = blockFormat.background();    if (bg != Qt::NoBrush)        fillBackground(painter, r, bg);    QVector<QTextLayout::FormatRange> selections;    int blpos = bl.position();    int bllen = bl.length();    const QTextCharFormat *selFormat = 0;    for (int i = 0; i < context.selections.size(); ++i) {        const QAbstractTextDocumentLayout::Selection &range = context.selections.at(i);        const int selStart = range.cursor.selectionStart() - blpos;        const int selEnd = range.cursor.selectionEnd() - blpos;        if (selStart < bllen && selEnd > 0             && selEnd > selStart) {            QTextLayout::FormatRange o;            o.start = selStart;            o.length = selEnd - selStart;            o.format = range.format;            selections.append(o);        } else if (range.format.hasProperty(QTextFormat::FullWidthSelection)                   && bl.contains(range.cursor.position())) {            // for full width selections we don't require an actual selection, just            // a position to specify the line. that's more convenience in usage.            QTextLayout::FormatRange o;            QTextLine l = tl->lineForTextPosition(range.cursor.position() - blpos);            o.start = l.textStart();            o.length = qMax(1, l.textLength());            o.format = range.format;            selections.append(o);       }        if (selStart <= 0 && selEnd >= 1)            selFormat = &range.format;    }    QTextObject *object = q->document()->objectForFormat(bl.blockFormat());    if (object && object->format().toListFormat().style() != QTextListFormat::ListStyleUndefined)        drawListItem(offset, painter, context, bl, selFormat);    QPen oldPen = painter->pen();    painter->setPen(context.palette.color(QPalette::Text));    tl->draw(painter, offset, selections, context.clip);    if ((context.cursorPosition >= blpos && context.cursorPosition < blpos + bllen)        || (context.cursorPosition < -1 && !tl->preeditAreaText().isEmpty())) {        int cpos = context.cursorPosition;        if (cpos < -1)            cpos = tl->preeditAreaPosition() - (cpos + 2);        else            cpos -= blpos;        tl->drawCursor(painter, offset, cpos, cursorWidth);    }    if (blockFormat.hasProperty(QTextFormat::BlockTrailingHorizontalRulerWidth)) {        const qreal width = blockFormat.lengthProperty(QTextFormat::BlockTrailingHorizontalRulerWidth).value(r.width());        painter->setPen(context.palette.color(QPalette::Dark));        qreal y = r.bottom();        if (bl.length() == 1)            y = r.top() + r.height() / 2;        const qreal middleX = r.left() + r.width() / 2;        painter->drawLine(QLineF(middleX - width / 2, y, middleX + width / 2, y));    }    painter->setPen(oldPen);}void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *painter,                                              const QAbstractTextDocumentLayout::PaintContext &context,                                              QTextBlock bl, const QTextCharFormat *selectionFormat) const{    Q_Q(const QTextDocumentLayout);    const QTextBlockFormat blockFormat = bl.blockFormat();    const QTextCharFormat charFormat = QTextCursor(bl).charFormat();    QFont font(charFormat.font());    if (q->paintDevice())        font = QFont(font, q->paintDevice());    const QFontMetrics fontMetrics(font);    QTextObject * const object = q->document()->objectForFormat(blockFormat);    const QTextListFormat lf = object->format().toListFormat();    int style = lf.style();    QString itemText;    QSizeF size;    if (blockFormat.hasProperty(QTextFormat::ListStyle))        style = QTextListFormat::Style(blockFormat.intProperty(QTextFormat::ListStyle));    QTextLayout *layout = bl.layout();    if (layout->lineCount() == 0)        return;    QTextLine firstLine = layout->lineAt(0);    Q_ASSERT(firstLine.isValid());    QPointF pos = (offset + layout->position()).toPoint();    Qt::LayoutDirection dir = blockFormat.layoutDirection();    {        QRectF textRect = firstLine.naturalTextRect();        pos += textRect.topLeft().toPoint();        if (dir == Qt::RightToLeft)            pos.rx() += textRect.width();    }    switch (style) {    case QTextListFormat::ListDecimal:    case QTextListFormat::ListLowerAlpha:    case QTextListFormat::ListUpperAlpha:        itemText = static_cast<QTextList *>(object)->itemText(bl);        size.setWidth(fontMetrics.width(itemText));        size.setHeight(fontMetrics.height());        break;    case QTextListFormat::ListSquare:    case QTextListFormat::ListCircle:    case QTextListFormat::ListDisc:        size.setWidth(fontMetrics.lineSpacing() / 3);        size.setHeight(size.width());        break;    case QTextListFormat::ListStyleUndefined:        return;    default: return;    }    QRectF r(pos, size);    qreal xoff = fontMetrics.width(QLatin1Char(' '));    if (dir == Qt::LeftToRight)        xoff = -xoff - size.width();    r.translate( xoff, (fontMetrics.height() / 2 - size.height() / 2));    painter->save();    painter->setRenderHint(QPainter::Antialiasing);    if (selectionFormat) {        painter->setPen(QPen(selectionFormat->foreground(), 0));        painter->fillRect(r, selectionFormat->background());    } else {        QBrush fg = charFormat.foreground();        if (fg == Qt::NoBrush)            fg = context.palette.text();        painter->setPen(QPen(fg, 0));    }    QBrush brush = context.palette.brush(QPalette::Text);    switch (style) {    case QTextListFormat::ListDecimal:    case QTextListFormat::ListLowerAlpha:    case QTextListFormat::ListUpperAlpha: {        QTextLayout layout(itemText, font, q->paintDevice());        layout.setCacheEnabled(true);        QTextOption option(Qt::AlignLeft | Qt::AlignAbsolute);        option.setTextDirection(dir);        layout.setTextOption(option);        layout.beginLayout();        layout.createLine();        layout.endLayout();        layout.draw(painter, QPointF(r.left(), pos.y()));        break;    }    case QTextListFormat::ListSquare:        painter->fillRect(r, brush);        break;    case QTextListFormat::ListCircle:        painter->drawEllipse(r);        break;    case QTextListFormat::ListDisc:        painter->setBrush(brush);        painter->setPen(Qt::NoPen);        painter->drawEllipse(r);        painter->setBrush(Qt::NoBrush);        break;    case QTextListFormat::ListStyleUndefined:        break;    default:        break;    }

⌨️ 快捷键说明

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