diff options
author | axis <qt-info@nokia.com> | 2009-04-24 14:03:55 (GMT) |
---|---|---|
committer | axis <qt-info@nokia.com> | 2009-04-27 07:09:01 (GMT) |
commit | e74c8dc65e2feffb9a55d00aee5ca634fba41df8 (patch) | |
tree | 3a131f9235fb6a455793178d8313655e4fd0036e /src/gui/painting | |
parent | 8f427b2b914d5b575a4a7c0ed65d2fb8f45acc76 (diff) | |
parent | 211bea9838bcc2acd7f54b65468fe1be2d81b1e0 (diff) | |
download | Qt-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')
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 ®ion) 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 ®ion); 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; |