summaryrefslogtreecommitdiffstats
path: root/src/gui/painting/qpaintengine_raster.cpp
diff options
context:
space:
mode:
authorKim Motoyoshi Kalland <kim.kalland@nokia.com>2009-08-18 13:46:00 (GMT)
committerKim Motoyoshi Kalland <kim.kalland@nokia.com>2009-08-18 14:31:33 (GMT)
commit89cc6c1b49e3e33fc7787f1dd9cfaadb43ad4bac (patch)
tree4fd9ffc845a4372250520e7664b844afd198eaec /src/gui/painting/qpaintengine_raster.cpp
parentd136f3c444041d07a7a5fe9358c9200c8bdb7602 (diff)
downloadQt-89cc6c1b49e3e33fc7787f1dd9cfaadb43ad4bac.zip
Qt-89cc6c1b49e3e33fc7787f1dd9cfaadb43ad4bac.tar.gz
Qt-89cc6c1b49e3e33fc7787f1dd9cfaadb43ad4bac.tar.bz2
Fixed QRasterPaintEngine::drawImage() for 1x1 source rectangles.
QRasterPaintEngine::drawImage() used an optimized code path when the source rectangle was 1x1. It would sample the source image at the source rectangle's top-left corner and use the sampled color to fill the entire target rectangle. There were two bugs, however: 1) The sampled color was assumed to be non-premultiplied, so you could end up with premultiplying the color twice. This was fixed by avoiding premultiplying a second time if the source image has a premultiplied format. 2) Since the source rectangle is a QRectF, it could easily cross pixel boundaries even if it's 1x1. In this case, it is not correct to fill the target rectangle with a single color. This was fixed by checking if the entire source rectangle is contained in a single pixel before taking the optimized code path. Task-number: 256950 Reviewed-by: Trond
Diffstat (limited to 'src/gui/painting/qpaintengine_raster.cpp')
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp36
1 files changed, 34 insertions, 2 deletions
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 547818c..63c4e32 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -2544,12 +2544,44 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
Q_D(QRasterPaintEngine);
QRasterPaintEngineState *s = state();
const bool aa = s->flags.antialiased || s->flags.bilinear;
- if (!aa && sr.size() == QSize(1, 1)) {
+ int sr_l = qFloor(sr.left());
+ int sr_r = qCeil(sr.right()) - 1;
+ int sr_t = qFloor(sr.top());
+ int sr_b = qCeil(sr.bottom()) - 1;
+
+ if (!aa && sr_l == sr_r && sr_t == sr_b) {
// as fillRect will apply the aliased coordinate delta we need to
// subtract it here as we don't use it for image drawing
QTransform old = s->matrix;
s->matrix = s->matrix * QTransform::fromTranslate(-aliasedCoordinateDelta, -aliasedCoordinateDelta);
- fillRect(r, QColor::fromRgba(img.pixel(sr.x(), sr.y())));
+
+ // Do whatever fillRect() does, but without premultiplying the color if it's already premultiplied.
+ QRgb color = img.pixel(sr_l, sr_t);
+ switch (img.format()) {
+ case QImage::Format_ARGB32_Premultiplied:
+ case QImage::Format_ARGB8565_Premultiplied:
+ case QImage::Format_ARGB6666_Premultiplied:
+ case QImage::Format_ARGB8555_Premultiplied:
+ case QImage::Format_ARGB4444_Premultiplied:
+ // Combine premultiplied color with the opacity set on the painter.
+ d->solid_color_filler.solid.color =
+ ((((color & 0x00ff00ff) * s->intOpacity) >> 8) & 0x00ff00ff)
+ | ((((color & 0xff00ff00) >> 8) * s->intOpacity) & 0xff00ff00);
+ break;
+ default:
+ d->solid_color_filler.solid.color = PREMUL(ARGB_COMBINE_ALPHA(color, s->intOpacity));
+ break;
+ }
+
+ if ((d->solid_color_filler.solid.color & 0xff000000) == 0
+ && s->composition_mode == QPainter::CompositionMode_SourceOver) {
+ return;
+ }
+
+ d->solid_color_filler.clip = d->clip();
+ d->solid_color_filler.adjustSpanMethods();
+ fillRect(r, &d->solid_color_filler);
+
s->matrix = old;
return;
}