Qt源码分析--QPainter(3)

59 篇文章 1 订阅
37 篇文章 1 订阅

1.inline void drawLine(const QPoint &p1, const QPoint &p2);

inline void QPainter::drawLine(const QPoint &p1, const QPoint &p2)
{
    QLine l(p1, p2);
    drawLines(&l, 1);
}
void QPainter::drawLines(const QLine *lines, int lineCount)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::drawLine(), line count=%d\n", lineCount);
#endif
    Q_D(QPainter);
    if (!d->engine || lineCount < 1)
        return;
    if (d->extended) {
        d->extended->drawLines(lines, lineCount);
        return;
    }
    d->updateState(d->state);
    uint lineEmulation = line_emulation(d->state->emulationSpecifier);
    if (lineEmulation) {
        if (lineEmulation == QPaintEngine::PrimitiveTransform
            && d->state->matrix.type() == QTransform::TxTranslate) {
            for (int i = 0; i < lineCount; ++i) {
                QLineF line = lines[i];
                line.translate(d->state->matrix.dx(), d->state->matrix.dy());
                d->engine->drawLines(&line, 1);
            }
        } else {
            QPainterPath linePath;
            for (int i = 0; i < lineCount; ++i) {
                linePath.moveTo(lines[i].p1());
                linePath.lineTo(lines[i].p2());
            }
            d->draw_helper(linePath, QPainterPrivate::StrokeDraw);
        }
        return;
    }
    d->engine->drawLines(lines, lineCount);
}

看一下通过engine画线的实现。

void QPaintEngine::drawLines(const QLineF *lines, int lineCount)
{
    for (int i=0; i<lineCount; ++i) {
        QPointF pts[2] = { lines[i].p1(), lines[i].p2() };
        if (pts[0] == pts[1]) {
            if (state->pen().capStyle() != Qt::FlatCap)
                drawPoints(pts, 1);
            continue;
        }
        drawPolygon(pts, 2, PolylineMode);
    }
}

可见, 画线时是根据线的数量,一段一段画的。

2. void fillRect(const QRect &, const QColor &color);

void QPainter::fillRect(const QRect &r, const QColor &color)
{
    Q_D(QPainter);
    if (!d->engine)
        return;
    if (d->extended) {
        d->extended->fillRect(r, color);
        return;
    }
    fillRect(r, QBrush(color));
}
void QPainter::fillRect(const QRect &r, const QBrush &brush)
{
    Q_D(QPainter);
    if (!d->engine)
        return;
    if (d->extended) {
        const QGradient *g = brush.gradient();
        if (!g || g->coordinateMode() == QGradient::LogicalMode) {
            d->extended->fillRect(r, brush);
            return;
        }
    }
    QPen oldPen = pen();
    QBrush oldBrush = this->brush();
    setPen(Qt::NoPen);
    if (brush.style() == Qt::SolidPattern) {
        d->colorBrush.setStyle(Qt::SolidPattern);
        d->colorBrush.setColor(brush.color());
        setBrush(d->colorBrush);
    } else {
        setBrush(brush);
    }
    drawRect(r);
    setBrush(oldBrush);
    setPen(oldPen);
}
void QPainter::setBrush(const QBrush &brush)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::setBrush(), color=%04x, style=%d\n", brush.color().rgb(), brush.style());
#endif
    Q_D(QPainter);
    if (!d->engine) {
        qWarning("QPainter::setBrush: Painter not active");
        return;
    }
    if (d->state->brush.d == brush.d)
        return;
    if (d->extended) {
        d->state->brush = brush;
        d->checkEmulation();
        d->extended->brushChanged();
        return;
    }
    d->state->brush = brush;
    d->state->dirtyFlags |= QPaintEngine::DirtyBrush;
}
inline void QPainter::drawRect(const QRect &r)
{
    drawRects(&r, 1);
}

void QPainter::drawRects(const QRect *rects, int rectCount)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::drawRects(), count=%d\n", rectCount);
#endif
    Q_D(QPainter);
    if (!d->engine) {
        qWarning("QPainter::drawRects: Painter not active");
        return;
    }
    if (rectCount <= 0)
        return;
    if (d->extended) {
        d->extended->drawRects(rects, rectCount);
        return;
    }
    d->updateState(d->state);
    if (!d->state->emulationSpecifier) {
        d->engine->drawRects(rects, rectCount);
        return;
    }
    if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
        && d->state->matrix.type() == QTransform::TxTranslate) {
        for (int i=0; i<rectCount; ++i) {
            QRectF r(rects[i].x() + d->state->matrix.dx(),
                     rects[i].y() + d->state->matrix.dy(),
                     rects[i].width(),
                     rects[i].height());
            d->engine->drawRects(&r, 1);
        }
    } else {
        if (d->state->brushNeedsResolving() || d->state->penNeedsResolving()) {
            for (int i=0; i<rectCount; ++i) {
                QPainterPath rectPath;
                rectPath.addRect(rects[i]);
                d->draw_helper(rectPath, QPainterPrivate::StrokeAndFillDraw);
            }
        } else {
            QPainterPath rectPath;
            for (int i=0; i<rectCount; ++i)
                rectPath.addRect(rects[i]);
            d->draw_helper(rectPath, QPainterPrivate::StrokeAndFillDraw);
        }
    }
}
void QPaintEngine::drawRects(const QRectF *rects, int rectCount)
{
    if (hasFeature(PainterPaths) &&
        !state->penNeedsResolving() &&
        !state->brushNeedsResolving()) {
        for (int i=0; i<rectCount; ++i) {
            QPainterPath path;
            path.addRect(rects[i]);
            if (path.isEmpty())
                continue;
            drawPath(path);
        }
    } else {
        for (int i=0; i<rectCount; ++i) {
            QRectF rf = rects[i];
            QPointF pts[4] = { QPointF(rf.x(), rf.y()),
                               QPointF(rf.x() + rf.width(), rf.y()),
                               QPointF(rf.x() + rf.width(), rf.y() + rf.height()),
                               QPointF(rf.x(), rf.y() + rf.height()) };
            drawPolygon(pts, 4, ConvexMode);
        }
    }
}

先设置实心画刷,再画矩形。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天天进步2015

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值