qt5base-lts/tests/benchmarks/gui/painting/qpainter/tst_qpainter.cpp
Qt by Nokia 38be0d1383 Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you
want to look at revision history older than this, please refer to the
Qt Git wiki for how to use Git history grafting. At the time of
writing, this wiki is located here:

http://qt.gitorious.org/qt/pages/GitIntroductionWithQt

If you have already performed the grafting and you don't see any
history beyond this commit, try running "git log" with the "--follow"
argument.

Branched from the monolithic repo, Qt master branch, at commit
896db169ea224deb96c59ce8af800d019de63f12
2011-04-27 12:05:43 +02:00

1667 lines
50 KiB
C++

/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <qtest.h>
#include <QPainter>
#include <QPixmap>
#include <QDialog>
#include <QImage>
#include <QPaintEngine>
#include <math.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#include <private/qpixmap_raster_p.h>
Q_DECLARE_METATYPE(QLine)
Q_DECLARE_METATYPE(QRect)
Q_DECLARE_METATYPE(QSize)
Q_DECLARE_METATYPE(QPoint)
Q_DECLARE_METATYPE(QPainterPath)
Q_DECLARE_METATYPE(QPainter::RenderHint)
Q_DECLARE_METATYPE(QPainter::CompositionMode)
Q_DECLARE_METATYPE(QImage::Format)
enum PrimitiveType {
Primitive_Int_DiagLine,
Primitive_Int_VerLine,
Primitive_Int_HorLine,
Primitive_Int_Rect,
Primitive_Int_Ellipse,
Primitive_Int_Pie,
Primitive_Int_Arc,
Primitive_Int_Chord,
Primitive_Int_TriPoly,
Primitive_Int_RectPoly,
Primitive_Int_2RectPoly,
Primitive_Float_DiagLine,
Primitive_Float_VerLine,
Primitive_Float_HorLine,
Primitive_Float_Rect,
Primitive_Float_Ellipse,
Primitive_Float_Pie,
Primitive_Float_Arc,
Primitive_Float_Chord,
Primitive_Float_TriPoly,
Primitive_Float_RectPoly,
Primitive_Float_2RectPoly,
Primitive_Float_TriPath,
Primitive_Float_RectPath,
Primitive_Float_2RectPath,
Primitive_Float_EllipsePath,
Primitive_Last_Primitive
};
enum StateChanges {
ChangePen = 0x0001,
ChangeBrush = 0x0002,
ChangeClip = 0x0004,
ChangeTransform = 0x0008
};
struct PrimitiveSet {
QRect i_rect;
QLine i_line_diag;
QLine i_line_ver;
QLine i_line_hor;
QPolygon i_poly_tri;
QPolygon i_poly_2rects;
QPolygon i_poly_rect;
QRectF f_rect;
QLineF f_line_diag;
QLineF f_line_ver;
QLineF f_line_hor;
QPolygonF f_poly_tri;
QPolygonF f_poly_2rects;
QPolygonF f_poly_rect;
QPainterPath f_path_tri;
QPainterPath f_path_2rects;
QPainterPath f_path_rect;
QPainterPath f_path_ellipse;
};
QPixmap rasterPixmap(int width, int height)
{
QPixmapData *data =
new QRasterPixmapData(QPixmapData::PixmapType);
data->resize(width, height);
return QPixmap(data);
}
QPixmap rasterPixmap(const QSize &size)
{
return rasterPixmap(size.width(), size.height());
}
QPixmap rasterPixmap(const QImage &image)
{
QPixmapData *data =
new QRasterPixmapData(QPixmapData::PixmapType);
data->fromImage(image, Qt::AutoColor);
return QPixmap(data);
}
class tst_QPainter : public QObject
{
Q_OBJECT
public:
tst_QPainter()
{
setupBrushes();
createPrimitives();
m_surface = surface();
}
private slots:
void beginAndEnd();
void saveRestore_data();
void saveRestore();
void drawLine_data();
void drawLine();
void drawLine_clipped_data();
void drawLine_clipped();
void drawLine_antialiased_clipped_data();
void drawLine_antialiased_clipped();
void drawPixmap_data();
void drawPixmap();
void drawImage_data();
void drawImage();
void drawTiledPixmap_data();
void drawTiledPixmap();
void compositionModes_data();
void compositionModes();
void fillPrimitives_10_data() { drawPrimitives_data_helper(false); }
void fillPrimitives_100_data() { drawPrimitives_data_helper(false); }
void fillPrimitives_1000_data() { drawPrimitives_data_helper(false); }
void fillPrimitives_10();
void fillPrimitives_100();
void fillPrimitives_1000();
void strokePrimitives_10_data() { drawPrimitives_data_helper(true); }
void strokePrimitives_100_data() { drawPrimitives_data_helper(true); }
void strokePrimitives_1000_data() { drawPrimitives_data_helper(true); }
void strokePrimitives_10();
void strokePrimitives_100();
void strokePrimitives_1000();
void drawText_data();
void drawText();
void clipAndFill_data();
void clipAndFill();
void drawRoundedRect();
void drawScaledRoundedRect();
void drawTransformedRoundedRect();
void drawScaledAntialiasedRoundedRect_data();
void drawTransformedAntialiasedRoundedRect_data();
void drawAntialiasedRoundedRect();
void drawScaledAntialiasedRoundedRect();
void drawTransformedAntialiasedRoundedRect();
void drawScaledImageRoundedRect_data();
void drawTransformedImageRoundedRect_data();
void drawImageRoundedRect();
void drawScaledImageRoundedRect();
void drawTransformedImageRoundedRect();
void drawScaledBorderPixmapRoundedRect_data();
void drawTransformedBorderPixmapRoundedRect_data();
void drawBorderPixmapRoundedRect();
void drawScaledBorderPixmapRoundedRect();
void drawTransformedBorderPixmapRoundedRect();
void drawTransformedTransparentImage_data();
void drawTransformedSemiTransparentImage_data();
void drawTransformedFilledImage_data();
void drawTransformedTransparentImage();
void drawTransformedSemiTransparentImage();
void drawTransformedFilledImage();
private:
void setupBrushes();
void createPrimitives();
void drawPrimitives_data_helper(bool fancypens);
void fillPrimitives_helper(QPainter *painter, PrimitiveType type, PrimitiveSet *s);
QTransform transformForAngle(qreal angle);
QPaintDevice *surface()
{
m_pixmap = rasterPixmap(1024, 1024);
return &m_pixmap;
}
QMap<QString, QPen> m_pens;
QMap<QString, QBrush> m_brushes;
PrimitiveSet m_primitives_10;
PrimitiveSet m_primitives_100;
PrimitiveSet m_primitives_1000;
QPixmap m_pixmap;
QPaintDevice *m_surface;
QPainter m_painter;
};
void tst_QPainter::createPrimitives()
{
for (int i=0; i<3; ++i) {
PrimitiveSet *ps;
int size;
switch (i) {
case 0:
ps = &m_primitives_10;
size = 10;
break;
case 1:
ps = &m_primitives_100;
size = 100;
break;
case 2:
ps = &m_primitives_1000;
size = 1000;
break;
}
ps->f_rect = QRectF(0, 0, size, size);
ps->f_line_diag = QLineF(0, 0, size, size);
ps->f_line_ver = QLineF(10, 0, 10, size);
ps->f_line_hor = QLineF(0, 10, size, 10);
ps->f_poly_rect = QPolygonF() << QPointF(0, 0)
<< QPointF(size, 0)
<< QPointF(size, size)
<< QPointF(0, size);
ps->f_poly_2rects = QPolygonF() << QPointF(0, 0)
<< QPointF(size * 0.75, 0)
<< QPointF(size * 0.75, size * 0.75)
<< QPointF(size * 0.25, size * 0.75)
<< QPointF(size * 0.25, size * 0.25)
<< QPointF(size, size * 0.25)
<< QPointF(size, size)
<< QPointF(0, size);
ps->f_poly_tri = QPolygonF() << QPointF(size / 2.0, 0)
<< QPointF(0, size)
<< QPointF(size, size);
ps->f_path_tri.addPolygon(ps->f_poly_tri);
ps->f_path_rect.addRect(ps->f_rect);
ps->f_path_2rects.addPolygon(ps->f_poly_2rects);
ps->f_path_ellipse.addEllipse(ps->f_rect);
ps->i_rect = ps->f_rect.toRect();
ps->i_line_diag = ps->f_line_diag.toLine();
ps->i_line_hor = ps->f_line_hor.toLine();
ps->i_line_ver = ps->f_line_ver.toLine();
ps->i_poly_tri = ps->f_poly_tri.toPolygon();
ps->i_poly_rect = ps->f_poly_rect.toPolygon();
ps->i_poly_2rects = ps->f_poly_2rects.toPolygon();
}
}
void tst_QPainter::drawLine_data()
{
QTest::addColumn<QLine>("line");
QTest::addColumn<QPen>("pen");
QVector<QPen> pens;
pens << QPen(Qt::black)
<< QPen(Qt::black, 0, Qt::DashDotLine)
<< QPen(Qt::black, 4)
<< QPen(Qt::black, 4, Qt::DashDotLine)
<< QPen(QColor(255, 0, 0, 200))
<< QPen(QColor(255, 0, 0, 200), 0, Qt::DashDotLine)
<< QPen(QColor(255, 0, 0, 200), 4)
<< QPen(QColor(255, 0, 0, 200), 4, Qt::DashDotLine);
QStringList penNames;
penNames << "black-0"
<< "black-0-dashdot"
<< "black-4"
<< "black-4-dashdot"
<< "alpha-0"
<< "alpha-0-dashdot"
<< "alpha-4"
<< "alpha-4-dashdot";
int i = 0;
foreach (QPen pen, pens) {
const QString s = QString(QLatin1String("%1:%2")).arg(penNames[i]);
QTest::newRow(qPrintable(s.arg("horizontal")))
<< QLine(0, 20, 100, 20) << pen;
QTest::newRow(qPrintable(s.arg("vertical:")))
<< QLine(20, 0, 20, 100) << pen;
QTest::newRow(qPrintable(s.arg("0-45:")))
<< QLine(0, 20, 100, 0) << pen;
QTest::newRow(qPrintable(s.arg("45-90:")))
<< QLine(0, 100, 20, 0) << pen;
QTest::newRow(qPrintable(s.arg("90-135:")))
<< QLine(20, 100, 0, 0) << pen;
QTest::newRow(qPrintable(s.arg("135-180:")))
<< QLine(100, 20, 0, 0) << pen;
QTest::newRow(qPrintable(s.arg("180-225:")))
<< QLine(100, 0, 0, 20) << pen;
QTest::newRow(qPrintable(s.arg("225-270:")))
<< QLine(20, 0, 0, 100) << pen;
QTest::newRow(qPrintable(s.arg("270-315:")))
<< QLine(0, 0, 20, 100) << pen;
QTest::newRow(qPrintable(s.arg("315-360:")))
<< QLine(0, 0, 100, 20) << pen;
++i;
}
}
void tst_QPainter::setupBrushes()
{
// Solid brushes...
m_brushes["black-brush"] = QBrush(Qt::black);
m_brushes["white-brush"] = QBrush(Qt::white);
m_brushes["transparent-brush"] = QBrush(QColor(255, 255, 255, 0));
m_brushes["alpha1-brush"] = QBrush(QColor(255, 255, 255, 100));
m_brushes["alpha2-brush"] = QBrush(QColor(255, 255, 255, 200));
// Patterns
m_brushes["dense1-brush"] = QBrush(Qt::Dense1Pattern);
m_brushes["dense2-brush"] = QBrush(Qt::Dense2Pattern);
m_brushes["dense3-brush"] = QBrush(Qt::Dense3Pattern);
m_brushes["dense4-brush"] = QBrush(Qt::Dense4Pattern);
m_brushes["dense5-brush"] = QBrush(Qt::Dense5Pattern);
m_brushes["dense6-brush"] = QBrush(Qt::Dense6Pattern);
m_brushes["dense7-brush"] = QBrush(Qt::Dense7Pattern);
m_brushes["hor-brush"] = QBrush(Qt::HorPattern);
m_brushes["ver-brush"] = QBrush(Qt::VerPattern);
m_brushes["cross-brush"] = QBrush(Qt::CrossPattern);
m_brushes["bdiag-brush"] = QBrush(Qt::BDiagPattern);
m_brushes["fdiag-brush"] = QBrush(Qt::FDiagPattern);
m_brushes["diagcross-brush"] = QBrush(Qt::DiagCrossPattern);
// Gradients
QGradientStops gradient_white_black;
gradient_white_black << QPair<qreal, QColor>(0, QColor(Qt::white));
gradient_white_black << QPair<qreal, QColor>(1, QColor(Qt::black));
QGradientStops gradient_white_black10;
for (int i=0; i<10; ++i) {
gradient_white_black10 << QPair<qreal, QColor>(i/10.0, QColor(Qt::white));
gradient_white_black10 << QPair<qreal, QColor>(i/10.0+0.05, QColor(Qt::black));
}
QGradientStops gradient_white_alpha;
gradient_white_alpha << QPair<qreal, QColor>(0, QColor(Qt::white));
gradient_white_alpha << QPair<qreal, QColor>(0, QColor(Qt::transparent));
QGradientStops gradient_white_alpha10;
for (int i=0; i<10; ++i) {
gradient_white_alpha10 << QPair<qreal, QColor>(i/10.0, QColor(Qt::white));
gradient_white_alpha10 << QPair<qreal, QColor>(i/10.0+0.05, QColor(Qt::black));
}
for (int j=0; j<4; ++j) {
QLinearGradient lg;
lg.setStart(0, 0);
QRadialGradient rg;
QConicalGradient cg;
QGradientStops stops;
if (j == 0) stops = gradient_white_black;
else if (j == 1) stops = gradient_white_black10;
else if (j == 2) stops = gradient_white_alpha;
else if (j == 3) stops = gradient_white_alpha10;
lg.setStops(stops);
rg.setStops(stops);
cg.setStops(stops);
for (int i=0; i<6; ++i) {
lg.setSpread((QGradient::Spread) (i % 3));
lg.setCoordinateMode((QGradient::CoordinateMode) (j / 3));
QString name = QString::fromLatin1("-%1%2")
.arg(lg.spread())
.arg(lg.coordinateMode());
lg.setFinalStop(100, 0);
m_brushes["hor-lingrad-w/b-brush" + name] = QBrush(lg);
lg.setFinalStop(0, 100);
m_brushes["ver-lingrad-w/b-brush" + name] = QBrush(lg);
lg.setFinalStop(100, 100);
m_brushes["diag-lingrad-w/b-brush" + name] = QBrush(lg);
rg.setRadius(100);
rg.setCenter(0, 0);
rg.setFocalPoint(50, 50);
m_brushes["radgrad-brush" + name] = QBrush(rg);
cg.setCenter(0, 0);
cg.setAngle(40);
m_brushes["congrad-brush" + name] = QBrush(cg);
}
}
// Set up pens...
// m_pens["black-pen"] = QPen(Qt::black);
// m_pens["white-pen"] = QPen(Qt::white);
// m_pens["transparent-pen"] = QPen(QColor(255, 255, 255, 0));
// m_pens["translucent1-pen"] = QPen(QColor(255, 255, 255, 100));
// m_pens["translucent2-pen"] = QPen(QColor(255, 255, 255, 200));
}
// void QPainter_Primitives::fillRect_data() {
// QTest::addColumn<QBrush>("brush");
// QTest::addColumn<QSize>("size");
// for (QMap<QString, QBrush>::const_iterator it = m_brushes.constBegin();
// it != m_brushes.constEnd(); ++it) {
// for (int w=2; w<1025; w*=2) {
// for (int h=2; h<1025; h*=2) {
// QTest::newRow(QString("brush=%1; size=[%2,%3]").arg(it.key()).arg(w).arg(h).toAscii().data())
// << *it << QSize(w, h);
// }
// }
// }
// }
// void QPainter_Primitives::fillRect()
// {
// QFETCH(QBrush, brush);
// QFETCH(QSize, size);
// QImage img(1024, 1024, QImage::Format_ARGB32_Premultiplied);
// QPainter p(&img);
// p.setPen(Qt::NoPen);
// p.setBrush(brush);
// QRect rect(QPoint(0, 0), size);
// QBENCHMARK {
// p.drawRect(rect);
// }
// }
void tst_QPainter::beginAndEnd()
{
QPixmap pixmap = rasterPixmap(100, 100);
QBENCHMARK {
QPainter p;
p.begin(&pixmap);
p.end();
}
}
void tst_QPainter::drawLine()
{
QFETCH(QLine, line);
QFETCH(QPen, pen);
const int offset = 5;
QPixmap pixmapUnclipped =
rasterPixmap(qMin(line.x1(), line.x2())
+ 2*offset + qAbs(line.dx()),
qMin(line.y1(), line.y2())
+ 2*offset + qAbs(line.dy()));
pixmapUnclipped.fill(Qt::white);
QPainter p(&pixmapUnclipped);
p.translate(offset, offset);
p.setPen(pen);
p.paintEngine()->syncState();
QBENCHMARK {
p.drawLine(line);
}
p.end();
}
void tst_QPainter::drawLine_clipped_data()
{
drawLine_data();
}
void tst_QPainter::drawLine_clipped()
{
QFETCH(QLine, line);
QFETCH(QPen, pen);
const int offset = 5;
QPixmap pixmapClipped
= rasterPixmap(qMin(line.x1(), line.x2())
+ 2*offset + qAbs(line.dx()),
qMin(line.y1(), line.y2())
+ 2*offset + qAbs(line.dy()));
const QRect clip = QRect(line.p1(), line.p2()).normalized();
pixmapClipped.fill(Qt::white);
QPainter p(&pixmapClipped);
p.translate(offset, offset);
p.setClipRect(clip);
p.setPen(pen);
p.paintEngine()->syncState();
QBENCHMARK {
p.drawLine(line);
}
p.end();
}
void tst_QPainter::drawLine_antialiased_clipped_data()
{
drawLine_data();
}
void tst_QPainter::drawLine_antialiased_clipped()
{
QFETCH(QLine, line);
QFETCH(QPen, pen);
const int offset = 5;
QPixmap pixmapClipped
= rasterPixmap(qMin(line.x1(), line.x2())
+ 2*offset + qAbs(line.dx()),
qMin(line.y1(), line.y2())
+ 2*offset + qAbs(line.dy()));
const QRect clip = QRect(line.p1(), line.p2()).normalized();
pixmapClipped.fill(Qt::white);
QPainter p(&pixmapClipped);
p.setRenderHint(QPainter::Antialiasing);
p.translate(offset, offset);
p.setClipRect(clip);
p.setPen(pen);
p.paintEngine()->syncState();
QBENCHMARK {
p.drawLine(line);
}
p.end();
}
void tst_QPainter::drawPixmap_data()
{
QTest::addColumn<QImage::Format>("sourceFormat");
QTest::addColumn<QImage::Format>("targetFormat");
QTest::addColumn<QSize>("size");
QTest::addColumn<int>("type"); // 0 = circle, 1 = diag line, 2 = solid rect, 3 = alpharect
QList<QSize> sizes;
sizes << QSize(1, 1)
<< QSize(10, 10)
<< QSize(100, 100)
<< QSize(1000, 1000);
const char *typeNames[] = {
"circle",
"line",
"solidrect",
"alpharect"
};
const char *formatNames[] = {
"Invalid",
"Mono",
"MonoLSB",
"Indexed8",
"RGB32",
"ARGB32",
"ARGB32_pm",
"RGB16",
"ARGB8565_pm",
"RGB666",
"ARGB6666_pm",
"RGB555",
"ARGB8555_pm",
"RGB888",
"RGB444",
"ARGB4444_pm"
};
for (int tar=4; tar<QImage::NImageFormats; ++tar) {
for (int src=4; src<QImage::NImageFormats; ++src) {
// skip the low-priority formats to keep resultset manageable...
if (tar == QImage::Format_RGB444 || src == QImage::Format_RGB444
|| tar == QImage::Format_RGB555 || src == QImage::Format_RGB555
|| tar == QImage::Format_RGB666 || src == QImage::Format_RGB666
|| tar == QImage::Format_RGB888 || src == QImage::Format_RGB888
|| tar == QImage::Format_ARGB4444_Premultiplied
|| src == QImage::Format_ARGB4444_Premultiplied
|| tar == QImage::Format_ARGB6666_Premultiplied
|| src == QImage::Format_ARGB6666_Premultiplied)
continue;
foreach (const QSize &s, sizes) {
for (int type=0; type<=3; ++type) {
QString name = QString::fromLatin1("%1 on %2, (%3x%4), %5")
.arg(formatNames[src])
.arg(formatNames[tar])
.arg(s.width()).arg(s.height())
.arg(typeNames[type]);
QTest::newRow(name.toLatin1()) << (QImage::Format) src
<< (QImage::Format) tar
<< s
<< type;
}
}
}
}
}
static QImage createImage(int type, const QSize &size) {
QImage base(size, QImage::Format_ARGB32_Premultiplied);
base.fill(0);
QPainter p(&base);
p.setRenderHint(QPainter::Antialiasing);
switch (type) {
case 0: // ellipse
p.setBrush(Qt::red);
p.drawEllipse(0, 0, size.width(), size.height());
break;
case 1: // line
p.drawLine(0, 0, size.width(), size.height());
break;
case 2:
p.fillRect(0, 0, size.width(), size.height(), Qt::red);
break;
case 3:
p.fillRect(0, 0, size.width(), size.height(), QColor(0, 255, 0, 127));
break;
}
p.end();
return base;
}
void tst_QPainter::drawPixmap()
{
QFETCH(QImage::Format, sourceFormat);
QFETCH(QImage::Format, targetFormat);
QFETCH(QSize, size);
QFETCH(int, type);
QImage sourceImage = createImage(type, size).convertToFormat(sourceFormat);
QImage targetImage(size, targetFormat);
QPixmap sourcePixmap = rasterPixmap(sourceImage);
QPixmap targetPixmap = rasterPixmap(targetImage);
QPainter p(&targetPixmap);
QBENCHMARK {
p.drawPixmap(0, 0, sourcePixmap);
}
}
void tst_QPainter::drawImage_data()
{
drawPixmap_data();
}
void tst_QPainter::drawImage()
{
QFETCH(QImage::Format, sourceFormat);
QFETCH(QImage::Format, targetFormat);
QFETCH(QSize, size);
QFETCH(int, type);
QImage sourceImage = createImage(type, size).convertToFormat(sourceFormat);
QImage targetImage(size, targetFormat);
QPainter p(&targetImage);
QBENCHMARK {
p.drawImage(0, 0, sourceImage);
}
}
void tst_QPainter::compositionModes_data()
{
QTest::addColumn<QPainter::CompositionMode>("mode");
QTest::addColumn<QSize>("size");
QTest::addColumn<QColor>("color");
const int n = QPainter::RasterOp_SourceAndNotDestination;
for (int i = 0; i <= n; ++i) {
QString title("%1:%2");
QTest::newRow(qPrintable(title.arg(i).arg("10x10:opaque")))
<< (QPainter::CompositionMode)(i)
<< QSize(10, 10) << QColor(255, 0, 0);
QTest::newRow(qPrintable(title.arg(i).arg("10x10:!opaque")))
<< (QPainter::CompositionMode)(i)
<< QSize(10, 10) << QColor(127, 127, 127, 127);
QTest::newRow(qPrintable(title.arg(i).arg("300x300:opaque")))
<< (QPainter::CompositionMode)(i)
<< QSize(300, 300) << QColor(255, 0, 0);
QTest::newRow(qPrintable(title.arg(i).arg("300x300:!opaque")))
<< (QPainter::CompositionMode)(i)
<< QSize(300, 300) << QColor(127, 127, 127, 127);
}
}
void tst_QPainter::compositionModes()
{
QFETCH(QPainter::CompositionMode, mode);
QFETCH(QSize, size);
QFETCH(QColor, color);
QPixmap src = rasterPixmap(size);
src.fill(color);
QPixmap dest = rasterPixmap(size);
if (mode < QPainter::RasterOp_SourceOrDestination)
color.setAlpha(127); // porter-duff needs an alpha channel
dest.fill(color);
QPainter p(&dest);
p.setCompositionMode(mode);
QBENCHMARK {
p.drawPixmap(0, 0, src);
}
}
void tst_QPainter::drawTiledPixmap_data()
{
QTest::addColumn<QSize>("srcSize");
QTest::addColumn<QSize>("dstSize");
QTest::addColumn<QTransform>("transform");
QTest::addColumn<QColor>("color");
QTest::addColumn<QPainter::RenderHint>("renderHint");
QTest::newRow("10x10=>20x20")
<< QSize(10, 10) << QSize(20, 20) << (QTransform())
<< QColor(Qt::black) << QPainter::RenderHint(0);
QTest::newRow("10x10=>20x20, smooth")
<< QSize(10, 10) << QSize(20, 20) << (QTransform())
<< QColor(Qt::black) << QPainter::SmoothPixmapTransform;
QTest::newRow("10x10=>20x20, !opaque")
<< QSize(10, 10) << QSize(20, 20) << (QTransform())
<< QColor(127, 127, 127, 127) << QPainter::RenderHint(0);
QTest::newRow("10x10=>20x20, !opaque, smooth")
<< QSize(10, 10) << QSize(20, 20) << (QTransform())
<< QColor(127, 127, 127, 127) << QPainter::SmoothPixmapTransform;
QTest::newRow("10x10=>20x20, rotate(30)")
<< QSize(10, 10) << QSize(20, 20) << (QTransform().rotate(30))
<< QColor(Qt::black) << QPainter::RenderHint(0);
QTest::newRow("10x10=>20x20, rotate(30), smooth")
<< QSize(10, 10) << QSize(20, 20) << (QTransform().rotate(30))
<< QColor(Qt::black) << QPainter::SmoothPixmapTransform;
QTest::newRow("10x10=>20x20, rotate(30), !opaque")
<< QSize(10, 10) << QSize(20, 20) << (QTransform().rotate(30))
<< QColor(127, 127, 127, 127) << QPainter::RenderHint(0);
QTest::newRow("10x10=>20x20, rotate(30), !opaque, smooth")
<< QSize(10, 10) << QSize(20, 20) << (QTransform().rotate(30))
<< QColor(127, 127, 127, 127) << QPainter::SmoothPixmapTransform;
QTest::newRow("100x100=>200x200")
<< QSize(100, 100) << QSize(200, 200) << (QTransform())
<< QColor(Qt::black) << QPainter::RenderHint(0);
QTest::newRow("100x100=>200x200, smooth")
<< QSize(100, 100) << QSize(200, 200) << (QTransform())
<< QColor(Qt::black) << QPainter::SmoothPixmapTransform;
QTest::newRow("100x100=>200x200, !opaque")
<< QSize(100, 100) << QSize(200, 200) << (QTransform())
<< QColor(127, 127, 127, 127) << QPainter::RenderHint(0);
QTest::newRow("100x100=>200x200, !opaque, smooth")
<< QSize(100, 100) << QSize(200, 200) << (QTransform())
<< QColor(127, 127, 127, 127) << QPainter::SmoothPixmapTransform;
QTest::newRow("100x100=>200x200, rotate(30)")
<< QSize(100, 100) << QSize(200, 200) << (QTransform().rotate(30))
<< QColor(Qt::black) << QPainter::RenderHint(0);
QTest::newRow("100x100=>200x200, rotate(30), smooth")
<< QSize(100, 100) << QSize(200, 200) << (QTransform().rotate(30))
<< QColor(Qt::black) << QPainter::SmoothPixmapTransform;
QTest::newRow("100x100=>200x200, rotate(30), !opaque")
<< QSize(100, 100) << QSize(200, 200) << (QTransform().rotate(30))
<< QColor(127, 127, 127, 127) << QPainter::RenderHint(0);
QTest::newRow("100x100=>200x200, rotate(30), !opaque, smooth")
<< QSize(100, 100) << QSize(200, 200) << (QTransform().rotate(30))
<< QColor(127, 127, 127, 127) << QPainter::SmoothPixmapTransform;
}
void tst_QPainter::drawTiledPixmap()
{
QFETCH(QSize, srcSize);
QFETCH(QSize, dstSize);
QFETCH(QTransform, transform);
QFETCH(QColor, color);
QFETCH(QPainter::RenderHint, renderHint);
QPixmap src = rasterPixmap(srcSize);
src.fill(color);
const QRect dstRect = transform.mapRect(QRect(QPoint(), dstSize));
QPixmap dst = rasterPixmap(dstRect.right() + 5, dstRect.bottom() + 5);
QPainter p(&dst);
p.setTransform(transform);
p.setRenderHint(renderHint);
QBENCHMARK {
p.drawTiledPixmap(QRect(QPoint(), dstSize), src);
}
}
void tst_QPainter::fillPrimitives_helper(QPainter *p, PrimitiveType type, PrimitiveSet *s)
{
p->paintEngine()->syncState();
switch (type) {
case Primitive_Int_DiagLine: QBENCHMARK { p->drawLine(s->i_line_diag); } break;
case Primitive_Int_VerLine: QBENCHMARK { p->drawLine(s->i_line_ver); } break;
case Primitive_Int_HorLine: QBENCHMARK { p->drawLine(s->i_line_hor); } break;
case Primitive_Int_Rect: QBENCHMARK { p->drawRect(s->i_rect); } break;
case Primitive_Int_Ellipse: QBENCHMARK { p->drawEllipse(s->i_rect); } break;
case Primitive_Int_Pie: QBENCHMARK { p->drawPie(s->i_rect, 45*16, 270*16); } break;
case Primitive_Int_Arc: QBENCHMARK { p->drawArc(s->i_rect, 45*16, 270*16); } break;
case Primitive_Int_Chord: QBENCHMARK { p->drawChord(s->i_rect, 45*16, 270*16); } break;
case Primitive_Int_TriPoly: QBENCHMARK { p->drawPolygon(s->i_poly_tri); } break;
case Primitive_Int_RectPoly: QBENCHMARK { p->drawPolygon(s->i_poly_rect); } break;
case Primitive_Int_2RectPoly: QBENCHMARK { p->drawPolygon(s->i_poly_2rects); } break;
case Primitive_Float_DiagLine: QBENCHMARK { p->drawLine(s->f_line_diag); } break;
case Primitive_Float_VerLine: QBENCHMARK { p->drawLine(s->f_line_ver); } break;
case Primitive_Float_HorLine: QBENCHMARK { p->drawLine(s->f_line_hor); } break;
case Primitive_Float_Rect: QBENCHMARK { p->drawRect(s->f_rect); } break;
case Primitive_Float_Ellipse: QBENCHMARK { p->drawEllipse(s->f_rect); } break;
case Primitive_Float_Pie: QBENCHMARK { p->drawPie(s->f_rect, 45*16, 270*16); } break;
case Primitive_Float_Arc: QBENCHMARK { p->drawArc(s->f_rect, 45*16, 270*16); } break;
case Primitive_Float_Chord: QBENCHMARK { p->drawChord(s->f_rect, 45*16, 270*16); } break;
case Primitive_Float_TriPoly: QBENCHMARK { p->drawPolygon(s->f_poly_tri); } break;
case Primitive_Float_RectPoly: QBENCHMARK { p->drawPolygon(s->f_poly_rect); } break;
case Primitive_Float_2RectPoly: QBENCHMARK { p->drawPolygon(s->f_poly_2rects); } break;
case Primitive_Float_TriPath: QBENCHMARK { p->drawPath(s->f_path_tri); } break;
case Primitive_Float_RectPath: QBENCHMARK { p->drawPath(s->f_path_rect); } break;
case Primitive_Float_2RectPath: QBENCHMARK { p->drawPath(s->f_path_2rects); } break;
case Primitive_Float_EllipsePath: QBENCHMARK { p->drawPath(s->f_path_ellipse); } break;
}
}
void tst_QPainter::drawPrimitives_data_helper(bool fancypens)
{
QTest::addColumn<int>("type");
QTest::addColumn<bool>("aa");
QTest::addColumn<bool>("dash");
QTest::addColumn<int>("width");
const char * const names[] = {
"IDLine",
"IVLine",
"IHLine",
"IRect",
"IElli",
"IPie",
"IArc",
"IChord",
"ITriPol",
"IRectPol",
"I2RectPol",
"FDLine",
"FVLine",
"FHLine",
"FRect",
"FElli",
"FPie",
"FArc",
"FChord",
"FTriPol",
"FRectPol",
"F2RectPol",
"FTriPa",
"FRectPa",
"F2RectPa",
"FElliPa"
};
if (fancypens) {
for (int dash=0; dash<2; ++dash) {
for (int width=0; width<=4; width+=4) {
for (int aa=0; aa<2; ++aa) {
for (int type=0; type<Primitive_Last_Primitive; ++type) {
QString name = QString::fromLatin1(names[type]);
if (aa) name += " aa";
if (dash) name += " dotted";
if (width) name += QString::fromLatin1(" width=%1").arg(width);
QTest::newRow(name.toLatin1()) << type << (bool) aa << (bool) dash << width;
}
}
}
}
} else {
for (int aa=0; aa<2; ++aa) {
for (int type=0; type<Primitive_Last_Primitive; ++type) {
QString name = QString::fromLatin1(names[type]);
if (aa) name += " aa";
QTest::newRow(name.toLatin1()) << type << (bool) aa;
}
}
}
}
void tst_QPainter::fillPrimitives_10()
{
QFETCH(int, type);
QFETCH(bool, aa);
QPainter p(m_surface);
p.setPen(Qt::NoPen);
p.setBrush(Qt::red);
p.setRenderHint(QPainter::Antialiasing, aa);
fillPrimitives_helper(&p, (PrimitiveType) type, &m_primitives_10);
}
void tst_QPainter::fillPrimitives_100()
{
QFETCH(int, type);
QFETCH(bool, aa);
QPainter p(m_surface);
p.setPen(Qt::NoPen);
p.setBrush(Qt::red);
p.setRenderHint(QPainter::Antialiasing, aa);
fillPrimitives_helper(&p, (PrimitiveType) type, &m_primitives_100);
}
void tst_QPainter::fillPrimitives_1000()
{
QFETCH(int, type);
QFETCH(bool, aa);
QPainter p(m_surface);
p.setPen(Qt::NoPen);
p.setBrush(Qt::red);
p.setRenderHint(QPainter::Antialiasing, aa);
fillPrimitives_helper(&p, (PrimitiveType) type, &m_primitives_1000);
}
void tst_QPainter::strokePrimitives_10()
{
QFETCH(int, type);
QFETCH(bool, aa);
QFETCH(bool, dash);
QFETCH(int, width);
QPainter p(m_surface);
p.setPen(QPen(Qt::red, width, dash ? Qt::DashLine : Qt::SolidLine));
p.setBrush(Qt::NoBrush);
p.setRenderHint(QPainter::Antialiasing, aa);
fillPrimitives_helper(&p, (PrimitiveType) type, &m_primitives_10);
}
void tst_QPainter::strokePrimitives_100()
{
QFETCH(int, type);
QFETCH(bool, aa);
QFETCH(bool, dash);
QFETCH(int, width);
QPainter p(m_surface);
p.setPen(QPen(Qt::red, width, dash ? Qt::DashLine : Qt::SolidLine));
p.setBrush(Qt::NoBrush);
p.setRenderHint(QPainter::Antialiasing, aa);
fillPrimitives_helper(&p, (PrimitiveType) type, &m_primitives_100);
}
void tst_QPainter::strokePrimitives_1000()
{
QFETCH(int, type);
QFETCH(bool, aa);
QFETCH(bool, dash);
QFETCH(int, width);
QPainter p(m_surface);
p.setPen(QPen(Qt::red, width, dash ? Qt::DashLine : Qt::SolidLine));
p.setBrush(Qt::NoBrush);
p.setRenderHint(QPainter::Antialiasing, aa);
fillPrimitives_helper(&p, (PrimitiveType) type, &m_primitives_1000);
}
void tst_QPainter::drawText_data()
{
QTest::addColumn<QString>("text");
QTest::newRow("a") << QString::fromLatin1("a");
QTest::newRow("ab") << QString::fromLatin1("ab");
QTest::newRow("abc") << QString::fromLatin1("abc");
QTest::newRow("abcd") << QString::fromLatin1("abcd");
QTest::newRow("abcde") << QString::fromLatin1("abcde");
QTest::newRow("abcdef") << QString::fromLatin1("abcdef");
QTest::newRow("abcdefg") << QString::fromLatin1("abcdefg");
}
void tst_QPainter::drawText()
{
QFETCH(QString, text);
QPainter p(m_surface);
QBENCHMARK {
p.drawText(QPointF(5, 5), text);
}
}
void tst_QPainter::saveRestore_data()
{
QTest::addColumn<int>("change");
for (int i=0; i<16; ++i) {
QString change = "change=";
if (i == 0) change += " none";
if (i & ChangePen) change += " pen";
if (i & ChangeBrush) change += " brush";
if (i & ChangeClip) change += " clip";
if (i & ChangeTransform) change += " xform";
QTest::newRow(change.toLatin1()) << i;
}
}
void tst_QPainter::saveRestore()
{
QFETCH(int, change);
QPen pen(Qt::blue);
QBrush brush(Qt::green);
QRect r(100, 100, 100, 20);
QPainter p(m_surface);
p.setPen(Qt::NoPen);
p.setBrush(Qt::NoBrush);
QBENCHMARK {
p.save();
if (change & ChangePen) { p.setPen(pen); p.setPen(Qt::NoPen); }
if (change & ChangeBrush) { p.setBrush(brush); p.setBrush(Qt::NoBrush); }
if (change & ChangeClip) p.setClipRect(r);
if (change & ChangeTransform) { p.scale(3, 5); p.scale(1/3.0, 1/5.0); }
p.drawRect(0, 0, 1, 1);
p.restore();
};
}
enum ClipType {
RectClipType,
RectPathClipType,
RectRegionClipType,
RegionClipType,
PathClipType
};
void tst_QPainter::clipAndFill_data()
{
QTest::addColumn<int>("type");
QTest::newRow("rect") << (int) RectClipType;
QTest::newRow("rectpath") << (int) RectPathClipType;
QTest::newRow("rectregion") << (int) RectRegionClipType;
QTest::newRow("ellipseRegion") << (int) RegionClipType;
QTest::newRow("ellipsePath") << (int) PathClipType;
}
void tst_QPainter::clipAndFill()
{
QFETCH(int, type);
QRegion region;
QPainterPath path;
QRectF rect;
switch (type) {
case RectClipType:
rect = QRectF(100, 100, 100, 100);
break;
case RectPathClipType:
path.addRect(100, 100, 100, 100);
break;
case RectRegionClipType:
region = QRegion(100, 100, 100, 100);
break;
case RegionClipType:
region = QRegion(100, 100, 100, 100, QRegion::Ellipse);
break;
case PathClipType:
path.addEllipse(100, 100, 100, 100);
break;
}
QPainter p(m_surface);
p.setPen(Qt::NoPen);
p.setBrush(Qt::red);
QBENCHMARK {
if (type == RectClipType)
p.setClipRect(rect);
else if (type == RectPathClipType || type == PathClipType)
p.setClipPath(path);
else
p.setClipRegion(region);
p.drawRect(110, 110, 10, 10);
}
}
QTransform tst_QPainter::transformForAngle(qreal angle)
{
const qreal inv_dist_to_plane = 1. / 1024.;
QTransform transform;
QTransform rotTrans;
rotTrans.translate(-40, 0);
QTransform rotTrans2;
rotTrans2.translate(40, 0);
qreal rad = angle * 2. * M_PI / 360.;
qreal c = ::cos(rad);
qreal s = ::sin(rad);
qreal x = 0;
qreal y = 80;
qreal z = 0;
qreal len = x * x + y * y + z * z;
if (len != 1.) {
len = ::sqrt(len);
x /= len;
y /= len;
z /= len;
}
QTransform rot(x*x*(1-c)+c, x*y*(1-c)-z*s, x*z*(1-c)+y*s*inv_dist_to_plane,
y*x*(1-c)+z*s, y*y*(1-c)+c, y*z*(1-c)-x*s*inv_dist_to_plane,
0, 0, 1);
transform *= rotTrans;
transform *= rot;
transform *= rotTrans2;
return transform;
}
void tst_QPainter::drawRoundedRect()
{
QImage surface(100, 100, QImage::Format_RGB16);
surface.fill(QColor(255,255,255).rgb());
QPainter p(&surface);
p.setPen(QPen(Qt::black, 1));
p.setBrush(Qt::red);
QBENCHMARK {
p.drawRoundedRect(QRectF(.5, .5, 80, 80), 10, 10);
}
}
void tst_QPainter::drawScaledRoundedRect()
{
QImage surface(400, 400, QImage::Format_RGB16);
surface.fill(QColor(255,255,255).rgb());
QPainter p(&surface);
p.setPen(QPen(Qt::black, 1));
p.setBrush(Qt::red);
p.scale(3, 3);
QBENCHMARK {
p.drawRoundedRect(10, 10, 80, 80, 10, 10);
}
}
void tst_QPainter::drawTransformedRoundedRect()
{
QImage surface(400, 400, QImage::Format_RGB16);
surface.fill(QColor(255,255,255).rgb());
QPainter p(&surface);
p.setPen(QPen(Qt::black, 1));
p.setBrush(Qt::red);
QBENCHMARK {
p.setWorldTransform(QTransform(0.956957, 0, 0.000704124, 0, 1, 0, 16.141, 0, 0.735953));
p.drawRoundedRect(100, 100, 80, 80, 10, 10);
}
}
void tst_QPainter::drawAntialiasedRoundedRect()
{
QImage surface(100, 100, QImage::Format_RGB16);
surface.fill(QColor(255,255,255).rgb());
QPainter p(&surface);
p.setRenderHint(QPainter::Antialiasing, true);
p.setPen(QPen(Qt::black, 1));
p.setBrush(Qt::red);
QBENCHMARK {
p.drawRoundedRect(QRectF(.5, .5, 80, 80), 10, 10);
}
}
void tst_QPainter::drawScaledAntialiasedRoundedRect_data()
{
QTest::addColumn<float>("scale");
for (float i = 0; i < 3; i += .1)
QTest::newRow(QString(QLatin1String("scale=%1")).arg(i).toLatin1()) << i;
}
void tst_QPainter::drawScaledAntialiasedRoundedRect()
{
QFETCH(float, scale);
QImage surface(400, 400, QImage::Format_RGB16);
surface.fill(QColor(255,255,255).rgb());
QPainter p(&surface);
p.setRenderHint(QPainter::Antialiasing, true);
p.setPen(QPen(Qt::black, 1));
p.setBrush(Qt::red);
p.scale(scale, scale);
QBENCHMARK {
p.drawRoundedRect(10, 10, 80, 80, 10, 10);
}
}
void tst_QPainter::drawTransformedAntialiasedRoundedRect_data()
{
QTest::addColumn<QTransform>("transform");
for (float angle = 0; angle < 360; angle += 10)
QTest::newRow(QString(QLatin1String("angle=%1")).arg(angle).toLatin1()) << transformForAngle(angle);
}
void tst_QPainter::drawTransformedAntialiasedRoundedRect()
{
QFETCH(QTransform, transform);
QImage surface(400, 400, QImage::Format_RGB16);
surface.fill(QColor(255,255,255).rgb());
QPainter p(&surface);
p.setRenderHint(QPainter::Antialiasing, true);
p.setPen(QPen(Qt::black, 1));
p.setBrush(Qt::red);
QBENCHMARK {
p.setWorldTransform(transform);
p.drawRoundedRect(100, 100, 80, 80, 10, 10);
}
}
void tst_QPainter::drawImageRoundedRect()
{
//setup image
const int radius = 10;
QImage rectImage(81, 81, QImage::Format_ARGB32_Premultiplied);
rectImage.fill(0);
QPainter rp(&rectImage);
rp.setRenderHint(QPainter::Antialiasing);
rp.setPen(Qt::black);
rp.setBrush(Qt::red);
rp.drawRoundedRect(QRectF(.5, .5, 80, 80), radius, radius);
//setup surface
QImage surface(100, 100, QImage::Format_RGB16);
surface.fill(QColor(255,255,255).rgb());
QPainter p(&surface);
QBENCHMARK {
p.drawImage(0,0, rectImage);
}
}
void tst_QPainter::drawScaledImageRoundedRect_data()
{
QTest::addColumn<int>("imageType");
QTest::newRow("imagetype=ARGB32_Pre") << (int)QImage::Format_ARGB32_Premultiplied;
QTest::newRow("imagetype=ARGB8565_Pre") << (int)QImage::Format_ARGB8565_Premultiplied;
}
void tst_QPainter::drawScaledImageRoundedRect()
{
QFETCH(int, imageType);
//setup image
const int radius = 10;
QImage rectImage(81, 81, (QImage::Format)imageType);
rectImage.fill(0);
QPainter rp(&rectImage);
rp.setRenderHint(QPainter::Antialiasing);
rp.setPen(Qt::black);
rp.setBrush(Qt::red);
rp.drawRoundedRect(QRectF(.5, .5, 80, 80), radius, radius);
//setup surface
QImage surface(400, 400, QImage::Format_RGB16);
surface.fill(QColor(255,255,255).rgb());
QPainter p(&surface);
p.scale(3, 3);
QBENCHMARK {
p.drawImage(0,0, rectImage);
}
}
void tst_QPainter::drawTransformedImageRoundedRect_data()
{
QTest::addColumn<int>("imageType");
QTest::newRow("imagetype=ARGB32_Pre") << (int)QImage::Format_ARGB32_Premultiplied;
QTest::newRow("imagetype=ARGB8565_Pre") << (int)QImage::Format_ARGB8565_Premultiplied;
}
void tst_QPainter::drawTransformedImageRoundedRect()
{
QFETCH(int, imageType);
//setup image
const int radius = 10;
QImage rectImage(81, 81, (QImage::Format)imageType);
rectImage.fill(0);
QPainter rp(&rectImage);
rp.setRenderHint(QPainter::Antialiasing);
rp.setPen(Qt::black);
rp.setBrush(Qt::red);
rp.drawRoundedRect(QRectF(.5, .5, 80, 80), radius, radius);
//setup surface
QImage surface(400, 400, QImage::Format_RGB16);
surface.fill(QColor(255,255,255).rgb());
QPainter p(&surface);
QBENCHMARK {
p.setWorldTransform(QTransform(0.956957, 0, 0.000704124, 0, 1, 0, 16.141, 0, 0.735953));
p.drawImage(100,100, rectImage);
}
}
//code from QDeclarativeRectangle for drawing rounded rects
void tst_QPainter::drawBorderPixmapRoundedRect()
{
//setup image
const int pw = 1;
const int radius = 10;
QImage rectImage(radius*2 + 3 + pw*2, radius*2 + 3 + pw*2, QImage::Format_ARGB32_Premultiplied);
rectImage.fill(0);
QPainter rp(&rectImage);
rp.setRenderHint(QPainter::Antialiasing);
rp.setPen(Qt::black);
rp.setBrush(Qt::red);
if (pw%2)
rp.drawRoundedRect(QRectF(qreal(pw)/2+1, qreal(pw)/2+1, rectImage.width()-(pw+1), rectImage.height()-(pw+1)), radius, radius);
else
rp.drawRoundedRect(QRectF(qreal(pw)/2, qreal(pw)/2, rectImage.width()-pw, rectImage.height()-pw), radius, radius);
QPixmap rectPixmap = rasterPixmap(rectImage);
//setup surface
QImage surface(100, 100, QImage::Format_RGB16);
surface.fill(QColor(255,255,255).rgb());
QPainter p(&surface);
QBENCHMARK {
const int pw = 2;
int width = 80;
int height = 80;
int xOffset = (rectPixmap.width()-1)/2;
int yOffset = (rectPixmap.height()-1)/2;
Q_ASSERT(rectPixmap.width() == 2*xOffset + 1);
Q_ASSERT(rectPixmap.height() == 2*yOffset + 1);
QMargins margins(xOffset, yOffset, xOffset, yOffset);
QTileRules rules(Qt::StretchTile, Qt::StretchTile);
//NOTE: even though our item may have qreal-based width and height, qDrawBorderPixmap only supports QRects
qDrawBorderPixmap(&p, QRect(-pw/2, -pw/2, width+pw, height+pw), margins, rectPixmap, rectPixmap.rect(), margins, rules);
}
}
void tst_QPainter::drawScaledBorderPixmapRoundedRect_data()
{
QTest::addColumn<float>("scale");
QTest::addColumn<int>("imageType");
for (float i = 0; i < 3; i += .1)
QTest::newRow(QString(QLatin1String("scale=%1; imagetype=ARGB32_Pre")).arg(i).toLatin1()) << i << (int)QImage::Format_ARGB32_Premultiplied;
//for (float i = 0; i < 3; i += .1)
// QTest::newRow(QString(QLatin1String("scale=%1; imagetype=ARGB8565_Pre")).arg(i).toLatin1()) << i << (int)QImage::Format_ARGB8565_Premultiplied;
}
//code from QDeclarativeRectangle for drawing rounded rects
void tst_QPainter::drawScaledBorderPixmapRoundedRect()
{
QFETCH(float, scale);
QFETCH(int, imageType);
//setup image
const int pw = 1;
const int radius = 10;
QImage rectImage(radius*2 + 3 + pw*2, radius*2 + 3 + pw*2, (QImage::Format)imageType);
rectImage.fill(0);
QPainter rp(&rectImage);
rp.setRenderHint(QPainter::Antialiasing);
rp.setPen(Qt::black);
rp.setBrush(Qt::red);
if (pw%2)
rp.drawRoundedRect(QRectF(qreal(pw)/2+1, qreal(pw)/2+1, rectImage.width()-(pw+1), rectImage.height()-(pw+1)), radius, radius);
else
rp.drawRoundedRect(QRectF(qreal(pw)/2, qreal(pw)/2, rectImage.width()-pw, rectImage.height()-pw), radius, radius);
QPixmap rectPixmap = rasterPixmap(rectImage);
//setup surface
QImage surface(400, 400, QImage::Format_RGB16);
surface.fill(QColor(255,255,255).rgb());
QPainter p(&surface);
p.scale(scale, scale);
QBENCHMARK {
const int pw = 2;
int width = 80;
int height = 80;
int xOffset = (rectPixmap.width()-1)/2;
int yOffset = (rectPixmap.height()-1)/2;
Q_ASSERT(rectPixmap.width() == 2*xOffset + 1);
Q_ASSERT(rectPixmap.height() == 2*yOffset + 1);
QMargins margins(xOffset, yOffset, xOffset, yOffset);
QTileRules rules(Qt::StretchTile, Qt::StretchTile);
qDrawBorderPixmap(&p, QRect(-pw/2, -pw/2, width+pw, height+pw), margins, rectPixmap, rectPixmap.rect(), margins, rules);
}
}
void tst_QPainter::drawTransformedBorderPixmapRoundedRect_data()
{
QTest::addColumn<QTransform>("transform");
QTest::addColumn<int>("imageType");
for (float angle = 0; angle < 360; angle += 10)
QTest::newRow(QString(QLatin1String("angle=%1; imagetype=ARGB32_Pre")).arg(angle).toLatin1()) << transformForAngle(angle) << (int)QImage::Format_ARGB32_Premultiplied;
//for (float angle = 0; angle < 360; angle += 10)
// QTest::newRow(QString(QLatin1String("angle=%1; imagetype=ARGB8565_Pre")).arg(angle).toLatin1()) << transformForAngle(angle) << (int)QImage::Format_ARGB8565_Premultiplied;
}
//code from QDeclarativeRectangle for drawing rounded rects
void tst_QPainter::drawTransformedBorderPixmapRoundedRect()
{
QFETCH(QTransform, transform);
QFETCH(int, imageType);
//setup image
const int pw = 1;
const int radius = 10;
QImage rectImage(radius*2 + 3 + pw*2, radius*2 + 3 + pw*2, (QImage::Format)imageType);
rectImage.fill(0);
QPainter rp(&rectImage);
rp.setRenderHint(QPainter::Antialiasing);
rp.setPen(Qt::black);
rp.setBrush(Qt::red);
if (pw%2)
rp.drawRoundedRect(QRectF(qreal(pw)/2+1, qreal(pw)/2+1, rectImage.width()-(pw+1), rectImage.height()-(pw+1)), radius, radius);
else
rp.drawRoundedRect(QRectF(qreal(pw)/2, qreal(pw)/2, rectImage.width()-pw, rectImage.height()-pw), radius, radius);
QPixmap rectPixmap = rasterPixmap(rectImage);
//setup surface
QImage surface(400, 400, QImage::Format_RGB16);
surface.fill(QColor(255,255,255).rgb());
QPainter p(&surface);
QBENCHMARK {
p.setWorldTransform(transform);
const int pw = 2;
int width = 80;
int height = 80;
int xOffset = (rectPixmap.width()-1)/2;
int yOffset = (rectPixmap.height()-1)/2;
Q_ASSERT(rectPixmap.width() == 2*xOffset + 1);
Q_ASSERT(rectPixmap.height() == 2*yOffset + 1);
QMargins margins(xOffset, yOffset, xOffset, yOffset);
QTileRules rules(Qt::StretchTile, Qt::StretchTile);
qDrawBorderPixmap(&p, QRect(-pw/2, -pw/2, width+pw, height+pw), margins, rectPixmap, rectPixmap.rect(), margins, rules);
}
}
void tst_QPainter::drawTransformedTransparentImage_data()
{
QTest::addColumn<int>("imageType");
QTest::newRow("imagetype=ARGB32_Pre") << (int)QImage::Format_ARGB32_Premultiplied;
QTest::newRow("imagetype=ARGB8565_Pre") << (int)QImage::Format_ARGB8565_Premultiplied;
}
void tst_QPainter::drawTransformedTransparentImage()
{
QFETCH(int, imageType);
//setup image
QImage transImage(200, 200, (QImage::Format)imageType);
transImage.fill(0);
//setup surface
QImage surface(200, 200, QImage::Format_RGB16);
surface.fill(QColor(255,255,255).rgb());
QPainter p(&surface);
QBENCHMARK {
p.setWorldTransform(QTransform(0.956957, 0, 0.000704124, 0, 1, 0, 16.141, 0, 0.735953));
p.drawImage(0,0, transImage);
}
}
void tst_QPainter::drawTransformedSemiTransparentImage_data()
{
QTest::addColumn<int>("imageType");
QTest::newRow("imagetype=ARGB32_Pre") << (int)QImage::Format_ARGB32_Premultiplied;
QTest::newRow("imagetype=ARGB8565_Pre") << (int)QImage::Format_ARGB8565_Premultiplied;
}
void tst_QPainter::drawTransformedSemiTransparentImage()
{
QFETCH(int, imageType);
//setup image
QImage transImage(200, 200, (QImage::Format)imageType);
transImage.fill(QColor(0,0,0, 128).rgba());
//setup surface
QImage surface(200, 200, QImage::Format_RGB16);
surface.fill(QColor(255,255,255).rgb());
QPainter p(&surface);
QBENCHMARK {
p.setWorldTransform(QTransform(0.956957, 0, 0.000704124, 0, 1, 0, 16.141, 0, 0.735953));
p.drawImage(0,0, transImage);
}
}
void tst_QPainter::drawTransformedFilledImage_data()
{
QTest::addColumn<int>("imageType");
QTest::newRow("imagetype=ARGB32_Pre") << (int)QImage::Format_ARGB32_Premultiplied;
QTest::newRow("imagetype=ARGB8565_Pre") << (int)QImage::Format_ARGB8565_Premultiplied;
}
void tst_QPainter::drawTransformedFilledImage()
{
QFETCH(int, imageType);
//setup image
QImage filledImage(200, 200, (QImage::Format)imageType);
filledImage.fill(QColor(0,0,0).rgb());
//setup surface
QImage surface(200, 200, QImage::Format_RGB16);
surface.fill(QColor(255,255,255).rgb());
QPainter p(&surface);
QBENCHMARK {
p.setWorldTransform(QTransform(0.956957, 0, 0.000704124, 0, 1, 0, 16.141, 0, 0.735953));
p.drawImage(0,0, filledImage);
}
}
QTEST_MAIN(tst_QPainter)
#include "tst_qpainter.moc"