diff options
author | Liang Qi <liang.qi@theqtcompany.com> | 2015-04-22 09:04:29 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@theqtcompany.com> | 2015-04-22 09:25:54 +0200 |
commit | aed5a7168354c6ae47687d20b4bd3f0adcc14f8e (patch) | |
tree | d2060479a7c12fdba8c1955e5d363754feffabb8 /src/gui | |
parent | d3d10cf23d61f4a011f1a7e9abdee1a92717e80f (diff) | |
parent | 628fa13ea4d6ff0e2e2ee76c9adfc78676de3c59 (diff) |
Merge remote-tracking branch 'origin/5.5' into dev
Conflicts:
src/corelib/statemachine/qstatemachine.cpp
src/corelib/statemachine/qstatemachine_p.h
src/gui/painting/qdrawhelper.cpp
src/plugins/platforms/xcb/qxcbnativeinterface.cpp
src/plugins/platforms/xcb/qxcbwindow.cpp
src/plugins/platforms/xcb/qxcbwindow.h
src/testlib/qtestblacklist.cpp
src/tools/qdoc/node.cpp
src/tools/qdoc/node.h
tests/auto/gui/painting/qcolor/tst_qcolor.cpp
Change-Id: I6c78b7b162001712d5774293f501b06b4ff32684
Diffstat (limited to 'src/gui')
37 files changed, 1334 insertions, 3132 deletions
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index b35012d4fe..cac3d268c5 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -4347,11 +4347,15 @@ int QImage::bitPlaneCount() const static QImage smoothScaled(const QImage &source, int w, int h) { QImage src = source; - bool canSkipConversion = (src.format() == QImage::Format_RGB32 || src.format() == QImage::Format_ARGB32_Premultiplied); + switch (src.format()) { + case QImage::Format_RGB32: + case QImage::Format_ARGB32_Premultiplied: #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN - canSkipConversion = canSkipConversion || (src.format() == QImage::Format_RGBX8888 || src.format() == QImage::Format_RGBA8888_Premultiplied); + case QImage::Format_RGBX8888: #endif - if (!canSkipConversion) { + case QImage::Format_RGBA8888_Premultiplied: + break; + default: if (src.hasAlphaChannel()) src = src.convertToFormat(QImage::Format_ARGB32_Premultiplied); else diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index 28e3a48689..8cb886e09b 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -117,7 +117,7 @@ static const uint *QT_FASTCALL convertRGB32ToARGB32PM(uint *buffer, const uint * return buffer; } -#ifdef QT_COMPILER_SUPPORTS_SSE4_1 +#if defined(QT_COMPILER_SUPPORTS_SSE4_1) && !defined(__SSE4_1__) extern const uint *QT_FASTCALL convertRGB32FromARGB32PM_sse4(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *); #endif @@ -144,7 +144,7 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio if (src->format == QImage::Format_RGB32) convertToARGB32PM = convertRGB32ToARGB32PM; if (dest->format == QImage::Format_RGB32) { -#ifdef QT_COMPILER_SUPPORTS_SSE4_1 +#if defined(QT_COMPILER_SUPPORTS_SSE4_1) && !defined(__SSE4_1__) if (qCpuHasFeature(SSE4_1)) convertFromARGB32PM = convertRGB32FromARGB32PM_sse4; else @@ -193,7 +193,7 @@ bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::Im if (data->format == QImage::Format_RGB32) convertToARGB32PM = convertRGB32ToARGB32PM; if (dst_format == QImage::Format_RGB32) { -#ifdef QT_COMPILER_SUPPORTS_SSE4_1 +#if defined(QT_COMPILER_SUPPORTS_SSE4_1) && !defined(__SSE4_1__) if (qCpuHasFeature(SSE4_1)) convertFromARGB32PM = convertRGB32FromARGB32PM_sse4; else diff --git a/src/gui/image/qimage_sse4.cpp b/src/gui/image/qimage_sse4.cpp index 5fad4f572a..fb63f5bff9 100644 --- a/src/gui/image/qimage_sse4.cpp +++ b/src/gui/image/qimage_sse4.cpp @@ -33,7 +33,6 @@ #include <qimage.h> #include <private/qdrawhelper_p.h> -#include <private/qdrawingprimitive_sse2_p.h> #include <private/qimage_p.h> #include <private/qsimd_p.h> @@ -45,7 +44,7 @@ const uint *QT_FASTCALL convertRGB32FromARGB32PM_sse4(uint *buffer, const uint * const QPixelLayout *, const QRgb *) { for (int i = 0; i < count; ++i) - buffer[i] = 0xff000000 | qUnpremultiply_sse4(src[i]); + buffer[i] = 0xff000000 | qUnpremultiply(src[i]); return buffer; } diff --git a/src/gui/kernel/qclipboard.cpp b/src/gui/kernel/qclipboard.cpp index 35e74946ee..402f5005fd 100644 --- a/src/gui/kernel/qclipboard.cpp +++ b/src/gui/kernel/qclipboard.cpp @@ -584,6 +584,6 @@ void QClipboard::emitChanged(Mode mode) emit changed(mode); } -#endif // QT_NO_CLIPBOARD - QT_END_NAMESPACE + +#endif // QT_NO_CLIPBOARD diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 9f73f019a3..926ec16f19 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -185,6 +185,7 @@ extern void qRegisterGuiVariant(); #ifndef QT_NO_ANIMATION extern void qRegisterGuiGetInterpolator(); #endif +extern void qInitBlendFunctions(); extern void qInitDrawhelperAsm(); extern void qInitImageConversions(); @@ -1279,6 +1280,8 @@ void QGuiApplicationPrivate::init() if (platform_integration == 0) createPlatformIntegration(); + // Set up blend function tables. + qInitBlendFunctions(); // Set up which span functions should be used in raster engine... qInitDrawhelperAsm(); // and QImage conversion functions @@ -2754,6 +2757,7 @@ void QGuiApplication::setPalette(const QPalette &pal) else *QGuiApplicationPrivate::app_pal = pal; applicationResourceFlags |= ApplicationPaletteExplicitlySet; + QCoreApplication::setAttribute(Qt::AA_SetPalette); emit qGuiApp->paletteChanged(*QGuiApplicationPrivate::app_pal); } @@ -2837,6 +2841,9 @@ void QGuiApplication::setWindowIcon(const QIcon &icon) if (!QGuiApplicationPrivate::app_icon) QGuiApplicationPrivate::app_icon = new QIcon(); *QGuiApplicationPrivate::app_icon = icon; + if (QGuiApplicationPrivate::platform_integration + && QGuiApplicationPrivate::platform_integration->hasCapability(QPlatformIntegration::ApplicationIcon)) + QGuiApplicationPrivate::platform_integration->setApplicationIcon(icon); if (QGuiApplicationPrivate::is_app_running && !QGuiApplicationPrivate::is_app_closing) QGuiApplicationPrivate::self->notifyWindowIconChanged(); } diff --git a/src/gui/kernel/qpaintdevicewindow.cpp b/src/gui/kernel/qpaintdevicewindow.cpp index b32ab3b34d..ff661d017d 100644 --- a/src/gui/kernel/qpaintdevicewindow.cpp +++ b/src/gui/kernel/qpaintdevicewindow.cpp @@ -60,6 +60,9 @@ QT_BEGIN_NAMESPACE \note Subsequent calls to this function before the next paint event will get ignored. + + \note For non-exposed windows the update is deferred until the + window becomes exposed again. */ void QPaintDeviceWindow::update() { @@ -70,26 +73,34 @@ void QPaintDeviceWindow::update() Marks the \a rect of the window as dirty and schedules a repaint. \note Subsequent calls to this function before the next paint - event will get ignored. + event will get ignored, but \a rect is added to the region to update. + + \note For non-exposed windows the update is deferred until the + window becomes exposed again. */ void QPaintDeviceWindow::update(const QRect &rect) { Q_D(QPaintDeviceWindow); d->dirtyRegion += rect; - requestUpdate(); + if (isExposed()) + requestUpdate(); } /*! Marks the \a region of the window as dirty and schedules a repaint. \note Subsequent calls to this function before the next paint - event will get ignored. + event will get ignored, but \a region is added to the region to update. + + \note For non-exposed windows the update is deferred until the + window becomes exposed again. */ void QPaintDeviceWindow::update(const QRegion ®ion) { Q_D(QPaintDeviceWindow); d->dirtyRegion += region; - requestUpdate(); + if (isExposed()) + requestUpdate(); } /*! @@ -168,6 +179,9 @@ void QPaintDeviceWindow::exposeEvent(QExposeEvent *exposeEvent) // sometimes relative to the parent, depending on the platform plugin. // We require local coords here. d->doFlush(QRect(QPoint(0, 0), size())); + } else if (!d->dirtyRegion.isEmpty()) { + // Updates while non-exposed were ignored. Schedule an update now. + requestUpdate(); } } diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp index f2a92e10df..4d973d47a5 100644 --- a/src/gui/kernel/qplatformintegration.cpp +++ b/src/gui/kernel/qplatformintegration.cpp @@ -231,6 +231,8 @@ QPlatformServices *QPlatformIntegration::services() const implementation for QOpenGLContext::getProcAddress() and support returning a function pointer also for the standard, non-extension functions. This capability is a prerequisite for dynamic OpenGL loading. + + \value ApplicationIcon The platform supports setting the application icon. (since 5.5) */ /*! @@ -394,6 +396,8 @@ QVariant QPlatformIntegration::styleHint(StyleHint hint) const return QPlatformTheme::defaultThemeHint(QPlatformTheme::TabFocusBehavior); case ReplayMousePressOutsidePopup: return true; + case ItemViewActivateItemOnSingleClick: + return QPlatformTheme::defaultThemeHint(QPlatformTheme::ItemViewActivateItemOnSingleClick); } return 0; @@ -544,4 +548,16 @@ QOpenGLContext::OpenGLModuleType QPlatformIntegration::openGLModuleType() } #endif +/*! + \since 5.5 + + Platform integration function for setting the application icon. + + \sa QGuiApplication::setWindowIcon() +*/ +void QPlatformIntegration::setApplicationIcon(const QIcon &icon) const +{ + Q_UNUSED(icon); +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatformintegration.h b/src/gui/kernel/qplatformintegration.h index 34639e6929..2aa502b3d2 100644 --- a/src/gui/kernel/qplatformintegration.h +++ b/src/gui/kernel/qplatformintegration.h @@ -90,7 +90,8 @@ public: WindowManagement, SyncState, RasterGLSurface, - AllGLFunctionsQueryable + AllGLFunctionsQueryable, + ApplicationIcon }; virtual ~QPlatformIntegration() { } @@ -146,7 +147,8 @@ public: ShowIsMaximized, MousePressAndHoldInterval, TabFocusBehavior, - ReplayMousePressOutsidePopup + ReplayMousePressOutsidePopup, + ItemViewActivateItemOnSingleClick }; virtual QVariant styleHint(StyleHint hint) const; @@ -169,7 +171,7 @@ public: #ifndef QT_NO_OPENGL virtual QOpenGLContext::OpenGLModuleType openGLModuleType(); #endif - + virtual void setApplicationIcon(const QIcon &icon) const; protected: void screenAdded(QPlatformScreen *screen, bool isPrimary = false); void destroyScreen(QPlatformScreen *screen); diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp index aa49d64309..36a71fe2da 100644 --- a/src/gui/kernel/qplatformtheme.cpp +++ b/src/gui/kernel/qplatformtheme.cpp @@ -434,6 +434,8 @@ QVariant QPlatformTheme::themeHint(ThemeHint hint) const return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::PasswordMaskCharacter); case QPlatformTheme::MousePressAndHoldInterval: return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::MousePressAndHoldInterval); + case QPlatformTheme::ItemViewActivateItemOnSingleClick: + return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::ItemViewActivateItemOnSingleClick); default: return QPlatformTheme::defaultThemeHint(hint); } diff --git a/src/gui/kernel/qstylehints.cpp b/src/gui/kernel/qstylehints.cpp index b7af2e759f..7ff0f9f860 100644 --- a/src/gui/kernel/qstylehints.cpp +++ b/src/gui/kernel/qstylehints.cpp @@ -377,4 +377,16 @@ Qt::TabFocusBehavior QStyleHints::tabFocusBehavior() const return Qt::TabFocusBehavior(themeableHint(QPlatformTheme::TabFocusBehavior, QPlatformIntegration::TabFocusBehavior).toInt()); } +/*! + \property QStyleHints::singleClickActivation + \brief \c true if items should be activated by single click, \b false + if they should be activated by double click instead. + + \since 5.5 +*/ +bool QStyleHints::singleClickActivation() const +{ + return themeableHint(QPlatformTheme::ItemViewActivateItemOnSingleClick, QPlatformIntegration::ItemViewActivateItemOnSingleClick).toBool(); +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qstylehints.h b/src/gui/kernel/qstylehints.h index 5fbc851ee9..82eb8a6f7d 100644 --- a/src/gui/kernel/qstylehints.h +++ b/src/gui/kernel/qstylehints.h @@ -61,6 +61,7 @@ class Q_GUI_EXPORT QStyleHints : public QObject Q_PROPERTY(int startDragVelocity READ startDragVelocity STORED false CONSTANT FINAL) Q_PROPERTY(bool useRtlExtensions READ useRtlExtensions STORED false CONSTANT FINAL) Q_PROPERTY(Qt::TabFocusBehavior tabFocusBehavior READ tabFocusBehavior STORED false CONSTANT FINAL) + Q_PROPERTY(bool singleClickActivation READ singleClickActivation STORED false CONSTANT FINAL) public: void setMouseDoubleClickInterval(int mouseDoubleClickInterval); @@ -83,6 +84,7 @@ public: bool useRtlExtensions() const; bool setFocusOnTouchRelease() const; Qt::TabFocusBehavior tabFocusBehavior() const; + bool singleClickActivation() const; Q_SIGNALS: void cursorFlashTimeChanged(int cursorFlashTime); diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 19f7cafbcb..e697efe31c 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -1075,6 +1075,10 @@ Qt::ScreenOrientation QWindow::contentOrientation() const Common values are 1.0 on normal displays and 2.0 on Apple "retina" displays. + \note For windows not backed by a platform window, meaning that create() was not + called, the function will fall back to QGuiApplication::devicePixelRatio() which in + turn returns the highest screen device pixel ratio found on the system. + \sa QScreen::devicePixelRatio(), QGuiApplication::devicePixelRatio() */ qreal QWindow::devicePixelRatio() const diff --git a/src/gui/opengl/qopengl.cpp b/src/gui/opengl/qopengl.cpp index 61d0614724..c8d33df4ba 100644 --- a/src/gui/opengl/qopengl.cpp +++ b/src/gui/opengl/qopengl.cpp @@ -36,6 +36,7 @@ #include "qopenglcontext.h" #include "qopenglfunctions.h" +#include "qoffscreensurface.h" #include <QtCore/QDebug> #include <QtCore/QJsonDocument> @@ -89,8 +90,8 @@ QOpenGLExtensionMatcher::QOpenGLExtensionMatcher() } /* Helpers to read out the list of features matching a device from - * a Chromium driver bug list of the format using a subset of keys - * (namely, matching by gl_vendor RegExp is not implemented): + * a Chromium driver bug list. Note that not all keys are supported and + * some may behave differently: gl_vendor is a substring match instead of regex. { "entries": [ { @@ -291,14 +292,14 @@ static bool matches(const QJsonObject &object, const QJsonValue vendorV = object.value(vendorIdKey()); if (vendorV.isString()) { - if (gpu.vendorId != vendorV.toString().toUInt(Q_NULLPTR, /* base */ 0)) - return false; + if (gpu.vendorId != vendorV.toString().toUInt(Q_NULLPTR, /* base */ 0)) + return false; } else { if (object.contains(glVendorKey())) { - qWarning().nospace() << "Id " << object.value(idKey()).toInt() - << ": Matching by " << glVendorKey() << " is not implemented."; - return false; - } + const QByteArray glVendorV = object.value(glVendorKey()).toString().toUtf8(); + if (!gpu.glVendor.contains(glVendorV)) + return false; + } } if (gpu.deviceId) { @@ -447,5 +448,30 @@ QSet<QString> QOpenGLConfig::gpuFeatures(const Gpu &gpu, const QString &fileName return gpuFeatures(gpu, OsTypeTerm::hostOs(), OsTypeTerm::hostKernelVersion(), fileName); } +QOpenGLConfig::Gpu QOpenGLConfig::Gpu::fromContext() +{ + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + QScopedPointer<QOpenGLContext> tmpContext; + QScopedPointer<QOffscreenSurface> tmpSurface; + if (!ctx) { + tmpContext.reset(new QOpenGLContext); + if (!tmpContext->create()) { + qWarning("QOpenGLConfig::Gpu::fromContext: Failed to create temporary context"); + return QOpenGLConfig::Gpu(); + } + tmpSurface.reset(new QOffscreenSurface); + tmpSurface->setFormat(tmpContext->format()); + tmpSurface->create(); + tmpContext->makeCurrent(tmpSurface.data()); + } + + QOpenGLConfig::Gpu gpu; + ctx = QOpenGLContext::currentContext(); + const GLubyte *p = ctx->functions()->glGetString(GL_VENDOR); + if (p) + gpu.glVendor = QByteArray(reinterpret_cast<const char *>(p)); + + return gpu; +} QT_END_NAMESPACE diff --git a/src/gui/opengl/qopengl_p.h b/src/gui/opengl/qopengl_p.h index e04ae05120..980e02aea6 100644 --- a/src/gui/opengl/qopengl_p.h +++ b/src/gui/opengl/qopengl_p.h @@ -74,16 +74,34 @@ private: class Q_GUI_EXPORT QOpenGLConfig { public: - struct Gpu { + struct Q_GUI_EXPORT Gpu { Gpu() : vendorId(0), deviceId(0) {} - bool isValid() const { return deviceId; } + bool isValid() const { return deviceId || !glVendor.isEmpty(); } bool equals(const Gpu &other) const { - return vendorId == other.vendorId && deviceId == other.deviceId && driverVersion == other.driverVersion; + return vendorId == other.vendorId && deviceId == other.deviceId && driverVersion == other.driverVersion + && glVendor == other.glVendor; } uint vendorId; uint deviceId; QVersionNumber driverVersion; + QByteArray glVendor; + + static Gpu fromDevice(uint vendorId, uint deviceId, QVersionNumber driverVersion) { + Gpu gpu; + gpu.vendorId = vendorId; + gpu.deviceId = deviceId; + gpu.driverVersion = driverVersion; + return gpu; + } + + static Gpu fromGLVendor(const QByteArray &glVendor) { + Gpu gpu; + gpu.glVendor = glVendor; + return gpu; + } + + static Gpu fromContext(); }; static QSet<QString> gpuFeatures(const Gpu &gpu, diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp index 9bc9926b70..baa702a982 100644 --- a/src/gui/opengl/qopengltexture.cpp +++ b/src/gui/opengl/qopengltexture.cpp @@ -120,7 +120,8 @@ QOpenGLTexturePrivate::QOpenGLTexturePrivate(QOpenGLTexture::Target textureTarge swizzleMask[2] = QOpenGLTexture::BlueValue; swizzleMask[3] = QOpenGLTexture::AlphaValue; - wrapModes[0] = wrapModes[1] = wrapModes[2] = QOpenGLTexture::ClampToEdge; + wrapModes[0] = wrapModes[1] = wrapModes[2] = target == QOpenGLTexture::TargetRectangle + ? QOpenGLTexture::ClampToEdge : QOpenGLTexture::Repeat; } QOpenGLTexturePrivate::~QOpenGLTexturePrivate() @@ -215,7 +216,8 @@ void QOpenGLTexturePrivate::destroy() swizzleMask[2] = QOpenGLTexture::BlueValue; swizzleMask[3] = QOpenGLTexture::AlphaValue; - wrapModes[0] = wrapModes[1] = wrapModes[2] = QOpenGLTexture::ClampToEdge; + wrapModes[0] = wrapModes[1] = wrapModes[2] = target == QOpenGLTexture::TargetRectangle + ? QOpenGLTexture::ClampToEdge : QOpenGLTexture::Repeat; } void QOpenGLTexturePrivate::bind() @@ -1393,7 +1395,7 @@ QOpenGLTexture::WrapMode QOpenGLTexturePrivate::wrapMode(QOpenGLTexture::Coordin case QOpenGLTexture::DirectionT: case QOpenGLTexture::DirectionR: - qWarning("QOpenGLTexture::setWrapMode() direction not valid for this texture target"); + qWarning("QOpenGLTexture::wrapMode() direction not valid for this texture target"); return QOpenGLTexture::Repeat; } break; @@ -1413,7 +1415,7 @@ QOpenGLTexture::WrapMode QOpenGLTexturePrivate::wrapMode(QOpenGLTexture::Coordin return wrapModes[1]; case QOpenGLTexture::DirectionR: - qWarning("QOpenGLTexture::setWrapMode() direction not valid for this texture target"); + qWarning("QOpenGLTexture::wrapMode() direction not valid for this texture target"); return QOpenGLTexture::Repeat; } break; diff --git a/src/gui/opengl/qopengltexturehelper.cpp b/src/gui/opengl/qopengltexturehelper.cpp index 3635a7dd1b..440fdad081 100644 --- a/src/gui/opengl/qopengltexturehelper.cpp +++ b/src/gui/opengl/qopengltexturehelper.cpp @@ -179,7 +179,7 @@ QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context) GetTexParameteriv = ::glGetTexParameteriv; GetTexParameterfv = ::glGetTexParameterfv; GetTexImage = 0; - TexImage2D = ::glTexImage2D; + TexImage2D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(::glTexImage2D); TexImage1D = 0; TexParameteriv = ::glTexParameteriv; TexParameteri = ::glTexParameteri; diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index bd98f4ae46..791b5f1a9a 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -96,7 +96,8 @@ SOURCES += \ SSE2_SOURCES += painting/qdrawhelper_sse2.cpp SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp -SSE4_1_SOURCES += painting/qdrawhelper_sse4.cpp +SSE4_1_SOURCES += painting/qdrawhelper_sse4.cpp \ + painting/qimagescale_sse4.cpp AVX2_SOURCES += painting/qdrawhelper_avx2.cpp !ios { diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp index 478fe6564c..b3710411c9 100644 --- a/src/gui/painting/qblendfunctions.cpp +++ b/src/gui/painting/qblendfunctions.cpp @@ -432,10 +432,10 @@ static void qt_blend_argb32pm_on_a2rgb30pm(uchar *destPixels, int dbpl, } template<QtPixelOrder PixelOrder> -void qt_blend_rgb32_on_rgb30(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha) +static void qt_blend_rgb32_on_rgb30(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + int w, int h, + int const_alpha) { #ifdef QT_DEBUG_DRAW fprintf(stdout, "qt_blend_rgb32_on_rgb30: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n", @@ -496,10 +496,10 @@ static void qt_blend_a2rgb30pm_on_a2rgb30pm(uchar *destPixels, int dbpl, } -void qt_blend_rgb30_on_rgb30(uchar *destPixels, int dbpl, - const uchar *srcPixels, int sbpl, - int w, int h, - int const_alpha) +static void qt_blend_rgb30_on_rgb30(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + int w, int h, + int const_alpha) { #ifdef QT_DEBUG_DRAW fprintf(stdout, "qt_blend_rgb30_on_rgb30: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n", @@ -740,2071 +740,75 @@ void qt_transform_image_argb32_on_argb32(uchar *destPixels, int dbpl, } } -SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = { - { // Format_Invalid - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGRs30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_Mono - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_MonoLSB - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_Indexed8 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_RGB32 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - qt_scale_image_rgb32_on_rgb32, // Format_RGB32, - 0, // Format_ARGB32, - qt_scale_image_argb32_on_argb32, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_ARGB32 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_ARGB32_Premultiplied - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - qt_scale_image_rgb32_on_rgb32, // Format_RGB32, - 0, // Format_ARGB32, - qt_scale_image_argb32_on_argb32, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_RGB16 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - qt_scale_image_argb32_on_rgb16, // Format_ARGB32_Premultiplied, - qt_scale_image_rgb16_on_rgb16, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_ARGB8565_Premultiplied - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_RGB666 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_ARGB6666_Premultiplied - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_RGB555 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_ARGB8555_Premultiplied - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_RGB888 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_RGB444 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_ARGB4444_Premultiplied - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_RGBX8888 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, -#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN - qt_scale_image_rgb32_on_rgb32, // Format_RGBX8888, - 0, // Format_RGBA8888, - qt_scale_image_argb32_on_argb32, // Format_RGBA8888_Premultiplied, -#else - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, -#endif - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_RGBA8888 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_RGBA8888_Premultiplied - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, -#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN - qt_scale_image_rgb32_on_rgb32, // Format_RGBX8888, - 0, // Format_RGBA8888, - qt_scale_image_argb32_on_argb32, // Format_RGBA8888_Premultiplied, -#else - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, -#endif - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_BGR30 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_A2BGR30_Premultiplied - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_RGB30 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_A2RGB30_Premultiplied - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_Alpha8 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_Grayscale8 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - } -}; - +SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats]; +SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats]; +SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFormats]; -SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats] = { - { // Format_Invalid - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_Mono - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_MonoLSB - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_Indexed8 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_RGB32 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - qt_blend_rgb32_on_rgb32, // Format_RGB32, - 0, // Format_ARGB32, - qt_blend_argb32_on_argb32, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_ARGB32 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_ARGB32_Premultiplied - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - qt_blend_rgb32_on_rgb32, // Format_RGB32, - 0, // Format_ARGB32, - qt_blend_argb32_on_argb32, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_RGB16 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - qt_blend_rgb32_on_rgb16, // Format_RGB32, - 0, // Format_ARGB32, - qt_blend_argb32_on_rgb16, // Format_ARGB32_Premultiplied, - qt_blend_rgb16_on_rgb16, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_ARGB8565_Premultiplied - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_RGB666 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_ARGB6666_Premultiplied - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_RGB555 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_ARGB8555_Premultiplied - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_RGB888 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_RGB444 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_ARGB4444_Premultiplied - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_RGBX8888 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, -#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN - qt_blend_rgb32_on_rgb32, // Format_RGBX8888, - 0, // Format_RGBA8888, - qt_blend_argb32_on_argb32, // Format_RGBA8888_Premultiplied, -#else - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, -#endif - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_RGBA8888 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_RGBA8888_Premultiplied - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, +void qInitBlendFunctions() +{ + qScaleFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_scale_image_rgb32_on_rgb32; + qScaleFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32; + qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_scale_image_rgb32_on_rgb32; + qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32; + qScaleFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_rgb16; + qScaleFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_scale_image_rgb16_on_rgb16; #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN - qt_blend_rgb32_on_rgb32, // Format_RGBX8888, - 0, // Format_RGBA8888, - qt_blend_argb32_on_argb32, // Format_RGBA8888_Premultiplied, -#else - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, + qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_scale_image_rgb32_on_rgb32; + qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32; + qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_scale_image_rgb32_on_rgb32; + qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32; #endif - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_BGR30 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - qt_blend_rgb32_on_rgb30<PixelOrderBGR>, // Format_RGB32, - 0, // Format_ARGB32, - qt_blend_argb32pm_on_a2rgb30pm<PixelOrderBGR>, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - qt_blend_rgb30_on_rgb30, // Format_RGB30, - qt_blend_a2rgb30pm_on_a2rgb30pm, // Format_A2RGB30_Premultiplied, - qt_blend_a2bgr30pm_on_a2rgb30pm, // Format_RGB30, - qt_blend_a2bgr30pm_on_a2rgb30pm, // Format_A2RGB30_Premultiplied, - 0, 0, - }, - { // Format_A2BGR30_Premultiplied - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - qt_blend_rgb32_on_rgb30<PixelOrderBGR>, // Format_RGB32, - 0, // Format_ARGB32, - qt_blend_argb32pm_on_a2rgb30pm<PixelOrderBGR>, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - qt_blend_rgb30_on_rgb30, // Format_BGR30, - qt_blend_a2rgb30pm_on_a2rgb30pm, // Format_A2BGR30_Premultiplied, - qt_blend_a2bgr30pm_on_a2rgb30pm, // Format_RGB30, - qt_blend_a2bgr30pm_on_a2rgb30pm, // Format_A2RGB30_Premultiplied, - 0, 0, - }, - { // Format_RGB30 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - qt_blend_rgb32_on_rgb30<PixelOrderRGB>, // Format_RGB32, - 0, // Format_ARGB32, - qt_blend_argb32pm_on_a2rgb30pm<PixelOrderRGB>, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - qt_blend_a2bgr30pm_on_a2rgb30pm, // Format_BGR30, - qt_blend_a2bgr30pm_on_a2rgb30pm, // Format_A2BGR30_Premultiplied, - qt_blend_rgb30_on_rgb30, // Format_RGB30, - qt_blend_a2rgb30pm_on_a2rgb30pm, // Format_A2RGB30_Premultiplied, - 0, 0, - }, - { // Format_A2RGB30_Premultiplied - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - qt_blend_rgb32_on_rgb30<PixelOrderRGB>, // Format_RGB32, - 0, // Format_ARGB32, - qt_blend_argb32pm_on_a2rgb30pm<PixelOrderRGB>, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - qt_blend_a2bgr30pm_on_a2rgb30pm, // Format_BGR30, - qt_blend_a2bgr30pm_on_a2rgb30pm, // Format_A2BGR30_Premultiplied, - qt_blend_rgb30_on_rgb30, // Format_RGB30, - qt_blend_a2rgb30pm_on_a2rgb30pm, // Format_A2RGB30_Premultiplied, - 0, 0, - }, - { // Format_Alpha8 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_Grayscale8 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - } -}; -SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFormats] = { - { // Format_Invalid - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_Mono - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_MonoLSB - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_Indexed8 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_RGB32 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - qt_transform_image_rgb32_on_rgb32, // Format_RGB32, - 0, // Format_ARGB32, - qt_transform_image_argb32_on_argb32, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_ARGB32 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_ARGB32_Premultiplied - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - qt_transform_image_rgb32_on_rgb32, // Format_RGB32, - 0, // Format_ARGB32, - qt_transform_image_argb32_on_argb32, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_RGB16 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - qt_transform_image_argb32_on_rgb16, // Format_ARGB32_Premultiplied, - qt_transform_image_rgb16_on_rgb16, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_ARGB8565_Premultiplied - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_RGB666 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_ARGB6666_Premultiplied - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_RGB555 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_ARGB8555_Premultiplied - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_RGB888 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_RGB444 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_ARGB4444_Premultiplied - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_RGBX8888 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, + qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32; + qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32; + qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32; + qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32; + qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb16; + qBlendFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_rgb16; + qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16; #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN - qt_transform_image_rgb32_on_rgb32, // Format_RGBX8888, - 0, // Format_RGBA8888, - qt_transform_image_argb32_on_argb32, // Format_RGBA8888_Premultiplied, -#else - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, + qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32; + qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32; + qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32; + qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32; #endif - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_RGBA8888 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_RGBA8888_Premultiplied - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, + qBlendFunctions[QImage::Format_BGR30][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb30<PixelOrderBGR>; + qBlendFunctions[QImage::Format_BGR30][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32pm_on_a2rgb30pm<PixelOrderBGR>; + qBlendFunctions[QImage::Format_BGR30][QImage::Format_BGR30] = qt_blend_rgb30_on_rgb30; + qBlendFunctions[QImage::Format_BGR30][QImage::Format_A2BGR30_Premultiplied] = qt_blend_a2rgb30pm_on_a2rgb30pm; + qBlendFunctions[QImage::Format_BGR30][QImage::Format_RGB30] = qt_blend_a2bgr30pm_on_a2rgb30pm; + qBlendFunctions[QImage::Format_BGR30][QImage::Format_A2RGB30_Premultiplied] = qt_blend_a2bgr30pm_on_a2rgb30pm; + qBlendFunctions[QImage::Format_A2BGR30_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb30<PixelOrderBGR>; + qBlendFunctions[QImage::Format_A2BGR30_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32pm_on_a2rgb30pm<PixelOrderBGR>; + qBlendFunctions[QImage::Format_A2BGR30_Premultiplied][QImage::Format_BGR30] = qt_blend_rgb30_on_rgb30; + qBlendFunctions[QImage::Format_A2BGR30_Premultiplied][QImage::Format_A2BGR30_Premultiplied] = qt_blend_a2rgb30pm_on_a2rgb30pm; + qBlendFunctions[QImage::Format_A2BGR30_Premultiplied][QImage::Format_RGB30] = qt_blend_a2bgr30pm_on_a2rgb30pm; + qBlendFunctions[QImage::Format_A2BGR30_Premultiplied][QImage::Format_A2RGB30_Premultiplied] = qt_blend_a2bgr30pm_on_a2rgb30pm; + qBlendFunctions[QImage::Format_RGB30][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb30<PixelOrderRGB>; + qBlendFunctions[QImage::Format_RGB30][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32pm_on_a2rgb30pm<PixelOrderRGB>; + qBlendFunctions[QImage::Format_RGB30][QImage::Format_BGR30] = qt_blend_a2bgr30pm_on_a2rgb30pm; + qBlendFunctions[QImage::Format_RGB30][QImage::Format_A2BGR30_Premultiplied] = qt_blend_a2bgr30pm_on_a2rgb30pm; + qBlendFunctions[QImage::Format_RGB30][QImage::Format_RGB30] = qt_blend_rgb30_on_rgb30; + qBlendFunctions[QImage::Format_RGB30][QImage::Format_A2RGB30_Premultiplied] = qt_blend_a2rgb30pm_on_a2rgb30pm; + qBlendFunctions[QImage::Format_A2RGB30_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb30<PixelOrderRGB>; + qBlendFunctions[QImage::Format_A2RGB30_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32pm_on_a2rgb30pm<PixelOrderRGB>; + qBlendFunctions[QImage::Format_A2RGB30_Premultiplied][QImage::Format_BGR30] = qt_blend_a2bgr30pm_on_a2rgb30pm; + qBlendFunctions[QImage::Format_A2RGB30_Premultiplied][QImage::Format_A2BGR30_Premultiplied] = qt_blend_a2bgr30pm_on_a2rgb30pm; + qBlendFunctions[QImage::Format_A2RGB30_Premultiplied][QImage::Format_RGB30] = qt_blend_rgb30_on_rgb30; + qBlendFunctions[QImage::Format_A2RGB30_Premultiplied][QImage::Format_A2RGB30_Premultiplied] = qt_blend_a2rgb30pm_on_a2rgb30pm; + + qTransformFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_transform_image_rgb32_on_rgb32; + qTransformFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_transform_image_argb32_on_argb32; + qTransformFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_transform_image_rgb32_on_rgb32; + qTransformFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_transform_image_argb32_on_argb32; + qTransformFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_transform_image_argb32_on_rgb16; + qTransformFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_transform_image_rgb16_on_rgb16; #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN - qt_transform_image_rgb32_on_rgb32, // Format_RGBX8888, - 0, // Format_RGBA8888, - qt_transform_image_argb32_on_argb32, // Format_RGBA8888_Premultiplied, -#else - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, + qTransformFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_transform_image_rgb32_on_rgb32; + qTransformFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_transform_image_argb32_on_argb32; + qTransformFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_transform_image_rgb32_on_rgb32; + qTransformFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_transform_image_argb32_on_argb32; #endif - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_BGR30 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_A2BGR30_Premultiplied - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_RGB30 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_A2RGB30_Premultiplied - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_Alpha8 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, - { // Format_Grayscale8 - 0, // Format_Invalid, - 0, // Format_Mono, - 0, // Format_MonoLSB, - 0, // Format_Indexed8, - 0, // Format_RGB32, - 0, // Format_ARGB32, - 0, // Format_ARGB32_Premultiplied, - 0, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, - 0, // Format_RGB666, - 0, // Format_ARGB6666_Premultiplied, - 0, // Format_RGB555, - 0, // Format_ARGB8555_Premultiplied, - 0, // Format_RGB888, - 0, // Format_RGB444, - 0, // Format_ARGB4444_Premultiplied, - 0, // Format_RGBX8888, - 0, // Format_RGBA8888, - 0, // Format_RGBA8888_Premultiplied, - 0, // Format_BGR30, - 0, // Format_A2BGR30_Premultiplied, - 0, // Format_RGB30, - 0, // Format_A2RGB30_Premultiplied, - 0, // Format_Alpha8 - 0, // Format_Grayscale8 - }, -}; +} QT_END_NAMESPACE diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 954c4c539a..b3f9fd9f60 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -1798,43 +1798,6 @@ static inline uint interpolate_4_pixels_16(uint tl, uint tr, uint bl, uint br, i #endif #if defined(__SSE2__) -static inline uint interpolate_4_pixels(uint tl, uint tr, uint bl, uint br, uint distx, uint disty) -{ - // First interpolate right and left pixels in parallel. - __m128i vl = _mm_unpacklo_epi32(_mm_cvtsi32_si128(tl), _mm_cvtsi32_si128(bl)); - __m128i vr = _mm_unpacklo_epi32(_mm_cvtsi32_si128(tr), _mm_cvtsi32_si128(br)); - vl = _mm_unpacklo_epi8(vl, _mm_setzero_si128()); - vr = _mm_unpacklo_epi8(vr, _mm_setzero_si128()); - vl = _mm_mullo_epi16(vl, _mm_set1_epi16(256 - distx)); - vr = _mm_mullo_epi16(vr, _mm_set1_epi16(distx)); - __m128i vtb = _mm_add_epi16(vl, vr); - vtb = _mm_srli_epi16(vtb, 8); - // vtb now contains the result of the first two interpolate calls vtb = unpacked((xbot << 64) | xtop) - - // Now the last interpolate between top and bottom interpolations. - const __m128i vidisty = _mm_shufflelo_epi16(_mm_cvtsi32_si128(256 - disty), _MM_SHUFFLE(0, 0, 0, 0)); - const __m128i vdisty = _mm_shufflelo_epi16(_mm_cvtsi32_si128(disty), _MM_SHUFFLE(0, 0, 0, 0)); - const __m128i vmuly = _mm_unpacklo_epi16(vidisty, vdisty); - vtb = _mm_unpacklo_epi16(vtb, _mm_srli_si128(vtb, 8)); - // vtb now contains the colors of top and bottom interleaved { ta, ba, tr, br, tg, bg, tb, bb } - vtb = _mm_madd_epi16(vtb, vmuly); // Multiply and horizontal add. - vtb = _mm_srli_epi32(vtb, 8); - vtb = _mm_packs_epi32(vtb, _mm_setzero_si128()); - vtb = _mm_packus_epi16(vtb, _mm_setzero_si128()); - return _mm_cvtsi128_si32(vtb); -} -#else -static inline uint interpolate_4_pixels(uint tl, uint tr, uint bl, uint br, uint distx, uint disty) -{ - uint idistx = 256 - distx; - uint idisty = 256 - disty; - uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx); - uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx); - return INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty); -} -#endif - -#if defined(__SSE2__) static inline QRgba64 interpolate_4_pixels_rgb64(QRgba64 t[], QRgba64 b[], uint distx, uint disty) { const __m128i vdistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(distx), _MM_SHUFFLE(0, 0, 0, 0)); @@ -2556,10 +2519,17 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper int x2; fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2); - buf1[i * 2 + 0] = fetch(s1, x1); - buf1[i * 2 + 1] = fetch(s1, x2); - buf2[i * 2 + 0] = fetch(s2, x1); - buf2[i * 2 + 1] = fetch(s2, x2); + if (layout->bpp == QPixelLayout::BPP32) { + buf1[i * 2 + 0] = ((const uint*)s1)[x1]; + buf1[i * 2 + 1] = ((const uint*)s1)[x2]; + buf2[i * 2 + 0] = ((const uint*)s2)[x1]; + buf2[i * 2 + 1] = ((const uint*)s2)[x2]; + } else { + buf1[i * 2 + 0] = fetch(s1, x1); + buf1[i * 2 + 1] = fetch(s1, x2); + buf2[i * 2 + 0] = fetch(s2, x1); + buf2[i * 2 + 1] = fetch(s2, x2); + } fx += fdx; } @@ -2614,10 +2584,17 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper const uchar *s1 = data->texture.scanLine(y1); const uchar *s2 = data->texture.scanLine(y2); - buf1[i * 2 + 0] = fetch(s1, x1); - buf1[i * 2 + 1] = fetch(s1, x2); - buf2[i * 2 + 0] = fetch(s2, x1); - buf2[i * 2 + 1] = fetch(s2, x2); + if (layout->bpp == QPixelLayout::BPP32) { + buf1[i * 2 + 0] = ((const uint*)s1)[x1]; + buf1[i * 2 + 1] = ((const uint*)s1)[x2]; + buf2[i * 2 + 0] = ((const uint*)s2)[x1]; + buf2[i * 2 + 1] = ((const uint*)s2)[x2]; + } else { + buf1[i * 2 + 0] = fetch(s1, x1); + buf1[i * 2 + 1] = fetch(s1, x2); + buf2[i * 2 + 0] = fetch(s2, x1); + buf2[i * 2 + 1] = fetch(s2, x2); + } fx += fdx; fy += fdy; @@ -2699,10 +2676,17 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper const uchar *s1 = data->texture.scanLine(y1); const uchar *s2 = data->texture.scanLine(y2); - buf1[i * 2 + 0] = fetch(s1, x1); - buf1[i * 2 + 1] = fetch(s1, x2); - buf2[i * 2 + 0] = fetch(s2, x1); - buf2[i * 2 + 1] = fetch(s2, x2); + if (layout->bpp == QPixelLayout::BPP32) { + buf1[i * 2 + 0] = ((const uint*)s1)[x1]; + buf1[i * 2 + 1] = ((const uint*)s1)[x2]; + buf2[i * 2 + 0] = ((const uint*)s2)[x1]; + buf2[i * 2 + 1] = ((const uint*)s2)[x2]; + } else { + buf1[i * 2 + 0] = fetch(s1, x1); + buf1[i * 2 + 1] = fetch(s1, x2); + buf2[i * 2 + 0] = fetch(s2, x1); + buf2[i * 2 + 1] = fetch(s2, x2); + } fx += fdx; fy += fdy; @@ -6368,24 +6352,22 @@ void qInitDrawhelperAsm() } #endif // SSSE3 -#if QT_COMPILER_SUPPORTS_SSE4_1 +#if defined(QT_COMPILER_SUPPORTS_SSE4_1) && !defined(__SSE4_1__) if (qCpuHasFeature(SSE4_1)) { -#if !defined(__SSE4_1__) extern const uint *QT_FASTCALL convertARGB32ToARGB32PM_sse4(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *); extern const uint *QT_FASTCALL convertRGBA8888ToARGB32PM_sse4(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *); - qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_sse4; - qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_sse4; -#endif extern const uint *QT_FASTCALL convertARGB32FromARGB32PM_sse4(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *); extern const uint *QT_FASTCALL convertRGBA8888FromARGB32PM_sse4(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *); extern const uint *QT_FASTCALL convertRGBXFromARGB32PM_sse4(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *); + qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_sse4; + qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_sse4; qPixelLayouts[QImage::Format_ARGB32].convertFromARGB32PM = convertARGB32FromARGB32PM_sse4; qPixelLayouts[QImage::Format_RGBA8888].convertFromARGB32PM = convertRGBA8888FromARGB32PM_sse4; qPixelLayouts[QImage::Format_RGBX8888].convertFromARGB32PM = convertRGBXFromARGB32PM_sse4; } #endif -#if QT_COMPILER_SUPPORTS_AVX2 && !defined(__AVX2__) +#if defined(QT_COMPILER_SUPPORTS_AVX2) && !defined(__AVX2__) if (qCpuHasFeature(AVX2)) { extern const uint *QT_FASTCALL convertARGB32ToARGB32PM_avx2(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *); extern const uint *QT_FASTCALL convertRGBA8888ToARGB32PM_avx2(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *); diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 019e1864f9..f8865a6f7e 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -634,6 +634,42 @@ static Q_ALWAYS_INLINE uint BYTE_MUL(uint x, uint a) { } #endif +#ifdef __SSE2__ +static inline uint interpolate_4_pixels(uint tl, uint tr, uint bl, uint br, uint distx, uint disty) +{ + // First interpolate right and left pixels in parallel. + __m128i vl = _mm_unpacklo_epi32(_mm_cvtsi32_si128(tl), _mm_cvtsi32_si128(bl)); + __m128i vr = _mm_unpacklo_epi32(_mm_cvtsi32_si128(tr), _mm_cvtsi32_si128(br)); + vl = _mm_unpacklo_epi8(vl, _mm_setzero_si128()); + vr = _mm_unpacklo_epi8(vr, _mm_setzero_si128()); + vl = _mm_mullo_epi16(vl, _mm_set1_epi16(256 - distx)); + vr = _mm_mullo_epi16(vr, _mm_set1_epi16(distx)); + __m128i vtb = _mm_add_epi16(vl, vr); + vtb = _mm_srli_epi16(vtb, 8); + // vtb now contains the result of the first two interpolate calls vtb = unpacked((xbot << 64) | xtop) + + // Now the last interpolate between top and bottom interpolations. + const __m128i vidisty = _mm_shufflelo_epi16(_mm_cvtsi32_si128(256 - disty), _MM_SHUFFLE(0, 0, 0, 0)); + const __m128i vdisty = _mm_shufflelo_epi16(_mm_cvtsi32_si128(disty), _MM_SHUFFLE(0, 0, 0, 0)); + const __m128i vmuly = _mm_unpacklo_epi16(vidisty, vdisty); + vtb = _mm_unpacklo_epi16(vtb, _mm_srli_si128(vtb, 8)); + // vtb now contains the colors of top and bottom interleaved { ta, ba, tr, br, tg, bg, tb, bb } + vtb = _mm_madd_epi16(vtb, vmuly); // Multiply and horizontal add. + vtb = _mm_srli_epi32(vtb, 8); + vtb = _mm_packs_epi32(vtb, _mm_setzero_si128()); + vtb = _mm_packus_epi16(vtb, _mm_setzero_si128()); + return _mm_cvtsi128_si32(vtb); +} +#else +static inline uint interpolate_4_pixels(uint tl, uint tr, uint bl, uint br, uint distx, uint disty) +{ + uint idistx = 256 - distx; + uint idisty = 256 - disty; + uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx); + uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx); + return INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty); +} +#endif #if Q_BYTE_ORDER == Q_BIG_ENDIAN static Q_ALWAYS_INLINE quint32 RGBA2ARGB(quint32 x) { diff --git a/src/gui/painting/qdrawhelper_sse4.cpp b/src/gui/painting/qdrawhelper_sse4.cpp index 43a3958997..8e0b2cbb18 100644 --- a/src/gui/painting/qdrawhelper_sse4.cpp +++ b/src/gui/painting/qdrawhelper_sse4.cpp @@ -32,7 +32,6 @@ ****************************************************************************/ #include <private/qdrawhelper_p.h> -#include <private/qdrawingprimitive_sse2_p.h> #if defined(QT_COMPILER_SUPPORTS_SSE4_1) @@ -54,7 +53,7 @@ const uint *QT_FASTCALL convertARGB32FromARGB32PM_sse4(uint *buffer, const uint const QPixelLayout *, const QRgb *) { for (int i = 0; i < count; ++i) - buffer[i] = qUnpremultiply_sse4(src[i]); + buffer[i] = qUnpremultiply(src[i]); return buffer; } @@ -62,7 +61,7 @@ const uint *QT_FASTCALL convertRGBA8888FromARGB32PM_sse4(uint *buffer, const uin const QPixelLayout *, const QRgb *) { for (int i = 0; i < count; ++i) - buffer[i] = ARGB2RGBA(qUnpremultiply_sse4(src[i])); + buffer[i] = ARGB2RGBA(qUnpremultiply(src[i])); return buffer; } @@ -70,7 +69,7 @@ const uint *QT_FASTCALL convertRGBXFromARGB32PM_sse4(uint *buffer, const uint *s const QPixelLayout *, const QRgb *) { for (int i = 0; i < count; ++i) - buffer[i] = ARGB2RGBA(0xff000000 | qUnpremultiply_sse4(src[i])); + buffer[i] = ARGB2RGBA(0xff000000 | qUnpremultiply(src[i])); return buffer; } diff --git a/src/gui/painting/qdrawingprimitive_sse2_p.h b/src/gui/painting/qdrawingprimitive_sse2_p.h index 4d0790a502..fbee06e157 100644 --- a/src/gui/painting/qdrawingprimitive_sse2_p.h +++ b/src/gui/painting/qdrawingprimitive_sse2_p.h @@ -236,25 +236,4 @@ QT_END_NAMESPACE #endif // __SSE2__ -QT_BEGIN_NAMESPACE -#if QT_COMPILER_SUPPORTS_HERE(SSE4_1) -QT_FUNCTION_TARGET(SSE4_1) -inline QRgb qUnpremultiply_sse4(QRgb p) -{ - const uint alpha = qAlpha(p); - const uint invAlpha = qt_inv_premul_factor[alpha]; - const __m128i via = _mm_set1_epi32(invAlpha); - const __m128i vr = _mm_set1_epi32(0x8000); - __m128i vl = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(p)); - vl = _mm_mullo_epi32(vl, via); - vl = _mm_add_epi32(vl, vr); - vl = _mm_srai_epi32(vl, 16); - vl = _mm_insert_epi32(vl, alpha, 3); - vl = _mm_packus_epi32(vl, _mm_setzero_si128()); - vl = _mm_packus_epi16(vl, _mm_setzero_si128()); - return _mm_cvtsi128_si32(vl); -} -#endif -QT_END_NAMESPACE - #endif // QDRAWINGPRIMITIVE_SSE2_P_H diff --git a/src/gui/painting/qimagescale.cpp b/src/gui/painting/qimagescale.cpp index 58e9112dd6..5f1b25e189 100644 --- a/src/gui/painting/qimagescale.cpp +++ b/src/gui/painting/qimagescale.cpp @@ -38,10 +38,6 @@ QT_BEGIN_NAMESPACE -namespace QImageScale { - struct QImageScaleInfo; -} - typedef void (*qt_qimageScaleFunc)(QImageScale::QImageScaleInfo *isi, unsigned int *dest, int dxx, int dyy, int dx, int dy, int dw, int dh, int dow, int sow); @@ -105,15 +101,7 @@ qt_qimageScaleFunc qt_qimageScaleRgb = qt_qimageScaleAARGB; namespace QImageScale { - struct QImageScaleInfo { - int *xpoints; - const unsigned int **ypoints; - int *xapoints, *yapoints; - int xup_yup; - }; - - const unsigned int** qimageCalcYPoints(const unsigned int *src, int sw, int sh, - int dh); + const unsigned int** qimageCalcYPoints(const unsigned int *src, int sw, int sh, int dh); int* qimageCalcXPoints(int sw, int dw); int* qimageCalcApoints(int s, int d, int up); QImageScaleInfo* qimageFreeScaleInfo(QImageScaleInfo *isi); @@ -134,16 +122,11 @@ using namespace QImageScale; #define G_VAL(p) (qGreen(*p)) #define B_VAL(p) (qBlue(*p)) -#define INV_XAP (256 - xapoints[x]) -#define XAP (xapoints[x]) -#define INV_YAP (256 - yapoints[dyy + y]) -#define YAP (yapoints[dyy + y]) - const unsigned int** QImageScale::qimageCalcYPoints(const unsigned int *src, int sw, int sh, int dh) { const unsigned int **p; - int i, j = 0, rv = 0; + int j = 0, rv = 0; qint64 val, inc; if(dh < 0){ @@ -155,12 +138,12 @@ const unsigned int** QImageScale::qimageCalcYPoints(const unsigned int *src, int up = qAbs(dh) >= sh; val = up ? 0x8000 * sh / dh - 0x8000 : 0; inc = (((qint64)sh) << 16) / dh; - for(i = 0; i < dh; i++){ + for (int i = 0; i < dh; i++) { p[j++] = src + qMax(0LL, val >> 16) * sw; val += inc; } - if(rv){ - for(i = dh / 2; --i >= 0; ){ + if (rv) { + for (int i = dh / 2; --i >= 0; ) { const unsigned int *tmp = p[i]; p[i] = p[dh - i - 1]; p[dh - i - 1] = tmp; @@ -171,7 +154,7 @@ const unsigned int** QImageScale::qimageCalcYPoints(const unsigned int *src, int* QImageScale::qimageCalcXPoints(int sw, int dw) { - int *p, i, j = 0, rv = 0; + int *p, j = 0, rv = 0; qint64 val, inc; if(dw < 0){ @@ -183,13 +166,13 @@ int* QImageScale::qimageCalcXPoints(int sw, int dw) int up = qAbs(dw) >= sw; val = up ? 0x8000 * sw / dw - 0x8000 : 0; inc = (((qint64)sw) << 16) / dw; - for(i = 0; i < dw; i++){ + for (int i = 0; i < dw; i++) { p[j++] = qMax(0LL, val >> 16); val += inc; } - if(rv){ - for(i = dw / 2; --i >= 0; ){ + if (rv) { + for (int i = dw / 2; --i >= 0; ) { int tmp = p[i]; p[i] = p[dw - i - 1]; p[dw - i - 1] = tmp; @@ -200,7 +183,7 @@ int* QImageScale::qimageCalcXPoints(int sw, int dw) int* QImageScale::qimageCalcApoints(int s, int d, int up) { - int *p, i, j = 0, rv = 0; + int *p, j = 0, rv = 0; if(d < 0){ rv = 1; @@ -214,7 +197,7 @@ int* QImageScale::qimageCalcApoints(int s, int d, int up) val = 0x8000 * s / d - 0x8000; inc = (((qint64)s) << 16) / d; - for(i = 0; i < d; i++){ + for (int i = 0; i < d; i++) { int pos = val >> 16; if (pos < 0) p[j++] = 0; @@ -226,14 +209,12 @@ int* QImageScale::qimageCalcApoints(int s, int d, int up) } } /* scaling down */ - else{ - qint64 val, inc; - int ap, Cp; - val = 0; - inc = (((qint64)s) << 16) / d; - Cp = ((d << 14) / s) + 1; - for(i = 0; i < d; i++){ - ap = ((0x100 - ((val >> 8) & 0xff)) * Cp) >> 8; + else { + qint64 val = 0; + qint64 inc = (((qint64)s) << 16) / d; + int Cp = (((d << 14) + s - 1) / s); + for (int i = 0; i < d; i++) { + int ap = ((0x10000 - (val & 0xffff)) * Cp) >> 16; p[j] = ap | (Cp << 16); j++; val += inc; @@ -241,13 +222,13 @@ int* QImageScale::qimageCalcApoints(int s, int d, int up) } if(rv){ int tmp; - for(i = d / 2; --i >= 0; ){ + for (int i = d / 2; --i >= 0; ) { tmp = p[i]; p[i] = p[d - i - 1]; p[d - i - 1] = tmp; } } - return(p); + return p; } QImageScaleInfo* QImageScale::qimageFreeScaleInfo(QImageScaleInfo *isi) @@ -297,700 +278,500 @@ QImageScaleInfo* QImageScale::qimageCalcScaleInfo(const QImage &img, return(isi); } -/* FIXME: NEED to optimize ScaleAARGBA - currently its "ok" but needs work*/ -/* scale by area sampling */ -static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest, - int dxx, int dyy, int dx, int dy, int dw, - int dh, int dow, int sow) +static void qt_qimageScaleAARGBA_up_x_down_y(QImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, + int dw, int dh, int dow, int sow); + +static void qt_qimageScaleAARGBA_down_x_up_y(QImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, + int dw, int dh, int dow, int sow); + +static void qt_qimageScaleAARGBA_down_xy(QImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, int dw, + int dh, int dow, int sow); + +#if defined(QT_COMPILER_SUPPORTS_SSE4_1) +template<bool RGB> +void qt_qimageScaleAARGBA_up_x_down_y_sse4(QImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, + int dw, int dh, int dow, int sow); +template<bool RGB> +void qt_qimageScaleAARGBA_down_x_up_y_sse4(QImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, + int dw, int dh, int dow, int sow); +template<bool RGB> +void qt_qimageScaleAARGBA_down_xy_sse4(QImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, + int dw, int dh, int dow, int sow); +#endif + +static void qt_qimageScaleAARGBA_up_xy(QImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, + int dw, int dh, int dow, int sow) { - const unsigned int *sptr; - unsigned int *dptr; - int x, y, end; const unsigned int **ypoints = isi->ypoints; int *xpoints = isi->xpoints; int *xapoints = isi->xapoints; int *yapoints = isi->yapoints; - end = dxx + dw; - /* scaling up both ways */ - if(isi->xup_yup == 3){ - /* go through every scanline in the output buffer */ - for(y = 0; y < dh; y++){ - /* calculate the source line we'll scan from */ - dptr = dest + dx + ((y + dy) * dow); - sptr = ypoints[dyy + y]; - if(YAP > 0){ - for(x = dxx; x < end; x++){ - int r, g, b, a; - int rr, gg, bb, aa; - const unsigned int *pix; - - if(XAP > 0){ - pix = ypoints[dyy + y] + xpoints[x]; - r = R_VAL(pix) * INV_XAP; - g = G_VAL(pix) * INV_XAP; - b = B_VAL(pix) * INV_XAP; - a = A_VAL(pix) * INV_XAP; - pix++; - r += R_VAL(pix) * XAP; - g += G_VAL(pix) * XAP; - b += B_VAL(pix) * XAP; - a += A_VAL(pix) * XAP; - pix += sow; - rr = R_VAL(pix) * XAP; - gg = G_VAL(pix) * XAP; - bb = B_VAL(pix) * XAP; - aa = A_VAL(pix) * XAP; - pix--; - rr += R_VAL(pix) * INV_XAP; - gg += G_VAL(pix) * INV_XAP; - bb += B_VAL(pix) * INV_XAP; - aa += A_VAL(pix) * INV_XAP; - r = ((rr * YAP) + (r * INV_YAP)) >> 16; - g = ((gg * YAP) + (g * INV_YAP)) >> 16; - b = ((bb * YAP) + (b * INV_YAP)) >> 16; - a = ((aa * YAP) + (a * INV_YAP)) >> 16; - *dptr++ = qRgba(r, g, b, a); - } - else{ - pix = ypoints[dyy + y] + xpoints[x]; - r = R_VAL(pix) * INV_YAP; - g = G_VAL(pix) * INV_YAP; - b = B_VAL(pix) * INV_YAP; - a = A_VAL(pix) * INV_YAP; - pix += sow; - r += R_VAL(pix) * YAP; - g += G_VAL(pix) * YAP; - b += B_VAL(pix) * YAP; - a += A_VAL(pix) * YAP; - r >>= 8; - g >>= 8; - b >>= 8; - a >>= 8; - *dptr++ = qRgba(r, g, b, a); - } - } + int end = dxx + dw; + /* go through every scanline in the output buffer */ + for (int y = 0; y < dh; y++) { + /* calculate the source line we'll scan from */ + const unsigned int *sptr = ypoints[dyy + y]; + unsigned int *dptr = dest + dx + ((y + dy) * dow); + const int yap = yapoints[dyy + y]; + if (yap > 0) { + for (int x = dxx; x < end; x++) { + const unsigned int *pix = sptr + xpoints[x]; + const int xap = xapoints[x]; + if (xap > 0) + *dptr = interpolate_4_pixels(pix[0], pix[1], pix[sow], pix[sow + 1], xap, yap); + else + *dptr = INTERPOLATE_PIXEL_256(pix[0], 256 - yap, pix[sow], yap); + dptr++; } - else{ - for(x = dxx; x < end; x++){ - int r, g, b, a; - const unsigned int *pix; - - if(XAP > 0){ - pix = ypoints[dyy + y] + xpoints[x]; - r = R_VAL(pix) * INV_XAP; - g = G_VAL(pix) * INV_XAP; - b = B_VAL(pix) * INV_XAP; - a = A_VAL(pix) * INV_XAP; - pix++; - r += R_VAL(pix) * XAP; - g += G_VAL(pix) * XAP; - b += B_VAL(pix) * XAP; - a += A_VAL(pix) * XAP; - r >>= 8; - g >>= 8; - b >>= 8; - a >>= 8; - *dptr++ = qRgba(r, g, b, a); - } - else - *dptr++ = sptr[xpoints[x] ]; - } + } else { + for (int x = dxx; x < end; x++) { + const unsigned int *pix = sptr + xpoints[x]; + const int xap = xapoints[x]; + *dptr = INTERPOLATE_PIXEL_256(pix[0], 256 - xap, pix[1], xap); + dptr++; } } } +} + +/* scale by area sampling */ +static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, int dw, + int dh, int dow, int sow) +{ + /* scaling up both ways */ + if (isi->xup_yup == 3){ + qt_qimageScaleAARGBA_up_xy(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow); + } /* if we're scaling down vertically */ - else if(isi->xup_yup == 1){ - /*\ 'Correct' version, with math units prepared for MMXification \*/ - int Cy, j; - const unsigned int *pix; - int r, g, b, a, rr, gg, bb, aa; - int yap; - - /* go through every scanline in the output buffer */ - for(y = 0; y < dh; y++){ - Cy = YAP >> 16; - yap = YAP & 0xffff; - - dptr = dest + dx + ((y + dy) * dow); - for(x = dxx; x < end; x++){ - pix = ypoints[dyy + y] + xpoints[x]; - r = R_VAL(pix) * yap; - g = G_VAL(pix) * yap; - b = B_VAL(pix) * yap; - a = A_VAL(pix) * yap; - for(j = (1 << 14) - yap; j > Cy; j -= Cy){ - pix += sow; - r += R_VAL(pix) * Cy; - g += G_VAL(pix) * Cy; - b += B_VAL(pix) * Cy; - a += A_VAL(pix) * Cy; - } - if(j > 0){ - pix += sow; - r += R_VAL(pix) * j; - g += G_VAL(pix) * j; - b += B_VAL(pix) * j; - a += A_VAL(pix) * j; - } - if(XAP > 0){ - pix = ypoints[dyy + y] + xpoints[x] + 1; - rr = R_VAL(pix) * yap; - gg = G_VAL(pix) * yap; - bb = B_VAL(pix) * yap; - aa = A_VAL(pix) * yap; - for(j = (1 << 14) - yap; j > Cy; j -= Cy){ - pix += sow; - rr += R_VAL(pix) * Cy; - gg += G_VAL(pix) * Cy; - bb += B_VAL(pix) * Cy; - aa += A_VAL(pix) * Cy; - } - if(j > 0){ - pix += sow; - rr += R_VAL(pix) * j; - gg += G_VAL(pix) * j; - bb += B_VAL(pix) * j; - aa += A_VAL(pix) * j; - } - r = r * INV_XAP; - g = g * INV_XAP; - b = b * INV_XAP; - a = a * INV_XAP; - r = (r + ((rr * XAP))) >> 12; - g = (g + ((gg * XAP))) >> 12; - b = (b + ((bb * XAP))) >> 12; - a = (a + ((aa * XAP))) >> 12; - } - else{ - r >>= 4; - g >>= 4; - b >>= 4; - a >>= 4; - } - *dptr = qRgba(r >> 10, g >> 10, b >> 10, a >> 10); - dptr++; - } - } + else if (isi->xup_yup == 1) { +#ifdef QT_COMPILER_SUPPORTS_SSE4_1 + if (qCpuHasFeature(SSE4_1)) + qt_qimageScaleAARGBA_up_x_down_y_sse4<false>(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow); + else +#endif + qt_qimageScaleAARGBA_up_x_down_y(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow); } /* if we're scaling down horizontally */ - else if(isi->xup_yup == 2){ - /*\ 'Correct' version, with math units prepared for MMXification \*/ - int Cx, j; - const unsigned int *pix; - int r, g, b, a, rr, gg, bb, aa; - int xap; - - /* go through every scanline in the output buffer */ - for(y = 0; y < dh; y++){ - dptr = dest + dx + ((y + dy) * dow); - for(x = dxx; x < end; x++){ - Cx = XAP >> 16; - xap = XAP & 0xffff; - - pix = ypoints[dyy + y] + xpoints[x]; - r = R_VAL(pix) * xap; - g = G_VAL(pix) * xap; - b = B_VAL(pix) * xap; - a = A_VAL(pix) * xap; - for(j = (1 << 14) - xap; j > Cx; j -= Cx){ - pix++; - r += R_VAL(pix) * Cx; - g += G_VAL(pix) * Cx; - b += B_VAL(pix) * Cx; - a += A_VAL(pix) * Cx; - } - if(j > 0){ - pix++; - r += R_VAL(pix) * j; - g += G_VAL(pix) * j; - b += B_VAL(pix) * j; - a += A_VAL(pix) * j; - } - if(YAP > 0){ - pix = ypoints[dyy + y] + xpoints[x] + sow; - rr = R_VAL(pix) * xap; - gg = G_VAL(pix) * xap; - bb = B_VAL(pix) * xap; - aa = A_VAL(pix) * xap; - for(j = (1 << 14) - xap; j > Cx; j -= Cx){ - pix++; - rr += R_VAL(pix) * Cx; - gg += G_VAL(pix) * Cx; - bb += B_VAL(pix) * Cx; - aa += A_VAL(pix) * Cx; - } - if(j > 0){ - pix++; - rr += R_VAL(pix) * j; - gg += G_VAL(pix) * j; - bb += B_VAL(pix) * j; - aa += A_VAL(pix) * j; - } - r = r * INV_YAP; - g = g * INV_YAP; - b = b * INV_YAP; - a = a * INV_YAP; - r = (r + ((rr * YAP))) >> 12; - g = (g + ((gg * YAP))) >> 12; - b = (b + ((bb * YAP))) >> 12; - a = (a + ((aa * YAP))) >> 12; - } - else{ - r >>= 4; - g >>= 4; - b >>= 4; - a >>= 4; - } - *dptr = qRgba(r >> 10, g >> 10, b >> 10, a >> 10); - dptr++; - } - } + else if (isi->xup_yup == 2) { +#ifdef QT_COMPILER_SUPPORTS_SSE4_1 + if (qCpuHasFeature(SSE4_1)) + qt_qimageScaleAARGBA_down_x_up_y_sse4<false>(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow); + else +#endif + qt_qimageScaleAARGBA_down_x_up_y(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow); } /* if we're scaling down horizontally & vertically */ - else{ - /*\ 'Correct' version, with math units prepared for MMXification: - |*| The operation 'b = (b * c) >> 16' translates to pmulhw, - |*| so the operation 'b = (b * c) >> d' would translate to - |*| psllw (16 - d), %mmb; pmulh %mmc, %mmb - \*/ - int Cx, Cy, i, j; - const unsigned int *pix; - int a, r, g, b, ax, rx, gx, bx; - int xap, yap; - - for(y = 0; y < dh; y++){ - Cy = YAP >> 16; - yap = YAP & 0xffff; - - dptr = dest + dx + ((y + dy) * dow); - for(x = dxx; x < end; x++){ - Cx = XAP >> 16; - xap = XAP & 0xffff; - - sptr = ypoints[dyy + y] + xpoints[x]; - pix = sptr; - sptr += sow; - rx = R_VAL(pix) * xap; - gx = G_VAL(pix) * xap; - bx = B_VAL(pix) * xap; - ax = A_VAL(pix) * xap; - - pix++; - for(i = (1 << 14) - xap; i > Cx; i -= Cx){ - rx += R_VAL(pix) * Cx; - gx += G_VAL(pix) * Cx; - bx += B_VAL(pix) * Cx; - ax += A_VAL(pix) * Cx; - pix++; - } - if(i > 0){ - rx += R_VAL(pix) * i; - gx += G_VAL(pix) * i; - bx += B_VAL(pix) * i; - ax += A_VAL(pix) * i; - } - - r = (rx >> 5) * yap; - g = (gx >> 5) * yap; - b = (bx >> 5) * yap; - a = (ax >> 5) * yap; - - for(j = (1 << 14) - yap; j > Cy; j -= Cy){ - pix = sptr; - sptr += sow; - rx = R_VAL(pix) * xap; - gx = G_VAL(pix) * xap; - bx = B_VAL(pix) * xap; - ax = A_VAL(pix) * xap; - pix++; - for(i = (1 << 14) - xap; i > Cx; i -= Cx){ - rx += R_VAL(pix) * Cx; - gx += G_VAL(pix) * Cx; - bx += B_VAL(pix) * Cx; - ax += A_VAL(pix) * Cx; - pix++; - } - if(i > 0){ - rx += R_VAL(pix) * i; - gx += G_VAL(pix) * i; - bx += B_VAL(pix) * i; - ax += A_VAL(pix) * i; - } - - r += (rx >> 5) * Cy; - g += (gx >> 5) * Cy; - b += (bx >> 5) * Cy; - a += (ax >> 5) * Cy; - } - if(j > 0){ - pix = sptr; - sptr += sow; - rx = R_VAL(pix) * xap; - gx = G_VAL(pix) * xap; - bx = B_VAL(pix) * xap; - ax = A_VAL(pix) * xap; - pix++; - for(i = (1 << 14) - xap; i > Cx; i -= Cx){ - rx += R_VAL(pix) * Cx; - gx += G_VAL(pix) * Cx; - bx += B_VAL(pix) * Cx; - ax += A_VAL(pix) * Cx; - pix++; - } - if(i > 0){ - rx += R_VAL(pix) * i; - gx += G_VAL(pix) * i; - bx += B_VAL(pix) * i; - ax += A_VAL(pix) * i; - } - - r += (rx >> 5) * j; - g += (gx >> 5) * j; - b += (bx >> 5) * j; - a += (ax >> 5) * j; - } - - *dptr = qRgba(r >> 23, g >> 23, b >> 23, a >> 23); - dptr++; + else { +#ifdef QT_COMPILER_SUPPORTS_SSE4_1 + if (qCpuHasFeature(SSE4_1)) + qt_qimageScaleAARGBA_down_xy_sse4<false>(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow); + else +#endif + qt_qimageScaleAARGBA_down_xy(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow); + } +} + +inline static void qt_qimageScaleAARGBA_helper_x(const unsigned int *pix, int xap, int Cx, int &r, int &g, int &b, int &a) +{ + r = R_VAL(pix) * xap; + g = G_VAL(pix) * xap; + b = B_VAL(pix) * xap; + a = A_VAL(pix) * xap; + int j; + for (j = (1 << 14) - xap; j > Cx; j -= Cx ){ + pix++; + r += R_VAL(pix) * Cx; + g += G_VAL(pix) * Cx; + b += B_VAL(pix) * Cx; + a += A_VAL(pix) * Cx; + } + pix++; + r += R_VAL(pix) * j; + g += G_VAL(pix) * j; + b += B_VAL(pix) * j; + a += A_VAL(pix) * j; +} + +inline static void qt_qimageScaleAARGBA_helper_y(const unsigned int *pix, int yap, int Cy, int sow, int &r, int &g, int &b, int &a) +{ + r = R_VAL(pix) * yap; + g = G_VAL(pix) * yap; + b = B_VAL(pix) * yap; + a = A_VAL(pix) * yap; + int j; + for (j = (1 << 14) - yap; j > Cy; j -= Cy ){ + pix += sow; + r += R_VAL(pix) * Cy; + g += G_VAL(pix) * Cy; + b += B_VAL(pix) * Cy; + a += A_VAL(pix) * Cy; + } + pix += sow; + r += R_VAL(pix) * j; + g += G_VAL(pix) * j; + b += B_VAL(pix) * j; + a += A_VAL(pix) * j; +} + +static void qt_qimageScaleAARGBA_up_x_down_y(QImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, + int dw, int dh, int dow, int sow) +{ + const unsigned int **ypoints = isi->ypoints; + int *xpoints = isi->xpoints; + int *xapoints = isi->xapoints; + int *yapoints = isi->yapoints; + + int end = dxx + dw; + + /* go through every scanline in the output buffer */ + for (int y = 0; y < dh; y++) { + int Cy = (yapoints[dyy + y]) >> 16; + int yap = (yapoints[dyy + y]) & 0xffff; + + unsigned int *dptr = dest + dx + ((y + dy) * dow); + for (int x = dxx; x < end; x++) { + const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; + int r, g, b, a; + qt_qimageScaleAARGBA_helper_y(sptr, yap, Cy, sow, r, g, b, a); + + int xap = xapoints[x]; + if (xap > 0) { + int rr, gg, bb, aa; + qt_qimageScaleAARGBA_helper_y(sptr + 1, yap, Cy, sow, rr, gg, bb, aa); + + r = r * (256 - xap); + g = g * (256 - xap); + b = b * (256 - xap); + a = a * (256 - xap); + r = (r + (rr * xap)) >> 8; + g = (g + (gg * xap)) >> 8; + b = (b + (bb * xap)) >> 8; + a = (a + (aa * xap)) >> 8; } + *dptr++ = qRgba(r >> 14, g >> 14, b >> 14, a >> 14); } } } -/* scale by area sampling - IGNORE the ALPHA byte*/ -static void qt_qimageScaleAARGB(QImageScaleInfo *isi, unsigned int *dest, - int dxx, int dyy, int dx, int dy, int dw, - int dh, int dow, int sow) +static void qt_qimageScaleAARGBA_down_x_up_y(QImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, + int dw, int dh, int dow, int sow) { - const unsigned int *sptr; - unsigned int *dptr; - int x, y, end; const unsigned int **ypoints = isi->ypoints; int *xpoints = isi->xpoints; int *xapoints = isi->xapoints; int *yapoints = isi->yapoints; - end = dxx + dw; - /* scaling up both ways */ - if(isi->xup_yup == 3){ - /* go through every scanline in the output buffer */ - for(y = 0; y < dh; y++){ - /* calculate the source line we'll scan from */ - dptr = dest + dx + ((y + dy) * dow); - sptr = ypoints[dyy + y]; - if(YAP > 0){ - for(x = dxx; x < end; x++){ - int r = 0, g = 0, b = 0; - int rr = 0, gg = 0, bb = 0; - const unsigned int *pix; - - if(XAP > 0){ - pix = ypoints[dyy + y] + xpoints[x]; - r = R_VAL(pix) * INV_XAP; - g = G_VAL(pix) * INV_XAP; - b = B_VAL(pix) * INV_XAP; - pix++; - r += R_VAL(pix) * XAP; - g += G_VAL(pix) * XAP; - b += B_VAL(pix) * XAP; - pix += sow; - rr = R_VAL(pix) * XAP; - gg = G_VAL(pix) * XAP; - bb = B_VAL(pix) * XAP; - pix --; - rr += R_VAL(pix) * INV_XAP; - gg += G_VAL(pix) * INV_XAP; - bb += B_VAL(pix) * INV_XAP; - r = ((rr * YAP) + (r * INV_YAP)) >> 16; - g = ((gg * YAP) + (g * INV_YAP)) >> 16; - b = ((bb * YAP) + (b * INV_YAP)) >> 16; - *dptr++ = qRgba(r, g, b, 0xff); - } - else{ - pix = ypoints[dyy + y] + xpoints[x]; - r = R_VAL(pix) * INV_YAP; - g = G_VAL(pix) * INV_YAP; - b = B_VAL(pix) * INV_YAP; - pix += sow; - r += R_VAL(pix) * YAP; - g += G_VAL(pix) * YAP; - b += B_VAL(pix) * YAP; - r >>= 8; - g >>= 8; - b >>= 8; - *dptr++ = qRgba(r, g, b, 0xff); - } - } - } - else{ - for(x = dxx; x < end; x++){ - int r = 0, g = 0, b = 0; - const unsigned int *pix; - - if(XAP > 0){ - pix = ypoints[dyy + y] + xpoints[x]; - r = R_VAL(pix) * INV_XAP; - g = G_VAL(pix) * INV_XAP; - b = B_VAL(pix) * INV_XAP; - pix++; - r += R_VAL(pix) * XAP; - g += G_VAL(pix) * XAP; - b += B_VAL(pix) * XAP; - r >>= 8; - g >>= 8; - b >>= 8; - *dptr++ = qRgba(r, g, b, 0xff); - } - else - *dptr++ = sptr[xpoints[x] ]; - } + int end = dxx + dw; + + /* go through every scanline in the output buffer */ + for (int y = 0; y < dh; y++) { + unsigned int *dptr = dest + dx + ((y + dy) * dow); + for (int x = dxx; x < end; x++) { + int Cx = xapoints[x] >> 16; + int xap = xapoints[x] & 0xffff; + + const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; + int r, g, b, a; + qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, r, g, b, a); + + int yap = yapoints[dyy + y]; + if (yap > 0) { + int rr, gg, bb, aa; + qt_qimageScaleAARGBA_helper_x(sptr + sow, xap, Cx, rr, gg, bb, aa); + + r = r * (256 - yap); + g = g * (256 - yap); + b = b * (256 - yap); + a = a * (256 - yap); + r = (r + (rr * yap)) >> 8; + g = (g + (gg * yap)) >> 8; + b = (b + (bb * yap)) >> 8; + a = (a + (aa * yap)) >> 8; } + *dptr = qRgba(r >> 14, g >> 14, b >> 14, a >> 14); + dptr++; } } - /* if we're scaling down vertically */ - else if(isi->xup_yup == 1){ - /*\ 'Correct' version, with math units prepared for MMXification \*/ - int Cy, j; - const unsigned int *pix; - int r, g, b, rr, gg, bb; - int yap; - - /* go through every scanline in the output buffer */ - for(y = 0; y < dh; y++){ - Cy = YAP >> 16; - yap = YAP & 0xffff; - - dptr = dest + dx + ((y + dy) * dow); - for(x = dxx; x < end; x++){ - pix = ypoints[dyy + y] + xpoints[x]; - r = R_VAL(pix) * yap; - g = G_VAL(pix) * yap; - b = B_VAL(pix) * yap; - pix += sow; - for(j = (1 << 14) - yap; j > Cy; j -= Cy){ - r += R_VAL(pix) * Cy; - g += G_VAL(pix) * Cy; - b += B_VAL(pix) * Cy; - pix += sow; - } - if(j > 0){ - r += R_VAL(pix) * j; - g += G_VAL(pix) * j; - b += B_VAL(pix) * j; - } - if(XAP > 0){ - pix = ypoints[dyy + y] + xpoints[x] + 1; - rr = R_VAL(pix) * yap; - gg = G_VAL(pix) * yap; - bb = B_VAL(pix) * yap; - pix += sow; - for(j = (1 << 14) - yap; j > Cy; j -= Cy){ - rr += R_VAL(pix) * Cy; - gg += G_VAL(pix) * Cy; - bb += B_VAL(pix) * Cy; - pix += sow; - } - if(j > 0){ - rr += R_VAL(pix) * j; - gg += G_VAL(pix) * j; - bb += B_VAL(pix) * j; - } - r = r * INV_XAP; - g = g * INV_XAP; - b = b * INV_XAP; - r = (r + ((rr * XAP))) >> 12; - g = (g + ((gg * XAP))) >> 12; - b = (b + ((bb * XAP))) >> 12; - } - else{ - r >>= 4; - g >>= 4; - b >>= 4; - } - *dptr = qRgba(r >> 10, g >> 10, b >> 10, 0xff); - dptr++; +} + +static void qt_qimageScaleAARGBA_down_xy(QImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, int dw, + int dh, int dow, int sow) +{ + const unsigned int **ypoints = isi->ypoints; + int *xpoints = isi->xpoints; + int *xapoints = isi->xapoints; + int *yapoints = isi->yapoints; + + int end = dxx + dw; + + for (int y = 0; y < dh; y++) { + int Cy = (yapoints[dyy + y]) >> 16; + int yap = (yapoints[dyy + y]) & 0xffff; + + unsigned int *dptr = dest + dx + ((y + dy) * dow); + for (int x = dxx; x < end; x++) { + int Cx = xapoints[x] >> 16; + int xap = xapoints[x] & 0xffff; + + const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; + int rx, gx, bx, ax; + qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, rx, gx, bx, ax); + + int r = ((rx>>4) * yap); + int g = ((gx>>4) * yap); + int b = ((bx>>4) * yap); + int a = ((ax>>4) * yap); + + int j; + for (j = (1 << 14) - yap; j > Cy; j -= Cy) { + sptr += sow; + qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, rx, gx, bx, ax); + r += ((rx>>4) * Cy); + g += ((gx>>4) * Cy); + b += ((bx>>4) * Cy); + a += ((ax>>4) * Cy); } + sptr += sow; + qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, rx, gx, bx, ax); + + r += ((rx>>4) * j); + g += ((gx>>4) * j); + b += ((bx>>4) * j); + a += ((ax>>4) * j); + + *dptr = qRgba(r >> 24, g >> 24, b >> 24, a >> 24); + dptr++; } } +} + +static void qt_qimageScaleAARGB_up_x_down_y(QImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, int dw, + int dh, int dow, int sow); + +static void qt_qimageScaleAARGB_down_x_up_y(QImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, int dw, + int dh, int dow, int sow); + +static void qt_qimageScaleAARGB_down_xy(QImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, int dw, + int dh, int dow, int sow); + +/* scale by area sampling - IGNORE the ALPHA byte*/ +static void qt_qimageScaleAARGB(QImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, + int dw, int dh, int dow, int sow) +{ + /* scaling up both ways */ + if (isi->xup_yup == 3) { + qt_qimageScaleAARGBA_up_xy(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow); + } + /* if we're scaling down vertically */ + else if (isi->xup_yup == 1) { +#ifdef QT_COMPILER_SUPPORTS_SSE4_1 + if (qCpuHasFeature(SSE4_1)) + qt_qimageScaleAARGBA_up_x_down_y_sse4<true>(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow); + else +#endif + qt_qimageScaleAARGB_up_x_down_y(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow); + } /* if we're scaling down horizontally */ - else if(isi->xup_yup == 2){ - /*\ 'Correct' version, with math units prepared for MMXification \*/ - int Cx, j; - const unsigned int *pix; - int r, g, b, rr, gg, bb; - int xap; - - /* go through every scanline in the output buffer */ - for(y = 0; y < dh; y++){ - dptr = dest + dx + ((y + dy) * dow); - for(x = dxx; x < end; x++){ - Cx = XAP >> 16; - xap = XAP & 0xffff; - - pix = ypoints[dyy + y] + xpoints[x]; - r = R_VAL(pix) * xap; - g = G_VAL(pix) * xap; - b = B_VAL(pix) * xap; - pix++; - for(j = (1 << 14) - xap; j > Cx; j -= Cx){ - r += R_VAL(pix) * Cx; - g += G_VAL(pix) * Cx; - b += B_VAL(pix) * Cx; - pix++; - } - if(j > 0){ - r += R_VAL(pix) * j; - g += G_VAL(pix) * j; - b += B_VAL(pix) * j; - } - if(YAP > 0){ - pix = ypoints[dyy + y] + xpoints[x] + sow; - rr = R_VAL(pix) * xap; - gg = G_VAL(pix) * xap; - bb = B_VAL(pix) * xap; - pix++; - for(j = (1 << 14) - xap; j > Cx; j -= Cx){ - rr += R_VAL(pix) * Cx; - gg += G_VAL(pix) * Cx; - bb += B_VAL(pix) * Cx; - pix++; - } - if(j > 0){ - rr += R_VAL(pix) * j; - gg += G_VAL(pix) * j; - bb += B_VAL(pix) * j; - } - r = r * INV_YAP; - g = g * INV_YAP; - b = b * INV_YAP; - r = (r + ((rr * YAP))) >> 12; - g = (g + ((gg * YAP))) >> 12; - b = (b + ((bb * YAP))) >> 12; - } - else{ - r >>= 4; - g >>= 4; - b >>= 4; - } - *dptr = qRgba(r >> 10, g >> 10, b >> 10, 0xff); - dptr++; - } - } + else if (isi->xup_yup == 2) { +#ifdef QT_COMPILER_SUPPORTS_SSE4_1 + if (qCpuHasFeature(SSE4_1)) + qt_qimageScaleAARGBA_down_x_up_y_sse4<true>(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow); + else +#endif + qt_qimageScaleAARGB_down_x_up_y(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow); } - /* fully optimized (i think) - onyl change of algorithm can help */ /* if we're scaling down horizontally & vertically */ - else{ - /*\ 'Correct' version, with math units prepared for MMXification \*/ - int Cx, Cy, i, j; - const unsigned int *pix; - int r, g, b, rx, gx, bx; - int xap, yap; - - for(y = 0; y < dh; y++){ - Cy = YAP >> 16; - yap = YAP & 0xffff; - - dptr = dest + dx + ((y + dy) * dow); - for(x = dxx; x < end; x++){ - Cx = XAP >> 16; - xap = XAP & 0xffff; - - sptr = ypoints[dyy + y] + xpoints[x]; - pix = sptr; - sptr += sow; - rx = R_VAL(pix) * xap; - gx = G_VAL(pix) * xap; - bx = B_VAL(pix) * xap; - pix++; - for(i = (1 << 14) - xap; i > Cx; i -= Cx){ - rx += R_VAL(pix) * Cx; - gx += G_VAL(pix) * Cx; - bx += B_VAL(pix) * Cx; - pix++; - } - if(i > 0){ - rx += R_VAL(pix) * i; - gx += G_VAL(pix) * i; - bx += B_VAL(pix) * i; - } - - r = (rx >> 5) * yap; - g = (gx >> 5) * yap; - b = (bx >> 5) * yap; - - for(j = (1 << 14) - yap; j > Cy; j -= Cy){ - pix = sptr; - sptr += sow; - rx = R_VAL(pix) * xap; - gx = G_VAL(pix) * xap; - bx = B_VAL(pix) * xap; - pix++; - for(i = (1 << 14) - xap; i > Cx; i -= Cx){ - rx += R_VAL(pix) * Cx; - gx += G_VAL(pix) * Cx; - bx += B_VAL(pix) * Cx; - pix++; - } - if(i > 0){ - rx += R_VAL(pix) * i; - gx += G_VAL(pix) * i; - bx += B_VAL(pix) * i; - } - - r += (rx >> 5) * Cy; - g += (gx >> 5) * Cy; - b += (bx >> 5) * Cy; - } - if(j > 0){ - pix = sptr; - sptr += sow; - rx = R_VAL(pix) * xap; - gx = G_VAL(pix) * xap; - bx = B_VAL(pix) * xap; - pix++; - for(i = (1 << 14) - xap; i > Cx; i -= Cx){ - rx += R_VAL(pix) * Cx; - gx += G_VAL(pix) * Cx; - bx += B_VAL(pix) * Cx; - pix++; - } - if(i > 0){ - rx += R_VAL(pix) * i; - gx += G_VAL(pix) * i; - bx += B_VAL(pix) * i; - } - - r += (rx >> 5) * j; - g += (gx >> 5) * j; - b += (bx >> 5) * j; - } - - *dptr = qRgb(r >> 23, g >> 23, b >> 23); - dptr++; + else { +#ifdef QT_COMPILER_SUPPORTS_SSE4_1 + if (qCpuHasFeature(SSE4_1)) + qt_qimageScaleAARGBA_down_xy_sse4<true>(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow); + else +#endif + qt_qimageScaleAARGB_down_xy(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow); + } +} + + +inline static void qt_qimageScaleAARGB_helper_x(const unsigned int *pix, int xap, int Cx, int &r, int &g, int &b) +{ + r = R_VAL(pix) * xap; + g = G_VAL(pix) * xap; + b = B_VAL(pix) * xap; + int j; + for (j = (1 << 14) - xap; j > Cx; j -= Cx ){ + pix++; + r += R_VAL(pix) * Cx; + g += G_VAL(pix) * Cx; + b += B_VAL(pix) * Cx; + } + pix++; + r += R_VAL(pix) * j; + g += G_VAL(pix) * j; + b += B_VAL(pix) * j; +} + +inline static void qt_qimageScaleAARGB_helper_y(const unsigned int *pix, int yap, int Cy, int sow, int &r, int &g, int &b) +{ + r = R_VAL(pix) * yap; + g = G_VAL(pix) * yap; + b = B_VAL(pix) * yap; + int j; + for (j = (1 << 14) - yap; j > Cy; j -= Cy ){ + pix += sow; + r += R_VAL(pix) * Cy; + g += G_VAL(pix) * Cy; + b += B_VAL(pix) * Cy; + } + pix += sow; + r += R_VAL(pix) * j; + g += G_VAL(pix) * j; + b += B_VAL(pix) * j; +} + +static void qt_qimageScaleAARGB_up_x_down_y(QImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, int dw, + int dh, int dow, int sow) +{ + const unsigned int **ypoints = isi->ypoints; + int *xpoints = isi->xpoints; + int *xapoints = isi->xapoints; + int *yapoints = isi->yapoints; + + int end = dxx + dw; + + /* go through every scanline in the output buffer */ + for (int y = 0; y < dh; y++) { + int Cy = (yapoints[dyy + y]) >> 16; + int yap = (yapoints[dyy + y]) & 0xffff; + + unsigned int *dptr = dest + dx + ((y + dy) * dow); + for (int x = dxx; x < end; x++) { + const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; + int r, g, b; + qt_qimageScaleAARGB_helper_y(sptr, yap, Cy, sow, r, g, b); + + int xap = xapoints[x]; + if (xap > 0) { + int rr, bb, gg; + qt_qimageScaleAARGB_helper_y(sptr + 1, yap, Cy, sow, rr, gg, bb); + + r = r * (256 - xap); + g = g * (256 - xap); + b = b * (256 - xap); + r = (r + (rr * xap)) >> 8; + g = (g + (gg * xap)) >> 8; + b = (b + (bb * xap)) >> 8; } + *dptr++ = qRgb(r >> 14, g >> 14, b >> 14); } } } -#if 0 -static void qt_qimageScaleAARGBASetup(QImageScaleInfo *isi, unsigned int *dest, - int dxx, int dyy, int dx, int dy, int dw, - int dh, int dow, int sow) +static void qt_qimageScaleAARGB_down_x_up_y(QImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, int dw, + int dh, int dow, int sow) { - qInitDrawhelperAsm(); - qt_qimageScaleAARGBA(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow); + const unsigned int **ypoints = isi->ypoints; + int *xpoints = isi->xpoints; + int *xapoints = isi->xapoints; + int *yapoints = isi->yapoints; + + int end = dxx + dw; + + /* go through every scanline in the output buffer */ + for (int y = 0; y < dh; y++) { + unsigned int *dptr = dest + dx + ((y + dy) * dow); + for (int x = dxx; x < end; x++) { + int Cx = xapoints[x] >> 16; + int xap = xapoints[x] & 0xffff; + + const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; + int r, g, b; + qt_qimageScaleAARGB_helper_x(sptr, xap, Cx, r, g, b); + + int yap = yapoints[dyy + y]; + if (yap > 0) { + int rr, bb, gg; + qt_qimageScaleAARGB_helper_x(sptr + sow, xap, Cx, rr, gg, bb); + + r = r * (256 - yap); + g = g * (256 - yap); + b = b * (256 - yap); + r = (r + (rr * yap)) >> 8; + g = (g + (gg * yap)) >> 8; + b = (b + (bb * yap)) >> 8; + } + *dptr++ = qRgb(r >> 14, g >> 14, b >> 14); + } + } } -static void qt_qimageScaleAARGBSetup(QImageScaleInfo *isi, unsigned int *dest, - int dxx, int dyy, int dx, int dy, int dw, - int dh, int dow, int sow) +static void qt_qimageScaleAARGB_down_xy(QImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, int dw, + int dh, int dow, int sow) { - qInitDrawhelperAsm(); - qt_qimageScaleAARGB(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow); + const unsigned int **ypoints = isi->ypoints; + int *xpoints = isi->xpoints; + int *xapoints = isi->xapoints; + int *yapoints = isi->yapoints; + + int end = dxx + dw; + + for (int y = 0; y < dh; y++) { + int Cy = (yapoints[dyy + y]) >> 16; + int yap = (yapoints[dyy + y]) & 0xffff; + + unsigned int *dptr = dest + dx + ((y + dy) * dow); + for (int x = dxx; x < end; x++) { + int Cx = xapoints[x] >> 16; + int xap = xapoints[x] & 0xffff; + + const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; + int rx, gx, bx; + qt_qimageScaleAARGB_helper_x(sptr, xap, Cx, rx, gx, bx); + + int r = (rx >> 4) * yap; + int g = (gx >> 4) * yap; + int b = (bx >> 4) * yap; + + int j; + for (j = (1 << 14) - yap; j > Cy; j -= Cy) { + sptr += sow; + qt_qimageScaleAARGB_helper_x(sptr, xap, Cx, rx, gx, bx); + + r += (rx >> 4) * Cy; + g += (gx >> 4) * Cy; + b += (bx >> 4) * Cy; + } + sptr += sow; + qt_qimageScaleAARGB_helper_x(sptr, xap, Cx, rx, gx, bx); + + r += (rx >> 4) * j; + g += (gx >> 4) * j; + b += (bx >> 4) * j; + + *dptr = qRgb(r >> 24, g >> 24, b >> 24); + dptr++; + } + } } -#endif QImage qSmoothScaleImage(const QImage &src, int dw, int dh) { @@ -1012,7 +793,7 @@ QImage qSmoothScaleImage(const QImage &src, int dw, int dh) return QImage(); } - if (src.format() == QImage::Format_ARGB32_Premultiplied || src.format() == QImage::Format_RGBA8888_Premultiplied) + if (src.hasAlphaChannel()) qt_qimageScaleArgb(scaleinfo, (unsigned int *)buffer.scanLine(0), 0, 0, 0, 0, dw, dh, dw, src.bytesPerLine() / 4); else diff --git a/src/gui/painting/qimagescale_p.h b/src/gui/painting/qimagescale_p.h index 512ec6488e..c35aea451a 100644 --- a/src/gui/painting/qimagescale_p.h +++ b/src/gui/painting/qimagescale_p.h @@ -53,6 +53,15 @@ QT_BEGIN_NAMESPACE */ QImage qSmoothScaleImage(const QImage &img, int w, int h); +namespace QImageScale { + struct QImageScaleInfo { + int *xpoints; + const unsigned int **ypoints; + int *xapoints, *yapoints; + int xup_yup; + }; +} + QT_END_NAMESPACE #endif diff --git a/src/gui/painting/qimagescale_sse4.cpp b/src/gui/painting/qimagescale_sse4.cpp new file mode 100644 index 0000000000..565ea4daa1 --- /dev/null +++ b/src/gui/painting/qimagescale_sse4.cpp @@ -0,0 +1,247 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qimagescale_p.h" +#include "qimage.h" +#include <private/qsimd_p.h> + +#if defined(QT_COMPILER_SUPPORTS_SSE4_1) + +QT_BEGIN_NAMESPACE + +using namespace QImageScale; + +inline static __m128i qt_qimageScaleAARGBA_helper_x(const unsigned int *pix, int xap, int Cx, const __m128i vxap, const __m128i vCx) +{ + __m128i vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); + __m128i vx = _mm_mullo_epi32(vpix, vxap); + int i; + for (i = (1 << 14) - xap; i > Cx; i -= Cx) { + pix++; + vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); + vx = _mm_add_epi32(vx, _mm_mullo_epi32(vpix, vCx)); + } + pix++; + vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); + vx = _mm_add_epi32(vx, _mm_mullo_epi32(vpix, _mm_set1_epi32(i))); + return vx; +} + +inline static __m128i qt_qimageScaleAARGBA_helper_y(const unsigned int *pix, int yap, int Cy, int sow, const __m128i vyap, const __m128i vCy) +{ + __m128i vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); + __m128i vx = _mm_mullo_epi32(vpix, vyap); + int i; + for (i = (1 << 14) - yap; i > Cy; i -= Cy) { + pix += sow; + vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); + vx = _mm_add_epi32(vx, _mm_mullo_epi32(vpix, vCy)); + } + pix += sow; + vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); + vx = _mm_add_epi32(vx, _mm_mullo_epi32(vpix, _mm_set1_epi32(i))); + return vx; +} + +template<bool RGB> +void qt_qimageScaleAARGBA_up_x_down_y_sse4(QImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, + int dw, int dh, int dow, int sow) +{ + const unsigned int **ypoints = isi->ypoints; + int *xpoints = isi->xpoints; + int *xapoints = isi->xapoints; + int *yapoints = isi->yapoints; + + int end = dxx + dw; + + const __m128i v256 = _mm_set1_epi32(256); + + /* go through every scanline in the output buffer */ + for (int y = 0; y < dh; y++) { + int Cy = (yapoints[dyy + y]) >> 16; + int yap = (yapoints[dyy + y]) & 0xffff; + const __m128i vCy = _mm_set1_epi32(Cy); + const __m128i vyap = _mm_set1_epi32(yap); + + unsigned int *dptr = dest + dx + ((y + dy) * dow); + for (int x = dxx; x < end; x++) { + const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; + __m128i vx = qt_qimageScaleAARGBA_helper_y(sptr, yap, Cy, sow, vyap, vCy); + + int xap = xapoints[x]; + if (xap > 0) { + const __m128i vxap = _mm_set1_epi32(xap); + const __m128i vinvxap = _mm_sub_epi32(v256, vxap); + __m128i vr = qt_qimageScaleAARGBA_helper_y(sptr + 1, yap, Cy, sow, vyap, vCy); + + vx = _mm_mullo_epi32(vx, vinvxap); + vr = _mm_mullo_epi32(vr, vxap); + vx = _mm_add_epi32(vx, vr); + vx = _mm_srli_epi32(vx, 8); + } + vx = _mm_srli_epi32(vx, 14); + vx = _mm_packus_epi32(vx, _mm_setzero_si128()); + vx = _mm_packus_epi16(vx, _mm_setzero_si128()); + *dptr = _mm_cvtsi128_si32(vx); + if (RGB) + *dptr |= 0xff000000; + dptr++; + } + } +} + +template<bool RGB> +void qt_qimageScaleAARGBA_down_x_up_y_sse4(QImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, + int dw, int dh, int dow, int sow) +{ + const unsigned int **ypoints = isi->ypoints; + int *xpoints = isi->xpoints; + int *xapoints = isi->xapoints; + int *yapoints = isi->yapoints; + + int end = dxx + dw; + + const __m128i v256 = _mm_set1_epi32(256); + + /* go through every scanline in the output buffer */ + for (int y = 0; y < dh; y++) { + unsigned int *dptr = dest + dx + ((y + dy) * dow); + for (int x = dxx; x < end; x++) { + int Cx = xapoints[x] >> 16; + int xap = xapoints[x] & 0xffff; + const __m128i vCx = _mm_set1_epi32(Cx); + const __m128i vxap = _mm_set1_epi32(xap); + + const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; + __m128i vx = qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, vxap, vCx); + + int yap = yapoints[dyy + y]; + if (yap > 0) { + const __m128i vyap = _mm_set1_epi32(yap); + const __m128i vinvyap = _mm_sub_epi32(v256, vyap); + __m128i vr = qt_qimageScaleAARGBA_helper_x(sptr + sow, xap, Cx, vxap, vCx); + + vx = _mm_mullo_epi32(vx, vinvyap); + vr = _mm_mullo_epi32(vr, vyap); + vx = _mm_add_epi32(vx, vr); + vx = _mm_srli_epi32(vx, 8); + } + vx = _mm_srli_epi32(vx, 14); + vx = _mm_packus_epi32(vx, _mm_setzero_si128()); + vx = _mm_packus_epi16(vx, _mm_setzero_si128()); + *dptr = _mm_cvtsi128_si32(vx); + if (RGB) + *dptr |= 0xff000000; + dptr++; + } + } +} + +template<bool RGB> +void qt_qimageScaleAARGBA_down_xy_sse4(QImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, + int dw, int dh, int dow, int sow) +{ + const unsigned int **ypoints = isi->ypoints; + int *xpoints = isi->xpoints; + int *xapoints = isi->xapoints; + int *yapoints = isi->yapoints; + + for (int y = 0; y < dh; y++) { + int Cy = (yapoints[dyy + y]) >> 16; + int yap = (yapoints[dyy + y]) & 0xffff; + const __m128i vCy = _mm_set1_epi32(Cy); + const __m128i vyap = _mm_set1_epi32(yap); + + unsigned int *dptr = dest + dx + ((y + dy) * dow); + int end = dxx + dw; + for (int x = dxx; x < end; x++) { + const int Cx = xapoints[x] >> 16; + const int xap = xapoints[x] & 0xffff; + const __m128i vCx = _mm_set1_epi32(Cx); + const __m128i vxap = _mm_set1_epi32(xap); + + const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; + __m128i vx = qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, vxap, vCx); + __m128i vr = _mm_mullo_epi32(_mm_srli_epi32(vx, 4), vyap); + + int j; + for (j = (1 << 14) - yap; j > Cy; j -= Cy) { + sptr += sow; + vx = qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, vxap, vCx); + vr = _mm_add_epi32(vr, _mm_mullo_epi32(_mm_srli_epi32(vx, 4), vCy)); + } + sptr += sow; + vx = qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, vxap, vCx); + vr = _mm_add_epi32(vr, _mm_mullo_epi32(_mm_srli_epi32(vx, 4), _mm_set1_epi32(j))); + + vr = _mm_srli_epi32(vr, 24); + vr = _mm_packus_epi32(vr, _mm_setzero_si128()); + vr = _mm_packus_epi16(vr, _mm_setzero_si128()); + *dptr = _mm_cvtsi128_si32(vr); + if (RGB) + *dptr |= 0xff000000; + dptr++; + } + } +} + +template void qt_qimageScaleAARGBA_up_x_down_y_sse4<false>(QImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, + int dw, int dh, int dow, int sow); + +template void qt_qimageScaleAARGBA_up_x_down_y_sse4<true>(QImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, + int dw, int dh, int dow, int sow); + +template void qt_qimageScaleAARGBA_down_x_up_y_sse4<false>(QImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, + int dw, int dh, int dow, int sow); + +template void qt_qimageScaleAARGBA_down_x_up_y_sse4<true>(QImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, + int dw, int dh, int dow, int sow); + +template void qt_qimageScaleAARGBA_down_xy_sse4<false>(QImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, + int dw, int dh, int dow, int sow); + +template void qt_qimageScaleAARGBA_down_xy_sse4<true>(QImageScaleInfo *isi, unsigned int *dest, + int dxx, int dyy, int dx, int dy, + int dw, int dh, int dow, int sow); + +QT_END_NAMESPACE + +#endif diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index cc1ad02eee..3f2ebb92a0 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -66,12 +66,9 @@ QT_BEGIN_NAMESPACE inline QPaintEngine::PaintEngineFeatures qt_pdf_decide_features() { QPaintEngine::PaintEngineFeatures f = QPaintEngine::AllFeatures; - f &= ~(QPaintEngine::PorterDuff | QPaintEngine::PerspectiveTransform + f &= ~(QPaintEngine::PorterDuff + | QPaintEngine::PerspectiveTransform | QPaintEngine::ObjectBoundingModeGradients -#ifndef USE_NATIVE_GRADIENTS - | QPaintEngine::LinearGradientFill -#endif - | QPaintEngine::RadialGradientFill | QPaintEngine::ConicalGradientFill); return f; } @@ -548,189 +545,6 @@ QByteArray QPdf::patternForBrush(const QBrush &b) return pattern_for_brush[style]; } -#ifdef USE_NATIVE_GRADIENTS -static void writeTriangleLine(uchar *&data, int xpos, int ypos, int xoff, int yoff, uint rgb, uchar flag, bool alpha) -{ - data[0] = flag; - data[1] = (uchar)(xpos >> 16); - data[2] = (uchar)(xpos >> 8); - data[3] = (uchar)(xpos >> 0); - data[4] = (uchar)(ypos >> 16); - data[5] = (uchar)(ypos >> 8); - data[6] = (uchar)(ypos >> 0); - data += 7; - if (alpha) { - *data++ = (uchar)qAlpha(rgb); - } else { - *data++ = (uchar)qRed(rgb); - *data++ = (uchar)qGreen(rgb); - *data++ = (uchar)qBlue(rgb); - } - xpos += xoff; - ypos += yoff; - data[0] = flag; - data[1] = (uchar)(xpos >> 16); - data[2] = (uchar)(xpos >> 8); - data[3] = (uchar)(xpos >> 0); - data[4] = (uchar)(ypos >> 16); - data[5] = (uchar)(ypos >> 8); - data[6] = (uchar)(ypos >> 0); - data += 7; - if (alpha) { - *data++ = (uchar)qAlpha(rgb); - } else { - *data++ = (uchar)qRed(rgb); - *data++ = (uchar)qGreen(rgb); - *data++ = (uchar)qBlue(rgb); - } -} - - -QByteArray QPdf::generateLinearGradientShader(const QLinearGradient *gradient, const QPointF *page_rect, bool alpha) -{ - // generate list of triangles with colors - QPointF start = gradient->start(); - QPointF stop = gradient->finalStop(); - QGradientStops stops = gradient->stops(); - QPointF offset = stop - start; - QGradient::Spread spread = gradient->spread(); - - if (gradient->spread() == QGradient::ReflectSpread) { - offset *= 2; - for (int i = stops.size() - 2; i >= 0; --i) { - QGradientStop stop = stops.at(i); - stop.first = 2. - stop.first; - stops.append(stop); - } - for (int i = 0 ; i < stops.size(); ++i) - stops[i].first /= 2.; - } - - QPointF orthogonal(offset.y(), -offset.x()); - qreal length = offset.x()*offset.x() + offset.y()*offset.y(); - - // find the max and min values in offset and orth direction that are needed to cover - // the whole page - int off_min = INT_MAX; - int off_max = INT_MIN; - qreal ort_min = INT_MAX; - qreal ort_max = INT_MIN; - for (int i = 0; i < 4; ++i) { - qreal off = ((page_rect[i].x() - start.x()) * offset.x() + (page_rect[i].y() - start.y()) * offset.y())/length; - qreal ort = ((page_rect[i].x() - start.x()) * orthogonal.x() + (page_rect[i].y() - start.y()) * orthogonal.y())/length; - off_min = qMin(off_min, qFloor(off)); - off_max = qMax(off_max, qCeil(off)); - ort_min = qMin(ort_min, ort); - ort_max = qMax(ort_max, ort); - } - ort_min -= 1; - ort_max += 1; - - start += off_min * offset + ort_min * orthogonal; - orthogonal *= (ort_max - ort_min); - int num = off_max - off_min; - - QPointF gradient_rect[4] = { start, - start + orthogonal, - start + num*offset, - start + num*offset + orthogonal }; - qreal xmin = gradient_rect[0].x(); - qreal xmax = gradient_rect[0].x(); - qreal ymin = gradient_rect[0].y(); - qreal ymax = gradient_rect[0].y(); - for (int i = 1; i < 4; ++i) { - xmin = qMin(xmin, gradient_rect[i].x()); - xmax = qMax(xmax, gradient_rect[i].x()); - ymin = qMin(ymin, gradient_rect[i].y()); - ymax = qMax(ymax, gradient_rect[i].y()); - } - xmin -= 1000; - xmax += 1000; - ymin -= 1000; - ymax += 1000; - start -= QPointF(xmin, ymin); - qreal factor_x = qreal(1<<24)/(xmax - xmin); - qreal factor_y = qreal(1<<24)/(ymax - ymin); - int xoff = (int)(orthogonal.x()*factor_x); - int yoff = (int)(orthogonal.y()*factor_y); - - QByteArray triangles; - triangles.resize(spread == QGradient::PadSpread ? 20*(stops.size()+2) : 20*num*stops.size()); - uchar *data = (uchar *) triangles.data(); - if (spread == QGradient::PadSpread) { - if (off_min > 0 || off_max < 1) { - // linear gradient outside of page - const QGradientStop ¤t_stop = off_min > 0 ? stops.at(stops.size()-1) : stops.at(0); - uint rgb = current_stop.second.rgba(); - int xpos = (int)(start.x()*factor_x); - int ypos = (int)(start.y()*factor_y); - writeTriangleLine(data, xpos, ypos, xoff, yoff, rgb, 0, alpha); - start += num*offset; - xpos = (int)(start.x()*factor_x); - ypos = (int)(start.y()*factor_y); - writeTriangleLine(data, xpos, ypos, xoff, yoff, rgb, 1, alpha); - } else { - int flag = 0; - if (off_min < 0) { - uint rgb = stops.at(0).second.rgba(); - int xpos = (int)(start.x()*factor_x); - int ypos = (int)(start.y()*factor_y); - writeTriangleLine(data, xpos, ypos, xoff, yoff, rgb, flag, alpha); - start -= off_min*offset; - flag = 1; - } - for (int s = 0; s < stops.size(); ++s) { - const QGradientStop ¤t_stop = stops.at(s); - uint rgb = current_stop.second.rgba(); - int xpos = (int)(start.x()*factor_x); - int ypos = (int)(start.y()*factor_y); - writeTriangleLine(data, xpos, ypos, xoff, yoff, rgb, flag, alpha); - if (s < stops.size()-1) - start += offset*(stops.at(s+1).first - stops.at(s).first); - flag = 1; - } - if (off_max > 1) { - start += (off_max - 1)*offset; - uint rgb = stops.at(stops.size()-1).second.rgba(); - int xpos = (int)(start.x()*factor_x); - int ypos = (int)(start.y()*factor_y); - writeTriangleLine(data, xpos, ypos, xoff, yoff, rgb, flag, alpha); - } - } - } else { - for (int i = 0; i < num; ++i) { - uchar flag = 0; - for (int s = 0; s < stops.size(); ++s) { - uint rgb = stops.at(s).second.rgba(); - int xpos = (int)(start.x()*factor_x); - int ypos = (int)(start.y()*factor_y); - writeTriangleLine(data, xpos, ypos, xoff, yoff, rgb, flag, alpha); - if (s < stops.size()-1) - start += offset*(stops.at(s+1).first - stops.at(s).first); - flag = 1; - } - } - } - triangles.resize((char *)data - triangles.constData()); - - QByteArray shader; - QPdf::ByteStream s(&shader); - s << "<<\n" - "/ShadingType 4\n" - "/ColorSpace " << (alpha ? "/DeviceGray\n" : "/DeviceRGB\n") << - "/AntiAlias true\n" - "/BitsPerCoordinate 24\n" - "/BitsPerComponent 8\n" - "/BitsPerFlag 8\n" - "/Decode [" << xmin << xmax << ymin << ymax << (alpha ? "0 1]\n" : "0 1 0 1 0 1]\n") << - "/AntiAlias true\n" - "/Length " << triangles.length() << "\n" - ">>\n" - "stream\n" << triangles << "endstream\n" - "endobj\n"; - return shader; -} -#endif static void moveToHook(qfixed x, qfixed y, void *data) { @@ -1381,6 +1195,8 @@ void QPdfEngine::setBrush() bool specifyColor; int gStateObject = 0; int patternObject = d->addBrushPattern(d->stroker.matrix, &specifyColor, &gStateObject); + if (!patternObject && !specifyColor) + return; *d->currentPage << (patternObject ? "/PCSp cs " : "/CSp cs "); if (specifyColor) { @@ -2116,34 +1932,263 @@ int QPdfEnginePrivate::writeImage(const QByteArray &data, int width, int height, return image; } -#ifdef USE_NATIVE_GRADIENTS -int QPdfEnginePrivate::gradientBrush(const QBrush &b, const QMatrix &matrix, int *gStateObject) +struct QGradientBound { + qreal start; + qreal stop; + int function; + bool reverse; +}; + +int QPdfEnginePrivate::createShadingFunction(const QGradient *gradient, int from, int to, bool reflect, bool alpha) { - const QGradient *gradient = b.gradient(); - if (!gradient) - return 0; + QGradientStops stops = gradient->stops(); + if (stops.isEmpty()) { + stops << QGradientStop(0, Qt::black); + stops << QGradientStop(1, Qt::white); + } + if (stops.at(0).first > 0) + stops.prepend(QGradientStop(0, stops.at(0).second)); + if (stops.at(stops.size() - 1).first < 1) + stops.append(QGradientStop(1, stops.at(stops.size() - 1).second)); + + QVector<int> functions; + for (int i = 0; i < stops.size() - 1; ++i) { + int f = addXrefEntry(-1); + QByteArray data; + QPdf::ByteStream s(&data); + s << "<<\n" + "/FunctionType 2\n" + "/Domain [0 1]\n" + "/N 1\n"; + if (alpha) { + s << "/C0 [" << stops.at(i).second.alphaF() << "]\n" + "/C1 [" << stops.at(i + 1).second.alphaF() << "]\n"; + } else { + s << "/C0 [" << stops.at(i).second.redF() << stops.at(i).second.greenF() << stops.at(i).second.blueF() << "]\n" + "/C1 [" << stops.at(i + 1).second.redF() << stops.at(i + 1).second.greenF() << stops.at(i + 1).second.blueF() << "]\n"; + } + s << ">>\n" + "endobj\n"; + write(data); + functions << f; + } + + QVector<QGradientBound> gradientBounds; - QTransform inv = matrix.inverted(); - QPointF page_rect[4] = { inv.map(QPointF(0, 0)), - inv.map(QPointF(width_, 0)), - inv.map(QPointF(0, height_)), - inv.map(QPointF(width_, height_)) }; + for (int step = from; step < to; ++step) { + if (reflect && step % 2) { + for (int i = stops.size() - 1; i > 0; --i) { + QGradientBound b; + b.start = step + 1 - qBound(0., stops.at(i).first, 1.); + b.stop = step + 1 - qBound(0., stops.at(i - 1).first, 1.); + b.function = functions.at(i - 1); + b.reverse = true; + gradientBounds << b; + } + } else { + for (int i = 0; i < stops.size() - 1; ++i) { + QGradientBound b; + b.start = step + qBound(0., stops.at(i).first, 1.); + b.stop = step + qBound(0., stops.at(i + 1).first, 1.); + b.function = functions.at(i); + b.reverse = false; + gradientBounds << b; + } + } + } - bool opaque = b.isOpaque(); + // normalize bounds to [0..1] + qreal bstart = gradientBounds.at(0).start; + qreal bend = gradientBounds.at(gradientBounds.size() - 1).stop; + qreal norm = 1./(bend - bstart); + for (int i = 0; i < gradientBounds.size(); ++i) { + gradientBounds[i].start = (gradientBounds[i].start - bstart)*norm; + gradientBounds[i].stop = (gradientBounds[i].stop - bstart)*norm; + } - QByteArray shader; - QByteArray alphaShader; - if (gradient->type() == QGradient::LinearGradient) { - const QLinearGradient *lg = static_cast<const QLinearGradient *>(gradient); - shader = QPdf::generateLinearGradientShader(lg, page_rect); - if (!opaque) - alphaShader = QPdf::generateLinearGradientShader(lg, page_rect, true); + int function; + if (gradientBounds.size() > 1) { + function = addXrefEntry(-1); + QByteArray data; + QPdf::ByteStream s(&data); + s << "<<\n" + "/FunctionType 3\n" + "/Domain [0 1]\n" + "/Bounds ["; + for (int i = 1; i < gradientBounds.size(); ++i) + s << gradientBounds.at(i).start; + s << "]\n" + "/Encode ["; + for (int i = 0; i < gradientBounds.size(); ++i) + s << (gradientBounds.at(i).reverse ? "1 0 " : "0 1 "); + s << "]\n" + "/Functions ["; + for (int i = 0; i < gradientBounds.size(); ++i) + s << gradientBounds.at(i).function << "0 R "; + s << "]\n" + ">>\n"; + write(data); } else { - // ############# - return 0; + function = functions.at(0); + } + return function; +} + +int QPdfEnginePrivate::generateLinearGradientShader(const QLinearGradient *gradient, const QTransform &matrix, bool alpha) +{ + QPointF start = gradient->start(); + QPointF stop = gradient->finalStop(); + QPointF offset = stop - start; + Q_ASSERT(gradient->coordinateMode() == QGradient::LogicalMode); + + int from = 0; + int to = 1; + bool reflect = false; + switch (gradient->spread()) { + case QGradient::PadSpread: + break; + case QGradient::ReflectSpread: + reflect = true; + // fall through + case QGradient::RepeatSpread: { + // calculate required bounds + QRectF pageRect = m_pageLayout.fullRectPixels(resolution); + QTransform inv = matrix.inverted(); + QPointF page_rect[4] = { inv.map(pageRect.topLeft()), + inv.map(pageRect.topRight()), + inv.map(pageRect.bottomLeft()), + inv.map(pageRect.bottomRight()) }; + + qreal length = offset.x()*offset.x() + offset.y()*offset.y(); + + // find the max and min values in offset and orth direction that are needed to cover + // the whole page + from = INT_MAX; + to = INT_MIN; + for (int i = 0; i < 4; ++i) { + qreal off = ((page_rect[i].x() - start.x()) * offset.x() + (page_rect[i].y() - start.y()) * offset.y())/length; + from = qMin(from, qFloor(off)); + to = qMax(to, qCeil(off)); + } + + stop = start + to * offset; + start = start + from * offset;\ + break; + } + } + + int function = createShadingFunction(gradient, from, to, reflect, alpha); + + QByteArray shader; + QPdf::ByteStream s(&shader); + s << "<<\n" + "/ShadingType 2\n" + "/ColorSpace " << (alpha ? "/DeviceGray\n" : "/DeviceRGB\n") << + "/AntiAlias true\n" + "/Coords [" << start.x() << start.y() << stop.x() << stop.y() << "]\n" + "/Extend [true true]\n" + "/Function " << function << "0 R\n" + ">>\n" + "endobj\n"; + int shaderObject = addXrefEntry(-1); + write(shader); + return shaderObject; +} + +int QPdfEnginePrivate::generateRadialGradientShader(const QRadialGradient *gradient, const QTransform &matrix, bool alpha) +{ + QPointF p1 = gradient->center(); + double r1 = gradient->centerRadius(); + QPointF p0 = gradient->focalPoint(); + double r0 = gradient->focalRadius(); + + Q_ASSERT(gradient->coordinateMode() == QGradient::LogicalMode); + + int from = 0; + int to = 1; + bool reflect = false; + switch (gradient->spread()) { + case QGradient::PadSpread: + break; + case QGradient::ReflectSpread: + reflect = true; + // fall through + case QGradient::RepeatSpread: { + Q_ASSERT(qFuzzyIsNull(r0)); // QPainter emulates if this is not 0 + + QRectF pageRect = m_pageLayout.fullRectPixels(resolution); + QTransform inv = matrix.inverted(); + QPointF page_rect[4] = { inv.map(pageRect.topLeft()), + inv.map(pageRect.topRight()), + inv.map(pageRect.bottomLeft()), + inv.map(pageRect.bottomRight()) }; + + // increase to until the whole page fits into it + bool done = false; + while (!done) { + QPointF center = QPointF(p0.x() + to*(p1.x() - p0.x()), p0.y() + to*(p1.y() - p0.y())); + double radius = r0 + to*(r1 - r0); + double r2 = radius*radius; + done = true; + for (int i = 0; i < 4; ++i) { + QPointF off = page_rect[i] - center; + if (off.x()*off.x() + off.y()*off.y() > r2) { + ++to; + done = false; + break; + } + } + } + p1 = QPointF(p0.x() + to*(p1.x() - p0.x()), p0.y() + to*(p1.y() - p0.y())); + r1 = r0 + to*(r1 - r0); + break; + } } + + int function = createShadingFunction(gradient, from, to, reflect, alpha); + + QByteArray shader; + QPdf::ByteStream s(&shader); + s << "<<\n" + "/ShadingType 3\n" + "/ColorSpace " << (alpha ? "/DeviceGray\n" : "/DeviceRGB\n") << + "/AntiAlias true\n" + "/Domain [0 1]\n" + "/Coords [" << p0.x() << p0.y() << r0 << p1.x() << p1.y() << r1 << "]\n" + "/Extend [true true]\n" + "/Function " << function << "0 R\n" + ">>\n" + "endobj\n"; int shaderObject = addXrefEntry(-1); write(shader); + return shaderObject; +} + +int QPdfEnginePrivate::generateGradientShader(const QGradient *gradient, const QTransform &matrix, bool alpha) +{ + switch (gradient->type()) { + case QGradient::LinearGradient: + return generateLinearGradientShader(static_cast<const QLinearGradient *>(gradient), matrix, alpha); + case QGradient::RadialGradient: + return generateRadialGradientShader(static_cast<const QRadialGradient *>(gradient), matrix, alpha); + case QGradient::ConicalGradient: + default: + qWarning() << "Implement me!"; + } + return 0; +} + +int QPdfEnginePrivate::gradientBrush(const QBrush &b, const QTransform &matrix, int *gStateObject) +{ + const QGradient *gradient = b.gradient(); + + if (!gradient || gradient->coordinateMode() != QGradient::LogicalMode) + return 0; + + QRectF pageRect = m_pageLayout.fullRectPixels(resolution); + + QTransform m = b.transform() * matrix; + int shaderObject = generateGradientShader(gradient, m); QByteArray str; QPdf::ByteStream s(&str); @@ -2152,12 +2197,12 @@ int QPdfEnginePrivate::gradientBrush(const QBrush &b, const QMatrix &matrix, int "/PatternType 2\n" "/Shading " << shaderObject << "0 R\n" "/Matrix [" - << matrix.m11() - << matrix.m12() - << matrix.m21() - << matrix.m22() - << matrix.dx() - << matrix.dy() << "]\n"; + << m.m11() + << m.m12() + << m.m21() + << m.m22() + << m.dx() + << m.dy() << "]\n"; s << ">>\n" "endobj\n"; @@ -2165,7 +2210,7 @@ int QPdfEnginePrivate::gradientBrush(const QBrush &b, const QMatrix &matrix, int write(str); currentPage->patterns.append(patternObj); - if (!opaque) { + if (!b.isOpaque()) { bool ca = true; QGradientStops stops = gradient->stops(); int a = stops.at(0).second.alpha(); @@ -2178,8 +2223,7 @@ int QPdfEnginePrivate::gradientBrush(const QBrush &b, const QMatrix &matrix, int if (ca) { *gStateObject = addConstantAlphaObject(stops.at(0).second.alpha()); } else { - int alphaShaderObject = addXrefEntry(-1); - write(alphaShader); + int alphaShaderObject = generateGradientShader(gradient, m, true); QByteArray content; QPdf::ByteStream c(&content); @@ -2190,7 +2234,7 @@ int QPdfEnginePrivate::gradientBrush(const QBrush &b, const QMatrix &matrix, int f << "<<\n" "/Type /XObject\n" "/Subtype /Form\n" - "/BBox [0 0 " << width_ << height_ << "]\n" + "/BBox [0 0 " << pageRect.width() << pageRect.height() << "]\n" "/Group <</S /Transparency >>\n" "/Resources <<\n" "/Shading << /Shader" << alphaShaderObject << alphaShaderObject << "0 R >>\n" @@ -2214,7 +2258,6 @@ int QPdfEnginePrivate::gradientBrush(const QBrush &b, const QMatrix &matrix, int return patternObj; } -#endif int QPdfEnginePrivate::addConstantAlphaObject(int brushAlpha, int penAlpha) { @@ -2236,6 +2279,7 @@ int QPdfEnginePrivate::addConstantAlphaObject(int brushAlpha, int penAlpha) return object; } + int QPdfEnginePrivate::addBrushPattern(const QTransform &m, bool *specifyColor, int *gStateObject) { int paintType = 2; // Uncolored tiling @@ -2251,13 +2295,9 @@ int QPdfEnginePrivate::addBrushPattern(const QTransform &m, bool *specifyColor, //qDebug() << brushOrigin << matrix; Qt::BrushStyle style = brush.style(); - if (style == Qt::LinearGradientPattern) {// && style <= Qt::ConicalGradientPattern) { -#ifdef USE_NATIVE_GRADIENTS + if (style == Qt::LinearGradientPattern || style == Qt::RadialGradientPattern) {// && style <= Qt::ConicalGradientPattern) { *specifyColor = false; - return gradientBrush(b, matrix, gStateObject); -#else - return 0; -#endif + return gradientBrush(brush, matrix, gStateObject); } if ((!brush.isOpaque() && brush.style() < Qt::LinearGradientPattern) || opacity != 1.0) diff --git a/src/gui/painting/qpdf_p.h b/src/gui/painting/qpdf_p.h index e7ff09cd3b..94e74f30b9 100644 --- a/src/gui/painting/qpdf_p.h +++ b/src/gui/painting/qpdf_p.h @@ -58,8 +58,6 @@ #include "private/qfontsubset_p.h" #include "qpagelayout.h" -// #define USE_NATIVE_GRADIENTS - QT_BEGIN_NAMESPACE const char *qt_real_to_string(qreal val, char *buf); @@ -116,9 +114,6 @@ namespace QPdf { QByteArray generateMatrix(const QTransform &matrix); QByteArray generateDashes(const QPen &pen); QByteArray patternForBrush(const QBrush &b); -#ifdef USE_NATIVE_GRADIENTS - QByteArray generateLinearGradientShader(const QLinearGradient *lg, const QPointF *page_rect, bool alpha = false); -#endif struct Stroker { Stroker(); @@ -276,9 +271,11 @@ public: QPageLayout m_pageLayout; private: -#ifdef USE_NATIVE_GRADIENTS - int gradientBrush(const QBrush &b, const QMatrix &matrix, int *gStateObject); -#endif + int gradientBrush(const QBrush &b, const QTransform &matrix, int *gStateObject); + int generateGradientShader(const QGradient *gradient, const QTransform &matrix, bool alpha = false); + int generateLinearGradientShader(const QLinearGradient *lg, const QTransform &matrix, bool alpha); + int generateRadialGradientShader(const QRadialGradient *gradient, const QTransform &matrix, bool alpha); + int createShadingFunction(const QGradient *gradient, int from, int to, bool reflect, bool alpha); void writeInfo(); void writePageRoot(); diff --git a/src/gui/painting/qrgb.h b/src/gui/painting/qrgb.h index f7f2185bef..05b3a76bce 100644 --- a/src/gui/painting/qrgb.h +++ b/src/gui/painting/qrgb.h @@ -36,6 +36,11 @@ #include <QtCore/qglobal.h> #include <QtCore/qprocessordetection.h> +#if defined(__SSE4_1__) +#include <smmintrin.h> +#elif defined(__SSE2__) +#include <emmintrin.h> +#endif QT_BEGIN_NAMESPACE @@ -87,19 +92,45 @@ inline Q_DECL_RELAXED_CONSTEXPR QRgb qPremultiply(QRgb x) Q_GUI_EXPORT extern const uint qt_inv_premul_factor[]; +#if defined(__SSE2__) +inline QRgb qUnpremultiply(QRgb p) +{ + const uint alpha = qAlpha(p); + if (alpha == 255 || alpha == 0) + return p; + const uint invAlpha = qt_inv_premul_factor[alpha]; + const __m128i via = _mm_set1_epi32(invAlpha); + const __m128i vr = _mm_set1_epi32(0x8000); +#ifdef __SSE4_1__ + __m128i vl = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(p)); + vl = _mm_mullo_epi32(vl, via); +#else + __m128i vl = _mm_unpacklo_epi8(_mm_cvtsi32_si128(p), _mm_setzero_si128()); + vl = _mm_unpacklo_epi16(vl, vl); + __m128i vll = _mm_mullo_epi16(vl, via); + __m128i vlh = _mm_mulhi_epu16(vl, via); + vl = _mm_add_epi32(vll, _mm_slli_epi32(vlh, 16)); +#endif + vl = _mm_add_epi32(vl, vr); + vl = _mm_srli_epi32(vl, 16); + vl = _mm_packs_epi32(vl, _mm_setzero_si128()); + vl = _mm_insert_epi16(vl, alpha, 3); + vl = _mm_packus_epi16(vl, _mm_setzero_si128()); + return _mm_cvtsi128_si32(vl); +} +#else inline QRgb qUnpremultiply(QRgb p) { const uint alpha = qAlpha(p); // Alpha 255 and 0 are the two most common values, which makes them beneficial to short-cut. - if (alpha == 255) + if (alpha == 255 || alpha == 0) return p; - if (alpha == 0) - return 0; // (p*(0x00ff00ff/alpha)) >> 16 == (p*255)/alpha for all p and alpha <= 256. const uint invAlpha = qt_inv_premul_factor[alpha]; // We add 0x8000 to get even rounding. The rounding also ensures that qPremultiply(qUnpremultiply(p)) == p for all p. return qRgba((qRed(p)*invAlpha + 0x8000)>>16, (qGreen(p)*invAlpha + 0x8000)>>16, (qBlue(p)*invAlpha + 0x8000)>>16, alpha); } +#endif QT_END_NAMESPACE diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 1a71042648..0f3cb21c70 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -356,7 +356,6 @@ struct QtFontFamily populated(false), fixedPitch(false), name(n), count(0), foundries(0) - , bogusWritingSystems(false) , askedForFallback(false) { memset(writingSystems, 0, sizeof(writingSystems)); @@ -375,7 +374,6 @@ struct QtFontFamily int count; QtFontFoundry **foundries; - bool bogusWritingSystems; QStringList fallbackFamilies; bool askedForFallback; unsigned char writingSystems[QFontDatabase::WritingSystemsCount]; diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp index a151c515a3..eb51447105 100644 --- a/src/gui/text/qtextcursor.cpp +++ b/src/gui/text/qtextcursor.cpp @@ -424,9 +424,9 @@ bool QTextCursorPrivate::movePosition(QTextCursor::MoveOperation op, QTextCursor // skip if already at word start QTextEngine *engine = layout->engine(); - engine->attributes(); + const QCharAttributes *attributes = engine->attributes(); if ((relativePos == blockIt.length() - 1) - && (engine->atSpace(relativePos - 1) || engine->atWordSeparator(relativePos - 1))) + && (attributes[relativePos - 1].whiteSpace || engine->atWordSeparator(relativePos - 1))) return false; if (relativePos < blockIt.length()-1) @@ -499,7 +499,7 @@ bool QTextCursorPrivate::movePosition(QTextCursor::MoveOperation op, QTextCursor } case QTextCursor::EndOfWord: { QTextEngine *engine = layout->engine(); - engine->attributes(); + const QCharAttributes *attributes = engine->attributes(); const int len = blockIt.length() - 1; if (relativePos >= len) return false; @@ -508,7 +508,7 @@ bool QTextCursorPrivate::movePosition(QTextCursor::MoveOperation op, QTextCursor while (relativePos < len && engine->atWordSeparator(relativePos)) ++relativePos; } else { - while (relativePos < len && !engine->atSpace(relativePos) && !engine->atWordSeparator(relativePos)) + while (relativePos < len && !attributes[relativePos].whiteSpace && !engine->atWordSeparator(relativePos)) ++relativePos; } newPosition = blockIt.position() + relativePos; diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index e8dd663354..d3b70aaf26 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -1142,6 +1142,9 @@ void QTextDocument::setMetaInformation(MetaInformation info, const QString &stri Returns the plain text contained in the document. If you want formatting information use a QTextCursor instead. + \note Embedded objects, such as images, are represented by a + Unicode value U+FFFC (OBJECT REPLACEMENT CHARACTER). + \sa toHtml() */ QString QTextDocument::toPlainText() const diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 10a61d3c84..67a19804a3 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -2549,21 +2549,6 @@ bool QTextEngine::atWordSeparator(int position) const return false; } -bool QTextEngine::atSpace(int position) const -{ - const QChar c = layoutData->string.at(position); - switch (c.unicode()) { - case QChar::Tabulation: - case QChar::Space: - case QChar::Nbsp: - case QChar::LineSeparator: - return true; - default: - break; - } - return false; -} - void QTextEngine::setPreeditArea(int position, const QString &preeditText) { if (preeditText.isEmpty()) { diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index 8037fd5f6d..39b9e0cb5a 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -592,7 +592,6 @@ private: public: bool atWordSeparator(int position) const; - bool atSpace(int position) const; QString elidedText(Qt::TextElideMode mode, const QFixed &width, int flags = 0, int from = 0, int count = -1) const; diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp index a477aa2c99..d4eb1a4b0b 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -3027,8 +3027,8 @@ QTextTableFormat::QTextTableFormat(const QTextFormat &fmt) \ingroup richtext-processing \ingroup shared - Inline images are represented by an object replacement character - (0xFFFC in Unicode) which has an associated QTextImageFormat. The + Inline images are represented by a Unicode value U+FFFC (OBJECT + REPLACEMENT CHARACTER) which has an associated QTextImageFormat. The image format specifies a name with setName() that is used to locate the image. The size of the rectangle that the image will occupy is specified using setWidth() and setHeight(). diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index cab9f6ae61..7da3e84041 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -648,10 +648,10 @@ int QTextLayout::nextCursorPosition(int oldPos, CursorMode mode) const while (oldPos < len && d->atWordSeparator(oldPos)) oldPos++; } else { - while (oldPos < len && !d->atSpace(oldPos) && !d->atWordSeparator(oldPos)) + while (oldPos < len && !attributes[oldPos].whiteSpace && !d->atWordSeparator(oldPos)) oldPos++; } - while (oldPos < len && d->atSpace(oldPos)) + while (oldPos < len && attributes[oldPos].whiteSpace) oldPos++; } @@ -679,7 +679,7 @@ int QTextLayout::previousCursorPosition(int oldPos, CursorMode mode) const while (oldPos && !attributes[oldPos].graphemeBoundary) oldPos--; } else { - while (oldPos && d->atSpace(oldPos-1)) + while (oldPos > 0 && attributes[oldPos - 1].whiteSpace) oldPos--; if (oldPos && d->atWordSeparator(oldPos-1)) { @@ -687,7 +687,7 @@ int QTextLayout::previousCursorPosition(int oldPos, CursorMode mode) const while (oldPos && d->atWordSeparator(oldPos-1)) oldPos--; } else { - while (oldPos && !d->atSpace(oldPos-1) && !d->atWordSeparator(oldPos-1)) + while (oldPos > 0 && !attributes[oldPos - 1].whiteSpace && !d->atWordSeparator(oldPos-1)) oldPos--; } } diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp index 425126d474..df7c8b9c71 100644 --- a/src/gui/text/qtextobject.cpp +++ b/src/gui/text/qtextobject.cpp @@ -1561,7 +1561,7 @@ QTextBlock QTextBlock::next() const Returns the text block in the document before this block, or an empty text block if this is the first one. - Note that the next block may be in a different frame or table to this block. + Note that the previous block may be in a different frame or table to this block. \sa next(), begin(), end() */ diff --git a/src/gui/util/qvalidator.cpp b/src/gui/util/qvalidator.cpp index 6b1e20c844..31dfd20d1a 100644 --- a/src/gui/util/qvalidator.cpp +++ b/src/gui/util/qvalidator.cpp @@ -448,6 +448,8 @@ void QIntValidator::fixup(QString &input) const input = locale().toString(entered); } +// FIXME: Qt 6: Make QIntValidator::setRange() non-virtual + /*! Sets the range of the validator to only accept integers between \a bottom and \a top inclusive. @@ -696,6 +698,7 @@ QValidator::State QDoubleValidatorPrivate::validateWithLocale(QString &input, QL return QValidator::Intermediate; } +// FIXME: Qt 6: Make QDoubleValidator::setRange() non-virtual /*! Sets the validator to accept doubles from \a minimum to \a maximum |