diff options
author | Kim Motoyoshi Kalland <kim.kalland@nokia.com> | 2009-08-18 13:46:00 (GMT) |
---|---|---|
committer | Kim Motoyoshi Kalland <kim.kalland@nokia.com> | 2009-08-18 14:31:33 (GMT) |
commit | 89cc6c1b49e3e33fc7787f1dd9cfaadb43ad4bac (patch) | |
tree | 4fd9ffc845a4372250520e7664b844afd198eaec /src/gui/painting | |
parent | d136f3c444041d07a7a5fe9358c9200c8bdb7602 (diff) | |
download | Qt-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')
-rw-r--r-- | src/gui/painting/qpaintengine_raster.cpp | 36 |
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; } |