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

📄 qtextdocumentlayout.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            selectedTableCells[i * 4 + 3] = num_cols;        }        if (td->rowPageBreaks.isEmpty()) {            drawFrameDecoration(painter, frame, fd, context.clip, frameRect);        } else {            Q_ASSERT(td->rowPageBreaks.first() > 0);            QRectF rect = frameRect;            const qreal extraTableHeight = td->padding + td->border + td->cellSpacing // inter cell spacing                                           + td->margin + td->border + td->padding; // effective table margin            int lastVisibleRow = td->rowPageBreaks.first() - 1;            rect.setHeight(td->rowPositions.at(lastVisibleRow) + td->heights.at(lastVisibleRow) + extraTableHeight);            drawFrameDecoration(painter, frame, fd, context.clip, rect);            for (int i = 0; i < td->rowPageBreaks.count(); ++i) {                const int firstVisibleRow = td->rowPageBreaks.at(i);                if (i < td->rowPageBreaks.count() - 1)                    lastVisibleRow = td->rowPageBreaks.at(i + 1) - 1;                else                    lastVisibleRow = rows - 1;                rect.setTop(off.y() + td->rowPositions.at(firstVisibleRow) - extraTableHeight);                rect.setBottom(off.y() + td->rowPositions.at(lastVisibleRow) + td->heights.at(lastVisibleRow) + extraTableHeight);                drawFrameDecoration(painter, frame, fd, context.clip, rect);            }        }        int firstRow = 0;        int lastRow = rows;        if (context.clip.isValid()) {            QVector<qreal>::ConstIterator rowIt = qLowerBound(td->rowPositions.begin(), td->rowPositions.end(), context.clip.top() - off.y());            if (rowIt != td->rowPositions.end() && rowIt != td->rowPositions.begin()) {                --rowIt;                firstRow = rowIt - td->rowPositions.begin();            }            rowIt = qUpperBound(td->rowPositions.begin(), td->rowPositions.end(), context.clip.bottom() - off.y());            if (rowIt != td->rowPositions.end()) {                ++rowIt;                lastRow = rowIt - td->rowPositions.begin();            }        }        for (int c = 0; c < columns; ++c) {            QTextTableCell cell = table->cellAt(firstRow, c);            firstRow = qMin(firstRow, cell.row());        }        for (int r = firstRow; r < lastRow; ++r) {            for (int c = 0; c < columns; ++c) {                QTextTableCell cell = table->cellAt(r, c);                int rspan = cell.rowSpan();                int cspan = cell.columnSpan();                if (rspan != 1) {                    int cr = cell.row();                    if (cr != r)                        continue;                }                if (cspan != 1) {                    int cc = cell.column();                    if (cc != c)                        continue;                }                QRectF cellRect = td->cellRect(cell);                cellRect.translate(off);                // we draw the right/bottom border at left() + width(), so for the clipping test                // we have to enlarge the cell rect by one pixel in both directions                if (context.clip.isValid() && !cellRect.adjusted(0, 0, 1, 1).intersects(context.clip))                    continue;                if (fd->border) {                    const QBrush oldBrush = painter->brush();                    const QPen oldPen = painter->pen();                    painter->setBrush(Qt::darkGray);                    painter->setPen(Qt::NoPen);                    // top border                    painter->drawRect(QRectF(cellRect.left(), cellRect.top() - fd->border,                                             cellRect.width() + fd->border, fd->border));                    // left border                    painter->drawRect(QRectF(cellRect.left() - fd->border, cellRect.top() - fd->border,                                             fd->border, cellRect.height() + 2 * fd->border));                    painter->setBrush(Qt::lightGray);                    // bottom border                    painter->drawRect(QRectF(cellRect.left(), cellRect.top() + cellRect.height(),                                             cellRect.width() + fd->border, fd->border));                    // right border                    painter->drawRect(QRectF(cellRect.left() + cellRect.width(), cellRect.top(),                                             fd->border, cellRect.height()));                    painter->setBrush(oldBrush);                    painter->setPen(oldPen);                }                {                    const QBrush bg = cell.format().background();                    if (bg != Qt::NoBrush)                        painter->fillRect(cellRect, bg);                }                QAbstractTextDocumentLayout::PaintContext cell_context = context;                for (int i = 0; i < context.selections.size(); ++i) {                    int row_start = selectedTableCells[i * 4];                    int col_start = selectedTableCells[i * 4 + 1];                    int num_rows = selectedTableCells[i * 4 + 2];                    int num_cols = selectedTableCells[i * 4 + 3];                    if (row_start != -1) {                        if (r >= row_start && r < row_start + num_rows                            && c >= col_start && c < col_start + num_cols) {                            cell_context.selections[i].cursor.setPosition(cell.firstPosition());                            cell_context.selections[i].cursor.setPosition(cell.lastPosition(), QTextCursor::KeepAnchor);                        } else {                            cell_context.selections[i].cursor.clearSelection();                        }                    }                }                const QPointF cellPos = off + td->cellPosition(r, c);                QTextBlock repaintBlock;                drawFlow(cellPos, painter, cell_context, cell.begin(), &repaintBlock);                if (repaintBlock.isValid()) {                    cursorBlockNeedingRepaint = repaintBlock;                    offsetOfRepaintedCursorBlock = cellPos;                }            }        }    } else {        drawFrameDecoration(painter, frame, fd, context.clip, frameRect);        QTextFrame::Iterator it = frame->begin();        if (frame == q->document()->rootFrame())            it = iteratorForYPosition(context.clip.top());        drawFlow(off, painter, context, it, &cursorBlockNeedingRepaint);    }    if (cursorBlockNeedingRepaint.isValid()) {        const QPen oldPen = painter->pen();        painter->setPen(context.palette.color(QPalette::Text));        const int cursorPos = context.cursorPosition - cursorBlockNeedingRepaint.position();        cursorBlockNeedingRepaint.layout()->drawCursor(painter, offsetOfRepaintedCursorBlock,                                                       cursorPos);        painter->setPen(oldPen);    }//     DEC_INDENT;    return;}void QTextDocumentLayoutPrivate::drawFlow(const QPointF &offset, QPainter *painter, const QAbstractTextDocumentLayout::PaintContext &context,                                          QTextFrame::Iterator it, QTextBlock *cursorBlockNeedingRepaint) const{    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(), qreal(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 layouted 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();    }}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.intersects(context.clip))        return;//      LDEBUG << debug_indent << "drawBlock" << bl.position() << "at" << offset << "br" << tl->boundingRect();    QTextBlockFormat blockFormat = bl.blockFormat();    QBrush bg = blockFormat.background();    if (bg != Qt::NoBrush) {        // don't paint into the left margin. Right margin is already excluded by the line breaking        QRectF contentsRect = r;        contentsRect.setLeft(contentsRect.left() + bl.blockFormat().leftMargin());        painter->fillRect(contentsRect, 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) {            QTextLayout::FormatRange o;            o.start = selStart;            o.length = selEnd - selStart;            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);    }    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 = 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();    const int style = lf.style();    QString itemText;    QSizeF size;    QTextLayout *layout = bl.layout();    if (layout->lineCount() == 0)        return;    QTextLine firstLine = layout->lineAt(0);    Q_ASSERT(firstLine.isValid());    QPointF pos = (offset + layout->boundingRect().topLeft() + 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();

⌨️ 快捷键说明

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