summaryrefslogtreecommitdiffstats
path: root/src/gui/painting/qpaintengine_raster.cpp
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@nokia.com>2010-07-01 17:24:01 (GMT)
committerThiago Macieira <thiago.macieira@nokia.com>2010-07-01 17:24:01 (GMT)
commit745ecfd8925716d962c97a4415881377faf6bdd5 (patch)
treec4f78b3bd143af52372064cd3ba5c0ae440813c5 /src/gui/painting/qpaintengine_raster.cpp
parentbda164303570629e44185e8baa52908ced6da301 (diff)
parent8968c79c575755cdb52d5e615ed19e4529047464 (diff)
downloadQt-745ecfd8925716d962c97a4415881377faf6bdd5.zip
Qt-745ecfd8925716d962c97a4415881377faf6bdd5.tar.gz
Qt-745ecfd8925716d962c97a4415881377faf6bdd5.tar.bz2
Merge remote branch 'origin/4.7' into qt-master-from-4.7
Conflicts: bin/syncqt src/gui/text/qtextlayout.cpp tools/assistant/tools/assistant/helpviewer_qwv.cpp tools/assistant/tools/assistant/helpviewer_qwv.h tools/configure/configureapp.cpp
Diffstat (limited to 'src/gui/painting/qpaintengine_raster.cpp')
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp129
1 files changed, 119 insertions, 10 deletions
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 06effd4..fb93152 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -68,6 +68,7 @@
// #include <private/qrasterizer_p.h>
#include <private/qimage_p.h>
#include <private/qstatictext_p.h>
+#include "qmemrotate_p.h"
#include "qpaintengine_raster_p.h"
// #include "qbezier_p.h"
@@ -344,7 +345,7 @@ void QRasterPaintEngine::init()
// The antialiasing raster.
d->grayRaster.reset(new QT_FT_Raster);
Q_CHECK_PTR(d->grayRaster.data());
- if (qt_ft_grays_raster.raster_new(0, d->grayRaster.data()))
+ if (qt_ft_grays_raster.raster_new(d->grayRaster.data()))
QT_THROW(std::bad_alloc()); // an error creating the raster is caused by a bad malloc
@@ -458,13 +459,12 @@ bool QRasterPaintEngine::begin(QPaintDevice *device)
QRasterPaintEngineState *s = state();
ensureOutlineMapper();
- d->outlineMapper->m_clip_rect = d->deviceRect.adjusted(-10, -10, 10, 10);
-
- // This is the upp
- QRect bounds(-QT_RASTER_COORD_LIMIT, -QT_RASTER_COORD_LIMIT,
- QT_RASTER_COORD_LIMIT*2 - 1, QT_RASTER_COORD_LIMIT * 2 - 1);
- d->outlineMapper->m_clip_rect = bounds.intersected(d->outlineMapper->m_clip_rect);
+ d->outlineMapper->m_clip_rect = d->deviceRect;
+ if (d->outlineMapper->m_clip_rect.width() > QT_RASTER_COORD_LIMIT)
+ d->outlineMapper->m_clip_rect.setWidth(QT_RASTER_COORD_LIMIT);
+ if (d->outlineMapper->m_clip_rect.height() > QT_RASTER_COORD_LIMIT)
+ d->outlineMapper->m_clip_rect.setHeight(QT_RASTER_COORD_LIMIT);
d->rasterizer->setClipRect(d->deviceRect);
@@ -2521,6 +2521,58 @@ QRectF qt_mapRect_non_normalizing(const QRectF &r, const QTransform &t)
return QRectF(r.topLeft() * t, r.bottomRight() * t);
}
+namespace {
+ enum RotationType {
+ Rotation90,
+ Rotation180,
+ Rotation270,
+ NoRotation
+ };
+
+ inline RotationType qRotationType(const QTransform &transform)
+ {
+ QTransform::TransformationType type = transform.type();
+
+ if (type > QTransform::TxRotate)
+ return NoRotation;
+
+ if (type == QTransform::TxRotate && qFuzzyIsNull(transform.m11()) && qFuzzyCompare(transform.m12(), qreal(-1))
+ && qFuzzyCompare(transform.m21(), qreal(1)) && qFuzzyIsNull(transform.m22()))
+ return Rotation90;
+
+ if (type == QTransform::TxScale && qFuzzyCompare(transform.m11(), qreal(-1)) && qFuzzyIsNull(transform.m12())
+ && qFuzzyIsNull(transform.m21()) && qFuzzyCompare(transform.m22(), qreal(-1)))
+ return Rotation180;
+
+ if (type == QTransform::TxRotate && qFuzzyIsNull(transform.m11()) && qFuzzyCompare(transform.m12(), qreal(1))
+ && qFuzzyCompare(transform.m21(), qreal(-1)) && qFuzzyIsNull(transform.m22()))
+ return Rotation270;
+
+ return NoRotation;
+ }
+
+ template <typename T> void memRotate(RotationType type, const T *srcBase, int w, int h, int sbpl, T *dstBase, int dbpl)
+ {
+ switch (type) {
+ case Rotation90:
+ qt_memrotate90(srcBase, w, h, sbpl, dstBase, dbpl);
+ break;
+ case Rotation180:
+ qt_memrotate180(srcBase, w, h, sbpl, dstBase, dbpl);
+ break;
+ case Rotation270:
+ qt_memrotate270(srcBase, w, h, sbpl, dstBase, dbpl);
+ break;
+ case NoRotation:
+ break;
+ }
+ }
+
+ inline bool isPixelAligned(const QRectF &rect) {
+ return QRectF(rect.toRect()) == rect;
+ }
+}
+
/*!
\reimp
*/
@@ -2582,6 +2634,58 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
const QClipData *clip = d->clip();
+ if (s->matrix.type() > QTransform::TxTranslate
+ && !stretch_sr
+ && (!clip || clip->hasRectClip)
+ && s->intOpacity == 256
+ && (d->rasterBuffer->compositionMode == QPainter::CompositionMode_SourceOver
+ || d->rasterBuffer->compositionMode == QPainter::CompositionMode_Source)
+ && d->rasterBuffer->format == img.format()
+ && (d->rasterBuffer->format == QImage::Format_RGB16
+ || d->rasterBuffer->format == QImage::Format_RGB32
+ || (d->rasterBuffer->format == QImage::Format_ARGB32_Premultiplied
+ && d->rasterBuffer->compositionMode == QPainter::CompositionMode_Source)))
+ {
+ RotationType rotationType = qRotationType(s->matrix);
+
+ if (rotationType != NoRotation && img.rect().contains(sr.toAlignedRect())) {
+ QRectF transformedTargetRect = s->matrix.mapRect(r);
+
+ if ((!(s->renderHints & QPainter::SmoothPixmapTransform) && !(s->renderHints & QPainter::Antialiasing))
+ || (isPixelAligned(transformedTargetRect) && isPixelAligned(sr)))
+ {
+ QRect clippedTransformedTargetRect = transformedTargetRect.toRect().intersected(clip ? clip->clipRect : d->deviceRect);
+ if (clippedTransformedTargetRect.isNull())
+ return;
+
+ QRectF clippedTargetRect = s->matrix.inverted().mapRect(QRectF(clippedTransformedTargetRect));
+
+ QRect clippedSourceRect
+ = QRectF(sr.x() + clippedTargetRect.x() - r.x(), sr.y() + clippedTargetRect.y() - r.y(),
+ clippedTargetRect.width(), clippedTargetRect.height()).toRect();
+
+ uint dbpl = d->rasterBuffer->bytesPerLine();
+ uint sbpl = img.bytesPerLine();
+
+ uchar *dst = d->rasterBuffer->buffer();
+ uint bpp = img.depth() >> 3;
+
+ const uchar *srcBase = img.bits() + clippedSourceRect.y() * sbpl + clippedSourceRect.x() * bpp;
+ uchar *dstBase = dst + clippedTransformedTargetRect.y() * dbpl + clippedTransformedTargetRect.x() * bpp;
+
+ uint cw = clippedSourceRect.width();
+ uint ch = clippedSourceRect.height();
+
+ if (d->rasterBuffer->format == QImage::Format_RGB16)
+ memRotate(rotationType, (quint16 *)srcBase, cw, ch, sbpl, (quint16 *)dstBase, dbpl);
+ else
+ memRotate(rotationType, (quint32 *)srcBase, cw, ch, sbpl, (quint32 *)dstBase, dbpl);
+
+ return;
+ }
+ }
+ }
+
if (s->matrix.type() > QTransform::TxTranslate || stretch_sr) {
if (s->flags.fast_images) {
@@ -3685,6 +3789,7 @@ void QRasterPaintEngine::drawEllipse(const QRectF &rect)
if (((qpen_style(s->lastPen) == Qt::SolidLine && s->flags.fast_pen)
|| (qpen_style(s->lastPen) == Qt::NoPen && !s->flags.antialiased))
&& qMax(rect.width(), rect.height()) < QT_RASTER_COORD_LIMIT
+ && !rect.isEmpty()
&& s->matrix.type() <= QTransform::TxScale) // no shear
{
ensureBrush();
@@ -4081,7 +4186,11 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline,
return;
}
- const int rasterPoolInitialSize = 8192;
+ // Initial size for raster pool is MINIMUM_POOL_SIZE so as to
+ // minimize memory reallocations. However if initial size for
+ // raster pool is changed for lower value, reallocations will
+ // occur normally.
+ const int rasterPoolInitialSize = MINIMUM_POOL_SIZE;
int rasterPoolSize = rasterPoolInitialSize;
unsigned char *rasterPoolBase;
#if defined(Q_WS_WIN64)
@@ -4125,7 +4234,7 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline,
error = qt_ft_grays_raster.raster_render(*grayRaster.data(), &rasterParams);
// Out of memory, reallocate some more and try again...
- if (error == -6) { // -6 is Result_err_OutOfMemory
+ if (error == -6) { // ErrRaster_OutOfMemory from qgrayraster.c
int new_size = rasterPoolSize * 2;
if (new_size > 1024 * 1024) {
qWarning("QPainter: Rasterization of primitive failed");
@@ -4151,7 +4260,7 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline,
Q_CHECK_PTR(rasterPoolBase); // note: we just freed the old rasterPoolBase. I hope it's not fatal.
qt_ft_grays_raster.raster_done(*grayRaster.data());
- qt_ft_grays_raster.raster_new(0, grayRaster.data());
+ qt_ft_grays_raster.raster_new(grayRaster.data());
qt_ft_grays_raster.raster_reset(*grayRaster.data(), rasterPoolBase, rasterPoolSize);
} else {
done = true;