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);
}
}
}
先设置实心画刷,再画矩形。