From kde-commits Fri Oct 03 00:19:40 2008 From: Maks Orlovich Date: Fri, 03 Oct 2008 00:19:40 +0000 To: kde-commits Subject: KDE/kdelibs/khtml/rendering Message-Id: <1222993180.876748.24814.nullmailer () svn ! kde ! org> X-MARC-Message: https://marc.info/?l=kde-commits&m=122299319002996 SVN commit 867175 by orlovich: Merged revision 867171: Significantly improve the efficiency of how we paint images when full-page scaling, by doing scaling directly with imload. This avoids a lot of expensive operations (a drawPixmap on a scaled QPainter isn't pretty) and lets us take advantage of imload's internal caching infrastructure. Unfortunately, this doesn't help with background images; those also need a lot of thought on how to fully take advantage of imload, including unifying of cache and pre-tile management, etc. M +28 -3 render_image.cpp --- trunk/KDE/kdelibs/khtml/rendering/render_image.cpp #867174:867175 @@ -295,9 +295,21 @@ //const QPixmap& pix = i->pixmap(); if (!m_imagePainter) m_imagePainter = new ImagePainter(i->image()); - m_imagePainter->setSize(QSize(contentWidth(), contentHeight())); - //Intersect with the painting clip rectangle. + // If we have a scaled painter we want to handle the resizing ourselves, so figure out the scaled size, + QTransform painterTransform = paintInfo.p->transform(); + + bool scaled = painterTransform.isScaling() && !painterTransform.isRotating(); + + QRect scaledRect; // bounding box of the whole thing, transformed, so we also know where the origin goes. + if (scaled) { + scaledRect = painterTransform.mapRect(QRect(0, 0, contentWidth(), contentHeight())); + m_imagePainter->setSize(QSize(scaledRect.width(), scaledRect.height())); + } else { + m_imagePainter->setSize(QSize(contentWidth(), contentHeight())); + } + + // Now, figure out the rectangle to paint (in painter coordinates), by interesting us with the painting clip rectangle. int x = _tx + leftBorder + leftPad; int y = _ty + topBorder + topPad; QRect imageGeom = QRect(0, 0, contentWidth(), contentHeight()); @@ -305,10 +317,23 @@ QRect clipPortion = paintInfo.r.translated(-x, -y); imageGeom &= clipPortion; - m_imagePainter->paint(x + imageGeom.x(), y + imageGeom.y(), paintInfo.p, + QPoint destPos = QPoint(x + imageGeom.x(), y + imageGeom.y()); + + // If we're scaling, reset the painters transform, and apply it ourselves; though + // being careful not apply the translation to the source rect. + if (scaled) { + paintInfo.p->resetTransform(); + destPos = painterTransform.map(destPos); + imageGeom = painterTransform.mapRect(imageGeom).translated(-scaledRect.topLeft()); + } + + m_imagePainter->paint(destPos.x(), destPos.y(), paintInfo.p, imageGeom.x(), imageGeom.y(), imageGeom.width(), imageGeom.height()); + if (scaled) + paintInfo.p->setTransform(painterTransform); + } if (m_selectionState != SelectionNone) { // kDebug(6040) << "_tx " << _tx << " _ty " << _ty << " _x " << _x << " _y " << _y;