diff options
author | Thiago Macieira <thiago.macieira@nokia.com> | 2010-07-01 17:24:01 (GMT) |
---|---|---|
committer | Thiago Macieira <thiago.macieira@nokia.com> | 2010-07-01 17:24:01 (GMT) |
commit | 745ecfd8925716d962c97a4415881377faf6bdd5 (patch) | |
tree | c4f78b3bd143af52372064cd3ba5c0ae440813c5 /src/gui/painting/qpaintengine_raster.cpp | |
parent | bda164303570629e44185e8baa52908ced6da301 (diff) | |
parent | 8968c79c575755cdb52d5e615ed19e4529047464 (diff) | |
download | Qt-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.cpp | 129 |
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; |