summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Kjernåsen <trond@trolltech.com>2010-02-23 09:11:03 (GMT)
committerTrond Kjernåsen <trond@trolltech.com>2010-02-23 09:11:03 (GMT)
commit58533cbc7322c4f821f24043028e47925b537419 (patch)
tree6821780e44a2a603e828b10e6c7307b06ec1e8e3
parenta948f901b196bab121cb8b5736204b4ce0c09e94 (diff)
downloadQt-58533cbc7322c4f821f24043028e47925b537419.zip
Qt-58533cbc7322c4f821f24043028e47925b537419.tar.gz
Qt-58533cbc7322c4f821f24043028e47925b537419.tar.bz2
Made the qDrawPixmaps() API public (with modifications).
QPainter has now gotten a drawPixmapFragments() function together with a Fragment class that describes how each pixmap fragment is supposed to be drawn. Reviewed-by: Gunnar Reviewed-by: Samuel
-rw-r--r--src/declarative/graphicsitems/qmlgraphicsparticles.cpp12
-rw-r--r--src/gui/painting/qdrawutil.cpp210
-rw-r--r--src/gui/painting/qdrawutil.h25
-rw-r--r--src/gui/painting/qpaintengineex.cpp19
-rw-r--r--src/gui/painting/qpaintengineex_p.h2
-rw-r--r--src/gui/painting/qpainter.cpp154
-rw-r--r--src/gui/painting/qpainter.h25
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp50
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h4
-rw-r--r--src/openvg/qpaintengine_vg.cpp24
-rw-r--r--src/openvg/qpaintengine_vg_p.h2
-rw-r--r--tests/auto/qpainter/tst_qpainter.cpp48
12 files changed, 376 insertions, 199 deletions
diff --git a/src/declarative/graphicsitems/qmlgraphicsparticles.cpp b/src/declarative/graphicsitems/qmlgraphicsparticles.cpp
index 08fce74..b71b790 100644
--- a/src/declarative/graphicsitems/qmlgraphicsparticles.cpp
+++ b/src/declarative/graphicsitems/qmlgraphicsparticles.cpp
@@ -1196,7 +1196,7 @@ void QmlGraphicsParticlesPainter::paint(QPainter *p, const QStyleOptionGraphicsI
const int myX = x() + parentItem()->x();
const int myY = y() + parentItem()->y();
- QVarLengthArray<QDrawPixmaps::Data, 256> pixmapData;
+ QVarLengthArray<QPainter::Fragment, 256> pixmapData;
pixmapData.resize(d->particles.count());
const QRectF sourceRect = d->image.rect();
@@ -1204,16 +1204,20 @@ void QmlGraphicsParticlesPainter::paint(QPainter *p, const QStyleOptionGraphicsI
qreal halfPHeight = sourceRect.height()/2.;
for (int i = 0; i < d->particles.count(); ++i) {
const QmlGraphicsParticle &particle = d->particles.at(i);
- pixmapData[i].point = QPointF(particle.x - myX + halfPWidth, particle.y - myY + halfPHeight);
+ pixmapData[i].x = particle.x - myX + halfPWidth;
+ pixmapData[i].y = particle.y - myY + halfPHeight;
pixmapData[i].opacity = particle.opacity;
//these never change
pixmapData[i].rotation = 0;
pixmapData[i].scaleX = 1;
pixmapData[i].scaleY = 1;
- pixmapData[i].source = sourceRect;
+ pixmapData[i].sourceLeft = sourceRect.left();
+ pixmapData[i].sourceTop = sourceRect.top();
+ pixmapData[i].width = sourceRect.width();
+ pixmapData[i].height = sourceRect.height();
}
- qDrawPixmaps(p, pixmapData.data(), d->particles.count(), d->image);
+ p->drawPixmapFragments(pixmapData.data(), d->particles.count(), d->image);
}
void QmlGraphicsParticles::componentComplete()
diff --git a/src/gui/painting/qdrawutil.cpp b/src/gui/painting/qdrawutil.cpp
index 5619a2e..d76c709 100644
--- a/src/gui/painting/qdrawutil.cpp
+++ b/src/gui/painting/qdrawutil.cpp
@@ -1081,7 +1081,7 @@ void qDrawItem(QPainter *p, Qt::GUIStyle gs,
according to the \a margins structure.
*/
-typedef QVarLengthArray<QDrawPixmaps::Data, 16> QDrawPixmapsDataArray;
+typedef QVarLengthArray<QPainter::Fragment, 16> QPixmapFragmentsArray;
/*!
\since 4.6
@@ -1102,12 +1102,12 @@ void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargin
const QPixmap &pixmap, const QRect &sourceRect,const QMargins &sourceMargins,
const QTileRules &rules, QDrawBorderPixmap::DrawingHints hints)
{
- QDrawPixmaps::Data d;
+ QPainter::Fragment d;
d.opacity = 1.0;
d.rotation = 0.0;
- QDrawPixmapsDataArray opaqueData;
- QDrawPixmapsDataArray translucentData;
+ QPixmapFragmentsArray opaqueData;
+ QPixmapFragmentsArray translucentData;
// source center
const int sourceCenterTop = sourceRect.top() + sourceMargins.top();
@@ -1182,44 +1182,56 @@ void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargin
// corners
if (targetMargins.top() > 0 && targetMargins.left() > 0 && sourceMargins.top() > 0 && sourceMargins.left() > 0) { // top left
- d.point.setX(0.5 * (xTarget[1] + xTarget[0]));
- d.point.setY(0.5 * (yTarget[1] + yTarget[0]));
- d.source = QRectF(sourceRect.left(), sourceRect.top(), sourceMargins.left(), sourceMargins.top());
- d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.source.width();
- d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.source.height();
+ d.x = (0.5 * (xTarget[1] + xTarget[0]));
+ d.y = (0.5 * (yTarget[1] + yTarget[0]));
+ d.sourceLeft = sourceRect.left();
+ d.sourceTop = sourceRect.top();
+ d.width = sourceMargins.left();
+ d.height = sourceMargins.top();
+ d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width;
+ d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height;
if (hints & QDrawBorderPixmap::OpaqueTopLeft)
opaqueData.append(d);
else
translucentData.append(d);
}
if (targetMargins.top() > 0 && targetMargins.right() > 0 && sourceMargins.top() > 0 && sourceMargins.right() > 0) { // top right
- d.point.setX(0.5 * (xTarget[columns] + xTarget[columns - 1]));
- d.point.setY(0.5 * (yTarget[1] + yTarget[0]));
- d.source = QRectF(sourceCenterRight, sourceRect.top(), sourceMargins.right(), sourceMargins.top());
- d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.source.width();
- d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.source.height();
+ d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1]));
+ d.y = (0.5 * (yTarget[1] + yTarget[0]));
+ d.sourceLeft = sourceCenterRight;
+ d.sourceTop = sourceRect.top();
+ d.width = sourceMargins.right();
+ d.height = sourceMargins.top();
+ d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width;
+ d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height;
if (hints & QDrawBorderPixmap::OpaqueTopRight)
opaqueData.append(d);
else
translucentData.append(d);
}
if (targetMargins.bottom() > 0 && targetMargins.left() > 0 && sourceMargins.bottom() > 0 && sourceMargins.left() > 0) { // bottom left
- d.point.setX(0.5 * (xTarget[1] + xTarget[0]));
- d.point.setY(0.5 * (yTarget[rows] + yTarget[rows - 1]));
- d.source = QRectF(sourceRect.left(), sourceCenterBottom, sourceMargins.left(), sourceMargins.bottom());
- d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.source.width();
- d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.source.height();
+ d.x = (0.5 * (xTarget[1] + xTarget[0]));
+ d.y =(0.5 * (yTarget[rows] + yTarget[rows - 1]));
+ d.sourceLeft = sourceRect.left();
+ d.sourceTop = sourceCenterBottom;
+ d.width = sourceMargins.left();
+ d.height = sourceMargins.bottom();
+ d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width;
+ d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height;
if (hints & QDrawBorderPixmap::OpaqueBottomLeft)
opaqueData.append(d);
else
translucentData.append(d);
}
if (targetMargins.bottom() > 0 && targetMargins.right() > 0 && sourceMargins.bottom() > 0 && sourceMargins.right() > 0) { // bottom right
- d.point.setX(0.5 * (xTarget[columns] + xTarget[columns - 1]));
- d.point.setY(0.5 * (yTarget[rows] + yTarget[rows - 1]));
- d.source = QRectF(sourceCenterRight, sourceCenterBottom, sourceMargins.right(), sourceMargins.bottom());
- d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.source.width();
- d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.source.height();
+ d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1]));
+ d.y = (0.5 * (yTarget[rows] + yTarget[rows - 1]));
+ d.sourceLeft = sourceCenterRight;
+ d.sourceTop = sourceCenterBottom;
+ d.width = sourceMargins.right();
+ d.height = sourceMargins.bottom();
+ d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width;
+ d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height;
if (hints & QDrawBorderPixmap::OpaqueBottomRight)
opaqueData.append(d);
else
@@ -1229,151 +1241,107 @@ void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargin
// horizontal edges
if (targetCenterWidth > 0 && sourceCenterWidth > 0) {
if (targetMargins.top() > 0 && sourceMargins.top() > 0) { // top
- QDrawPixmapsDataArray &data = hints & QDrawBorderPixmap::OpaqueTop ? opaqueData : translucentData;
- d.source = QRectF(sourceCenterLeft, sourceRect.top(), sourceCenterWidth, sourceMargins.top());
- d.point.setY(0.5 * (yTarget[1] + yTarget[0]));
- d.scaleX = dx / d.source.width();
- d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.source.height();
+ QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueTop ? opaqueData : translucentData;
+ d.sourceLeft = sourceCenterLeft;
+ d.sourceTop = sourceRect.top();
+ d.width = sourceCenterWidth;
+ d.height = sourceMargins.top();
+ d.y = (0.5 * (yTarget[1] + yTarget[0]));
+ d.scaleX = dx / d.width;
+ d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height;
for (int i = 1; i < columns - 1; ++i) {
- d.point.setX(0.5 * (xTarget[i + 1] + xTarget[i]));
+ d.x = (0.5 * (xTarget[i + 1] + xTarget[i]));
data.append(d);
}
if (rules.horizontal == Qt::RepeatTile)
- data[data.size() - 1].source.setWidth((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX);
+ data[data.size() - 1].width = ((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX);
}
if (targetMargins.bottom() > 0 && sourceMargins.bottom() > 0) { // bottom
- QDrawPixmapsDataArray &data = hints & QDrawBorderPixmap::OpaqueBottom ? opaqueData : translucentData;
- d.source = QRectF(sourceCenterLeft, sourceCenterBottom, sourceCenterWidth, sourceMargins.bottom());;
- d.point.setY(0.5 * (yTarget[rows] + yTarget[rows - 1]));
- d.scaleX = dx / d.source.width();
- d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.source.height();
+ QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueBottom ? opaqueData : translucentData;
+ d.sourceLeft = sourceCenterLeft;
+ d.sourceTop = sourceCenterBottom;
+ d.width = sourceCenterWidth;
+ d.height = sourceMargins.bottom();
+ d.y = (0.5 * (yTarget[rows] + yTarget[rows - 1]));
+ d.scaleX = dx / d.width;
+ d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height;
for (int i = 1; i < columns - 1; ++i) {
- d.point.setX(0.5 * (xTarget[i + 1] + xTarget[i]));
+ d.x = (0.5 * (xTarget[i + 1] + xTarget[i]));
data.append(d);
}
if (rules.horizontal == Qt::RepeatTile)
- data[data.size() - 1].source.setWidth((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX);
+ data[data.size() - 1].width = ((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX);
}
}
// vertical edges
if (targetCenterHeight > 0 && sourceCenterHeight > 0) {
if (targetMargins.left() > 0 && sourceMargins.left() > 0) { // left
- QDrawPixmapsDataArray &data = hints & QDrawBorderPixmap::OpaqueLeft ? opaqueData : translucentData;
- d.source = QRectF(sourceRect.left(), sourceCenterTop, sourceMargins.left(), sourceCenterHeight);
- d.point.setX(0.5 * (xTarget[1] + xTarget[0]));
- d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.source.width();
- d.scaleY = dy / d.source.height();
+ QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueLeft ? opaqueData : translucentData;
+ d.sourceLeft = sourceRect.left();
+ d.sourceTop = sourceCenterTop;
+ d.width = sourceMargins.left();
+ d.height = sourceCenterHeight;
+ d.x = (0.5 * (xTarget[1] + xTarget[0]));
+ d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width;
+ d.scaleY = dy / d.height;
for (int i = 1; i < rows - 1; ++i) {
- d.point.setY(0.5 * (yTarget[i + 1] + yTarget[i]));
+ d.y = (0.5 * (yTarget[i + 1] + yTarget[i]));
data.append(d);
}
if (rules.vertical == Qt::RepeatTile)
- data[data.size() - 1].source.setHeight((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY);
+ data[data.size() - 1].height = ((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY);
}
if (targetMargins.right() > 0 && sourceMargins.right() > 0) { // right
- QDrawPixmapsDataArray &data = hints & QDrawBorderPixmap::OpaqueRight ? opaqueData : translucentData;
- d.source = QRectF(sourceCenterRight, sourceCenterTop, sourceMargins.right(), sourceCenterHeight);
- d.point.setX(0.5 * (xTarget[columns] + xTarget[columns - 1]));
- d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.source.width();
- d.scaleY = dy / d.source.height();
+ QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueRight ? opaqueData : translucentData;
+ d.sourceLeft = sourceCenterRight;
+ d.sourceTop = sourceCenterTop;
+ d.width = sourceMargins.right();
+ d.height = sourceCenterHeight;
+ d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1]));
+ d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width;
+ d.scaleY = dy / d.height;
for (int i = 1; i < rows - 1; ++i) {
- d.point.setY(0.5 * (yTarget[i + 1] + yTarget[i]));
+ d.y = (0.5 * (yTarget[i + 1] + yTarget[i]));
data.append(d);
}
if (rules.vertical == Qt::RepeatTile)
- data[data.size() - 1].source.setHeight((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY);
+ data[data.size() - 1].height = ((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY);
}
}
// center
if (targetCenterWidth > 0 && targetCenterHeight > 0 && sourceCenterWidth > 0 && sourceCenterHeight > 0) {
- QDrawPixmapsDataArray &data = hints & QDrawBorderPixmap::OpaqueCenter ? opaqueData : translucentData;
- d.source = QRectF(sourceCenterLeft, sourceCenterTop, sourceCenterWidth, sourceCenterHeight);
- d.scaleX = dx / d.source.width();
- d.scaleY = dy / d.source.height();
+ QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueCenter ? opaqueData : translucentData;
+ d.sourceLeft = sourceCenterLeft;
+ d.sourceTop = sourceCenterTop;
+ d.width = sourceCenterWidth;
+ d.height = sourceCenterHeight;
+ d.scaleX = dx / d.width;
+ d.scaleY = dy / d.height;
qreal repeatWidth = (xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX;
qreal repeatHeight = (yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY;
for (int j = 1; j < rows - 1; ++j) {
- d.point.setY(0.5 * (yTarget[j + 1] + yTarget[j]));
+ d.y = (0.5 * (yTarget[j + 1] + yTarget[j]));
for (int i = 1; i < columns - 1; ++i) {
- d.point.setX(0.5 * (xTarget[i + 1] + xTarget[i]));
+ d.x = (0.5 * (xTarget[i + 1] + xTarget[i]));
data.append(d);
}
if (rules.horizontal == Qt::RepeatTile)
- data[data.size() - 1].source.setWidth(repeatWidth);
+ data[data.size() - 1].width = repeatWidth;
}
if (rules.vertical == Qt::RepeatTile) {
for (int i = 1; i < columns - 1; ++i)
- data[data.size() - i].source.setHeight(repeatHeight);
+ data[data.size() - i].height = repeatHeight;
}
}
if (opaqueData.size())
- qDrawPixmaps(painter, opaqueData.data(), opaqueData.size(), pixmap, QDrawPixmaps::OpaqueHint);
+ painter->drawPixmapFragments(opaqueData.data(), opaqueData.size(), pixmap, QPainter::OpaqueHint);
if (translucentData.size())
- qDrawPixmaps(painter, translucentData.data(), translucentData.size(), pixmap);
-}
-
-/*!
- \class QDrawPixmaps::Data
- \since 4.6
- \internal
-
- This structure is used with the qDrawPixmaps() function.
-
- QPointF point: Specifies the center of the target rectangle.
- QRectF source: Specifies the source rectangle in the pixmap passed into the qDrawPixmaps() call.
- qreal scaleX: Specifies the horizontal scale of the target rectangle.
- qreal scaleY: Specifies the vertical scale of the target rectangle.
- qreal rotation: Specifies the rotation of the target rectangle in degrees.
- The target rectangle is rotated after scaling.
- qreal opacity: Specifies the opacity of the rectangle.
-*/
-
-/*!
- \enum QDrawPixmaps::DrawingHint
- \internal
-*/
-
-/*!
- \internal
- \since 4.6
-
- This function is used to draw \a pixmap, or a sub-rectangle of \a pixmap, at multiple positions
- with different scale, rotation and opacity on \a painter. \a drawingData is an array of \a
- dataCount elements specifying the parameters used to draw each pixmap instance.
- This can be used for example to implement a particle system.
-*/
-void qDrawPixmaps(QPainter *painter, const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints hints)
-{
- QPaintEngine *engine = painter->paintEngine();
- if (!engine)
- return;
-
- if (engine->isExtended()) {
- static_cast<QPaintEngineEx *>(engine)->drawPixmaps(drawingData, dataCount, pixmap, hints);
- } else {
- qreal oldOpacity = painter->opacity();
- QTransform oldTransform = painter->transform();
-
- for (int i = 0; i < dataCount; ++i) {
- QTransform transform = oldTransform;
- transform.translate(drawingData[i].point.x(), drawingData[i].point.y());
- transform.rotate(drawingData[i].rotation);
- painter->setOpacity(oldOpacity * drawingData[i].opacity);
- painter->setTransform(transform);
-
- qreal w = drawingData[i].scaleX * drawingData[i].source.width();
- qreal h = drawingData[i].scaleY * drawingData[i].source.height();
- painter->drawPixmap(QRectF(-0.5 * w, -0.5 * h, w, h), pixmap, drawingData[i].source);
- }
-
- painter->setOpacity(oldOpacity);
- painter->setTransform(oldTransform);
- }
+ painter->drawPixmapFragments(translucentData.data(), translucentData.size(), pixmap);
}
QT_END_NAMESPACE
diff --git a/src/gui/painting/qdrawutil.h b/src/gui/painting/qdrawutil.h
index 2801b2f..31e352f 100644
--- a/src/gui/painting/qdrawutil.h
+++ b/src/gui/painting/qdrawutil.h
@@ -188,31 +188,6 @@ inline void qDrawBorderPixmap(QPainter *painter,
qDrawBorderPixmap(painter, target, margins, pixmap, pixmap.rect(), margins);
}
-// For internal use only.
-namespace QDrawPixmaps
-{
- struct Data
- {
- QPointF point;
- QRectF source;
- qreal scaleX;
- qreal scaleY;
- qreal rotation;
- qreal opacity;
- };
-
- enum DrawingHint
- {
- OpaqueHint = 0x01
- };
-
- Q_DECLARE_FLAGS(DrawingHints, DrawingHint)
-}
-
-// This function is private and may change without notice. Do not use outside Qt!!!
-Q_GUI_EXPORT void qDrawPixmaps(QPainter *painter, const QDrawPixmaps::Data *drawingData,
- int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints hints = 0);
-
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
index 4f2fffa..ad486ba 100644
--- a/src/gui/painting/qpaintengineex.cpp
+++ b/src/gui/painting/qpaintengineex.cpp
@@ -970,23 +970,26 @@ void QPaintEngineEx::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, con
fill(path, brush);
}
-void QPaintEngineEx::drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints /*hints*/)
+void QPaintEngineEx::drawPixmapFragments(const QPainter::Fragment *fragments, int fragmentCount,
+ const QPixmap &pixmap, QPainter::FragmentHints /*hints*/)
{
qreal oldOpacity = state()->opacity;
QTransform oldTransform = state()->matrix;
- for (int i = 0; i < dataCount; ++i) {
+ for (int i = 0; i < fragmentCount; ++i) {
QTransform transform = oldTransform;
- transform.translate(drawingData[i].point.x(), drawingData[i].point.y());
- transform.rotate(drawingData[i].rotation);
- state()->opacity = oldOpacity * drawingData[i].opacity;
+ transform.translate(fragments[i].x, fragments[i].y);
+ transform.rotate(fragments[i].rotation);
+ state()->opacity = oldOpacity * fragments[i].opacity;
state()->matrix = transform;
opacityChanged();
transformChanged();
- qreal w = drawingData[i].scaleX * drawingData[i].source.width();
- qreal h = drawingData[i].scaleY * drawingData[i].source.height();
- drawPixmap(QRectF(-0.5 * w, -0.5 * h, w, h), pixmap, drawingData[i].source);
+ qreal w = fragments[i].scaleX * fragments[i].width;
+ qreal h = fragments[i].scaleY * fragments[i].height;
+ QRectF sourceRect(fragments[i].sourceLeft, fragments[i].sourceTop,
+ fragments[i].width, fragments[i].height);
+ drawPixmap(QRectF(-0.5 * w, -0.5 * h, w, h), pixmap, sourceRect);
}
state()->opacity = oldOpacity;
diff --git a/src/gui/painting/qpaintengineex_p.h b/src/gui/painting/qpaintengineex_p.h
index 90c4f9f..2401b94 100644
--- a/src/gui/painting/qpaintengineex_p.h
+++ b/src/gui/painting/qpaintengineex_p.h
@@ -197,7 +197,7 @@ public:
virtual void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s);
- virtual void drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QFlags<QDrawPixmaps::DrawingHint> hints);
+ virtual void drawPixmapFragments(const QPainter::Fragment *fragments, int fragmentCount, const QPixmap &pixmap, QFlags<QPainter::FragmentHint> hints);
virtual void updateState(const QPaintEngineState &state);
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index e69512d..6f5c732 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -8846,6 +8846,160 @@ QTransform QPainter::combinedTransform() const
return d->state->worldMatrix * d->viewTransform();
}
+/*!
+ \since 4.7
+
+ This function is used to draw \a pixmap, or a sub-rectangle of \a pixmap,
+ at multiple positions with different scale, rotation and opacity. \a
+ fragments is an array of \a fragmentCount elements specifying the
+ parameters used to draw each pixmap fragment. The \a hints
+ parameter can be used to pass in drawing hints.
+
+ This function is potentially faster than multiple calls to drawPixmap(),
+ since the backend can optimize state changes.
+
+ \sa QPainter::Fragment, QPainter::FragmentHint
+*/
+
+void QPainter::drawPixmapFragments(const Fragment *fragments, int fragmentCount,
+ const QPixmap &pixmap, FragmentHints hints)
+{
+ Q_D(QPainter);
+
+ if (!d->engine)
+ return;
+
+ if (d->engine->isExtended()) {
+ d->extended->drawPixmapFragments(fragments, fragmentCount, pixmap, hints);
+ } else {
+ qreal oldOpacity = opacity();
+ QTransform oldTransform = transform();
+
+ for (int i = 0; i < fragmentCount; ++i) {
+ QTransform transform = oldTransform;
+ transform.translate(fragments[i].x, fragments[i].y);
+ transform.rotate(fragments[i].rotation);
+ setOpacity(oldOpacity * fragments[i].opacity);
+ setTransform(transform);
+
+ qreal w = fragments[i].scaleX * fragments[i].width;
+ qreal h = fragments[i].scaleY * fragments[i].height;
+ QRectF sourceRect(fragments[i].sourceLeft, fragments[i].sourceTop,
+ fragments[i].width, fragments[i].height);
+ drawPixmap(QRectF(-0.5 * w, -0.5 * h, w, h), pixmap, sourceRect);
+ }
+
+ setOpacity(oldOpacity);
+ setTransform(oldTransform);
+ }
+}
+
+/*!
+ \since 4.7
+ \class QPainter::Fragment
+
+ \brief This class is used in conjunction with the
+ QPainter::drawPixmapFragments() function to specify how a pixmap, or
+ sub-rect of a pixmap, is drawn.
+
+ The \a sourceLeft, \a sourceTop, \a width and \a height variables are used
+ as a source rectangle within the pixmap passed into the
+ QPainter::drawPixmapFragments() function. The variables \a x, \a y, \a
+ width and \a height are used to calculate the target rectangle that is
+ drawn. \a x and \a y denotes the center of the target rectangle. The \a
+ width and \a heigth in the target rectangle is scaled by the \a scaleX and
+ \a scaleY values. The resulting target rectangle is then rotated \a
+ rotation degrees around the \a x, \a y center point.
+
+ \sa QPainter::drawPixmapFragments()
+*/
+
+/*!
+ \since 4.7
+
+ This is a convenience function that returns a QPainter::Fragment that is
+ initialized with the \a pos, \a sourceRect, \a scaleX, \a scaleY, \a
+ rotation, \a opacity parameters.
+*/
+
+QPainter::Fragment QPainter::Fragment::create(const QPointF &pos, const QRectF &sourceRect,
+ qreal scaleX, qreal scaleY, qreal rotation,
+ qreal opacity)
+{
+ Fragment fragment = {pos.x(), pos.y(), sourceRect.x(), sourceRect.y(), sourceRect.width(),
+ sourceRect.height(), scaleX, scaleY, rotation, opacity};
+ return fragment;
+}
+
+/*!
+ \variable QPainter::Fragment::x
+ \brief the x coordinate of center point in the target rectangle.
+*/
+
+/*!
+ \variable QPainter::Fragment::y
+ \brief the y coordinate of the center point in the target rectangle.
+*/
+
+/*!
+ \variable QPainter::Fragment::sourceLeft
+ \brief the left coordinate of the source rectangle.
+*/
+
+/*!
+ \variable QPainter::Fragment::sourceTop
+ \brief the top coordinate of the source rectangle.
+*/
+
+/*!
+ \variable QPainter::Fragment::width
+
+ \brief the width of the source rectangle and is used to calculate the width
+ of the target rectangle.
+*/
+
+/*!
+ \variable QPainter::Fragment::height
+
+ \brief the height of the source rectangle and is used to calculate the
+ height of the target rectangle.
+*/
+
+/*!
+ \variable QPainter::Fragment::scaleX
+ \brief the horizontal scale of the target rectangle.
+*/
+
+/*!
+ \variable QPainter::Fragment::scaleY
+ \brief the vertical scale of the target rectangle.
+*/
+
+/*!
+ \variable QPainter::Fragment::rotation
+
+ \brief the rotation of the target rectangle in degrees. The target
+ rectangle is rotated after it has been scaled.
+*/
+
+/*!
+ \variable QPainter::Fragment::opacity
+
+ \brief the opacity of the target rectangle, where 0.0 is fully transparent
+ and 1.0 is fully opaque.
+*/
+
+/*!
+ \since 4.7
+
+ \enum QPainter::FragmentHint
+
+ \value OpaqueHint Indicates that the pixmap fragments to be drawn are
+ opaque. Opaque fragments are potentially faster to draw.
+
+ \sa QPainter::drawPixmapFragments(), QPainter::Fragment
+*/
+
void qt_draw_helper(QPainterPrivate *p, const QPainterPath &path, QPainterPrivate::DrawOperation operation)
{
p->draw_helper(path, operation);
diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h
index e9fd532..4d52c5d 100644
--- a/src/gui/painting/qpainter.h
+++ b/src/gui/painting/qpainter.h
@@ -99,6 +99,28 @@ public:
Q_DECLARE_FLAGS(RenderHints, RenderHint)
+ class Fragment {
+ public:
+ qreal x;
+ qreal y;
+ qreal sourceLeft;
+ qreal sourceTop;
+ qreal width;
+ qreal height;
+ qreal scaleX;
+ qreal scaleY;
+ qreal rotation;
+ qreal opacity;
+ static Fragment create(const QPointF &pos, const QRectF &sourceRect, qreal scaleX = 1,
+ qreal scaleY = 1, qreal rotation = 0, qreal opacity = 1);
+ };
+
+ enum FragmentHint {
+ OpaqueHint = 0x01
+ };
+
+ Q_DECLARE_FLAGS(FragmentHints, FragmentHint)
+
QPainter();
explicit QPainter(QPaintDevice *);
~QPainter();
@@ -352,6 +374,9 @@ public:
inline void drawPixmap(const QRect &r, const QPixmap &pm);
inline void drawPixmap(int x, int y, int w, int h, const QPixmap &pm);
+ void drawPixmapFragments(const Fragment *fragments, int fragmentCount,
+ const QPixmap &pixmap, FragmentHints hints = 0);
+
void drawImage(const QRectF &targetRect, const QImage &image, const QRectF &sourceRect,
Qt::ImageConversionFlags flags = Qt::AutoColor);
inline void drawImage(const QRect &targetRect, const QImage &image, const QRect &sourceRect,
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index ea464d5..a967e96 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -1642,21 +1642,23 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp
s->matrix = old;
}
-void QGL2PaintEngineEx::drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints hints)
+void QGL2PaintEngineEx::drawPixmapFragments(const QPainter::Fragment *fragments, int fragmentCount, const QPixmap &pixmap, QPainter::FragmentHints hints)
{
Q_D(QGL2PaintEngineEx);
// Use fallback for extended composition modes.
if (state()->composition_mode > QPainter::CompositionMode_Plus) {
- QPaintEngineEx::drawPixmaps(drawingData, dataCount, pixmap, hints);
+ QPaintEngineEx::drawPixmapFragments(fragments, fragmentCount, pixmap, hints);
return;
}
ensureActive();
- d->drawPixmaps(drawingData, dataCount, pixmap, hints);
+ d->drawPixmapFragments(fragments, fragmentCount, pixmap, hints);
}
-void QGL2PaintEngineExPrivate::drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints hints)
+void QGL2PaintEngineExPrivate::drawPixmapFragments(const QPainter::Fragment *fragments,
+ int fragmentCount, const QPixmap &pixmap,
+ QPainter::FragmentHints hints)
{
GLfloat dx = 1.0f / pixmap.size().width();
GLfloat dy = 1.0f / pixmap.size().height();
@@ -1677,28 +1679,29 @@ void QGL2PaintEngineExPrivate::drawPixmaps(const QDrawPixmaps::Data *drawingData
bool allOpaque = true;
- for (int i = 0; i < dataCount; ++i) {
+ for (int i = 0; i < fragmentCount; ++i) {
qreal s = 0;
qreal c = 1;
- if (drawingData[i].rotation != 0) {
- s = qFastSin(drawingData[i].rotation * Q_PI / 180);
- c = qFastCos(drawingData[i].rotation * Q_PI / 180);
+ if (fragments[i].rotation != 0) {
+ s = qFastSin(fragments[i].rotation * Q_PI / 180);
+ c = qFastCos(fragments[i].rotation * Q_PI / 180);
}
- qreal right = 0.5 * drawingData[i].scaleX * drawingData[i].source.width();
- qreal bottom = 0.5 * drawingData[i].scaleY * drawingData[i].source.height();
+ qreal right = 0.5 * fragments[i].scaleX * fragments[i].width;
+ qreal bottom = 0.5 * fragments[i].scaleY * fragments[i].height;
QGLPoint bottomRight(right * c - bottom * s, right * s + bottom * c);
QGLPoint bottomLeft(-right * c - bottom * s, -right * s + bottom * c);
- vertexCoordinateArray.lineToArray(bottomRight.x + drawingData[i].point.x(), bottomRight.y + drawingData[i].point.y());
- vertexCoordinateArray.lineToArray(-bottomLeft.x + drawingData[i].point.x(), -bottomLeft.y + drawingData[i].point.y());
- vertexCoordinateArray.lineToArray(-bottomRight.x + drawingData[i].point.x(), -bottomRight.y + drawingData[i].point.y());
- vertexCoordinateArray.lineToArray(-bottomRight.x + drawingData[i].point.x(), -bottomRight.y + drawingData[i].point.y());
- vertexCoordinateArray.lineToArray(bottomLeft.x + drawingData[i].point.x(), bottomLeft.y + drawingData[i].point.y());
- vertexCoordinateArray.lineToArray(bottomRight.x + drawingData[i].point.x(), bottomRight.y + drawingData[i].point.y());
+ vertexCoordinateArray.lineToArray(bottomRight.x + fragments[i].x, bottomRight.y + fragments[i].y);
+ vertexCoordinateArray.lineToArray(-bottomLeft.x + fragments[i].x, -bottomLeft.y + fragments[i].y);
+ vertexCoordinateArray.lineToArray(-bottomRight.x + fragments[i].x, -bottomRight.y + fragments[i].y);
+ vertexCoordinateArray.lineToArray(-bottomRight.x + fragments[i].x, -bottomRight.y + fragments[i].y);
+ vertexCoordinateArray.lineToArray(bottomLeft.x + fragments[i].x, bottomLeft.y + fragments[i].y);
+ vertexCoordinateArray.lineToArray(bottomRight.x + fragments[i].x, bottomRight.y + fragments[i].y);
- QGLRect src(drawingData[i].source.left() * dx, drawingData[i].source.top() * dy,
- drawingData[i].source.right() * dx, drawingData[i].source.bottom() * dy);
+ QGLRect src(fragments[i].sourceLeft * dx, fragments[i].sourceTop * dy,
+ (fragments[i].sourceLeft + fragments[i].width) * dx,
+ (fragments[i].sourceTop + fragments[i].height) * dy);
textureCoordinateArray.lineToArray(src.right, src.bottom);
textureCoordinateArray.lineToArray(src.right, src.top);
@@ -1707,7 +1710,7 @@ void QGL2PaintEngineExPrivate::drawPixmaps(const QDrawPixmaps::Data *drawingData
textureCoordinateArray.lineToArray(src.left, src.bottom);
textureCoordinateArray.lineToArray(src.right, src.bottom);
- qreal opacity = drawingData[i].opacity * q->state()->opacity;
+ qreal opacity = fragments[i].opacity * q->state()->opacity;
opacityArray << opacity << opacity << opacity << opacity << opacity << opacity;
allOpaque &= (opacity >= 0.99f);
}
@@ -1720,21 +1723,22 @@ void QGL2PaintEngineExPrivate::drawPixmaps(const QDrawPixmaps::Data *drawingData
if (texture->options & QGLContext::InvertedYBindOption) {
// Flip texture y-coordinate.
QGLPoint *data = textureCoordinateArray.data();
- for (int i = 0; i < 6 * dataCount; ++i)
+ for (int i = 0; i < 6 * fragmentCount; ++i)
data[i].y = 1 - data[i].y;
}
transferMode(ImageArrayDrawingMode);
bool isBitmap = pixmap.isQBitmap();
- bool isOpaque = !isBitmap && (!pixmap.hasAlphaChannel() || (hints & QDrawPixmaps::OpaqueHint)) && allOpaque;
+ bool isOpaque = !isBitmap && (!pixmap.hasAlphaChannel() || (hints & QPainter::OpaqueHint)) && allOpaque;
updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
q->state()->renderHints & QPainter::SmoothPixmapTransform, texture->id);
// Setup for texture drawing
currentBrush = noBrush;
- shaderManager->setSrcPixelType(isBitmap ? QGLEngineShaderManager::PatternSrc : QGLEngineShaderManager::ImageSrc);
+ shaderManager->setSrcPixelType(isBitmap ? QGLEngineShaderManager::PatternSrc
+ : QGLEngineShaderManager::ImageSrc);
if (prepareForDraw(isOpaque))
shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::ImageTexture), QT_IMAGE_TEXTURE_UNIT);
@@ -1743,7 +1747,7 @@ void QGL2PaintEngineExPrivate::drawPixmaps(const QDrawPixmaps::Data *drawingData
shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::PatternColor), col);
}
- glDrawArrays(GL_TRIANGLES, 0, 6 * dataCount);
+ glDrawArrays(GL_TRIANGLES, 0, 6 * fragmentCount);
}
bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
index d4932be..5d3608b 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
@@ -125,7 +125,7 @@ public:
virtual void drawTexture(const QRectF &r, GLuint textureId, const QSize &size, const QRectF &sr);
virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
- virtual void drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints hints);
+ virtual void drawPixmapFragments(const QPainter::Fragment *fragments, int fragmentCount, const QPixmap &pixmap, QPainter::FragmentHints hints);
virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
Qt::ImageConversionFlags flags = Qt::AutoColor);
virtual void drawTextItem(const QPointF &p, const QTextItem &textItem);
@@ -196,7 +196,7 @@ public:
void fill(const QVectorPath &path);
void stroke(const QVectorPath &path, const QPen &pen);
void drawTexture(const QGLRect& dest, const QGLRect& src, const QSize &textureSize, bool opaque, bool pattern = false);
- void drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints hints);
+ void drawPixmapFragments(const QPainter::Fragment *fragments, int fragmentCount, const QPixmap &pixmap, QPainter::FragmentHints hints);
void drawCachedGlyphs(QFontEngineGlyphCache::Type glyphType, QStaticTextItem *staticTextItem,
bool includeMatrixInCache);
diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp
index 62f0293..24f678b 100644
--- a/src/openvg/qpaintengine_vg.cpp
+++ b/src/openvg/qpaintengine_vg.cpp
@@ -93,7 +93,7 @@ public:
VGFont font;
VGfloat scaleX;
VGfloat scaleY;
-
+
uint cachedGlyphsMask[256 / 32];
QSet<glyph_t> cachedGlyphs;
};
@@ -3035,9 +3035,8 @@ void QVGPaintEngine::drawTiledPixmap
// (i.e. no opacity), no rotation or scaling, and drawing the full
// pixmap rather than parts of the pixmap. Even having just one of
// these conditions will improve performance.
-void QVGPaintEngine::drawPixmaps
- (const QDrawPixmaps::Data *drawingData, int dataCount,
- const QPixmap &pixmap, QFlags<QDrawPixmaps::DrawingHint> hints)
+void QVGPaintEngine::drawPixmapFragments(const QPainter::Fragment *drawingData, int dataCount,
+ const QPixmap &pixmap, QFlags<QPainter::FragmentHint> hints)
{
#if !defined(QT_SHIVAVG)
Q_D(QVGPaintEngine);
@@ -3048,7 +3047,7 @@ void QVGPaintEngine::drawPixmaps
if (!pd)
return; // null QPixmap
if (pd->classId() != QPixmapData::OpenVGClass || !d->simpleTransform) {
- QPaintEngineEx::drawPixmaps(drawingData, dataCount, pixmap, hints);
+ QPaintEngineEx::drawPixmapFragments(drawingData, dataCount, pixmap, hints);
return;
}
@@ -3072,7 +3071,7 @@ void QVGPaintEngine::drawPixmaps
QVarLengthArray<QRect> cachedSources;
// Select the opacity paint object.
- if ((hints & QDrawPixmaps::OpaqueHint) != 0 && d->opacity == 1.0f) {
+ if ((hints & QPainter::OpaqueHint) != 0 && d->opacity == 1.0f) {
d->setImageMode(VG_DRAW_IMAGE_NORMAL);
} else {
hints = 0;
@@ -3089,7 +3088,8 @@ void QVGPaintEngine::drawPixmaps
VGImage child;
QSize imageSize = vgpd->size();
- QRectF sr = drawingData[i].source;
+ QRectF sr(drawingData[i].sourceLeft, drawingData[i].sourceTop,
+ drawingData[i].width, drawingData[i].height);
if (sr.topLeft().isNull() && sr.size() == imageSize) {
child = vgImg;
} else {
@@ -3118,7 +3118,7 @@ void QVGPaintEngine::drawPixmaps
transform.scale(scaleX, scaleY);
d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform);
- if ((hints & QDrawPixmaps::OpaqueHint) == 0) {
+ if ((hints & QPainter::OpaqueHint) == 0) {
qreal opacity = d->opacity * drawingData[i].opacity;
if (opacity != 1.0f) {
if (d->paintOpacity != opacity) {
@@ -3144,7 +3144,7 @@ void QVGPaintEngine::drawPixmaps
for (int i = 0; i < cachedImages.size(); ++i)
vgDestroyImage(cachedImages[i]);
#else
- QPaintEngineEx::drawPixmaps(drawingData, dataCount, pixmap, hints);
+ QPaintEngineEx::drawPixmapFragments(drawingData, dataCount, pixmap, hints);
#endif
}
@@ -3274,7 +3274,7 @@ void QVGPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
QPaintEngineEx::drawTextItem(p, textItem);
return;
}
-
+
// Get the glyphs and positions associated with the text item.
QVarLengthArray<QFixedPoint> positions;
QVarLengthArray<glyph_t> glyphs;
@@ -3284,7 +3284,7 @@ void QVGPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
(ti.glyphs, matrix, ti.flags, glyphs, positions);
if (!drawCachedGlyphs(glyphs.size(), glyphs.data(), ti.font(), ti.fontEngine, p))
- QPaintEngineEx::drawTextItem(p, textItem);
+ QPaintEngineEx::drawTextItem(p, textItem);
#else
// OpenGL 1.0 does not have support for VGFont and glyphs,
// so fall back to the default Qt path stroking algorithm.
@@ -3312,7 +3312,7 @@ void QVGPaintEngine::drawStaticTextItem(QStaticTextItem *textItem)
glyphCache = new QVGFontGlyphCache();
if (glyphCache->font == VG_INVALID_HANDLE) {
qWarning("QVGPaintEngine::drawTextItem: OpenVG fonts are not supported by the OpenVG engine");
- delete glyphCache;
+ delete glyphCache;
return false;
}
glyphCache->setScaleFromText(font, fontEngine);
diff --git a/src/openvg/qpaintengine_vg_p.h b/src/openvg/qpaintengine_vg_p.h
index 3f73fed..1203af5 100644
--- a/src/openvg/qpaintengine_vg_p.h
+++ b/src/openvg/qpaintengine_vg_p.h
@@ -137,7 +137,7 @@ public:
void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s);
- void drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QFlags<QDrawPixmaps::DrawingHint> hints);
+ void drawPixmapFragments(const QPainter::Fragment *drawingData, int dataCount, const QPixmap &pixmap, QFlags<QPainter::FragmentHint> hints);
void drawTextItem(const QPointF &p, const QTextItem &textItem);
void drawStaticTextItem(QStaticTextItem *staticTextItem);
diff --git a/tests/auto/qpainter/tst_qpainter.cpp b/tests/auto/qpainter/tst_qpainter.cpp
index beb83a1..a03b2c7 100644
--- a/tests/auto/qpainter/tst_qpainter.cpp
+++ b/tests/auto/qpainter/tst_qpainter.cpp
@@ -107,6 +107,7 @@ private slots:
void saveAndRestore();
void drawBorderPixmap();
+ void drawPixmapFragments();
void drawLine_data();
void drawLine();
@@ -994,6 +995,49 @@ void tst_QPainter::drawBorderPixmap()
QTileRules(Qt::StretchTile,Qt::StretchTile), 0);
}
+void tst_QPainter::drawPixmapFragments()
+{
+ QPixmap origPixmap(20, 20);
+ QPixmap resPixmap(20, 20);
+ QPainter::Fragment fragments[4] = { {15, 15, 0, 0, 10, 10, 1, 1, 0, 1},
+ { 5, 15, 10, 0, 10, 10, 1, 1, 0, 1},
+ {15, 5, 0, 10, 10, 10, 1, 1, 0, 1},
+ { 5, 5, 10, 10, 10, 10, 1, 1, 0, 1} };
+ {
+ QPainter p(&origPixmap);
+ p.fillRect(0, 0, 10, 10, Qt::red);
+ p.fillRect(10, 0, 10, 10, Qt::green);
+ p.fillRect(0, 10, 10, 10, Qt::blue);
+ p.fillRect(10, 10, 10, 10, Qt::yellow);
+ }
+ {
+ QPainter p(&resPixmap);
+ p.drawPixmapFragments(fragments, 4, origPixmap);
+ }
+
+ QImage origImage = origPixmap.toImage().convertToFormat(QImage::Format_ARGB32);
+ QImage resImage = resPixmap.toImage().convertToFormat(QImage::Format_ARGB32);
+
+ QVERIFY(resImage.size() == resPixmap.size());
+ QVERIFY(resImage.pixel(5, 5) == origImage.pixel(15, 15));
+ QVERIFY(resImage.pixel(5, 15) == origImage.pixel(15, 5));
+ QVERIFY(resImage.pixel(15, 5) == origImage.pixel(5, 15));
+ QVERIFY(resImage.pixel(15, 15) == origImage.pixel(5, 5));
+
+
+ QPainter::Fragment fragment = QPainter::Fragment::create(QPointF(20, 20), QRectF(30, 30, 2, 2));
+ QVERIFY(fragment.x == 20);
+ QVERIFY(fragment.y == 20);
+ QVERIFY(fragment.sourceLeft == 30);
+ QVERIFY(fragment.sourceTop == 30);
+ QVERIFY(fragment.width == 2);
+ QVERIFY(fragment.height == 2);
+ QVERIFY(fragment.scaleX == 1);
+ QVERIFY(fragment.scaleY == 1);
+ QVERIFY(fragment.rotation == 0);
+ QVERIFY(fragment.opacity == 1);
+}
+
void tst_QPainter::drawLine_data()
{
QTest::addColumn<QLine>("line");
@@ -3443,8 +3487,8 @@ bool verifyOutlineFillConsistency(const QImage &img, QRgb outside, QRgb inside,
if ((dx == 0) == (dy == 0))
continue;
QRgb neighbor = img.pixel(p.x() + dx, p.y() + dy);
- if (pixel == inside && neighbor == outside ||
- pixel == outside && neighbor == inside)
+ if ((pixel == inside && neighbor == outside) ||
+ (pixel == outside && neighbor == inside))
return false;
}
}