summaryrefslogtreecommitdiffstats
path: root/src/gui/painting
diff options
context:
space:
mode:
authoraxis <qt-info@nokia.com>2009-04-24 14:03:55 (GMT)
committeraxis <qt-info@nokia.com>2009-04-27 07:09:01 (GMT)
commite74c8dc65e2feffb9a55d00aee5ca634fba41df8 (patch)
tree3a131f9235fb6a455793178d8313655e4fd0036e /src/gui/painting
parent8f427b2b914d5b575a4a7c0ed65d2fb8f45acc76 (diff)
parent211bea9838bcc2acd7f54b65468fe1be2d81b1e0 (diff)
downloadQt-e74c8dc65e2feffb9a55d00aee5ca634fba41df8.zip
Qt-e74c8dc65e2feffb9a55d00aee5ca634fba41df8.tar.gz
Qt-e74c8dc65e2feffb9a55d00aee5ca634fba41df8.tar.bz2
Merge branch '4.5' of git@scm.dev.nokia.troll.no:qt/qt
Configure.exe recompiled with MSVC6. Conflicts: configure.exe examples/network/network.pro src/gui/dialogs/qfiledialog_p.h src/gui/dialogs/qfilesystemmodel_p.h src/gui/kernel/qapplication.cpp tests/auto/_Categories/qmake.txt tests/auto/qfile/test/test.pro tests/auto/qfile/tst_qfile.cpp tests/auto/qlibrary/tst_qlibrary.cpp tests/auto/qline/tst_qline.cpp tests/auto/qstyle/tst_qstyle.cpp tests/auto/qtextstream/tst_qtextstream.cpp tests/auto/qtranslator/qtranslator.pro tests/auto/qwaitcondition/tst_qwaitcondition.cpp translations/qt_ja_JP.ts
Diffstat (limited to 'src/gui/painting')
-rw-r--r--src/gui/painting/qblendfunctions.cpp159
-rw-r--r--src/gui/painting/qdrawhelper.cpp92
-rw-r--r--src/gui/painting/qmemrotate.cpp1
-rw-r--r--src/gui/painting/qmemrotate_p.h1
-rw-r--r--src/gui/painting/qpaintengine_alpha.cpp12
-rw-r--r--src/gui/painting/qpaintengine_alpha_p.h1
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp152
-rw-r--r--src/gui/painting/qpaintengine_raster_p.h2
-rw-r--r--src/gui/painting/qpaintengine_x11.cpp19
-rw-r--r--src/gui/painting/qpainter.cpp25
-rw-r--r--src/gui/painting/qpainterpath.cpp23
-rw-r--r--src/gui/painting/qpainterpath.h2
-rw-r--r--src/gui/painting/qpainterpath_p.h11
-rw-r--r--src/gui/painting/qpdf.cpp5
-rw-r--r--src/gui/painting/qprintengine_mac.mm66
-rw-r--r--src/gui/painting/qprintengine_mac_p.h1
-rw-r--r--src/gui/painting/qprintengine_win.cpp4
-rw-r--r--src/gui/painting/qprinter.cpp6
-rw-r--r--src/gui/painting/qregion.cpp24
-rw-r--r--src/gui/painting/qtransform.cpp93
-rw-r--r--src/gui/painting/qtransform.h8
-rw-r--r--src/gui/painting/qwindowsurface.cpp7
22 files changed, 404 insertions, 310 deletions
diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp
index d2f4ab7..dd7b016 100644
--- a/src/gui/painting/qblendfunctions.cpp
+++ b/src/gui/painting/qblendfunctions.cpp
@@ -44,19 +44,6 @@
QT_BEGIN_NAMESPACE
-
-// This ifdef is made with the best of intention. GCC fails to
-// optimzie the code properly so the bytemul approach is the fastest
-// it gets. Both on ARM and on MSVC the code is optimized to be better
-// than the bytemul approach... On the other hand... This code is
-// almost never run on i386 so it may be downright silly to have this
-// piece of code here...
-#if defined (Q_CC_GNU) && (defined (QT_ARCH_I386) || defined (QT_ARCH_X86_64))
-# define QT_BLEND_USE_BYTEMUL
-#endif
-
-// #define QT_DEBUG_DRAW
-
static const qreal aliasedCoordinateDelta = 0.5 - 0.015625;
struct SourceOnlyAlpha
@@ -286,7 +273,7 @@ static void qt_blend_rgb16_on_rgb16(uchar *dst, int dbpl,
int const_alpha)
{
#ifdef QT_DEBUG_DRAW
- printf("qt_blend_argb16_on_rgb16: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n",
+ printf("qt_blend_rgb16_on_rgb16: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n",
dst, dbpl, src, sbpl, w, h, const_alpha);
#endif
@@ -347,11 +334,6 @@ template <typename T> void qt_blend_argb24_on_rgb16(uchar *destPixels, int dbpl,
if (alpha == 255) {
*dst = spix;
} else if (alpha != 0) {
-#ifdef QT_BLEND_USE_BYTEMUL
- // truncate green channel to avoid overflow
- *dst = (alphaFunc.bytemul(spix) & 0xffdf)
- + (quint16) qrgb565(*dst).byte_mul(qrgb565::ialpha(alpha));
-#else
quint16 dpix = *dst;
quint32 sia = 255 - alpha;
@@ -363,12 +345,11 @@ template <typename T> void qt_blend_argb24_on_rgb16(uchar *destPixels, int dbpl,
quint32 siag = dg * sia;
quint32 siab = db * sia;
- quint32 rr = ((siar + (siar>>8) + (0x80 << 11)) >> 8) & 0xf800;
- quint32 rg = ((siag + (siag>>8) + (0x80 << 5)) >> 8) & 0x07e0;
- quint32 rb = ((siab + (siab>>8) + (0x80 >> 3)) >> 8);
+ quint32 rr = ((siar + (siar>>8) + (0x80 << 8)) >> 8) & 0xf800;
+ quint32 rg = ((siag + (siag>>8) + (0x80 << 3)) >> 8) & 0x07e0;
+ quint32 rb = ((siab + (siab>>8) + (0x80 >> 3)) >> 8) & 0x001f;
*dst = alphaFunc.bytemul(spix) + rr + rg + rb;
-#endif
}
++dst;
@@ -435,111 +416,45 @@ static void qt_blend_argb32_on_rgb16(uchar *destPixels, int dbpl,
}
quint16 *dst = (quint16 *) destPixels;
- int dstExtraStride = dbpl / 2 - w;
-
- const quint32 *src = (const quint32 *) srcPixels;
- int srcExtraStride = sbpl / 4 - w;
+ quint32 *src = (quint32 *) srcPixels;
for (int y=0; y<h; ++y) {
- int length = w;
- const int dstAlign = ((quintptr)dst) & 0x3;
- if (dstAlign) {
- const quint8 alpha = qAlpha(*src);
- if (alpha) {
- quint16 s = convert_argb32_to_rgb16(*src);
- if (alpha < 255)
- s += BYTE_MUL_RGB16(*dst, 255 - alpha);
- *dst = s;
- }
- ++dst;
- ++src;
- --length;
- }
+ for (int x=0; x<w; ++x) {
- const int length32 = length >> 1;
- const int srcAlign = ((quintptr)src) & 0x3;
- if (length32) {
- if (srcAlign) {
- for (int i = 0; i < length32; ++i) {
- quint32 *dest32 = reinterpret_cast<quint32*>(dst);
- const quint8 a1 = qAlpha(src[0]);
- const quint8 a2 = qAlpha(src[1]);
- quint32 s;
-
- if (!a1 && !a2) {
- src += 2;
- dst +=2;
- continue;
- }
-
- s = convert_argb32_to_rgb16(src[0])
- | (convert_argb32_to_rgb16(src[1]) << 16);
-
- if (a1 == a2) {
- if (a1 < 255) {
- const quint8 sa = ((255 - a1)+1) >> 3;
- s += BYTE_MUL_RGB16_32(*dest32, sa);
- }
- } else {
- if (a1 < 255)
- s += BYTE_MUL_RGB16(dst[0], 255 - a1);
- if (a2 < 255)
- s += BYTE_MUL_RGB16(dst[1], 255 - a2) << 16;
- }
-
- *dest32 = s;
- src += 2;
- dst += 2;
- }
- } else {
- for (int i = 0; i < length32; ++i) {
- quint32 *dest32 = reinterpret_cast<quint32*>(dst);
- const quint8 a1 = qAlpha(src[0]);
- const quint8 a2 = qAlpha(src[1]);
- quint32 s;
-
- if (!a1 && !a2) {
- src += 2;
- dst +=2;
- continue;
- }
-
- const quint64 *src64 =
- reinterpret_cast<const quint64*>(src);
- s = qConvertRgb32To16x2(*src64);
-
- if (a1 == a2) {
- if (a1 < 255) {
- const quint8 sa = ((255 - a1)+1) >> 3;
- s += BYTE_MUL_RGB16_32(*dest32, sa);
- }
- } else {
- if (a1 < 255)
- s += BYTE_MUL_RGB16(dst[0], 255 - a1);
- if (a2 < 255)
- s += BYTE_MUL_RGB16(dst[1], 255 - a2) << 16;
- }
-
- *dest32 = s;
- src += 2;
- dst += 2;
- }
- }
- }
- const int tail = length & 0x1;
- if (tail) {
- const quint8 alpha = qAlpha(*src);
- if (alpha) {
- quint16 s = convert_argb32_to_rgb16(*src);
- if (alpha < 255)
- s += BYTE_MUL_RGB16(*dst, 255 - alpha);
- *dst = s;
+ quint32 spix = src[x];
+ quint32 alpha = spix >> 24;
+
+ if (alpha == 255) {
+ dst[x] = convert_argb32_to_rgb16(spix);
+ } else if (alpha != 0) {
+ quint32 dpix = dst[x];
+
+ quint32 sia = 255 - alpha;
+
+ quint32 sr = (spix >> 8) & 0xf800;
+ quint32 sg = (spix >> 5) & 0x07e0;
+ quint32 sb = (spix >> 3) & 0x001f;
+
+ quint32 dr = (dpix & 0x0000f800);
+ quint32 dg = (dpix & 0x000007e0);
+ quint32 db = (dpix & 0x0000001f);
+
+ quint32 siar = dr * sia;
+ quint32 siag = dg * sia;
+ quint32 siab = db * sia;
+
+ quint32 rr = sr + ((siar + (siar>>8) + (0x80 << 8)) >> 8);
+ quint32 rg = sg + ((siag + (siag>>8) + (0x80 << 3)) >> 8);
+ quint32 rb = sb + ((siab + (siab>>8) + (0x80 >> 3)) >> 8);
+
+ dst[x] = (rr & 0xf800)
+ | (rg & 0x07e0)
+ | (rb);
}
}
- dst += dstExtraStride;
- src += srcExtraStride;
+ dst = (quint16 *) (((uchar *) dst) + dbpl);
+ src = (quint32 *) (((uchar *) src) + sbpl);
}
-
}
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index efdc778..c11837a 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -370,7 +370,7 @@ Q_STATIC_TEMPLATE_FUNCTION void QT_FASTCALL destStore(QRasterBuffer *rasterBuffe
Q_TEMPLATE_FIX(DST))
{
DST *dest = reinterpret_cast<DST*>(rasterBuffer->scanLine(y)) + x;
- const quint32 *src = reinterpret_cast<const quint32*>(buffer);
+ const quint32p *src = reinterpret_cast<const quint32p*>(buffer);
while (length--)
*dest++ = DST(*src++);
}
@@ -4763,7 +4763,7 @@ void QT_FASTCALL blendUntransformed(int count, const QSpan *spans, void *userDat
static void blend_untransformed_rgb888(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_24)
+#if defined(QT_QWS_DEPTH_24)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_RGB888)
@@ -4777,7 +4777,7 @@ static void blend_untransformed_rgb888(int count, const QSpan *spans,
static void blend_untransformed_argb6666(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_18)
+#if defined(QT_QWS_DEPTH_18)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB6666_Premultiplied)
@@ -4793,7 +4793,7 @@ static void blend_untransformed_argb6666(int count, const QSpan *spans,
static void blend_untransformed_rgb666(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_18)
+#if defined(QT_QWS_DEPTH_18)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB6666_Premultiplied)
@@ -4809,7 +4809,7 @@ static void blend_untransformed_rgb666(int count, const QSpan *spans,
static void blend_untransformed_argb8565(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16)
+#if defined(QT_QWS_DEPTH_16)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB8565_Premultiplied)
@@ -4825,7 +4825,7 @@ static void blend_untransformed_argb8565(int count, const QSpan *spans,
static void blend_untransformed_rgb565(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16)
+#if defined(QT_QWS_DEPTH_16)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB8565_Premultiplied)
@@ -4841,7 +4841,7 @@ static void blend_untransformed_rgb565(int count, const QSpan *spans,
static void blend_untransformed_argb8555(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_15)
+#if defined(QT_QWS_DEPTH_15)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB8555_Premultiplied)
@@ -4857,7 +4857,7 @@ static void blend_untransformed_argb8555(int count, const QSpan *spans,
static void blend_untransformed_rgb555(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_15)
+#if defined(QT_QWS_DEPTH_15)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB8555_Premultiplied)
@@ -4873,7 +4873,7 @@ static void blend_untransformed_rgb555(int count, const QSpan *spans,
static void blend_untransformed_argb4444(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_12)
+#if defined(QT_QWS_DEPTH_12)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB4444_Premultiplied)
@@ -4889,7 +4889,7 @@ static void blend_untransformed_argb4444(int count, const QSpan *spans,
static void blend_untransformed_rgb444(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_12)
+#if defined(QT_QWS_DEPTH_12)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB4444_Premultiplied)
@@ -5084,7 +5084,7 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTiled(int count, const QSpan *spans, void *
static void blend_tiled_rgb888(int count, const QSpan *spans, void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_24)
+#if defined(QT_QWS_DEPTH_24)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_RGB888)
@@ -5097,7 +5097,7 @@ static void blend_tiled_rgb888(int count, const QSpan *spans, void *userData)
static void blend_tiled_argb6666(int count, const QSpan *spans, void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_18)
+#if defined(QT_QWS_DEPTH_18)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB6666_Premultiplied)
@@ -5112,7 +5112,7 @@ static void blend_tiled_argb6666(int count, const QSpan *spans, void *userData)
static void blend_tiled_rgb666(int count, const QSpan *spans, void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_18)
+#if defined(QT_QWS_DEPTH_18)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB6666_Premultiplied)
@@ -5127,7 +5127,7 @@ static void blend_tiled_rgb666(int count, const QSpan *spans, void *userData)
static void blend_tiled_argb8565(int count, const QSpan *spans, void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16)
+#if defined(QT_QWS_DEPTH_16)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB8565_Premultiplied)
@@ -5142,7 +5142,7 @@ static void blend_tiled_argb8565(int count, const QSpan *spans, void *userData)
static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16)
+#if defined(QT_QWS_DEPTH_16)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB8565_Premultiplied)
@@ -5157,7 +5157,7 @@ static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData)
static void blend_tiled_argb8555(int count, const QSpan *spans, void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_15)
+#if defined(QT_QWS_DEPTH_15)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB8555_Premultiplied)
@@ -5172,7 +5172,7 @@ static void blend_tiled_argb8555(int count, const QSpan *spans, void *userData)
static void blend_tiled_rgb555(int count, const QSpan *spans, void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_15)
+#if defined(QT_QWS_DEPTH_15)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB8555_Premultiplied)
@@ -5187,7 +5187,7 @@ static void blend_tiled_rgb555(int count, const QSpan *spans, void *userData)
static void blend_tiled_argb4444(int count, const QSpan *spans, void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_12)
+#if defined(QT_QWS_DEPTH_12)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB4444_Premultiplied)
@@ -5202,7 +5202,7 @@ static void blend_tiled_argb4444(int count, const QSpan *spans, void *userData)
static void blend_tiled_rgb444(int count, const QSpan *spans, void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_12)
+#if defined(QT_QWS_DEPTH_12)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB4444_Premultiplied)
@@ -5599,7 +5599,7 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedBilinear(int count, const QSpan
static void blend_transformed_bilinear_rgb888(int count, const QSpan *spans, void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_24)
+#if defined(QT_QWS_DEPTH_24)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_RGB888)
@@ -5612,7 +5612,7 @@ static void blend_transformed_bilinear_rgb888(int count, const QSpan *spans, voi
static void blend_transformed_bilinear_argb6666(int count, const QSpan *spans, void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_18)
+#if defined(QT_QWS_DEPTH_18)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB6666_Premultiplied)
@@ -5627,7 +5627,7 @@ static void blend_transformed_bilinear_argb6666(int count, const QSpan *spans, v
static void blend_transformed_bilinear_rgb666(int count, const QSpan *spans, void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_18)
+#if defined(QT_QWS_DEPTH_18)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB6666_Premultiplied)
@@ -5642,7 +5642,7 @@ static void blend_transformed_bilinear_rgb666(int count, const QSpan *spans, voi
static void blend_transformed_bilinear_argb8565(int count, const QSpan *spans, void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16)
+#if defined(QT_QWS_DEPTH_16)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB8565_Premultiplied)
@@ -5658,7 +5658,7 @@ static void blend_transformed_bilinear_argb8565(int count, const QSpan *spans, v
static void blend_transformed_bilinear_rgb565(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16)
+#if defined(QT_QWS_DEPTH_16)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_RGB16)
@@ -5673,7 +5673,7 @@ static void blend_transformed_bilinear_rgb565(int count, const QSpan *spans,
static void blend_transformed_bilinear_argb8555(int count, const QSpan *spans, void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_15)
+#if defined(QT_QWS_DEPTH_15)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB8555_Premultiplied)
@@ -5688,7 +5688,7 @@ static void blend_transformed_bilinear_argb8555(int count, const QSpan *spans, v
static void blend_transformed_bilinear_rgb555(int count, const QSpan *spans, void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_15)
+#if defined(QT_QWS_DEPTH_15)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB8555_Premultiplied)
@@ -5703,7 +5703,7 @@ static void blend_transformed_bilinear_rgb555(int count, const QSpan *spans, voi
static void blend_transformed_bilinear_argb4444(int count, const QSpan *spans, void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_12)
+#if defined(QT_QWS_DEPTH_12)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB4444_Premultiplied)
@@ -5718,7 +5718,7 @@ static void blend_transformed_bilinear_argb4444(int count, const QSpan *spans, v
static void blend_transformed_bilinear_rgb444(int count, const QSpan *spans, void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_12)
+#if defined(QT_QWS_DEPTH_12)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB4444_Premultiplied)
@@ -6195,7 +6195,7 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformed(int count, const QSpan *spans,
static void blend_transformed_rgb888(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_24)
+#if defined(QT_QWS_DEPTH_24)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_RGB888)
@@ -6209,7 +6209,7 @@ static void blend_transformed_rgb888(int count, const QSpan *spans,
static void blend_transformed_argb6666(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_18)
+#if defined(QT_QWS_DEPTH_18)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB6666_Premultiplied)
@@ -6225,7 +6225,7 @@ static void blend_transformed_argb6666(int count, const QSpan *spans,
static void blend_transformed_rgb666(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_18)
+#if defined(QT_QWS_DEPTH_18)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB6666_Premultiplied)
@@ -6241,7 +6241,7 @@ static void blend_transformed_rgb666(int count, const QSpan *spans,
static void blend_transformed_argb8565(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16)
+#if defined(QT_QWS_DEPTH_16)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB8565_Premultiplied)
@@ -6257,7 +6257,7 @@ static void blend_transformed_argb8565(int count, const QSpan *spans,
static void blend_transformed_rgb565(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16)
+#if defined(QT_QWS_DEPTH_16)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB8565_Premultiplied)
@@ -6273,7 +6273,7 @@ static void blend_transformed_rgb565(int count, const QSpan *spans,
static void blend_transformed_argb8555(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_15)
+#if defined(QT_QWS_DEPTH_15)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB8555_Premultiplied)
@@ -6289,7 +6289,7 @@ static void blend_transformed_argb8555(int count, const QSpan *spans,
static void blend_transformed_rgb555(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_15)
+#if defined(QT_QWS_DEPTH_15)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB8555_Premultiplied)
@@ -6305,7 +6305,7 @@ static void blend_transformed_rgb555(int count, const QSpan *spans,
static void blend_transformed_argb4444(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_12)
+#if defined(QT_QWS_DEPTH_12)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB4444_Premultiplied)
@@ -6321,7 +6321,7 @@ static void blend_transformed_argb4444(int count, const QSpan *spans,
static void blend_transformed_rgb444(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_12)
+#if defined(QT_QWS_DEPTH_12)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB4444_Premultiplied)
@@ -6619,7 +6619,7 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedTiled(int count, const QSpan *sp
static void blend_transformed_tiled_rgb888(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_24)
+#if defined(QT_QWS_DEPTH_24)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_RGB888)
@@ -6633,7 +6633,7 @@ static void blend_transformed_tiled_rgb888(int count, const QSpan *spans,
static void blend_transformed_tiled_argb6666(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_18)
+#if defined(QT_QWS_DEPTH_18)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB6666_Premultiplied)
@@ -6649,7 +6649,7 @@ static void blend_transformed_tiled_argb6666(int count, const QSpan *spans,
static void blend_transformed_tiled_rgb666(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_18)
+#if defined(QT_QWS_DEPTH_18)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB6666_Premultiplied)
@@ -6665,7 +6665,7 @@ static void blend_transformed_tiled_rgb666(int count, const QSpan *spans,
static void blend_transformed_tiled_argb8565(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16)
+#if defined(QT_QWS_DEPTH_16)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB8565_Premultiplied)
@@ -6681,7 +6681,7 @@ static void blend_transformed_tiled_argb8565(int count, const QSpan *spans,
static void blend_transformed_tiled_rgb565(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16)
+#if defined(QT_QWS_DEPTH_16)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB8565_Premultiplied)
@@ -6697,7 +6697,7 @@ static void blend_transformed_tiled_rgb565(int count, const QSpan *spans,
static void blend_transformed_tiled_argb8555(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_15)
+#if defined(QT_QWS_DEPTH_15)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB8555_Premultiplied)
@@ -6713,7 +6713,7 @@ static void blend_transformed_tiled_argb8555(int count, const QSpan *spans,
static void blend_transformed_tiled_rgb555(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_15)
+#if defined(QT_QWS_DEPTH_15)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB8555_Premultiplied)
@@ -6729,7 +6729,7 @@ static void blend_transformed_tiled_rgb555(int count, const QSpan *spans,
static void blend_transformed_tiled_argb4444(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_12)
+#if defined(QT_QWS_DEPTH_12)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB4444_Premultiplied)
@@ -6745,7 +6745,7 @@ static void blend_transformed_tiled_argb4444(int count, const QSpan *spans,
static void blend_transformed_tiled_rgb444(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_12)
+#if defined(QT_QWS_DEPTH_12)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB4444_Premultiplied)
diff --git a/src/gui/painting/qmemrotate.cpp b/src/gui/painting/qmemrotate.cpp
index 7ad0e42..4058143 100644
--- a/src/gui/painting/qmemrotate.cpp
+++ b/src/gui/painting/qmemrotate.cpp
@@ -537,6 +537,7 @@ QT_IMPL_MEMROTATE(quint32, quint24)
QT_IMPL_MEMROTATE(quint32, quint18)
QT_IMPL_MEMROTATE(quint32, quint8)
QT_IMPL_MEMROTATE(quint16, quint8)
+QT_IMPL_MEMROTATE(qrgb444, quint8)
QT_IMPL_MEMROTATE(quint8, quint8)
#ifdef QT_QWS_DEPTH_GENERIC
QT_IMPL_MEMROTATE(quint32, qrgb_generic16)
diff --git a/src/gui/painting/qmemrotate_p.h b/src/gui/painting/qmemrotate_p.h
index bd6006b..c1eb93e 100644
--- a/src/gui/painting/qmemrotate_p.h
+++ b/src/gui/painting/qmemrotate_p.h
@@ -90,6 +90,7 @@ QT_DECL_MEMROTATE(quint32, quint24);
QT_DECL_MEMROTATE(quint32, quint18);
QT_DECL_MEMROTATE(quint32, quint8);
QT_DECL_MEMROTATE(quint16, quint8);
+QT_DECL_MEMROTATE(qrgb444, quint8);
QT_DECL_MEMROTATE(quint8, quint8);
#ifdef QT_QWS_DEPTH_GENERIC
QT_DECL_MEMROTATE(quint32, qrgb_generic16);
diff --git a/src/gui/painting/qpaintengine_alpha.cpp b/src/gui/painting/qpaintengine_alpha.cpp
index e38f6a4..74cbebe 100644
--- a/src/gui/painting/qpaintengine_alpha.cpp
+++ b/src/gui/painting/qpaintengine_alpha.cpp
@@ -80,6 +80,7 @@ bool QAlphaPaintEngine::begin(QPaintDevice *pdev)
d->m_advancedPen = false;
d->m_advancedBrush = false;
d->m_complexTransform = false;
+ d->m_emulateProjectiveTransforms = false;
// clear alpha region
d->m_alphargn = QRegion();
@@ -116,6 +117,9 @@ void QAlphaPaintEngine::updateState(const QPaintEngineState &state)
if (flags & QPaintEngine::DirtyTransform) {
d->m_transform = state.transform();
d->m_complexTransform = (d->m_transform.type() > QTransform::TxScale);
+ d->m_emulateProjectiveTransforms = !(d->m_savedcaps & QPaintEngine::PerspectiveTransform)
+ && !(d->m_savedcaps & QPaintEngine::AlphaBlend)
+ && (d->m_transform.type() >= QTransform::TxProject);
}
if (flags & QPaintEngine::DirtyPen) {
d->m_pen = state.pen();
@@ -163,7 +167,9 @@ void QAlphaPaintEngine::drawPath(const QPainterPath &path)
if (d->m_pass == 0) {
d->m_continueCall = false;
- if (d->m_hasalpha || d->m_advancedPen || d->m_advancedBrush) {
+ if (d->m_hasalpha || d->m_advancedPen || d->m_advancedBrush
+ || d->m_emulateProjectiveTransforms)
+ {
d->addAlphaRect(tr);
}
if (d->m_picengine)
@@ -187,7 +193,9 @@ void QAlphaPaintEngine::drawPolygon(const QPointF *points, int pointCount, Polyg
if (d->m_pass == 0) {
d->m_continueCall = false;
- if (d->m_hasalpha || d->m_advancedPen || d->m_advancedBrush) {
+ if (d->m_hasalpha || d->m_advancedPen || d->m_advancedBrush
+ || d->m_emulateProjectiveTransforms)
+ {
d->addAlphaRect(tr);
}
diff --git a/src/gui/painting/qpaintengine_alpha_p.h b/src/gui/painting/qpaintengine_alpha_p.h
index f510c73..f7d7a34 100644
--- a/src/gui/painting/qpaintengine_alpha_p.h
+++ b/src/gui/painting/qpaintengine_alpha_p.h
@@ -113,6 +113,7 @@ public:
bool m_advancedPen;
bool m_advancedBrush;
bool m_complexTransform;
+ bool m_emulateProjectiveTransforms;
bool m_continueCall;
QTransform m_transform;
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index c3addd8..19b2574 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -1142,6 +1142,33 @@ void QRasterPaintEnginePrivate::updateMatrixData(QSpanData *spanData, const QBru
}
}
+// #define QT_CLIPPING_RATIOS
+
+#ifdef QT_CLIPPING_RATIOS
+int rectClips;
+int regionClips;
+int totalClips;
+
+static void checkClipRatios(QRasterPaintEnginePrivate *d)
+{
+ if (d->clip()->hasRectClip)
+ rectClips++;
+ if (d->clip()->hasRegionClip)
+ regionClips++;
+ totalClips++;
+
+ if ((totalClips % 5000) == 0) {
+ printf("Clipping ratio: rectangular=%f%%, region=%f%%, complex=%f%%\n",
+ rectClips * 100.0 / (qreal) totalClips,
+ regionClips * 100.0 / (qreal) totalClips,
+ (totalClips - rectClips - regionClips) * 100.0 / (qreal) totalClips);
+ totalClips = 0;
+ rectClips = 0;
+ regionClips = 0;
+ }
+
+}
+#endif
/*!
\internal
@@ -1243,6 +1270,10 @@ void QRasterPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op)
d->solid_color_filler.clip = d->clip();
d->solid_color_filler.adjustSpanMethods();
+
+#ifdef QT_CLIPPING_RATIOS
+ checkClipRatios(d);
+#endif
}
@@ -1317,6 +1348,11 @@ void QRasterPaintEngine::clip(const QRect &rect, Qt::ClipOperation op)
d->solid_color_filler.clip = d->clip();
d->solid_color_filler.adjustSpanMethods();
+
+
+#ifdef QT_CLIPPING_RATIOS
+ checkClipRatios(d);
+#endif
}
/*!
@@ -1531,7 +1567,7 @@ void QRasterPaintEngine::drawRects(const QRectF *rects, int rectCount)
d->initializeRasterizer(&s->brushData);
for (int i = 0; i < rectCount; ++i) {
const QRectF &rect = rects[i].normalized();
- if (rects[i].isEmpty())
+ if (rect.isEmpty())
continue;
const QPointF a = s->matrix.map((rect.topLeft() + rect.bottomLeft()) * 0.5f);
const QPointF b = s->matrix.map((rect.topRight() + rect.bottomRight()) * 0.5f);
@@ -2357,11 +2393,6 @@ void QRasterPaintEngine::strokePolygonCosmetic(const QPoint *points, int pointCo
}
}
-#define IMAGE_FROM_PIXMAP(pixmap) \
- pixmap.data->classId() == QPixmapData::RasterClass \
- ? ((QRasterPixmapData *) pixmap.data)->image \
- : pixmap.toImage()
-
/*!
\internal
*/
@@ -2370,16 +2401,33 @@ void QRasterPaintEngine::drawPixmap(const QPointF &pos, const QPixmap &pixmap)
#ifdef QT_DEBUG_DRAW
qDebug() << " - QRasterPaintEngine::drawPixmap(), pos=" << pos << " pixmap=" << pixmap.size() << "depth=" << pixmap.depth();
#endif
- if (pixmap.depth() == 1) {
- Q_D(QRasterPaintEngine);
- QRasterPaintEngineState *s = state();
- if (s->matrix.type() <= QTransform::TxTranslate) {
- drawBitmap(pos + QPointF(s->matrix.dx(), s->matrix.dy()), pixmap, &s->penData);
+
+ if (pixmap.data->classId() == QPixmapData::RasterClass) {
+ const QImage &image = ((QRasterPixmapData *) pixmap.data)->image;
+ if (image.depth() == 1) {
+ Q_D(QRasterPaintEngine);
+ QRasterPaintEngineState *s = state();
+ if (s->matrix.type() <= QTransform::TxTranslate) {
+ drawBitmap(pos + QPointF(s->matrix.dx(), s->matrix.dy()), image, &s->penData);
+ } else {
+ drawImage(pos, d->rasterBuffer->colorizeBitmap(image, s->pen.color()));
+ }
} else {
- drawImage(pos, d->rasterBuffer->colorizeBitmap(IMAGE_FROM_PIXMAP(pixmap), s->pen.color()));
+ QRasterPaintEngine::drawImage(pos, image);
}
} else {
- QRasterPaintEngine::drawImage(pos, IMAGE_FROM_PIXMAP(pixmap));
+ const QImage image = pixmap.toImage();
+ if (pixmap.depth() == 1) {
+ Q_D(QRasterPaintEngine);
+ QRasterPaintEngineState *s = state();
+ if (s->matrix.type() <= QTransform::TxTranslate) {
+ drawBitmap(pos + QPointF(s->matrix.dx(), s->matrix.dy()), image, &s->penData);
+ } else {
+ drawImage(pos, d->rasterBuffer->colorizeBitmap(image, s->pen.color()));
+ }
+ } else {
+ QRasterPaintEngine::drawImage(pos, image);
+ }
}
}
@@ -2392,22 +2440,40 @@ void QRasterPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pixmap, cons
qDebug() << " - QRasterPaintEngine::drawPixmap(), r=" << r << " sr=" << sr << " pixmap=" << pixmap.size() << "depth=" << pixmap.depth();
#endif
- Q_D(QRasterPaintEngine);
- QRasterPaintEngineState *s = state();
-
- if (pixmap.depth() == 1) {
- if (s->matrix.type() <= QTransform::TxTranslate
- && r.size() == sr.size()
- && r.size() == pixmap.size()) {
- ensurePen();
- drawBitmap(r.topLeft() + QPointF(s->matrix.dx(), s->matrix.dy()), pixmap, &s->penData);
- return;
+ if (pixmap.data->classId() == QPixmapData::RasterClass) {
+ const QImage &image = ((QRasterPixmapData *) pixmap.data)->image;
+ if (image.depth() == 1) {
+ Q_D(QRasterPaintEngine);
+ QRasterPaintEngineState *s = state();
+ if (s->matrix.type() <= QTransform::TxTranslate
+ && r.size() == sr.size()
+ && r.size() == pixmap.size()) {
+ ensurePen();
+ drawBitmap(r.topLeft() + QPointF(s->matrix.dx(), s->matrix.dy()), image, &s->penData);
+ return;
+ } else {
+ drawImage(r, d->rasterBuffer->colorizeBitmap(image, s->pen.color()), sr);
+ }
} else {
- drawImage(r, d->rasterBuffer->colorizeBitmap(IMAGE_FROM_PIXMAP(pixmap),
- s->pen.color()), sr);
+ drawImage(r, image, sr);
}
} else {
- drawImage(r, IMAGE_FROM_PIXMAP(pixmap), sr);
+ const QImage image = pixmap.toImage();
+ if (image.depth() == 1) {
+ Q_D(QRasterPaintEngine);
+ QRasterPaintEngineState *s = state();
+ if (s->matrix.type() <= QTransform::TxTranslate
+ && r.size() == sr.size()
+ && r.size() == pixmap.size()) {
+ ensurePen();
+ drawBitmap(r.topLeft() + QPointF(s->matrix.dx(), s->matrix.dy()), image, &s->penData);
+ return;
+ } else {
+ drawImage(r, d->rasterBuffer->colorizeBitmap(image, s->pen.color()), sr);
+ }
+ } else {
+ drawImage(r, image, sr);
+ }
}
}
@@ -2616,10 +2682,15 @@ void QRasterPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap,
QRasterPaintEngineState *s = state();
QImage image;
- if (pixmap.depth() == 1)
- image = d->rasterBuffer->colorizeBitmap(IMAGE_FROM_PIXMAP(pixmap), s->pen.color());
- else
- image = IMAGE_FROM_PIXMAP(pixmap);
+
+ if (pixmap.data->classId() == QPixmapData::RasterClass) {
+ image = ((QRasterPixmapData *) pixmap.data)->image;
+ } else {
+ image = pixmap.toImage();
+ }
+
+ if (image.depth() == 1)
+ image = d->rasterBuffer->colorizeBitmap(image, s->pen.color());
if (s->matrix.type() > QTransform::TxTranslate) {
QTransform copy = s->matrix;
@@ -3652,14 +3723,13 @@ void QRasterPaintEngine::drawBufferSpan(const uint *buffer, int bufsize,
}
#endif // Q_WS_QWS
-void QRasterPaintEngine::drawBitmap(const QPointF &pos, const QPixmap &pm, QSpanData *fg)
+void QRasterPaintEngine::drawBitmap(const QPointF &pos, const QImage &image, QSpanData *fg)
{
Q_ASSERT(fg);
if (!fg->blend)
return;
Q_D(QRasterPaintEngine);
- const QImage image = IMAGE_FROM_PIXMAP(pm);
Q_ASSERT(image.depth() == 1);
const int spanCount = 256;
@@ -3667,8 +3737,8 @@ void QRasterPaintEngine::drawBitmap(const QPointF &pos, const QPixmap &pm, QSpan
int n = 0;
// Boundaries
- int w = pm.width();
- int h = pm.height();
+ int w = image.width();
+ int h = image.height();
int ymax = qMin(qRound(pos.y() + h), d->rasterBuffer->height());
int ymin = qMax(qRound(pos.y()), 0);
int xmax = qMin(qRound(pos.x() + w), d->rasterBuffer->width());
@@ -4343,6 +4413,9 @@ void QClipData::fixup()
*/
void QClipData::setClipRect(const QRect &rect)
{
+ if (rect == clipRect)
+ return;
+
// qDebug() << "setClipRect" << clipSpanHeight << count << allocated << rect;
hasRectClip = true;
clipRect = rect;
@@ -4352,6 +4425,11 @@ void QClipData::setClipRect(const QRect &rect)
ymin = qMin(rect.y(), clipSpanHeight);
ymax = qMin(rect.y() + rect.height(), clipSpanHeight);
+ if (m_spans) {
+ delete m_spans;
+ m_spans = 0;
+ }
+
// qDebug() << xmin << xmax << ymin << ymax;
}
@@ -4375,6 +4453,12 @@ void QClipData::setClipRegion(const QRegion &region)
ymin = rect.y();
ymax = rect.y() + rect.height();
}
+
+ if (m_spans) {
+ delete m_spans;
+ m_spans = 0;
+ }
+
}
/*!
diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h
index 0f8060a..26a2b3f 100644
--- a/src/gui/painting/qpaintengine_raster_p.h
+++ b/src/gui/painting/qpaintengine_raster_p.h
@@ -256,7 +256,7 @@ private:
void init();
void fillRect(const QRectF &rect, QSpanData *data);
- void drawBitmap(const QPointF &pos, const QPixmap &image, QSpanData *fill);
+ void drawBitmap(const QPointF &pos, const QImage &image, QSpanData *fill);
void drawCachedGlyphs(const QPointF &p, const QTextItemInt &ti);
diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp
index e9f1bb3..39ce59f 100644
--- a/src/gui/painting/qpaintengine_x11.cpp
+++ b/src/gui/painting/qpaintengine_x11.cpp
@@ -62,6 +62,7 @@
#include <private/qpaintengine_x11_p.h>
#include <private/qfontengine_x11_p.h>
#include <private/qwidget_p.h>
+#include <private/qpainterpath_p.h>
#include "qpen.h"
#include "qcolor.h"
@@ -1479,14 +1480,10 @@ void QX11PaintEngine::drawEllipse(const QRect &rect)
return;
}
d->setupAdaptedOrigin(rect.topLeft());
- if (d->has_brush) { // draw filled ellipse
- if (!d->has_pen) {
- XFillArc(d->dpy, d->hd, d->gc_brush, x, y, w-1, h-1, 0, 360*64);
+ if (d->has_brush) { // draw filled ellipse
+ XFillArc(d->dpy, d->hd, d->gc_brush, x, y, w, h, 0, 360*64);
+ if (!d->has_pen) // make smoother outline
XDrawArc(d->dpy, d->hd, d->gc_brush, x, y, w-1, h-1, 0, 360*64);
- return;
- } else{
- XFillArc(d->dpy, d->hd, d->gc_brush, x, y, w, h, 0, 360*64);
- }
}
if (d->has_pen) // draw outline
XDrawArc(d->dpy, d->hd, d->gc, x, y, w, h, 0, 360*64);
@@ -1760,9 +1757,14 @@ void QX11PaintEngine::drawPath(const QPainterPath &path)
QPainterPath stroke;
qreal width = d->cpen.widthF();
QPolygonF poly;
+ QRectF deviceRect(0, 0, d->pdev->width(), d->pdev->height());
// necessary to get aliased alphablended primitives to be drawn correctly
if (d->cpen.isCosmetic() || d->has_scaling_xform) {
- stroker.setWidth(width == 0 ? 1 : width * d->xform_scale);
+ if (d->cpen.isCosmetic())
+ stroker.setWidth(width == 0 ? 1 : width);
+ else
+ stroker.setWidth(width * d->xform_scale);
+ stroker.d_ptr->stroker.setClipRect(deviceRect);
stroke = stroker.createStroke(path * d->matrix);
if (stroke.isEmpty())
return;
@@ -1770,6 +1772,7 @@ void QX11PaintEngine::drawPath(const QPainterPath &path)
d->fillPath(stroke, QX11PaintEnginePrivate::PenGC, false);
} else {
stroker.setWidth(width);
+ stroker.d_ptr->stroker.setClipRect(d->matrix.inverted().mapRect(deviceRect));
stroke = stroker.createStroke(path);
if (stroke.isEmpty())
return;
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index e2d9b32..65d87fa 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -1293,7 +1293,7 @@ void QPainterPrivate::updateState(QPainterState *newState)
destination.
Note that composition transformation operates pixelwise. For that
- reason, there is a difference between using the grahic primitive
+ reason, there is a difference between using the graphic primitive
itself and its bounding rectangle: The bounding rect contains
pixels with alpha == 0 (i.e the pixels surrounding the
primitive). These pixels will overwrite the other image's pixels,
@@ -1465,8 +1465,8 @@ bool QPainter::isActive() const
/*!
Initializes the painters pen, background and font to the same as
- the given \a widget. Call this function after begin() while the
- painter is active.
+ the given \a widget. This function is called automatically when the
+ painter is opened on a QWidget.
\sa begin(), {QPainter#Settings}{Settings}
*/
@@ -1484,7 +1484,9 @@ void QPainter::initFrom(const QWidget *widget)
d->state->bgBrush = pal.brush(widget->backgroundRole());
d->state->deviceFont = QFont(widget->font(), const_cast<QWidget*> (widget));
d->state->font = d->state->deviceFont;
- if (d->engine) {
+ if (d->extended) {
+ d->extended->penChanged();
+ } else if (d->engine) {
d->engine->setDirty(QPaintEngine::DirtyPen);
d->engine->setDirty(QPaintEngine::DirtyBrush);
d->engine->setDirty(QPaintEngine::DirtyFont);
@@ -2371,6 +2373,11 @@ void QPainter::setClipping(bool enable)
Returns the currently set clip region. Note that the clip region
is given in logical coordinates.
+ \warning QPainter does not store the combined clip explicitly as
+ this is handled by the underlying QPaintEngine, so the path is
+ recreated on demand and transformed to the current logical
+ coordinate system. This is potentially an expensive operation.
+
\sa setClipRegion(), clipPath(), setClipping()
*/
@@ -2486,6 +2493,11 @@ extern QPainterPath qt_regionToPath(const QRegion &region);
Returns the currently clip as a path. Note that the clip path is
given in logical coordinates.
+ \warning QPainter does not store the combined clip explicitly as
+ this is handled by the underlying QPaintEngine, so the path is
+ recreated on demand and transformed to the current logical
+ coordinate system. This is potentially an expensive operation.
+
\sa setClipPath(), clipRegion(), setClipping()
*/
QPainterPath QPainter::clipPath() const
@@ -5155,7 +5167,7 @@ void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm)
Q_D(QPainter);
- if (!d->engine || pm.isNull())
+ if (!d->engine)
return;
#ifndef QT_NO_DEBUG
@@ -5173,6 +5185,9 @@ void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm)
int w = pm.width();
int h = pm.height();
+ if (w <= 0)
+ return;
+
// Emulate opaque background for bitmaps
if (d->state->bgMode == Qt::OpaqueMode && pm.isQBitmap()) {
fillRect(QRectF(x, y, w, h), d->state->bgBrush.color());
diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp
index bb07f81..e1f5eea 100644
--- a/src/gui/painting/qpainterpath.cpp
+++ b/src/gui/painting/qpainterpath.cpp
@@ -1725,7 +1725,7 @@ static void qt_painterpath_isect_curve(const QBezier &bezier, const QPointF &pt,
*/
bool QPainterPath::contains(const QPointF &pt) const
{
- if (isEmpty())
+ if (isEmpty() || !controlPointRect().contains(pt))
return false;
QPainterPathData *d = d_func();
@@ -2387,21 +2387,13 @@ void qt_path_stroke_cubic_to(qfixed c1x, qfixed c1y,
\sa QPen, QBrush
*/
-class QPainterPathStrokerPrivate
+QPainterPathStrokerPrivate::QPainterPathStrokerPrivate()
+ : dashOffset(0)
{
-public:
- QPainterPathStrokerPrivate()
- : dashOffset(0)
- {
- stroker.setMoveToHook(qt_path_stroke_move_to);
- stroker.setLineToHook(qt_path_stroke_line_to);
- stroker.setCubicToHook(qt_path_stroke_cubic_to);
- }
-
- QStroker stroker;
- QVector<qfixed> dashPattern;
- qreal dashOffset;
-};
+ stroker.setMoveToHook(qt_path_stroke_move_to);
+ stroker.setLineToHook(qt_path_stroke_line_to);
+ stroker.setCubicToHook(qt_path_stroke_cubic_to);
+}
/*!
Creates a new stroker.
@@ -2445,6 +2437,7 @@ QPainterPath QPainterPathStroker::createStroke(const QPainterPath &path) const
QDashStroker dashStroker(&d->stroker);
dashStroker.setDashPattern(d->dashPattern);
dashStroker.setDashOffset(d->dashOffset);
+ dashStroker.setClipRect(d->stroker.clipRect());
dashStroker.strokePath(path, &stroke, QTransform());
}
stroke.setFillRule(Qt::WindingFill);
diff --git a/src/gui/painting/qpainterpath.h b/src/gui/painting/qpainterpath.h
index 88fb19d..6cd2af8 100644
--- a/src/gui/painting/qpainterpath.h
+++ b/src/gui/painting/qpainterpath.h
@@ -277,6 +277,8 @@ public:
QPainterPath createStroke(const QPainterPath &path) const;
private:
+ friend class QX11PaintEngine;
+
QPainterPathStrokerPrivate *d_ptr;
};
diff --git a/src/gui/painting/qpainterpath_p.h b/src/gui/painting/qpainterpath_p.h
index 93f9704..29c48df 100644
--- a/src/gui/painting/qpainterpath_p.h
+++ b/src/gui/painting/qpainterpath_p.h
@@ -61,9 +61,20 @@
#include <qdebug.h>
#include <private/qvectorpath_p.h>
+#include <private/qstroker_p.h>
QT_BEGIN_NAMESPACE
+class QPainterPathStrokerPrivate
+{
+public:
+ QPainterPathStrokerPrivate();
+
+ QStroker stroker;
+ QVector<qfixed> dashPattern;
+ qreal dashOffset;
+};
+
class QPolygonF;
class QVectorPathConverter;
diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp
index b010209..55006f6 100644
--- a/src/gui/painting/qpdf.cpp
+++ b/src/gui/painting/qpdf.cpp
@@ -1106,6 +1106,11 @@ void QPdfBaseEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
if (!d->hasPen || (d->clipEnabled && d->allClipped))
return;
+ if (d->stroker.matrix.type() >= QTransform::TxProject) {
+ QPaintEngine::drawTextItem(p, textItem);
+ return;
+ }
+
*d->currentPage << "q\n";
if(!d->simplePen)
*d->currentPage << QPdf::generateMatrix(d->stroker.matrix);
diff --git a/src/gui/painting/qprintengine_mac.mm b/src/gui/painting/qprintengine_mac.mm
index 7a77e47..b1216b7 100644
--- a/src/gui/painting/qprintengine_mac.mm
+++ b/src/gui/painting/qprintengine_mac.mm
@@ -62,6 +62,10 @@ bool QMacPrintEngine::begin(QPaintDevice *dev)
{
Q_D(QMacPrintEngine);
+ Q_ASSERT(dev && dev->devType() == QInternal::Printer);
+ if (!static_cast<QPrinter *>(dev)->isValid())
+ return false;
+
if (d->state == QPrinter::Idle && !d->isPrintSessionInitialized()) // Need to reinitialize
d->initialize();
@@ -121,24 +125,8 @@ bool QMacPrintEngine::end()
if(d->paintEngine->type() == QPaintEngine::CoreGraphics)
static_cast<QCoreGraphicsPaintEngine*>(d->paintEngine)->d_func()->hd = 0;
d->paintEngine->end();
- if (d->state != QPrinter::Idle) {
-#ifndef QT_MAC_USE_COCOA
- if (d->shouldSuppressStatus()) {
- PMSessionEndPageNoDialog(d->session);
- PMSessionEndDocumentNoDialog(d->session);
- } else {
- PMSessionEndPage(d->session);
- PMSessionEndDocument(d->session);
- }
- PMRelease(d->session);
-#else
- PMSessionEndPageNoDialog(d->session);
- PMSessionEndDocumentNoDialog(d->session);
- [d->printInfo release];
-#endif
- d->printInfo = 0;
- d->session = 0;
- }
+ if (d->state != QPrinter::Idle)
+ d->releaseSession();
d->state = QPrinter::Idle;
return true;
}
@@ -509,6 +497,26 @@ void QMacPrintEnginePrivate::initialize()
}
}
+void QMacPrintEnginePrivate::releaseSession()
+{
+#ifndef QT_MAC_USE_COCOA
+ if (shouldSuppressStatus()) {
+ PMSessionEndPageNoDialog(session);
+ PMSessionEndDocumentNoDialog(session);
+ } else {
+ PMSessionEndPage(session);
+ PMSessionEndDocument(session);
+ }
+ PMRelease(session);
+#else
+ PMSessionEndPageNoDialog(session);
+ PMSessionEndDocumentNoDialog(session);
+ [printInfo release];
+#endif
+ printInfo = 0;
+ session = 0;
+}
+
bool QMacPrintEnginePrivate::newPage_helper()
{
Q_Q(QMacPrintEngine);
@@ -737,6 +745,7 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
d->setPaperSize(QPrinter::PaperSize(value.toInt()));
break;
case PPK_PrinterName: {
+ bool printerNameSet = false;
OSStatus status = noErr;
QCFType<CFArrayRef> printerList;
status = PMServerCreatePrinterList(kPMServerLocal, &printerList);
@@ -747,12 +756,18 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
QString name = QCFString::toQString(PMPrinterGetName(printer));
if (name == value.toString()) {
status = PMSessionSetCurrentPMPrinter(d->session, printer);
+ printerNameSet = true;
break;
}
}
}
if (status != noErr)
qWarning("QMacPrintEngine::setPrinterName: Error setting printer: %ld", long(status));
+ if (!printerNameSet) {
+ qWarning("QMacPrintEngine::setPrinterName: Failed to set printer named '%s'.", qPrintable(value.toString()));
+ d->releaseSession();
+ d->state = QPrinter::Idle;
+ }
break; }
case PPK_SuppressSystemPrintStatus:
d->suppressStatus = value.toBool();
@@ -876,17 +891,12 @@ QVariant QMacPrintEngine::property(PrintEnginePropertyKey key) const
ret = r;
break; }
case PPK_PrinterName: {
- CFIndex currIndex;
- PMPrinter unused;
- QCFType<CFArrayRef> printerList;
- OSStatus status = PMSessionCreatePrinterList(d->session, &printerList, &currIndex, &unused);
+ PMPrinter printer;
+ OSStatus status = PMSessionGetCurrentPrinter(d->session, &printer);
if (status != noErr)
- qWarning("QMacPrintEngine::printerName: Problem getting list of printers: %ld", long(status));
- if (currIndex != -1 && printerList && currIndex < CFArrayGetCount(printerList)) {
- const CFStringRef name = static_cast<CFStringRef>(CFArrayGetValueAtIndex(printerList, currIndex));
- if (name)
- ret = QCFString::toQString(name);
- }
+ qWarning("QMacPrintEngine::printerName: Failed getting current PMPrinter: %ld", long(status));
+ if (printer)
+ ret = QCFString::toQString(PMPrinterGetName(printer));
break; }
case PPK_Resolution: {
ret = d->resolution.hRes;
diff --git a/src/gui/painting/qprintengine_mac_p.h b/src/gui/painting/qprintengine_mac_p.h
index 5e18845..bc917e7 100644
--- a/src/gui/painting/qprintengine_mac_p.h
+++ b/src/gui/painting/qprintengine_mac_p.h
@@ -143,6 +143,7 @@ public:
hasCustomPaperSize(false), hasCustomPageMargins(false) {}
~QMacPrintEnginePrivate();
void initialize();
+ void releaseSession();
bool newPage_helper();
void setPaperSize(QPrinter::PaperSize ps);
QPrinter::PaperSize paperSize() const;
diff --git a/src/gui/painting/qprintengine_win.cpp b/src/gui/painting/qprintengine_win.cpp
index d48b525..7601beb 100644
--- a/src/gui/painting/qprintengine_win.cpp
+++ b/src/gui/painting/qprintengine_win.cpp
@@ -369,7 +369,7 @@ void QWin32PrintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem
QRgb brushColor = state->pen().brush().color().rgb();
bool fallBack = state->pen().brush().style() != Qt::SolidPattern
|| qAlpha(brushColor) != 0xff
- || QT_WA_INLINE(false, d->txop >= QTransform::TxScale)
+ || QT_WA_INLINE(d->txop >= QTransform::TxProject, d->txop >= QTransform::TxScale)
|| ti.fontEngine->type() != QFontEngine::Win;
@@ -1532,7 +1532,7 @@ QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const
value = rect;
} else {
value = QTransform(1/d->stretch_x, 0, 0, 1/d->stretch_y, 0, 0)
- .mapRect(d->fullPage ? d->devPaperRect : d->devPageRect);
+ .mapRect(d->fullPage ? d->devPhysicalPageRect : d->devPageRect);
}
break;
diff --git a/src/gui/painting/qprinter.cpp b/src/gui/painting/qprinter.cpp
index 413f4a1..4f3e71c 100644
--- a/src/gui/painting/qprinter.cpp
+++ b/src/gui/painting/qprinter.cpp
@@ -284,6 +284,10 @@ void QPrinterPrivate::addToManualSetList(QPrintEngine::PrintEnginePropertyKey ke
to send PostScript or PDF output to the printer. As an alternative,
the printProgram() function can be used to specify the command or utility
to use instead of the system default.
+
+ Note that setting parameters like paper size and resolution on an
+ invalid printer is undefined. You can use QPrinter::isValid() to
+ verify this before changing any parameters.
QPrinter supports a number of parameters, most of which can be
changed by the end user through a \l{QPrintDialog}{print dialog}. In
@@ -849,7 +853,7 @@ void QPrinter::setPrinterName(const QString &name)
Returns true if the printer currently selected is a valid printer
in the system, or a pure PDF/PostScript printer; otherwise returns false.
- To detect other failures check the output of QPainter::begin() or QPainter::nextPage().
+ To detect other failures check the output of QPainter::begin() or QPrinter::newPage().
\snippet doc/src/snippets/printing-qprinter/errors.cpp 0
diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp
index f728f9d..c88af7c 100644
--- a/src/gui/painting/qregion.cpp
+++ b/src/gui/painting/qregion.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qregion.h"
+#include "qpainterpath.h"
#include "qpolygon.h"
#include "qbuffer.h"
#include "qdatastream.h"
@@ -49,7 +50,6 @@
#include <qdebug.h>
#if defined(Q_OS_UNIX) || defined(Q_OS_WINCE)
-#include "qpainterpath.h"
#include "qimage.h"
#include "qbitmap.h"
#include <stdlib.h>
@@ -65,9 +65,17 @@ QT_BEGIN_NAMESPACE
\ingroup shared
QRegion is used with QPainter::setClipRegion() to limit the paint
- area to what needs to be painted. There is also a
- QWidget::repaint() function that takes a QRegion parameter.
- QRegion is the best tool for reducing flicker.
+ area to what needs to be painted. There is also a QWidget::repaint()
+ function that takes a QRegion parameter. QRegion is the best tool for
+ minimizing the amount of screen area to be updated by a repaint.
+
+ This class is not suitable for constructing shapes for rendering, especially
+ as outlines. Use QPainterPath to create paths and shapes for use with
+ QPainter.
+
+ QRegion is an \l{implicitly shared} class.
+
+ \section1 Creating and Using Regions
A region can be created from a rectangle, an ellipse, a polygon or
a bitmap. Complex regions may be created by combining simple
@@ -84,8 +92,6 @@ QT_BEGIN_NAMESPACE
Example of using complex regions:
\snippet doc/src/snippets/code/src_gui_painting_qregion.cpp 0
- QRegion is an \l{implicitly shared} class.
-
\warning Due to window system limitations, the whole coordinate space for a
region is limited to the points between -32767 and 32767 on Windows
95/98/ME. You can circumvent this limitation by using a QPainterPath.
@@ -93,7 +99,7 @@ QT_BEGIN_NAMESPACE
\section1 Additional License Information
On Embedded Linux, Windows CE and X11 platforms, parts of this class rely on
- code obtained under the following license:
+ code obtained under the following licenses:
\legalese
Copyright (c) 1987 X Consortium
@@ -120,9 +126,7 @@ QT_BEGIN_NAMESPACE
in this Software without prior written authorization from the X Consortium.
\endlegalese
- \raw HTML
- <hr />
- \endraw
+ \br
\legalese
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp
index da8c428..af27fd5 100644
--- a/src/gui/painting/qtransform.cpp
+++ b/src/gui/painting/qtransform.cpp
@@ -168,10 +168,10 @@ QT_BEGIN_NAMESPACE
\image qtransform-representation.png
- A QTransform object contains a 3 x 3 matrix. The \c dx and \c dy
- elements specify horizontal and vertical translation. The \c m11
- and \c m22 elements specify horizontal and vertical scaling. The
- \c m21 and \c m12 elements specify horizontal and vertical \e shearing.
+ A QTransform object contains a 3 x 3 matrix. The \c m31 (\c dx) and
+ \c m32 (\c dy) elements specify horizontal and vertical translation.
+ The \c m11 and \c m22 elements specify horizontal and vertical scaling.
+ The \c m21 and \c m12 elements specify horizontal and vertical \e shearing.
And finally, the \c m13 and \c m23 elements specify horizontal and vertical
projection, with \c m33 as an additional projection factor.
@@ -246,8 +246,10 @@ QTransform::QTransform()
}
/*!
- Constructs a matrix with the elements, \a h11, \a h12, \a h13,
- \a h21, \a h22, \a h23, \a h31, \a h32, \a h33.
+ \fn QTransform::QTransform(qreal m11, qreal m12, qreal m13, qreal m21, qreal m22, qreal m23, qreal m31, qreal m32, qreal m33)
+
+ Constructs a matrix with the elements, \a m11, \a m12, \a m13,
+ \a m21, \a m22, \a m23, \a m31, \a m32, \a m33.
\sa setMatrix()
*/
@@ -263,8 +265,9 @@ QTransform::QTransform(qreal h11, qreal h12, qreal h13,
}
/*!
- Constructs a matrix with the elements, \a h11, \a h12, \a h21, \a
- h22, \a dx and \a dy.
+ \fn QTransform::QTransform(qreal m11, qreal m12, qreal m21, qreal m22, qreal dx, qreal dy)
+
+ Constructs a matrix with the elements, \a m11, \a m12, \a m21, \a m22, \a dx and \a dy.
\sa setMatrix()
*/
@@ -396,6 +399,9 @@ QTransform QTransform::inverted(bool *invertible) const
*/
QTransform & QTransform::translate(qreal dx, qreal dy)
{
+ if (dx == 0 && dy == 0)
+ return *this;
+
switch(type()) {
case TxNone:
affine._dx = dx;
@@ -432,7 +438,10 @@ QTransform & QTransform::translate(qreal dx, qreal dy)
QTransform QTransform::fromTranslate(qreal dx, qreal dy)
{
QTransform transform(1, 0, 0, 1, dx, dy);
- transform.m_dirty = TxTranslate;
+ if (dx == 0 && dy == 0)
+ transform.m_dirty = TxNone;
+ else
+ transform.m_dirty = TxTranslate;
return transform;
}
@@ -444,6 +453,9 @@ QTransform QTransform::fromTranslate(qreal dx, qreal dy)
*/
QTransform & QTransform::scale(qreal sx, qreal sy)
{
+ if (sx == 1 && sy == 1)
+ return *this;
+
switch(type()) {
case TxNone:
case TxTranslate:
@@ -478,7 +490,10 @@ QTransform & QTransform::scale(qreal sx, qreal sy)
QTransform QTransform::fromScale(qreal sx, qreal sy)
{
QTransform transform(sx, 0, 0, sy, 0, 0);
- transform.m_dirty = TxScale;
+ if (sx == 1 && sy == 1)
+ transform.m_dirty = TxNone;
+ else
+ transform.m_dirty = TxScale;
return transform;
}
@@ -541,6 +556,9 @@ const qreal inv_dist_to_plane = 1. / 1024.;
*/
QTransform & QTransform::rotate(qreal a, Qt::Axis axis)
{
+ if (a == 0)
+ return *this;
+
qreal sina = 0;
qreal cosa = 0;
if (a == 90. || a == -270.)
@@ -712,7 +730,15 @@ bool QTransform::operator!=(const QTransform &o) const
*/
QTransform & QTransform::operator*=(const QTransform &o)
{
- TransformationType t = qMax(type(), o.type());
+ const TransformationType otherType = o.type();
+ if (otherType == TxNone)
+ return *this;
+
+ const TransformationType thisType = type();
+ if (thisType == TxNone)
+ return operator=(o);
+
+ TransformationType t = qMax(thisType, otherType);
switch(t) {
case TxNone:
break;
@@ -1219,7 +1245,8 @@ static QPolygonF mapProjective(const QTransform &transform, const QPolygonF &pol
*/
QPolygonF QTransform::map(const QPolygonF &a) const
{
- if (type() >= QTransform::TxProject)
+ TransformationType t = type();
+ if (t >= QTransform::TxProject)
return mapProjective(*this, a);
int size = a.size();
@@ -1228,7 +1255,6 @@ QPolygonF QTransform::map(const QPolygonF &a) const
const QPointF *da = a.constData();
QPointF *dp = p.data();
- TransformationType t = type();
for(i = 0; i < size; ++i) {
MAP(da[i].xp, da[i].yp, dp[i].xp, dp[i].yp);
}
@@ -1246,7 +1272,8 @@ QPolygonF QTransform::map(const QPolygonF &a) const
*/
QPolygon QTransform::map(const QPolygon &a) const
{
- if (type() >= QTransform::TxProject)
+ TransformationType t = type();
+ if (t >= QTransform::TxProject)
return mapProjective(*this, QPolygonF(a)).toPolygon();
int size = a.size();
@@ -1255,7 +1282,6 @@ QPolygon QTransform::map(const QPolygon &a) const
const QPoint *da = a.constData();
QPoint *dp = p.data();
- TransformationType t = type();
for(i = 0; i < size; ++i) {
qreal nx = 0, ny = 0;
MAP(da[i].xp, da[i].yp, nx, ny);
@@ -1689,13 +1715,12 @@ QRect QTransform::mapRect(const QRect &rect) const
return QRect(x, y, w, h);
} else if (t < TxProject) {
// see mapToPolygon for explanations of the algorithm.
- qreal x0 = 0, y0 = 0;
- qreal x, y;
- MAP(rect.left(), rect.top(), x0, y0);
- qreal xmin = x0;
- qreal ymin = y0;
- qreal xmax = x0;
- qreal ymax = y0;
+ qreal x = 0, y = 0;
+ MAP(rect.left(), rect.top(), x, y);
+ qreal xmin = x;
+ qreal ymin = y;
+ qreal xmax = x;
+ qreal ymax = y;
MAP(rect.right() + 1, rect.top(), x, y);
xmin = qMin(xmin, x);
ymin = qMin(ymin, y);
@@ -1756,13 +1781,12 @@ QRectF QTransform::mapRect(const QRectF &rect) const
}
return QRectF(x, y, w, h);
} else if (t < TxProject) {
- qreal x0 = 0, y0 = 0;
- qreal x, y;
- MAP(rect.x(), rect.y(), x0, y0);
- qreal xmin = x0;
- qreal ymin = y0;
- qreal xmax = x0;
- qreal ymax = y0;
+ qreal x = 0, y = 0;
+ MAP(rect.x(), rect.y(), x, y);
+ qreal xmin = x;
+ qreal ymin = y;
+ qreal xmax = x;
+ qreal ymax = y;
MAP(rect.x() + rect.width(), rect.y(), x, y);
xmin = qMin(xmin, x);
ymin = qMin(ymin, y);
@@ -1856,7 +1880,7 @@ const QMatrix &QTransform::toAffine() const
QTransform::TransformationType QTransform::type() const
{
if (m_dirty >= m_type) {
- if (m_dirty > TxShear && (!qFuzzyCompare(m_13 + 1, 1) || !qFuzzyCompare(m_23 + 1, 1)))
+ if (m_dirty > TxShear && (!qFuzzyCompare(m_13 + 1, 1) || !qFuzzyCompare(m_23 + 1, 1) || !qFuzzyCompare(m_33, 1)))
m_type = TxProject;
else if (m_dirty > TxScale && (!qFuzzyCompare(affine._m12 + 1, 1) || !qFuzzyCompare(affine._m21 + 1, 1))) {
const qreal dot = affine._m11 * affine._m12 + affine._m21 * affine._m22;
@@ -1864,7 +1888,7 @@ QTransform::TransformationType QTransform::type() const
m_type = TxRotate;
else
m_type = TxShear;
- } else if (m_dirty > TxTranslate && (!qFuzzyCompare(affine._m11, 1) || !qFuzzyCompare(affine._m22, 1) || !qFuzzyCompare(m_33, 1)))
+ } else if (m_dirty > TxTranslate && (!qFuzzyCompare(affine._m11, 1) || !qFuzzyCompare(affine._m22, 1)))
m_type = TxScale;
else if (m_dirty > TxNone && (!qFuzzyCompare(affine._dx + 1, 1) || !qFuzzyCompare(affine._dy + 1, 1)))
m_type = TxTranslate;
@@ -2058,10 +2082,11 @@ QTransform::operator QVariant() const
Q_GUI_EXPORT
bool qt_scaleForTransform(const QTransform &transform, qreal *scale)
{
- if (transform.type() <= QTransform::TxTranslate) {
+ const QTransform::TransformationType type = transform.type();
+ if (type <= QTransform::TxTranslate) {
*scale = 1;
return true;
- } else if (transform.type() == QTransform::TxScale) {
+ } else if (type == QTransform::TxScale) {
const qreal xScale = qAbs(transform.m11());
const qreal yScale = qAbs(transform.m22());
*scale = qMax(xScale, yScale);
@@ -2073,7 +2098,7 @@ bool qt_scaleForTransform(const QTransform &transform, qreal *scale)
const qreal yScale = transform.m12() * transform.m12()
+ transform.m22() * transform.m22();
*scale = qSqrt(qMax(xScale, yScale));
- return transform.type() == QTransform::TxRotate && qFuzzyCompare(xScale, yScale);
+ return type == QTransform::TxRotate && qFuzzyCompare(xScale, yScale);
}
QT_END_NAMESPACE
diff --git a/src/gui/painting/qtransform.h b/src/gui/painting/qtransform.h
index de7ebcd..c76409b 100644
--- a/src/gui/painting/qtransform.h
+++ b/src/gui/painting/qtransform.h
@@ -257,6 +257,8 @@ inline qreal QTransform::dy() const
inline QTransform &QTransform::operator*=(qreal num)
{
+ if (num == 1.)
+ return *this;
affine._m11 *= num;
affine._m12 *= num;
m_13 *= num;
@@ -271,11 +273,15 @@ inline QTransform &QTransform::operator*=(qreal num)
}
inline QTransform &QTransform::operator/=(qreal div)
{
+ if (div == 0)
+ return *this;
div = 1/div;
return operator*=(div);
}
inline QTransform &QTransform::operator+=(qreal num)
{
+ if (num == 0)
+ return *this;
affine._m11 += num;
affine._m12 += num;
m_13 += num;
@@ -290,6 +296,8 @@ inline QTransform &QTransform::operator+=(qreal num)
}
inline QTransform &QTransform::operator-=(qreal num)
{
+ if (num == 0)
+ return *this;
affine._m11 -= num;
affine._m12 -= num;
m_13 -= num;
diff --git a/src/gui/painting/qwindowsurface.cpp b/src/gui/painting/qwindowsurface.cpp
index bcb0380..d941a24 100644
--- a/src/gui/painting/qwindowsurface.cpp
+++ b/src/gui/painting/qwindowsurface.cpp
@@ -310,10 +310,13 @@ void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset)
int lineskip = img.bytesPerLine();
int depth = img.depth() >> 3;
-
- const QRect r = rect & QRect(0, 0, img.width(), img.height());
+ const QRect imageRect(0, 0, img.width(), img.height());
+ const QRect r = rect & imageRect & imageRect.translated(-offset);
const QPoint p = rect.topLeft() + offset;
+ if (r.isEmpty())
+ return;
+
const uchar *src;
uchar *dest;