From 45cdd701fa9e9e491bebde2b6fa11d7dd9250e1d Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Tue, 10 May 2011 15:15:15 +0200 Subject: [PATCH 01/27] Add QT_xxx_VERSION macros for each library in qtbase Provide version info for each library like QTCORE_VERSION and etc. Task-number: QTMODULARIZATION-44 Reviewed-by: axis --- .gitignore | 10 ++++++++++ bin/syncqt | 40 ++++++++++++++++++++++++++++++++++++++++ src/corelib/corelib.pro | 3 +++ src/dbus/dbus.pro | 3 +++ src/gui/gui.pro | 2 ++ src/network/network.pro | 3 +++ src/opengl/opengl.pro | 2 ++ src/openvg/openvg.pro | 2 ++ src/sql/sql.pro | 2 ++ src/testlib/testlib.pro | 3 +++ src/xml/xml.pro | 2 ++ sync.profile | 9 +++++++++ 12 files changed, 81 insertions(+) diff --git a/.gitignore b/.gitignore index 5b4d2f2440..0db34fab52 100644 --- a/.gitignore +++ b/.gitignore @@ -119,6 +119,16 @@ translations/*.qm translations/*_untranslated.ts qrc_*.cpp +src/corelib/qtcoreversion.h +src/dbus/qtdbusversion.h +src/gui/qtguiversion.h +src/network/qtnetworkversion.h +src/opengl/qtopenglversion.h +src/openvg/qtopenvgversion.h +src/sql/qtsqlversion.h +src/testlib/qttestversion.h +src/xml/qtxmlversion.h + # Test generated files QObject.log tst_* diff --git a/bin/syncqt b/bin/syncqt index 3d25ecc817..2ac67fe51d 100755 --- a/bin/syncqt +++ b/bin/syncqt @@ -47,6 +47,7 @@ my $copy_headers = 0; my $create_uic_class_map = 0; my $create_private_headers = 1; my $no_module_fwd = 0; +my $no_module_version_header = 0; my @modules_to_sync ; $force_relative = 1 if ( -d "/System/Library/Frameworks" ); @@ -77,6 +78,8 @@ sub showUsage print " Create headers for with original headers in relative to \n"; print " -private Force copy private headers (default: " . ($create_private_headers ? "yes" : "no") . ")\n"; print " -no-module-fwd Don't create fwd includes for module pri files\n"; + print " -no-module-version-header\n"; + print " Don't create module version header file\n"; print " -help This help\n"; exit 0; } @@ -619,6 +622,9 @@ while ( @ARGV ) { } elsif($arg eq "-no-module-fwd") { $var = "no_module_fwd"; $val = "yes"; + } elsif($arg eq "-no-module-version-header") { + $var = "no_module_version_header"; + $val = "yes"; } elsif($arg =~/^-/) { print "Unknown option: $arg\n\n" if(!$var); showUsage(); @@ -696,6 +702,8 @@ while ( @ARGV ) { } } elsif ($var eq "no_module_fwd") { $no_module_fwd = 1; + } elsif ($var eq "no_module_version_header") { + $no_module_version_header = 1; } elsif ($var eq "output") { my $outdir = $val; if(checkRelative($outdir)) { @@ -748,6 +756,9 @@ foreach my $lib (@modules_to_sync) { #iteration info my $dir = $modules{$lib}; my $module_version = ""; + my $module_major_version = ""; + my $module_minor_version = ""; + my $module_patch_version = ""; if (-e "$modulepris{$lib}") { my $content = fileContents($modulepris{$lib}); @@ -758,6 +769,13 @@ foreach my $lib (@modules_to_sync) { chomp $module_version; $module_version =~ s/^\s*QT\..*\.VERSION\s*=\s*([^#]+).*$/$1/; $module_version =~ s/\s+$//; + my @versions = split(/\./, $module_version); + $module_major_version = $versions[0]; + chomp $module_major_version; + $module_minor_version = $versions[1]; + chomp $module_minor_version; + $module_patch_version = $versions[2]; + chomp $module_patch_version; } } print "WARNING: Module $lib\'s pri missing QT..VERSION variable! Private headers not versioned!\n" if (!$module_version); @@ -1045,6 +1063,28 @@ foreach my $lib (@modules_to_sync) { print "WARNING: Module $lib\'s pri file '$modulepri' not found.\nSkipped creating forwarding pri for $lib.\n"; } } + + # create the version header files for each module + unless ($no_module_version_header) { + my $modulepri = $modulepris{$lib}; + if (-e $modulepri) { + my $modulepriname = basename($modulepri); + my $moduleversionheader = "$modules{$lib}/" . lc($lib) . "version.h"; + my $modulehexstring = sprintf("0x%02X%02X%02X", int($module_major_version), int($module_minor_version), int($module_patch_version)); + open MODULE_VERSION_HEADER_FILE, ">$moduleversionheader"; + print MODULE_VERSION_HEADER_FILE "/* This file was generated by syncqt with the info from sync.profile. */\n"; + print MODULE_VERSION_HEADER_FILE "#ifndef QT_". uc($lib) . "_VERSION_H\n"; + print MODULE_VERSION_HEADER_FILE "#define QT_". uc($lib) . "_VERSION_H\n"; + print MODULE_VERSION_HEADER_FILE "\n"; + print MODULE_VERSION_HEADER_FILE "#define " .uc($lib) . "_VERSION_STR \"" . $module_version . "\"\n"; + print MODULE_VERSION_HEADER_FILE "\n"; + print MODULE_VERSION_HEADER_FILE "#define " .uc($lib) . "_VERSION $modulehexstring\n", ; + print MODULE_VERSION_HEADER_FILE "\n"; + print MODULE_VERSION_HEADER_FILE "#endif // QT_". uc($lib) . "_VERSION_H\n"; + } elsif ($modulepri) { + print "WARNING: Module $lib\'s pri file '$modulepri' not found.\nSkipped creating module version header for $lib.\n"; + } + } } } unless($showonly || !$create_uic_class_map) { diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro index a31d1e5b7f..1e1e4dacf6 100644 --- a/src/corelib/corelib.pro +++ b/src/corelib/corelib.pro @@ -11,6 +11,9 @@ win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x67000000 irix-cc*:QMAKE_CXXFLAGS += -no_prelink -ptused include(../qbase.pri) + +HEADERS += $$QT_SOURCE_TREE/src/corelib/qtcoreversion.h + include(animation/animation.pri) include(arch/arch.pri) include(concurrent/concurrent.pri) diff --git a/src/dbus/dbus.pro b/src/dbus/dbus.pro index e73fa05a74..731d20a893 100644 --- a/src/dbus/dbus.pro +++ b/src/dbus/dbus.pro @@ -32,6 +32,9 @@ win32 { else:LIBS_PRIVATE += -ldbus-1 } include(../qbase.pri) + +HEADERS += $$QT_SOURCE_TREE/src/dub/qtdbusversion.h + PUB_HEADERS = qdbusargument.h \ qdbusconnectioninterface.h \ qdbusmacros.h \ diff --git a/src/gui/gui.pro b/src/gui/gui.pro index 072553a05c..7e9d78d0bb 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -15,6 +15,8 @@ unix|win32-g++*:QMAKE_PKGCONFIG_REQUIRES = QtCore include(../qbase.pri) +HEADERS += $$QT_SOURCE_TREE/src/gui/qtguiversion.h + contains(QT_CONFIG, x11sm):CONFIG += x11sm #platforms diff --git a/src/network/network.pro b/src/network/network.pro index fc5d08d936..4ee71b028e 100644 --- a/src/network/network.pro +++ b/src/network/network.pro @@ -19,6 +19,9 @@ win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x64000000 unix|win32-g++*:QMAKE_PKGCONFIG_REQUIRES = QtCore include(../qbase.pri) + +HEADERS += $$QT_SOURCE_TREE/src/network/qtnetworkversion.h + include(access/access.pri) include(bearer/bearer.pri) include(kernel/kernel.pri) diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro index 849bd9ebc7..b30d4057db 100644 --- a/src/opengl/opengl.pro +++ b/src/opengl/opengl.pro @@ -15,6 +15,8 @@ unix|win32-g++*:QMAKE_PKGCONFIG_REQUIRES = QtCore QtGui include(../qbase.pri) +HEADERS += $$QT_SOURCE_TREE/src/opengl/qtopenglversion.h + !win32:!embedded:!mac:!symbian:!qpa:CONFIG += x11 contains(QT_CONFIG, opengl):CONFIG += opengl contains(QT_CONFIG, opengles1):CONFIG += opengles1 diff --git a/src/openvg/openvg.pro b/src/openvg/openvg.pro index dbe1620f80..0e22503c3b 100644 --- a/src/openvg/openvg.pro +++ b/src/openvg/openvg.pro @@ -52,6 +52,8 @@ symbian { include(../qbase.pri) +HEADERS += $$QT_SOURCE_TREE/src/openvg/qtopenvgversion.h + unix|win32-g++*:QMAKE_PKGCONFIG_REQUIRES = QtCore QtGui symbian:TARGET.UID3 = 0x2001E62F diff --git a/src/sql/sql.pro b/src/sql/sql.pro index f1bdd6bda1..c7cbbc4985 100644 --- a/src/sql/sql.pro +++ b/src/sql/sql.pro @@ -13,6 +13,8 @@ unix|win32-g++*:QMAKE_PKGCONFIG_REQUIRES = QtCore include(../qbase.pri) +HEADERS += $$QT_SOURCE_TREE/src/sql/qtsqlversion.h + DEFINES += QT_NO_CAST_FROM_ASCII PRECOMPILED_HEADER = ../corelib/global/qt_pch.h SQL_P = sql diff --git a/src/testlib/testlib.pro b/src/testlib/testlib.pro index 311c79379b..3408c91420 100644 --- a/src/testlib/testlib.pro +++ b/src/testlib/testlib.pro @@ -85,6 +85,9 @@ qpa:mac: { } include(../qbase.pri) + +HEADERS += $$QT_SOURCE_TREE/src/testlib/qttestlibversion.h + QMAKE_TARGET_PRODUCT = QTestLib QMAKE_TARGET_DESCRIPTION = Qt \ Unit \ diff --git a/src/xml/xml.pro b/src/xml/xml.pro index 68bb20b009..986e478b69 100644 --- a/src/xml/xml.pro +++ b/src/xml/xml.pro @@ -12,6 +12,8 @@ unix|win32-g++*:QMAKE_PKGCONFIG_REQUIRES = QtCore include(../qbase.pri) +HEADERS += $$QT_SOURCE_TREE/src/xml/qtxmlversion.h + PRECOMPILED_HEADER = ../corelib/global/qt_pch.h win32-borland { diff --git a/sync.profile b/sync.profile index 8d838041f2..d180458445 100644 --- a/sync.profile +++ b/sync.profile @@ -28,6 +28,15 @@ "qtconcurrentmap.h" => "QtConcurrentMap", "qtconcurrentfilter.h" => "QtConcurrentFilter", "qtconcurrentrun.h" => "QtConcurrentRun", + "qtcoreversion.h" => "QtCoreVersion", + "qtdbusversion.h" => "QtDBusVersion", + "qtguiversion.h" => "QtGuiVersion", + "qtnetworkversion.h" => "QtNetworkVersion", + "qtopenglversion.h" => "QtOpenGLVersion", + "qtopenvgversion.h" => "QtOpenVGVersion", + "qtsqlversion.h" => "QtSqlVersion", + "qttestversion.h" => "QtTestVersion", + "qtxmlversion.h" => "QtXmlVersion", ); %mastercontent = ( "core" => "#include \n", From 236e794fc31ca2bcba0bdc06fa133646cef39480 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Wed, 11 May 2011 10:05:43 +0200 Subject: [PATCH 02/27] Fix a bug in syncqt. Move the generation of version header file before the sync of header files. Reviewed-by: TrustMe --- bin/syncqt | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/bin/syncqt b/bin/syncqt index 2ac67fe51d..3d668fa05e 100755 --- a/bin/syncqt +++ b/bin/syncqt @@ -847,6 +847,28 @@ foreach my $lib (@modules_to_sync) { } } + # create the version header files for each module + unless ($no_module_version_header) { + my $modulepri = $modulepris{$lib}; + if (-e $modulepri) { + my $modulepriname = basename($modulepri); + my $moduleversionheader = "$modules{$lib}/" . lc($lib) . "version.h"; + my $modulehexstring = sprintf("0x%02X%02X%02X", int($module_major_version), int($module_minor_version), int($module_patch_version)); + open MODULE_VERSION_HEADER_FILE, ">$moduleversionheader"; + print MODULE_VERSION_HEADER_FILE "/* This file was generated by syncqt with the info from sync.profile. */\n"; + print MODULE_VERSION_HEADER_FILE "#ifndef QT_". uc($lib) . "_VERSION_H\n"; + print MODULE_VERSION_HEADER_FILE "#define QT_". uc($lib) . "_VERSION_H\n"; + print MODULE_VERSION_HEADER_FILE "\n"; + print MODULE_VERSION_HEADER_FILE "#define " .uc($lib) . "_VERSION_STR \"" . $module_version . "\"\n"; + print MODULE_VERSION_HEADER_FILE "\n"; + print MODULE_VERSION_HEADER_FILE "#define " .uc($lib) . "_VERSION $modulehexstring\n", ; + print MODULE_VERSION_HEADER_FILE "\n"; + print MODULE_VERSION_HEADER_FILE "#endif // QT_". uc($lib) . "_VERSION_H\n"; + } elsif ($modulepri) { + print "WARNING: Module $lib\'s pri file '$modulepri' not found.\nSkipped creating module version header for $lib.\n"; + } + } + #create the new ones foreach my $current_dir (split(/;/, $dir)) { my $headers_dir = $current_dir; @@ -1063,28 +1085,6 @@ foreach my $lib (@modules_to_sync) { print "WARNING: Module $lib\'s pri file '$modulepri' not found.\nSkipped creating forwarding pri for $lib.\n"; } } - - # create the version header files for each module - unless ($no_module_version_header) { - my $modulepri = $modulepris{$lib}; - if (-e $modulepri) { - my $modulepriname = basename($modulepri); - my $moduleversionheader = "$modules{$lib}/" . lc($lib) . "version.h"; - my $modulehexstring = sprintf("0x%02X%02X%02X", int($module_major_version), int($module_minor_version), int($module_patch_version)); - open MODULE_VERSION_HEADER_FILE, ">$moduleversionheader"; - print MODULE_VERSION_HEADER_FILE "/* This file was generated by syncqt with the info from sync.profile. */\n"; - print MODULE_VERSION_HEADER_FILE "#ifndef QT_". uc($lib) . "_VERSION_H\n"; - print MODULE_VERSION_HEADER_FILE "#define QT_". uc($lib) . "_VERSION_H\n"; - print MODULE_VERSION_HEADER_FILE "\n"; - print MODULE_VERSION_HEADER_FILE "#define " .uc($lib) . "_VERSION_STR \"" . $module_version . "\"\n"; - print MODULE_VERSION_HEADER_FILE "\n"; - print MODULE_VERSION_HEADER_FILE "#define " .uc($lib) . "_VERSION $modulehexstring\n", ; - print MODULE_VERSION_HEADER_FILE "\n"; - print MODULE_VERSION_HEADER_FILE "#endif // QT_". uc($lib) . "_VERSION_H\n"; - } elsif ($modulepri) { - print "WARNING: Module $lib\'s pri file '$modulepri' not found.\nSkipped creating module version header for $lib.\n"; - } - } } } unless($showonly || !$create_uic_class_map) { From 7fce0a73cc9b099c4ca67b3bc2e8bbe3060230c6 Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Wed, 11 May 2011 10:53:00 +0200 Subject: [PATCH 03/27] Check if OES_texture_npot is present on OpenGL ES 2. Unless the OES_texture_npot extension is present, non-power- of-two textures have some restrictions on OpenGL ES 2. Reviewed-by: Samuel --- src/opengl/qglfunctions.cpp | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/opengl/qglfunctions.cpp b/src/opengl/qglfunctions.cpp index 8027081543..e478fa7a4c 100644 --- a/src/opengl/qglfunctions.cpp +++ b/src/opengl/qglfunctions.cpp @@ -211,19 +211,23 @@ QGLFunctions::QGLFunctions(const QGLContext *context) static int qt_gl_resolve_features() { #if defined(QT_OPENGL_ES_2) - return QGLFunctions::Multitexture | - QGLFunctions::Shaders | - QGLFunctions::Buffers | - QGLFunctions::Framebuffers | - QGLFunctions::BlendColor | - QGLFunctions::BlendEquation | - QGLFunctions::BlendEquationSeparate | - QGLFunctions::BlendFuncSeparate | - QGLFunctions::BlendSubtract | - QGLFunctions::CompressedTextures | - QGLFunctions::Multisample | - QGLFunctions::StencilSeparate | - QGLFunctions::NPOTTextures; + int features = QGLFunctions::Multitexture | + QGLFunctions::Shaders | + QGLFunctions::Buffers | + QGLFunctions::Framebuffers | + QGLFunctions::BlendColor | + QGLFunctions::BlendEquation | + QGLFunctions::BlendEquationSeparate | + QGLFunctions::BlendFuncSeparate | + QGLFunctions::BlendSubtract | + QGLFunctions::CompressedTextures | + QGLFunctions::Multisample | + QGLFunctions::StencilSeparate; + if (extensions.match("GL_OES_texture_npot")) + features |= QGLFunctions::NPOTTextures; + if (extensions.match("GL_IMG_texture_npot")) + features |= QGLFunctions::NPOTTextures; + return features; #elif defined(QT_OPENGL_ES) int features = QGLFunctions::Multitexture | QGLFunctions::Buffers | @@ -240,6 +244,8 @@ static int qt_gl_resolve_features() features |= QGLFunctions::BlendSubtract; if (extensions.match("GL_OES_texture_npot")) features |= QGLFunctions::NPOTTextures; + if (extensions.match("GL_IMG_texture_npot")) + features |= QGLFunctions::NPOTTextures; return features; #else int features = 0; From 698b3da842cd9df9719354837723b3a3eecff6fe Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Wed, 11 May 2011 19:57:01 +1000 Subject: [PATCH 04/27] tests: fixed or disabled qtbase tests with circular dependencies tst_lancelot did QT+=svg, but didn't actually use QtSvg. qlocalsocket/lackey uses QtScript, which is not available when compiling qtbase. Change-Id: Ic3cc5a6f74a58ee8f2fdc48b9c852d9551b85f68 --- tests/auto/gui.pro | 2 +- tests/auto/lancelot/lancelot.pro | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/gui.pro b/tests/auto/gui.pro index 0d77fff413..67de15c4ce 100644 --- a/tests/auto/gui.pro +++ b/tests/auto/gui.pro @@ -102,7 +102,7 @@ SUBDIRS=\ qlistview \ qlistwidget \ qlocale \ - qlocalsocket \ + #qlocalsocket \ # FIXME: uses qtscript, shouldn't be in qtbase qmacstyle \ qmainwindow \ qmatrixnxn \ diff --git a/tests/auto/lancelot/lancelot.pro b/tests/auto/lancelot/lancelot.pro index 11beb7ef29..c4eaaac6ab 100644 --- a/tests/auto/lancelot/lancelot.pro +++ b/tests/auto/lancelot/lancelot.pro @@ -1,5 +1,5 @@ load(qttest_p4) -QT += xml svg +QT += xml contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles1)|contains(QT_CONFIG, opengles2):QT += opengl SOURCES += tst_lancelot.cpp \ From 587f7f753a97ecf5b9c5b2ee7e562699331010bc Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Wed, 11 May 2011 14:24:45 +0200 Subject: [PATCH 05/27] Fix to commit 7fce0a73cc9b099c4ca67b3bc2e8bbe3060230c6. --- src/opengl/qglfunctions.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/opengl/qglfunctions.cpp b/src/opengl/qglfunctions.cpp index e478fa7a4c..173dd6838e 100644 --- a/src/opengl/qglfunctions.cpp +++ b/src/opengl/qglfunctions.cpp @@ -223,6 +223,7 @@ static int qt_gl_resolve_features() QGLFunctions::CompressedTextures | QGLFunctions::Multisample | QGLFunctions::StencilSeparate; + QGLExtensionMatcher extensions; if (extensions.match("GL_OES_texture_npot")) features |= QGLFunctions::NPOTTextures; if (extensions.match("GL_IMG_texture_npot")) From df4d7f18111420d05276312627c64c82c334e2a6 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Wed, 11 May 2011 12:32:46 +0200 Subject: [PATCH 06/27] Fix GLES2 include path for applications when not using the dash shell MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backslash escapes normally requires "-e" option to echo Reviewed-by: Jørgen (cherry picked from commit 68f37a29f911fce5bcdd285b1fc1bc6d4868d78e) --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index baa94cc1ba..6465146ebd 100755 --- a/configure +++ b/configure @@ -8438,7 +8438,7 @@ if [ -n "$QT_CFLAGS_FPU" ]; then fi if [ -n "$QMAKE_INCDIR_OPENGL_ES2" ]; then - echo "\n#Qt opengl include path" >> "$QTCONFIG.tmp" + echo "#Qt opengl include path" >> "$QTCONFIG.tmp" echo "QMAKE_INCDIR_OPENGL_ES2 = \"$QMAKE_INCDIR_OPENGL_ES2\"" >> "$QTCONFIG.tmp" fi From 3032ba0f8eae871db2f36443f26a7977b5261740 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Tue, 10 May 2011 13:30:33 +0200 Subject: [PATCH 07/27] Add some QRawFont related low level functions to avoid extra copying Added functions: - QRawFont::glyphIndexesForChars(const QChar *chars, int numChars, quint32 *glyphIndexes, int *numGlyphs) const - QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *advances, int numGlyphs) const Reviewed-by: Eskil (cherry picked from commit 965af9eb2932efae5d736df54c3859460017b6a5) --- src/gui/text/qrawfont.cpp | 58 +++++++++++++++++++++++++++++++++++---- src/gui/text/qrawfont.h | 2 ++ 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp index 29394e9b7a..44ddfd2d75 100644 --- a/src/gui/text/qrawfont.cpp +++ b/src/gui/text/qrawfont.cpp @@ -428,7 +428,7 @@ int QRawFont::weight() const of the text. To get the correctly shaped text, you can use QTextLayout to lay out and shape the text, and then call QTextLayout::glyphRuns() to get the set of glyph index list and QRawFont pairs. - \sa advancesForGlyphIndexes(), QGlyphRun, QTextLayout::glyphRuns(), QTextFragment::glyphRuns() + \sa advancesForGlyphIndexes(), glyphIndexesForChars(), QGlyphRun, QTextLayout::glyphRuns(), QTextFragment::glyphRuns() */ QVector QRawFont::glyphIndexesForString(const QString &text) const { @@ -437,11 +437,9 @@ QVector QRawFont::glyphIndexesForString(const QString &text) const int nglyphs = text.size(); QVarLengthGlyphLayoutArray glyphs(nglyphs); - if (!d->fontEngine->stringToCMap(text.data(), text.size(), &glyphs, &nglyphs, - QTextEngine::GlyphIndicesOnly)) { + if (!glyphIndexesForChars(text.data(), text.size(), glyphs.glyphs, &nglyphs)) { glyphs.resize(nglyphs); - if (!d->fontEngine->stringToCMap(text.data(), text.size(), &glyphs, &nglyphs, - QTextEngine::GlyphIndicesOnly)) { + if (!glyphIndexesForChars(text.data(), text.size(), glyphs.glyphs, &nglyphs)) { Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice"); return QVector(); } @@ -454,6 +452,26 @@ QVector QRawFont::glyphIndexesForString(const QString &text) const return glyphIndexes; } +/*! + Converts a string of unicode points to glyph indexes using the CMAP table in the + underlying font. The function works like glyphIndexesForString() except it take + an array (\a chars), the results will be returned though \a glyphIndexes array + and number of glyphs will be set in \a numGlyphs. The size of \a glyphIndexes array + must be at least \a numChars, if that's still not enough, this function will return + false, then you can resize \a glyphIndexes from the size returned in \a numGlyphs. + + \sa glyphIndexesForString(), advancesForGlyphIndexes(), QGlyphs, QTextLayout::glyphs(), QTextFragment::glyphs() +*/ +bool QRawFont::glyphIndexesForChars(const QChar *chars, int numChars, quint32 *glyphIndexes, int *numGlyphs) const +{ + if (!isValid()) + return false; + + QGlyphLayout glyphs; + glyphs.glyphs = glyphIndexes; + return d->fontEngine->stringToCMap(chars, numChars, &glyphs, numGlyphs, QTextEngine::GlyphIndicesOnly); +} + /*! Returns the QRawFont's advances for each of the \a glyphIndexes in pixel units. The advances give the distance from the position of a given glyph to where the next glyph should be drawn @@ -479,6 +497,36 @@ QVector QRawFont::advancesForGlyphIndexes(const QVector &glyph return advances; } +/*! + Returns the QRawFont's advances for each of the \a glyphIndexes in pixel units. The advances + give the distance from the position of a given glyph to where the next glyph should be drawn + to make it appear as if the two glyphs are unspaced. The glyph indexes are given with the + array \a glyphIndexes while the results are returned through \a advances, both of them must + have \a numGlyphs elements. + + \sa QTextLine::horizontalAdvance(), QFontMetricsF::width() +*/ +bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *advances, int numGlyphs) const +{ + if (!isValid()) + return false; + + QGlyphLayout glyphs; + glyphs.glyphs = const_cast(glyphIndexes); + glyphs.numGlyphs = numGlyphs; + QVarLengthArray advances_x(numGlyphs); + QVarLengthArray advances_y(numGlyphs); + glyphs.advances_x = advances_x.data(); + glyphs.advances_y = advances_y.data(); + + d->fontEngine->recalcAdvances(&glyphs, 0); + + for (int i=0; i glyphIndexesForString(const QString &text) const; QVector advancesForGlyphIndexes(const QVector &glyphIndexes) const; + bool glyphIndexesForChars(const QChar *chars, int numChars, quint32 *glyphIndexes, int *numGlyphs) const; + bool advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *advances, int numGlyphs) const; QImage alphaMapForGlyph(quint32 glyphIndex, AntialiasingType antialiasingType = SubPixelAntialiasing, From 16628b76c0d24927cb6160447a1439d40a4f0fea Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Wed, 11 May 2011 12:13:01 +0200 Subject: [PATCH 08/27] Move QTextCursor::MoveStyle to Qt namespace We cannot use QTextCursor::MoveStyle enums in QTextLine because QTextCursor is not a QObject, while referring to that enum in Q_PROPERTY requires it to be. That's why we need to move the enums in Qt namespace. Reviewed-by: David Boddie (cherry picked from commit 5eba82b752e85a5d6cb3a893214ed2646d75f362) --- src/corelib/global/qnamespace.h | 6 ++++++ src/gui/text/qtextcursor.cpp | 18 +++++++++--------- src/gui/text/qtextcursor.h | 4 ---- src/gui/text/qtextdocument.cpp | 6 +++--- src/gui/text/qtextdocument.h | 6 +++--- src/gui/text/qtextdocument_p.cpp | 2 +- src/gui/text/qtextdocument_p.h | 2 +- src/gui/text/qtextengine_p.h | 2 +- src/gui/text/qtextlayout.cpp | 14 +++++++------- src/gui/text/qtextlayout.h | 4 ++-- src/gui/widgets/qlinecontrol.cpp | 2 +- src/gui/widgets/qlinecontrol_p.h | 8 ++++---- src/gui/widgets/qlineedit.cpp | 8 ++++---- src/gui/widgets/qlineedit.h | 5 +++-- tests/auto/qcomplextext/tst_qcomplextext.cpp | 2 +- tests/auto/qlineedit/tst_qlineedit.cpp | 4 ++-- tests/auto/qtextedit/tst_qtextedit.cpp | 4 ++-- 17 files changed, 50 insertions(+), 47 deletions(-) diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 75ce68afbf..f086513e33 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -94,6 +94,7 @@ Qt { Q_ENUMS(GestureState) Q_ENUMS(GestureType) #endif + Q_ENUMS(CursorMoveStyle) #endif // (defined(Q_MOC_RUN) || defined(QT_JAMBI_RUN)) #if defined(Q_MOC_RUN) @@ -1784,6 +1785,11 @@ public: NavigationModeCursorAuto, NavigationModeCursorForceVisible }; + + enum CursorMoveStyle { + LogicalMoveStyle, + VisualMoveStyle + }; } #ifdef Q_MOC_RUN ; diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp index 4f6857a201..17bcc6c7aa 100644 --- a/src/gui/text/qtextcursor.cpp +++ b/src/gui/text/qtextcursor.cpp @@ -362,7 +362,7 @@ bool QTextCursorPrivate::movePosition(QTextCursor::MoveOperation op, QTextCursor currentCharFormat = -1; bool adjustX = true; QTextBlock blockIt = block(); - bool visualMovement = priv->defaultCursorMoveStyle == QTextCursor::Visual; + bool visualMovement = priv->defaultCursorMoveStyle == Qt::VisualMoveStyle; if (!blockIt.isValid()) return false; @@ -2568,18 +2568,18 @@ QTextDocument *QTextCursor::document() const } /*! - \enum QTextCursor::MoveStyle + \enum Qt::CursorMoveStyle - This enum describes the movement style available to QTextCursor. The options + This enum describes the movement style available to text cursors. The options are: - \value Logical Within a left-to-right text block, increase cursor position - when pressing left arrow key, decrease cursor position when pressing the - right arrow key. If the text block is right-to-left, the opposite behavior + \value LogicalMoveStyle Within a left-to-right text block, decrease cursor + position when pressing left arrow key, increase cursor position when pressing + the right arrow key. If the text block is right-to-left, the opposite behavior applies. - \value Visual Pressing the left arrow key will always cause the cursor to move - left, regardless of the text's writing direction. The same behavior applies to - right arrow key. + \value VisualMoveStyle Pressing the left arrow key will always cause the cursor + to move left, regardless of the text's writing direction. Pressing the right + arrow key will always cause the cursor to move right. */ QT_END_NAMESPACE diff --git a/src/gui/text/qtextcursor.h b/src/gui/text/qtextcursor.h index 9e4c0b82df..4eaeb41ee9 100644 --- a/src/gui/text/qtextcursor.h +++ b/src/gui/text/qtextcursor.h @@ -86,10 +86,6 @@ public: MoveAnchor, KeepAnchor }; - enum MoveStyle { - Logical, - Visual - }; void setPosition(int pos, MoveMode mode = MoveAnchor); int position() const; diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 9169955617..0d33912420 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -589,9 +589,9 @@ void QTextDocument::setDefaultTextOption(const QTextOption &option) \since 4.8 The default cursor movement style is used by all QTextCursor objects - created from the document. The default is QTextCursor::Logical. + created from the document. The default is Qt::LogicalMoveStyle. */ -QTextCursor::MoveStyle QTextDocument::defaultCursorMoveStyle() const +Qt::CursorMoveStyle QTextDocument::defaultCursorMoveStyle() const { Q_D(const QTextDocument); return d->defaultCursorMoveStyle; @@ -602,7 +602,7 @@ QTextCursor::MoveStyle QTextDocument::defaultCursorMoveStyle() const Set the default cursor movement style. */ -void QTextDocument::setDefaultCursorMoveStyle(QTextCursor::MoveStyle style) +void QTextDocument::setDefaultCursorMoveStyle(Qt::CursorMoveStyle style) { Q_D(QTextDocument); d->defaultCursorMoveStyle = style; diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h index e515b36cc0..b826dc1777 100644 --- a/src/gui/text/qtextdocument.h +++ b/src/gui/text/qtextdocument.h @@ -46,7 +46,6 @@ #include #include #include -#include QT_BEGIN_HEADER @@ -70,6 +69,7 @@ class QUrl; class QVariant; class QRectF; class QTextOption; +class QTextCursor; template class QVector; @@ -269,8 +269,8 @@ public: QTextOption defaultTextOption() const; void setDefaultTextOption(const QTextOption &option); - QTextCursor::MoveStyle defaultCursorMoveStyle() const; - void setDefaultCursorMoveStyle(QTextCursor::MoveStyle style); + Qt::CursorMoveStyle defaultCursorMoveStyle() const; + void setDefaultCursorMoveStyle(Qt::CursorMoveStyle style); Q_SIGNALS: void contentsChange(int from, int charsRemoves, int charsAdded); diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp index 779b1fff35..640f7aa4a3 100644 --- a/src/gui/text/qtextdocument_p.cpp +++ b/src/gui/text/qtextdocument_p.cpp @@ -209,7 +209,7 @@ QTextDocumentPrivate::QTextDocumentPrivate() defaultTextOption.setTabStop(80); // same as in qtextengine.cpp defaultTextOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); - defaultCursorMoveStyle = QTextCursor::Logical; + defaultCursorMoveStyle = Qt::LogicalMoveStyle; indentWidth = 40; documentMargin = 4; diff --git a/src/gui/text/qtextdocument_p.h b/src/gui/text/qtextdocument_p.h index 6563920c95..e72d676aa5 100644 --- a/src/gui/text/qtextdocument_p.h +++ b/src/gui/text/qtextdocument_p.h @@ -342,7 +342,7 @@ private: public: QTextOption defaultTextOption; - QTextCursor::MoveStyle defaultCursorMoveStyle; + Qt::CursorMoveStyle defaultCursorMoveStyle; #ifndef QT_NO_CSSPARSER QCss::StyleSheet parsedDefaultStyleSheet; #endif diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index c476485c1d..e06ca1cfbb 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -598,7 +598,7 @@ public: inline bool visualCursorMovement() const { return (visualMovement || - (block.docHandle() ? block.docHandle()->defaultCursorMoveStyle == QTextCursor::Visual : false)); + (block.docHandle() ? block.docHandle()->defaultCursorMoveStyle == Qt::VisualMoveStyle : false)); } struct SpecialData { diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 1280b4650b..07aeb72a49 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -579,27 +579,27 @@ bool QTextLayout::cacheEnabled() const } /*! - Set the visual cursor movement style. If the QTextLayout is backed by + Set the cursor movement style. If the QTextLayout is backed by a document, you can ignore this and use the option in QTextDocument, this option is for widgets like QLineEdit or custom widgets without - a QTextDocument. Default value is QTextCursor::Logical. + a QTextDocument. Default value is Qt::LogicalMoveStyle. \sa setCursorMoveStyle() */ -void QTextLayout::setCursorMoveStyle(QTextCursor::MoveStyle style) +void QTextLayout::setCursorMoveStyle(Qt::CursorMoveStyle style) { - d->visualMovement = style == QTextCursor::Visual ? true : false; + d->visualMovement = style == Qt::VisualMoveStyle ? true : false; } /*! The cursor movement style of this QTextLayout. The default is - QTextCursor::Logical. + Qt::LogicalMoveStyle. \sa setCursorMoveStyle() */ -QTextCursor::MoveStyle QTextLayout::cursorMoveStyle() const +Qt::CursorMoveStyle QTextLayout::cursorMoveStyle() const { - return d->visualMovement ? QTextCursor::Visual : QTextCursor::Logical; + return d->visualMovement ? Qt::VisualMoveStyle : Qt::LogicalMoveStyle; } /*! diff --git a/src/gui/text/qtextlayout.h b/src/gui/text/qtextlayout.h index 8fe488a95a..89fbfb2072 100644 --- a/src/gui/text/qtextlayout.h +++ b/src/gui/text/qtextlayout.h @@ -137,8 +137,8 @@ public: void setCacheEnabled(bool enable); bool cacheEnabled() const; - void setCursorMoveStyle(QTextCursor::MoveStyle style); - QTextCursor::MoveStyle cursorMoveStyle() const; + void setCursorMoveStyle(Qt::CursorMoveStyle style); + Qt::CursorMoveStyle cursorMoveStyle() const; void beginLayout(); void endLayout(); diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp index eb4e142328..40ebb65d0a 100644 --- a/src/gui/widgets/qlinecontrol.cpp +++ b/src/gui/widgets/qlinecontrol.cpp @@ -1585,7 +1585,7 @@ void QLineControl::processKeyEvent(QKeyEvent* event) } bool unknown = false; - bool visual = cursorMoveStyle() == QTextCursor::Visual; + bool visual = cursorMoveStyle() == Qt::VisualMoveStyle; if (false) { } diff --git a/src/gui/widgets/qlinecontrol_p.h b/src/gui/widgets/qlinecontrol_p.h index 0042f17261..6918b83b90 100644 --- a/src/gui/widgets/qlinecontrol_p.h +++ b/src/gui/widgets/qlinecontrol_p.h @@ -160,8 +160,8 @@ public: int cursorWidth() const { return m_cursorWidth; } void setCursorWidth(int value) { m_cursorWidth = value; } - QTextCursor::MoveStyle cursorMoveStyle() const { return m_textLayout.cursorMoveStyle(); } - void setCursorMoveStyle(QTextCursor::MoveStyle style) { m_textLayout.setCursorMoveStyle(style); } + Qt::CursorMoveStyle cursorMoveStyle() const { return m_textLayout.cursorMoveStyle(); } + void setCursorMoveStyle(Qt::CursorMoveStyle style) { m_textLayout.setCursorMoveStyle(style); } void moveCursor(int pos, bool mark = false); void cursorForward(bool mark, int steps) @@ -169,11 +169,11 @@ public: int c = m_cursor; if (steps > 0) { while (steps--) - c = cursorMoveStyle() == QTextCursor::Visual ? m_textLayout.rightCursorPosition(c) + c = cursorMoveStyle() == Qt::VisualMoveStyle ? m_textLayout.rightCursorPosition(c) : m_textLayout.nextCursorPosition(c); } else if (steps < 0) { while (steps++) - c = cursorMoveStyle() == QTextCursor::Visual ? m_textLayout.leftCursorPosition(c) + c = cursorMoveStyle() == Qt::VisualMoveStyle ? m_textLayout.leftCursorPosition(c) : m_textLayout.previousCursorPosition(c); } moveCursor(c, mark); diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp index 43c3f52d2b..3c9874ea4e 100644 --- a/src/gui/widgets/qlineedit.cpp +++ b/src/gui/widgets/qlineedit.cpp @@ -1116,24 +1116,24 @@ void QLineEdit::setDragEnabled(bool b) \brief the movement style of cursor in this line edit \since 4.8 - When this property is set to QTextCursor::Visual, the line edit will use visual + When this property is set to Qt::VisualMoveStyle, the line edit will use visual movement style. Pressing the left arrow key will always cause the cursor to move left, regardless of the text's writing direction. The same behavior applies to right arrow key. - When the property is QTextCursor::Logical (the default), within a LTR text block, + When the property is Qt::LogicalMoveStyle (the default), within a LTR text block, increase cursor position when pressing left arrow key, decrease cursor position when pressing the right arrow key. If the text block is right to left, the opposite behavior applies. */ -QTextCursor::MoveStyle QLineEdit::cursorMoveStyle() const +Qt::CursorMoveStyle QLineEdit::cursorMoveStyle() const { Q_D(const QLineEdit); return d->control->cursorMoveStyle(); } -void QLineEdit::setCursorMoveStyle(QTextCursor::MoveStyle style) +void QLineEdit::setCursorMoveStyle(Qt::CursorMoveStyle style) { Q_D(QLineEdit); d->control->setCursorMoveStyle(style); diff --git a/src/gui/widgets/qlineedit.h b/src/gui/widgets/qlineedit.h index 73a736c690..e88273fa7e 100644 --- a/src/gui/widgets/qlineedit.h +++ b/src/gui/widgets/qlineedit.h @@ -85,6 +85,7 @@ class Q_GUI_EXPORT QLineEdit : public QWidget Q_PROPERTY(bool redoAvailable READ isRedoAvailable) Q_PROPERTY(bool acceptableInput READ hasAcceptableInput) Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText) + Q_PROPERTY(Qt::CursorMoveStyle cursorMoveStyle READ cursorMoveStyle WRITE setCursorMoveStyle) public: explicit QLineEdit(QWidget* parent=0); @@ -159,8 +160,8 @@ public: void setDragEnabled(bool b); bool dragEnabled() const; - void setCursorMoveStyle(QTextCursor::MoveStyle style); - QTextCursor::MoveStyle cursorMoveStyle() const; + void setCursorMoveStyle(Qt::CursorMoveStyle style); + Qt::CursorMoveStyle cursorMoveStyle() const; QString inputMask() const; void setInputMask(const QString &inputMask); diff --git a/tests/auto/qcomplextext/tst_qcomplextext.cpp b/tests/auto/qcomplextext/tst_qcomplextext.cpp index 58b31b4aa4..ae63bacc80 100644 --- a/tests/auto/qcomplextext/tst_qcomplextext.cpp +++ b/tests/auto/qcomplextext/tst_qcomplextext.cpp @@ -214,7 +214,7 @@ void tst_QComplexText::bidiCursorMovement() QTextOption option = layout.textOption(); option.setTextDirection(basicDir == QChar::DirL ? Qt::LeftToRight : Qt::RightToLeft); layout.setTextOption(option); - layout.setCursorMoveStyle(QTextCursor::Visual); + layout.setCursorMoveStyle(Qt::VisualMoveStyle); bool moved; int oldPos, newPos = 0; qreal x, newX; diff --git a/tests/auto/qlineedit/tst_qlineedit.cpp b/tests/auto/qlineedit/tst_qlineedit.cpp index f45481ca8a..d5d9029b12 100644 --- a/tests/auto/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/qlineedit/tst_qlineedit.cpp @@ -3815,7 +3815,7 @@ void tst_QLineEdit::bidiVisualMovement() QLineEdit le; le.setText(logical); - le.setCursorMoveStyle(QTextCursor::Visual); + le.setCursorMoveStyle(Qt::VisualMoveStyle); le.setCursorPosition(0); bool moved; @@ -3863,7 +3863,7 @@ void tst_QLineEdit::bidiLogicalMovement() QLineEdit le; le.setText(logical); - le.setCursorMoveStyle(QTextCursor::Logical); + le.setCursorMoveStyle(Qt::LogicalMoveStyle); le.setCursorPosition(0); bool moved; diff --git a/tests/auto/qtextedit/tst_qtextedit.cpp b/tests/auto/qtextedit/tst_qtextedit.cpp index 5a645937d7..992d2f2682 100644 --- a/tests/auto/qtextedit/tst_qtextedit.cpp +++ b/tests/auto/qtextedit/tst_qtextedit.cpp @@ -2292,7 +2292,7 @@ void tst_QTextEdit::bidiVisualMovement() option.setTextDirection(basicDir == QChar::DirL ? Qt::LeftToRight : Qt::RightToLeft); ed->document()->setDefaultTextOption(option); - ed->document()->setDefaultCursorMoveStyle(QTextCursor::Visual); + ed->document()->setDefaultCursorMoveStyle(Qt::VisualMoveStyle); ed->moveCursor(QTextCursor::Start); ed->show(); @@ -2346,7 +2346,7 @@ void tst_QTextEdit::bidiLogicalMovement() option.setTextDirection(basicDir == QChar::DirL ? Qt::LeftToRight : Qt::RightToLeft); ed->document()->setDefaultTextOption(option); - ed->document()->setDefaultCursorMoveStyle(QTextCursor::Logical); + ed->document()->setDefaultCursorMoveStyle(Qt::LogicalMoveStyle); ed->moveCursor(QTextCursor::Start); ed->show(); From a1d91af499ccd4721f792400e96bf0d9c32a0daa Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Wed, 11 May 2011 15:21:14 +0200 Subject: [PATCH 09/27] Fix tst_QVariant::invalidColor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since a423ff5474b89028eeca95b254f5184311c8223b, the warning message is no longer produced. Reviewed-by: Samuel Rødal (cherry picked from commit 8a5e82732be3aac37d14ef85c6974add46c6b65f) --- tests/auto/qvariant/tst_qvariant.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/auto/qvariant/tst_qvariant.cpp b/tests/auto/qvariant/tst_qvariant.cpp index 6ebe84ea4e..3e65d7e728 100644 --- a/tests/auto/qvariant/tst_qvariant.cpp +++ b/tests/auto/qvariant/tst_qvariant.cpp @@ -2650,7 +2650,6 @@ void tst_QVariant::invalidAsByteArray() void tst_QVariant::invalidQColor() const { QVariant va("An invalid QColor::name() value."); - QTest::ignoreMessage(QtWarningMsg, "QColor::setNamedColor: Unknown color name 'An invalid QColor::name() value.'"); QVERIFY(va.canConvert(QVariant::Color)); QVERIFY(!va.convert(QVariant::Color)); From 605102d5c6df00d0d722826308e832c7058863db Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 12 Apr 2011 17:58:12 +0100 Subject: [PATCH 10/27] Fix some warnings in symbian network tests Ignore warning when the test intentionally sets an invalid socket descriptor. Make sure to set content type on all http post tests in tst_qnetworkreply. Run test with enough capabilities to avoid platsec errors when accessing certificate store. Reviewed-By: Markus Goetz (cherry picked from commit 9632fdefa9012ca11cd1345d66bafd6f417de88e) --- tests/auto/qnetworkreply/tst_qnetworkreply.cpp | 2 ++ tests/auto/qtcpserver/tst_qtcpserver.cpp | 3 +++ tests/auto/qtcpsocket/test/test.pro | 2 +- tests/auto/qtcpsocket/tst_qtcpsocket.cpp | 3 +++ 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index 6c77f11d03..d1dc62bbf4 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -4103,6 +4103,7 @@ void tst_QNetworkReply::ioPostToHttpFromMiddleOfQBufferFiveBytes() QUrl url = "http://" + QtNetworkSettings::serverName() + "/qtest/protected/cgi-bin/md5sum.cgi"; QNetworkRequest request(url); + request.setRawHeader("Content-Type", "application/octet-stream"); QNetworkReplyPtr reply = manager.post(request, &uploadBuffer); connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); @@ -4359,6 +4360,7 @@ void tst_QNetworkReply::ioPostToHttpUploadProgress() // create the request QUrl url = QUrl(QString("http://127.0.0.1:%1/").arg(server.serverPort())); QNetworkRequest request(url); + request.setRawHeader("Content-Type", "application/octet-stream"); QNetworkReplyPtr reply = manager.post(request, &sourceFile); QSignalSpy spy(reply, SIGNAL(uploadProgress(qint64,qint64))); connect(&server, SIGNAL(newConnection()), &QTestEventLoop::instance(), SLOT(exitLoop())); diff --git a/tests/auto/qtcpserver/tst_qtcpserver.cpp b/tests/auto/qtcpserver/tst_qtcpserver.cpp index 9cddc00059..2cd870f0fa 100644 --- a/tests/auto/qtcpserver/tst_qtcpserver.cpp +++ b/tests/auto/qtcpserver/tst_qtcpserver.cpp @@ -430,6 +430,9 @@ void tst_QTcpServer::waitForConnectionTest() void tst_QTcpServer::setSocketDescriptor() { QTcpServer server; +#ifdef Q_OS_SYMBIAN + QTest::ignoreMessage(QtWarningMsg, "QSymbianSocketEngine::initialize - socket descriptor not found"); +#endif QVERIFY(!server.setSocketDescriptor(42)); QCOMPARE(server.serverError(), QAbstractSocket::UnsupportedSocketOperationError); #ifndef Q_OS_SYMBIAN diff --git a/tests/auto/qtcpsocket/test/test.pro b/tests/auto/qtcpsocket/test/test.pro index f4207d6de9..7bf5ba0074 100644 --- a/tests/auto/qtcpsocket/test/test.pro +++ b/tests/auto/qtcpsocket/test/test.pro @@ -13,7 +13,7 @@ vxworks:QT -= gui symbian: { TARGET.EPOCHEAPSIZE="0x100 0x3000000" - TARGET.CAPABILITY = NetworkServices + TARGET.CAPABILITY = NetworkServices ReadUserData } TARGET = tst_qtcpsocket diff --git a/tests/auto/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/qtcpsocket/tst_qtcpsocket.cpp index 623e02bd94..f83c4cf99c 100644 --- a/tests/auto/qtcpsocket/tst_qtcpsocket.cpp +++ b/tests/auto/qtcpsocket/tst_qtcpsocket.cpp @@ -476,6 +476,9 @@ void tst_QTcpSocket::setInvalidSocketDescriptor() { QTcpSocket *socket = newSocket(); QCOMPARE(socket->socketDescriptor(), -1); +#ifdef Q_OS_SYMBIAN + QTest::ignoreMessage(QtWarningMsg, "QSymbianSocketEngine::initialize - socket descriptor not found"); +#endif QVERIFY(!socket->setSocketDescriptor(-5, QTcpSocket::UnconnectedState)); QCOMPARE(socket->socketDescriptor(), -1); From 7d505004f50d4dc75f358892069c7d6e7548336e Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 12 Apr 2011 18:01:49 +0100 Subject: [PATCH 11/27] Remove warnings when disabling notifications on a closed socket The generic layer calls setReadNotificationEnabled(false) on sockets after they are closed. This no longer causes a warning from the symbian socket engine. A warning will only be emitted if trying to enable notifications on a closed socket. Task-number: QTBUG-18713 Reviewed-by: Markus Goetz (cherry picked from commit 0aa780235c24ed724fcf6a9095a6467e34b9346e) --- src/network/socket/qsymbiansocketengine.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/network/socket/qsymbiansocketengine.cpp b/src/network/socket/qsymbiansocketengine.cpp index f1b2982626..b2b655e396 100644 --- a/src/network/socket/qsymbiansocketengine.cpp +++ b/src/network/socket/qsymbiansocketengine.cpp @@ -1440,6 +1440,7 @@ void QSymbianSocketEngine::startNotifications() qDebug() << "QSymbianSocketEngine::startNotifications" << d->readNotificationsEnabled << d->writeNotificationsEnabled << d->exceptNotificationsEnabled; #endif if (!d->asyncSelect && (d->readNotificationsEnabled || d->writeNotificationsEnabled || d->exceptNotificationsEnabled)) { + Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::startNotifications(), Q_VOID); if (d->threadData->eventDispatcher) { d->asyncSelect = q_check_ptr(new QAsyncSelect( static_cast (d->threadData->eventDispatcher), d->nativeSocket, @@ -1456,14 +1457,12 @@ void QSymbianSocketEngine::startNotifications() bool QSymbianSocketEngine::isReadNotificationEnabled() const { Q_D(const QSymbianSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::isReadNotificationEnabled(), false); return d->readNotificationsEnabled; } void QSymbianSocketEngine::setReadNotificationEnabled(bool enable) { Q_D(QSymbianSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::setReadNotificationEnabled(), Q_VOID); #ifdef QNATIVESOCKETENGINE_DEBUG qDebug() << "QSymbianSocketEngine::setReadNotificationEnabled" << enable << "socket" << d->socketDescriptor; #endif @@ -1474,14 +1473,12 @@ void QSymbianSocketEngine::setReadNotificationEnabled(bool enable) bool QSymbianSocketEngine::isWriteNotificationEnabled() const { Q_D(const QSymbianSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::isWriteNotificationEnabled(), false); return d->writeNotificationsEnabled; } void QSymbianSocketEngine::setWriteNotificationEnabled(bool enable) { Q_D(QSymbianSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::setWriteNotificationEnabled(), Q_VOID); #ifdef QNATIVESOCKETENGINE_DEBUG qDebug() << "QSymbianSocketEngine::setWriteNotificationEnabled" << enable << "socket" << d->socketDescriptor; #endif @@ -1492,7 +1489,6 @@ void QSymbianSocketEngine::setWriteNotificationEnabled(bool enable) bool QSymbianSocketEngine::isExceptionNotificationEnabled() const { Q_D(const QSymbianSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::isExceptionNotificationEnabled(), false); return d->exceptNotificationsEnabled; return false; } @@ -1500,7 +1496,6 @@ bool QSymbianSocketEngine::isExceptionNotificationEnabled() const void QSymbianSocketEngine::setExceptionNotificationEnabled(bool enable) { Q_D(QSymbianSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::setExceptionNotificationEnabled(), Q_VOID); #ifdef QNATIVESOCKETENGINE_DEBUG qDebug() << "QSymbianSocketEngine::setExceptionNotificationEnabled" << enable << "socket" << d->socketDescriptor; #endif From fe5613123685cf3db61484f5a43cfae3154d5f6f Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 13 Apr 2011 18:04:00 +0100 Subject: [PATCH 12/27] Optimisation - buffer packet read in pendingDatagramSize In Symbian, the OS function to get the size of a pending datagram also includes the size of the packet header (which is different for IPv4 and IPv6). We were reading the datagram with the "peek" flag set to implement pendingDatagramSize, then reading again normally when the client called read/readDatagram. This change removes the "peek" flag, and buffers the datagram in the socket engine, returning it and clearing the buffer when read or readDatagram is called. If there is no buffered data, the existing code path is followed - it isn't mandatory to call pendingDatagramSize before reading from the socket. Reviewed-by: Markus Goetz (cherry picked from commit dd8de4c2437397748daba49569cbc7f89a8bfbee) --- src/network/socket/qsymbiansocketengine.cpp | 63 ++++++++++++++++++--- src/network/socket/qsymbiansocketengine_p.h | 2 + 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/src/network/socket/qsymbiansocketengine.cpp b/src/network/socket/qsymbiansocketengine.cpp index b2b655e396..b6d12fe3cc 100644 --- a/src/network/socket/qsymbiansocketengine.cpp +++ b/src/network/socket/qsymbiansocketengine.cpp @@ -251,7 +251,8 @@ QSymbianSocketEnginePrivate::QSymbianSocketEnginePrivate() : readNotificationsEnabled(false), writeNotificationsEnabled(false), exceptNotificationsEnabled(false), - asyncSelect(0) + asyncSelect(0), + hasReceivedBufferedDatagram(false) { } @@ -781,21 +782,34 @@ qint64 QSymbianSocketEngine::pendingDatagramSize() const Q_D(const QSymbianSocketEngine); Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::pendingDatagramSize(), false); Q_CHECK_TYPE(QSymbianSocketEngine::hasPendingDatagrams(), QAbstractSocket::UdpSocket, false); - int nbytes; + //can only buffer one datagram at a time + if (d->hasReceivedBufferedDatagram) + return d->receivedDataBuffer.size(); + int nbytes = 0; TInt err = d->nativeSocket.GetOpt(KSOReadBytesPending,KSOLSocket, nbytes); if (nbytes > 0) { //nbytes includes IP header, which is of variable length (IPv4 with or without options, IPv6...) - QByteArray next(nbytes,0); - TPtr8 buffer((TUint8*)next.data(), next.size()); + //therefore read the datagram into a buffer to find its true size + d->receivedDataBuffer.resize(nbytes); + TPtr8 buffer((TUint8*)d->receivedDataBuffer.data(), nbytes); + //nbytes = size including IP header, buffer is a pointer descriptor backed by the receivedDataBuffer TInetAddr addr; TRequestStatus status; - //TODO: rather than peek, should we save this for next call to readDatagram? - //what if calls don't match though? - d->nativeSocket.RecvFrom(buffer, addr, KSockReadPeek, status); + //RecvFrom copies only the payload (we don't want the header so don't specify the option to retrieve it) + d->nativeSocket.RecvFrom(buffer, addr, 0, status); User::WaitForRequest(status); - if (status.Int()) + if (status != KErrNone) { + d->receivedDataBuffer.clear(); return 0; - return buffer.Length(); + } + nbytes = buffer.Length(); + //nbytes = size of payload, resize the receivedDataBuffer to the final size + d->receivedDataBuffer.resize(nbytes); + d->hasReceivedBufferedDatagram = true; + //now receivedDataBuffer contains one datagram, which has been removed from the socket's internal buffer +#if defined (QNATIVESOCKETENGINE_DEBUG) + qDebug() << "QSymbianSocketEngine::pendingDatagramSize buffering" << nbytes << "bytes"; +#endif } return qint64(nbytes); } @@ -807,6 +821,19 @@ qint64 QSymbianSocketEngine::readDatagram(char *data, qint64 maxSize, Q_D(QSymbianSocketEngine); Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::readDatagram(), -1); Q_CHECK_TYPE(QSymbianSocketEngine::readDatagram(), QAbstractSocket::UdpSocket, false); + + // if a datagram was buffered in pendingDatagramSize(), return it now + if (d->hasReceivedBufferedDatagram) { + qint64 size = qMin(maxSize, (qint64)d->receivedDataBuffer.size()); + memcpy(data, d->receivedDataBuffer.constData(), size); + d->receivedDataBuffer.clear(); + d->hasReceivedBufferedDatagram = false; +#if defined (QNATIVESOCKETENGINE_DEBUG) + qDebug() << "QSymbianSocketEngine::readDatagram returning" << size << "bytes from buffer"; +#endif + return size; + } + TPtr8 buffer((TUint8*)data, (int)maxSize); TInetAddr addr; TRequestStatus status; @@ -985,6 +1012,9 @@ void QSymbianSocketEngine::close() d->localAddress.clear(); d->peerPort = 0; d->peerAddress.clear(); + + d->hasReceivedBufferedDatagram = false; + d->receivedDataBuffer.clear(); } qint64 QSymbianSocketEngine::write(const char *data, qint64 len) @@ -1036,6 +1066,18 @@ qint64 QSymbianSocketEngine::read(char *data, qint64 maxSize) Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::read(), -1); Q_CHECK_STATES(QSymbianSocketEngine::read(), QAbstractSocket::ConnectedState, QAbstractSocket::BoundState, -1); + // if a datagram was buffered in pendingDatagramSize(), return it now + if (d->hasReceivedBufferedDatagram) { + qint64 size = qMin(maxSize, (qint64)d->receivedDataBuffer.size()); + memcpy(data, d->receivedDataBuffer.constData(), size); + d->receivedDataBuffer.clear(); + d->hasReceivedBufferedDatagram = false; +#if defined (QNATIVESOCKETENGINE_DEBUG) + qDebug() << "QSymbianSocketEngine::read returning" << size << "bytes from buffer"; +#endif + return size; + } + TPtr8 buffer((TUint8*)data, (int)maxSize); TSockXfrLength received = 0; TRequestStatus status; @@ -1655,6 +1697,9 @@ void QAsyncSelect::run() //when event loop disabled socket events, defer until later if (maybeDeferSocketEvent()) return; +#if defined (QNATIVESOCKETENGINE_DEBUG) + qDebug() << "QAsyncSelect::run" << m_selectBuf() << m_selectFlags; +#endif m_inSocketEvent = true; m_selectBuf() &= m_selectFlags; //the select ioctl reports everything, so mask to only what we requested //KSockSelectReadContinuation is for reading datagrams in a mode that doesn't discard when the diff --git a/src/network/socket/qsymbiansocketengine_p.h b/src/network/socket/qsymbiansocketengine_p.h index 85ab54af12..2e7c155f3a 100644 --- a/src/network/socket/qsymbiansocketengine_p.h +++ b/src/network/socket/qsymbiansocketengine_p.h @@ -196,6 +196,8 @@ public: bool exceptNotificationsEnabled; QAsyncSelect* asyncSelect; + mutable QByteArray receivedDataBuffer; + mutable bool hasReceivedBufferedDatagram; // FIXME this is duplicated from qnativesocketengine_p.h enum ErrorString { NonBlockingInitFailedErrorString, From 7ee981a834c8b0b8eddf600965a446c5bb124a91 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 20 Apr 2011 16:21:36 +0100 Subject: [PATCH 13/27] Fix crash when QSocketNotifier used with an invalid descriptor select code for open C file/socket descriptors was crashing in FD_SET if a QSocketNotifier was created with an invalid descriptor. Added two autotests to QSocketNotifier, one to check notifiers with bogus socket descriptors don't crash, the other to check that notifiers with posix socket descriptors do work. (symbian socket engine doesn't use them so they are not implicitly tested) Reviewed-by: mread Task-Number: QTBUG-18138 (cherry picked from commit 8a9a6afcf02f089f932bc81431ab46a60af32134) --- .../kernel/qeventdispatcher_symbian.cpp | 6 + .../auto/qsocketnotifier/qsocketnotifier.pro | 2 +- .../qsocketnotifier/tst_qsocketnotifier.cpp | 109 ++++++++++++++++++ 3 files changed, 116 insertions(+), 1 deletion(-) diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp index e0eeb0819a..bd12726508 100644 --- a/src/corelib/kernel/qeventdispatcher_symbian.cpp +++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp @@ -1111,6 +1111,12 @@ bool QEventDispatcherSymbian::hasPendingEvents() void QEventDispatcherSymbian::registerSocketNotifier ( QSocketNotifier * notifier ) { + //check socket descriptor is usable + if (notifier->socket() >= FD_SETSIZE || notifier->socket() < 0) { + //same warning message as the unix event dispatcher for easy testing + qWarning("QSocketNotifier: Internal error"); + return; + } //note - this is only for "open C" file descriptors //for native sockets, an active object in the symbian socket engine handles this QSocketActiveObject *socketAO = new QSocketActiveObject(this, notifier); diff --git a/tests/auto/qsocketnotifier/qsocketnotifier.pro b/tests/auto/qsocketnotifier/qsocketnotifier.pro index c43c96aa74..27484c89f7 100644 --- a/tests/auto/qsocketnotifier/qsocketnotifier.pro +++ b/tests/auto/qsocketnotifier/qsocketnotifier.pro @@ -4,7 +4,7 @@ QT = core network requires(contains(QT_CONFIG,private_tests)) -include(../qnativesocketengine/qsocketengine.pri) +include(../platformsocketengine/platformsocketengine.pri) symbian: TARGET.CAPABILITY = NetworkServices diff --git a/tests/auto/qsocketnotifier/tst_qsocketnotifier.cpp b/tests/auto/qsocketnotifier/tst_qsocketnotifier.cpp index 5594dc3f90..b31a6e6590 100644 --- a/tests/auto/qsocketnotifier/tst_qsocketnotifier.cpp +++ b/tests/auto/qsocketnotifier/tst_qsocketnotifier.cpp @@ -53,6 +53,11 @@ #include #define NATIVESOCKETENGINE QNativeSocketEngine #endif +#ifdef Q_OS_UNIX +#include +#endif +#include +#include class tst_QSocketNotifier : public QObject { @@ -64,6 +69,8 @@ public: private slots: void unexpectedDisconnection(); void mixingWithTimers(); + void posixSockets(); + void bogusFds(); }; tst_QSocketNotifier::tst_QSocketNotifier() @@ -114,6 +121,9 @@ signals: void tst_QSocketNotifier::unexpectedDisconnection() { +#ifdef Q_OS_SYMBIAN + QSKIP("Symbian socket engine psuedo descriptors can't be used for QSocketNotifier", SkipAll); +#else /* Given two sockets and two QSocketNotifiers registered on each their socket. If both sockets receive data, and the first slot @@ -163,10 +173,14 @@ void tst_QSocketNotifier::unexpectedDisconnection() UnexpectedDisconnectTester tester(&readEnd1, &readEnd2); + QTimer timer; + timer.setSingleShot(true); + timer.start(30000); do { // we have to wait until sequence value changes // as any event can make us jump out processing QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents); + QVERIFY(timer.isActive); //escape if test would hang } while(tester.sequence <= 0); QVERIFY(readEnd1.state() == QAbstractSocket::ConnectedState); @@ -179,6 +193,7 @@ void tst_QSocketNotifier::unexpectedDisconnection() writeEnd1->close(); writeEnd2->close(); server.close(); +#endif } class MixingWithTimersHelper : public QObject @@ -243,5 +258,99 @@ void tst_QSocketNotifier::mixingWithTimers() QCOMPARE(helper.socketActivated, true); } +void tst_QSocketNotifier::posixSockets() +{ +#ifndef Q_OS_UNIX + QSKIP("test only for posix", SkipAll); +#else + + QTcpServer server; + QVERIFY(server.listen(QHostAddress::LocalHost, 0)); + + int posixSocket = qt_safe_socket(AF_INET, SOCK_STREAM, 0); + sockaddr_in addr; + addr.sin_addr.s_addr = htonl(0x7f000001); + addr.sin_family = AF_INET; + addr.sin_port = htons(server.serverPort()); + qt_safe_connect(posixSocket, (const struct sockaddr*)&addr, sizeof(sockaddr_in)); + QVERIFY(server.waitForNewConnection(5000)); + QScopedPointer passive(server.nextPendingConnection()); + + ::fcntl(posixSocket, F_SETFL, ::fcntl(posixSocket, F_GETFL) | O_NONBLOCK); + + { + QSocketNotifier rn(posixSocket, QSocketNotifier::Read); + connect(&rn, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); + QSignalSpy readSpy(&rn, SIGNAL(activated(int))); + QSocketNotifier wn(posixSocket, QSocketNotifier::Write); + connect(&wn, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); + QSignalSpy writeSpy(&wn, SIGNAL(activated(int))); + QSocketNotifier en(posixSocket, QSocketNotifier::Exception); + connect(&en, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); + QSignalSpy errorSpy(&en, SIGNAL(activated(int))); + + passive->write("hello",6); + passive->waitForBytesWritten(5000); + + QTestEventLoop::instance().enterLoop(3); + QCOMPARE(readSpy.count(), 1); + QCOMPARE(writeSpy.count(), 0); + QCOMPARE(errorSpy.count(), 0); + + char buffer[100]; + qt_safe_read(posixSocket, buffer, 100); + QCOMPARE(buffer, "hello"); + + qt_safe_write(posixSocket, "goodbye", 8); + + QTestEventLoop::instance().enterLoop(3); + QCOMPARE(readSpy.count(), 1); + QCOMPARE(writeSpy.count(), 1); + QCOMPARE(errorSpy.count(), 0); + QCOMPARE(passive->readAll(), QByteArray("goodbye",8)); + } + qt_safe_close(posixSocket); +#endif +} + +void tst_QSocketNotifier::bogusFds() +{ +#ifndef Q_OS_WIN + QTest::ignoreMessage(QtWarningMsg, "QSocketNotifier: Internal error"); +#endif + QSocketNotifier max(std::numeric_limits::max(), QSocketNotifier::Read); + QTest::ignoreMessage(QtWarningMsg, "QSocketNotifier: Invalid socket specified"); +#ifndef Q_OS_WIN + QTest::ignoreMessage(QtWarningMsg, "QSocketNotifier: Internal error"); +#endif + QSocketNotifier min(std::numeric_limits::min(), QSocketNotifier::Write); +#ifndef Q_OS_WIN + QTest::ignoreMessage(QtWarningMsg, "QSocketNotifier: Internal error"); +#endif + //bogus magic number is the first pseudo socket descriptor from symbian socket engine. + QSocketNotifier bogus(0x40000000, QSocketNotifier::Exception); + QSocketNotifier largestlegal(FD_SETSIZE - 1, QSocketNotifier::Read); + + QSignalSpy maxspy(&max, SIGNAL(activated(int))); + QSignalSpy minspy(&min, SIGNAL(activated(int))); + QSignalSpy bogspy(&bogus, SIGNAL(activated(int))); + QSignalSpy llspy(&largestlegal, SIGNAL(activated(int))); + + //generate some unrelated socket activity + QTcpServer server; + QVERIFY(server.listen(QHostAddress::LocalHost)); + connect(&server, SIGNAL(newConnection()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTcpSocket client; + client.connectToHost(QHostAddress::LocalHost, server.serverPort()); + QTestEventLoop::instance().enterLoop(5); + QVERIFY(server.hasPendingConnections()); + + //check no activity on bogus notifiers + QCOMPARE(maxspy.count(), 0); + QCOMPARE(minspy.count(), 0); + QCOMPARE(bogspy.count(), 0); + QCOMPARE(llspy.count(), 0); +} + QTEST_MAIN(tst_QSocketNotifier) #include From 1e41e3076aab37f151ffc09e6cd5768289e0d3e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Mon, 2 May 2011 12:39:45 +0200 Subject: [PATCH 14/27] Fixes crash in QWidget::effectiveWinId. Widgets are left in a transitional (and incosistent) state while being re-parented, which caused QWidget::effectiveWinId() to crash in certain circumstances. See patch for more details. Auto test included. Reviewed-by: ogoffart (cherry picked from commit 6db0153cd7e35e4a919a76ae2aadbf2d2510bfb7) --- src/gui/kernel/qwidget.cpp | 20 ++++++++++++++++++++ src/gui/kernel/qwidget_p.h | 1 + tests/auto/qwidget/tst_qwidget.cpp | 25 +++++++++++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 434a788b89..d29a46a14f 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -299,6 +299,7 @@ QWidgetPrivate::QWidgetPrivate(int version) #ifndef QT_NO_IM , inheritsInputMethodHints(0) #endif + , inSetParent(0) #if defined(Q_WS_X11) , picture(0) #elif defined(Q_WS_WIN) @@ -2599,6 +2600,22 @@ WId QWidget::effectiveWinId() const if (id || !testAttribute(Qt::WA_WState_Created)) return id; QWidget *realParent = nativeParentWidget(); + if (!realParent && d_func()->inSetParent) { + // In transitional state. This is really just a workaround. The real problem + // is that QWidgetPrivate::setParent_sys (platform specific code) first sets + // the window id to 0 (setWinId(0)) before it sets the Qt::WA_WState_Created + // attribute to false. The correct way is to do it the other way around, and + // in that case the Qt::WA_WState_Created logic above will kick in and + // return 0 whenever the widget is in a transitional state. However, changing + // the original logic for all platforms is far more intrusive and might + // break existing applications. + // Note: The widget can only be in a transitional state when changing its + // parent -- everything else is an internal error -- hence explicitly checking + // against 'inSetParent' rather than doing an unconditional return whenever + // 'realParent' is 0 (which may cause strange artifacts and headache later). + return 0; + } + // This widget *must* have a native parent widget. Q_ASSERT(realParent); Q_ASSERT(realParent->internalWinId()); return realParent->internalWinId(); @@ -10111,6 +10128,7 @@ void QWidget::setParent(QWidget *parent) void QWidget::setParent(QWidget *parent, Qt::WindowFlags f) { Q_D(QWidget); + d->inSetParent = true; bool resized = testAttribute(Qt::WA_Resized); bool wasCreated = testAttribute(Qt::WA_WState_Created); QWidget *oldtlw = window(); @@ -10271,6 +10289,8 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f) ancestorProxy->d_func()->embedSubWindow(this); } #endif + + d->inSetParent = false; } /*! diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index 919f8bc3da..ca6983dbff 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -770,6 +770,7 @@ public: #ifndef QT_NO_IM uint inheritsInputMethodHints : 1; #endif + uint inSetParent : 1; // *************************** Platform specific ************************************ #if defined(Q_WS_X11) // <----------------------------------------------------------- X11 diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index e266efb794..f282b5d7d3 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -345,6 +345,7 @@ private slots: void immediateRepaintAfterInvalidateBuffer(); #endif void effectiveWinId(); + void effectiveWinId2(); void customDpi(); void customDpiProperty(); @@ -8495,6 +8496,30 @@ void tst_QWidget::effectiveWinId() QVERIFY(child.effectiveWinId()); } +void tst_QWidget::effectiveWinId2() +{ + QWidget parent; + + class MyWidget : public QWidget { + bool event(QEvent *e) + { + if (e->type() == QEvent::WinIdChange) { + // Shouldn't crash. + effectiveWinId(); + } + + return QWidget::event(e); + } + }; + + MyWidget child; + child.setParent(&parent); + parent.show(); + + child.setParent(0); + child.setParent(&parent); +} + class CustomWidget : public QWidget { public: From 4b2d966566a3329e0cb1776582dc508d8ffc0351 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 4 May 2011 17:41:22 +0100 Subject: [PATCH 15/27] Fix spelling mistake Reviewed-by: Trust Me (cherry picked from commit b166c30d8d0834518337ded44d2ebfe097ee312f) --- tests/auto/qsocketnotifier/tst_qsocketnotifier.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qsocketnotifier/tst_qsocketnotifier.cpp b/tests/auto/qsocketnotifier/tst_qsocketnotifier.cpp index b31a6e6590..f966e7fec0 100644 --- a/tests/auto/qsocketnotifier/tst_qsocketnotifier.cpp +++ b/tests/auto/qsocketnotifier/tst_qsocketnotifier.cpp @@ -122,7 +122,7 @@ signals: void tst_QSocketNotifier::unexpectedDisconnection() { #ifdef Q_OS_SYMBIAN - QSKIP("Symbian socket engine psuedo descriptors can't be used for QSocketNotifier", SkipAll); + QSKIP("Symbian socket engine pseudo descriptors can't be used for QSocketNotifier", SkipAll); #else /* Given two sockets and two QSocketNotifiers registered on each From a2e836f3c1acaef5e41893d1c4eb1ef8674b315e Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 5 May 2011 14:10:51 +0300 Subject: [PATCH 16/27] Fix initial main window dimensions for "fullscreen with softkeys" case The application main window defaults to fullscreen size when initially constructed, even if softkeys are specified for it, as the screen furniture is constructed later in show_sys. This resulted in the main window being partially under softkeys. Fixed by invoking handleClientAreaChange() explicitly in show_sys in fullscreen with softkeys case. Task-number: QTBUG-19043 Reviewed-by: Sami Merila (cherry picked from commit e8fc93973a41f193665baa5fdc26cba951bd692f) --- src/gui/kernel/qwidget_s60.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 12bcc4b4cc..24dd00a770 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -576,6 +576,11 @@ void QWidgetPrivate::show_sys() if (isFullscreen) { const bool cbaVisible = S60->buttonGroupContainer() && S60->buttonGroupContainer()->IsVisible(); S60->setStatusPaneAndButtonGroupVisibility(false, cbaVisible); + if (cbaVisible) { + // Fix window dimensions as without screen furniture they will have + // defaulted to full screen dimensions initially. + id->handleClientAreaChange(); + } } } } From 10646142aec3b332507b9e7e0028f001c2757a7d Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Thu, 5 May 2011 15:44:00 +0200 Subject: [PATCH 17/27] QNAM: Re-order checks in migrateBackend() Do the easy checks first, will avoid a crash in the HTTP code if request is serviced from the cache. Task-number: QTBUG-18770 Reviewed-by: Peter Hartmann (cherry picked from commit d03a28a289cf0665290e6ea0375b31cbb2d6649e) --- src/network/access/qnetworkreplyimpl.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index e50f3d627d..ac51119ce7 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -1018,10 +1018,6 @@ bool QNetworkReplyImplPrivate::migrateBackend() if (state == Finished || state == Aborted) return true; - // Backend does not support resuming download. - if (!backend->canResume()) - return false; - // Request has outgoing data, not migrating. if (outgoingData) return false; @@ -1030,6 +1026,10 @@ bool QNetworkReplyImplPrivate::migrateBackend() if (copyDevice) return true; + // Backend does not support resuming download. + if (!backend->canResume()) + return false; + state = QNetworkReplyImplPrivate::Reconnecting; if (backend) { From 119da2c8d49a1eadd8561b5c7fe04b251d34c96d Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Thu, 5 May 2011 16:32:11 +0100 Subject: [PATCH 18/27] Sockets: Fix potential null pointer usages QAbstractSocketEngine::createSocketEngine can return 0 as well as throw. In two cases the pointer was being used before the null check, in a 3rd case the null check was missing. Reviewed-by: Markus Goetz (cherry picked from commit 19edac88af53eea7f733cabbaee77f9b725b7ea9) --- src/network/socket/qabstractsocket.cpp | 16 ++++++++-------- src/network/socket/qtcpserver.cpp | 5 +++++ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index d8d263370d..fc0bb85a45 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -547,15 +547,15 @@ bool QAbstractSocketPrivate::initSocketLayer(QAbstractSocket::NetworkLayerProtoc resetSocketLayer(); socketEngine = QAbstractSocketEngine::createSocketEngine(q->socketType(), proxyInUse, q); -#ifndef QT_NO_BEARERMANAGEMENT - //copy network session down to the socket engine (if it has been set) - socketEngine->setProperty("_q_networksession", q->property("_q_networksession")); -#endif if (!socketEngine) { socketError = QAbstractSocket::UnsupportedSocketOperationError; q->setErrorString(QAbstractSocket::tr("Operation on socket is not supported")); return false; } +#ifndef QT_NO_BEARERMANAGEMENT + //copy network session down to the socket engine (if it has been set) + socketEngine->setProperty("_q_networksession", q->property("_q_networksession")); +#endif #ifndef QT_NO_NETWORKPROXY //copy user agent to socket engine (if it has been set) socketEngine->setProperty("_q_user-agent", q->property("_q_user-agent")); @@ -1609,15 +1609,15 @@ bool QAbstractSocket::setSocketDescriptor(int socketDescriptor, SocketState sock d->resetSocketLayer(); d->socketEngine = QAbstractSocketEngine::createSocketEngine(socketDescriptor, this); -#ifndef QT_NO_BEARERMANAGEMENT - //copy network session down to the socket engine (if it has been set) - d->socketEngine->setProperty("_q_networksession", property("_q_networksession")); -#endif if (!d->socketEngine) { d->socketError = UnsupportedSocketOperationError; setErrorString(tr("Operation on socket is not supported")); return false; } +#ifndef QT_NO_BEARERMANAGEMENT + //copy network session down to the socket engine (if it has been set) + d->socketEngine->setProperty("_q_networksession", property("_q_networksession")); +#endif bool result = d->socketEngine->initialize(socketDescriptor, socketState); if (!result) { d->socketError = d->socketEngine->error(); diff --git a/src/network/socket/qtcpserver.cpp b/src/network/socket/qtcpserver.cpp index 5a60764a3b..026ceb4932 100644 --- a/src/network/socket/qtcpserver.cpp +++ b/src/network/socket/qtcpserver.cpp @@ -416,6 +416,11 @@ bool QTcpServer::setSocketDescriptor(int socketDescriptor) if (d->socketEngine) delete d->socketEngine; d->socketEngine = QAbstractSocketEngine::createSocketEngine(socketDescriptor, this); + if (!d->socketEngine) { + d->serverSocketError = QAbstractSocket::UnsupportedSocketOperationError; + d->serverSocketErrorString = tr("Operation on socket is not supported"); + return false; + } #ifndef QT_NO_BEARERMANAGEMENT //copy network session down to the socket engine (if it has been set) d->socketEngine->setProperty("_q_networksession", property("_q_networksession")); From 86a6ffbc3e991c62ec9306f63a1d1d6721e2977e Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 20 Apr 2011 16:27:55 +0200 Subject: [PATCH 19/27] make relative paths in qt.conf work inside qmake Task-number: QTBUG-11602 Reviewed-by: joerg (cherry picked from commit e6bb6ba76942d98e4b50a7fd32bf44e211f2fa5e) --- src/corelib/global/qlibraryinfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index aca1cb1db6..180eadfdfc 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -453,7 +453,7 @@ QLibraryInfo::location(LibraryLocation loc) if (loc == PrefixPath) { // we make the prefix path absolute to the executable's directory #ifdef BOOTSTRAPPING - return QFileInfo(qmake_libraryInfoFile()).absolutePath(); + return QDir(QFileInfo(qmake_libraryInfoFile()).absolutePath()).absoluteFilePath(ret); #else if (QCoreApplication::instance()) { #ifdef Q_OS_MAC From 23db871a44ee857994cc7f26c9508e91b18f2761 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 20 Apr 2011 16:28:58 +0200 Subject: [PATCH 20/27] make QLibraryInfo return clean paths as a side effect, don't use QDir for path resolution - it doesn't buy us anything. Task-number: QTBUG-1371 Reviewed-by: joerg (cherry picked from commit 9cd62e4f7b23894a672297f6eebda64cdbd53cb0) --- src/corelib/global/qlibraryinfo.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index 180eadfdfc..005e90a823 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -450,10 +450,11 @@ QLibraryInfo::location(LibraryLocation loc) } if (QDir::isRelativePath(ret)) { + QString baseDir; if (loc == PrefixPath) { // we make the prefix path absolute to the executable's directory #ifdef BOOTSTRAPPING - return QDir(QFileInfo(qmake_libraryInfoFile()).absolutePath()).absoluteFilePath(ret); + baseDir = QFileInfo(qmake_libraryInfoFile()).absolutePath(); #else if (QCoreApplication::instance()) { #ifdef Q_OS_MAC @@ -466,15 +467,16 @@ QLibraryInfo::location(LibraryLocation loc) } } #endif - return QDir(QCoreApplication::applicationDirPath()).absoluteFilePath(ret); + baseDir = QCoreApplication::applicationDirPath(); } else { - return QDir::current().absoluteFilePath(ret); + baseDir = QDir::currentPath(); } #endif } else { // we make any other path absolute to the prefix directory - return QDir(location(PrefixPath)).absoluteFilePath(ret); + baseDir = location(PrefixPath); } + ret = QDir::cleanPath(baseDir + QLatin1Char('/') + ret); } return ret; } From c1077e9fb66833894ff1f36b70ca47f299f53da6 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 20 Apr 2011 19:47:49 +0200 Subject: [PATCH 21/27] don't ignore create_prl for static plugins Task-number: QTBUG-18436 Reviewed-by: joerg (cherry picked from commit 2ca4ce848c63c9fa0a48c0f9f4e7fdbc90463bf1) --- qmake/generators/makefile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 69dffba990..ace3531374 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -1109,7 +1109,7 @@ MakefileGenerator::writePrlFile() && project->isActiveConfig("create_prl") && (project->first("TEMPLATE") == "lib" || project->first("TEMPLATE") == "vclib") - && !project->isActiveConfig("plugin")) { //write prl file + && (!project->isActiveConfig("plugin") || project->isActiveConfig("static"))) { //write prl file QString local_prl = prlFileName(); QString prl = fileFixify(local_prl); mkdir(fileInfo(local_prl).path()); From 01cbab598a7c4f199fa5782efdf6dc5666d04ed3 Mon Sep 17 00:00:00 2001 From: Bernhard Rosenkraenzer Date: Mon, 9 May 2011 11:34:17 +0200 Subject: [PATCH 22/27] Don't run XLib check if -no-gui is used Currently, an attempt to compile Qt even with -no-gui on a Linux box that doesn't have libX11 installed fails becaue of the XLib functionality check in configure. This check can be turned off in -no-gui mode, since QtCore, QtXml, QtNetwork and friends don't use libX11. Merge-request: 1214 Reviewed-by: Oswald Buddenhagen (cherry picked from commit 912b6804bcacbf1b4f356d947986df8156a545a4) --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 6465146ebd..fdf46e4117 100755 --- a/configure +++ b/configure @@ -5774,7 +5774,7 @@ if [ "$PLATFORM_X11" = "yes" -o "$PLATFORM_QWS" = "yes" -o "$PLATFORM_QPA" = "ye fi # X11/QWS/Lighthouse # X11 -if [ "$PLATFORM_X11" = "yes" ]; then +if [ "$PLATFORM_X11" = "yes" -a "$CFG_GUI" != "no" ]; then x11tests="$relpath/config.tests/x11" X11TESTS_FLAGS= From 483807d4f24f9fa39727f0a83b31435d2774386a Mon Sep 17 00:00:00 2001 From: Martin Petersson Date: Mon, 9 May 2011 13:56:47 +0200 Subject: [PATCH 23/27] emit QNetWorkAccessManager::finished on QNetworkReply::abort() If we can not get online when the request is made then we are in the WaitingForSession state. This will happen for example if the device is in flight mode. This fix follows the same logic as in _q_networkSessionFailed, but we should look into why we have the WaitingForSession check in finished(). Task-number: QT-4747 Reviewed-by: Markus Goetz (cherry picked from commit 0c9cb9a34d6b472cb53bf1af4616af55b593b616) --- src/network/access/qnetworkreplyimpl.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index ac51119ce7..bf36ae8a4c 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -859,6 +859,8 @@ void QNetworkReplyImpl::abort() if (d->state != QNetworkReplyImplPrivate::Finished) { // call finished which will emit signals d->error(OperationCanceledError, tr("Operation canceled")); + if (d->state == QNetworkReplyImplPrivate::WaitingForSession) + d->state = QNetworkReplyImplPrivate::Working; d->finished(); } d->state = QNetworkReplyImplPrivate::Aborted; From 9d1a7b21c056fa986e5dd03dffa6dec192aae47f Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 10 May 2011 13:11:45 +0100 Subject: [PATCH 24/27] update def files Reviewed-by: Trust Me (cherry picked from commit 84cf56543c3e9add4f06ed65cf419561117ee739) --- src/s60installs/bwins/QtCoreu.def | 168 +++++++++++++++++++++++++++ src/s60installs/bwins/QtGuiu.def | 115 ++++++++++++++---- src/s60installs/bwins/QtNetworku.def | 5 + src/s60installs/eabi/QtCoreu.def | 162 ++++++++++++++++++++++++++ src/s60installs/eabi/QtGuiu.def | 119 ++++++++++++++----- src/s60installs/eabi/QtNetworku.def | 8 ++ 6 files changed, 526 insertions(+), 51 deletions(-) diff --git a/src/s60installs/bwins/QtCoreu.def b/src/s60installs/bwins/QtCoreu.def index 0e6021a022..f26b4d0402 100644 --- a/src/s60installs/bwins/QtCoreu.def +++ b/src/s60installs/bwins/QtCoreu.def @@ -4844,4 +4844,172 @@ EXPORTS ?staticMetaObjectExtraData@QEventTransition@@0UQMetaObjectExtraData@@B @ 4843 NONAME ; struct QMetaObjectExtraData const QEventTransition::staticMetaObjectExtraData ?qt_static_metacall@QEventLoop@@CAXPAVQObject@@W4Call@QMetaObject@@HPAPAX@Z @ 4844 NONAME ; void QEventLoop::qt_static_metacall(class QObject *, enum QMetaObject::Call, int, void * *) ?keys@QProcessEnvironment@@QBE?AVQStringList@@XZ @ 4845 NONAME ; class QStringList QProcessEnvironment::keys(void) const + ?progressTextChanged@QFutureWatcherBase@@IAEXABVQString@@@Z @ 4846 NONAME ; void QFutureWatcherBase::progressTextChanged(class QString const &) + ?timeAfterUser@BlockSizeManager@QtConcurrent@@QAEXXZ @ 4847 NONAME ; void QtConcurrent::BlockSizeManager::timeAfterUser(void) + ?hasThrown@ExceptionStore@internal@QtConcurrent@@QBE_NXZ @ 4848 NONAME ; bool QtConcurrent::internal::ExceptionStore::hasThrown(void) const + ??1ExceptionStore@internal@QtConcurrent@@QAE@XZ @ 4849 NONAME ; QtConcurrent::internal::ExceptionStore::~ExceptionStore(void) + ?isVector@ResultIteratorBase@QtConcurrent@@QBE_NXZ @ 4850 NONAME ; bool QtConcurrent::ResultIteratorBase::isVector(void) const + ?queryState@QFutureInterfaceBase@@QBE_NW4State@1@@Z @ 4851 NONAME ; bool QFutureInterfaceBase::queryState(enum QFutureInterfaceBase::State) const + ?end@ResultStoreBase@QtConcurrent@@QBE?AVResultIteratorBase@2@XZ @ 4852 NONAME ; class QtConcurrent::ResultIteratorBase QtConcurrent::ResultStoreBase::end(void) const + ?run@ThreadEngineBase@QtConcurrent@@EAEXXZ @ 4853 NONAME ; void QtConcurrent::ThreadEngineBase::run(void) + ?exception@ExceptionStore@internal@QtConcurrent@@QAE?AVExceptionHolder@23@XZ @ 4854 NONAME ; class QtConcurrent::internal::ExceptionHolder QtConcurrent::internal::ExceptionStore::exception(void) + ?isStarted@QFutureWatcherBase@@QBE_NXZ @ 4855 NONAME ; bool QFutureWatcherBase::isStarted(void) const + ?resultIndex@ResultIteratorBase@QtConcurrent@@QBEHXZ @ 4856 NONAME ; int QtConcurrent::ResultIteratorBase::resultIndex(void) const + ?qt_metacast@QFutureWatcherBase@@UAEPAXPBD@Z @ 4857 NONAME ; void * QFutureWatcherBase::qt_metacast(char const *) + ??9QFutureInterfaceBase@@QBE_NABV0@@Z @ 4858 NONAME ; bool QFutureInterfaceBase::operator!=(class QFutureInterfaceBase const &) const + ??0QFutureInterfaceBase@@QAE@W4State@0@@Z @ 4859 NONAME ; QFutureInterfaceBase::QFutureInterfaceBase(enum QFutureInterfaceBase::State) + ?staticMetaObjectExtraData@QFutureWatcherBase@@0UQMetaObjectExtraData@@B @ 4860 NONAME ; struct QMetaObjectExtraData const QFutureWatcherBase::staticMetaObjectExtraData + ??0QFutureWatcherBase@@QAE@PAVQObject@@@Z @ 4861 NONAME ; QFutureWatcherBase::QFutureWatcherBase(class QObject *) + ??1QFutureInterfaceBase@@UAE@XZ @ 4862 NONAME ; QFutureInterfaceBase::~QFutureInterfaceBase(void) + ?resume@QFutureWatcherBase@@QAEXXZ @ 4863 NONAME ; void QFutureWatcherBase::resume(void) + ?startSingleThreaded@ThreadEngineBase@QtConcurrent@@QAEXXZ @ 4864 NONAME ; void QtConcurrent::ThreadEngineBase::startSingleThreaded(void) + ?setPaused@QFutureWatcherBase@@QAEX_N@Z @ 4865 NONAME ; void QFutureWatcherBase::setPaused(bool) + ?waitForResume@QFutureInterfaceBase@@QAEXXZ @ 4866 NONAME ; void QFutureInterfaceBase::waitForResume(void) + ?progressMinimum@QFutureInterfaceBase@@QBEHXZ @ 4867 NONAME ; int QFutureInterfaceBase::progressMinimum(void) const + ?hasException@ExceptionStore@internal@QtConcurrent@@QBE_NXZ @ 4868 NONAME ; bool QtConcurrent::internal::ExceptionStore::hasException(void) const + ?tr@QFutureWatcherBase@@SA?AVQString@@PBD0H@Z @ 4869 NONAME ; class QString QFutureWatcherBase::tr(char const *, char const *, int) + ?resultAt@ResultStoreBase@QtConcurrent@@QBE?AVResultIteratorBase@2@H@Z @ 4870 NONAME ; class QtConcurrent::ResultIteratorBase QtConcurrent::ResultStoreBase::resultAt(int) const + ?connectOutputInterface@QFutureWatcherBase@@IAEXXZ @ 4871 NONAME ; void QFutureWatcherBase::connectOutputInterface(void) + ?insertResultItem@ResultStoreBase@QtConcurrent@@IAEHHAAVResultItem@2@@Z @ 4872 NONAME ; int QtConcurrent::ResultStoreBase::insertResultItem(int, class QtConcurrent::ResultItem &) + ?syncResultCount@ResultStoreBase@QtConcurrent@@IAEXXZ @ 4873 NONAME ; void QtConcurrent::ResultStoreBase::syncResultCount(void) + ?setProgressRange@ThreadEngineBase@QtConcurrent@@QAEXHH@Z @ 4874 NONAME ; void QtConcurrent::ThreadEngineBase::setProgressRange(int, int) + ??_EQFutureWatcherBase@@UAE@I@Z @ 4875 NONAME ; QFutureWatcherBase::~QFutureWatcherBase(unsigned int) + ?progressValueChanged@QFutureWatcherBase@@IAEXH@Z @ 4876 NONAME ; void QFutureWatcherBase::progressValueChanged(int) + ?threadExit@ThreadEngineBase@QtConcurrent@@AAEXXZ @ 4877 NONAME ; void QtConcurrent::ThreadEngineBase::threadExit(void) + ?mutex@QFutureInterfaceBase@@QBEPAVQMutex@@XZ @ 4878 NONAME ; class QMutex * QFutureInterfaceBase::mutex(void) const + ?staticMetaObject@QFutureWatcherBase@@2UQMetaObject@@B @ 4879 NONAME ; struct QMetaObject const QFutureWatcherBase::staticMetaObject + ?setException@ExceptionStore@internal@QtConcurrent@@QAEXABVException@3@@Z @ 4880 NONAME ; void QtConcurrent::internal::ExceptionStore::setException(class QtConcurrent::Exception const &) + ??0ResultIteratorBase@QtConcurrent@@QAE@XZ @ 4881 NONAME ; QtConcurrent::ResultIteratorBase::ResultIteratorBase(void) + ?hasNextResult@ResultStoreBase@QtConcurrent@@QBE_NXZ @ 4882 NONAME ; bool QtConcurrent::ResultStoreBase::hasNextResult(void) const + ??_EResultStoreBase@QtConcurrent@@UAE@I@Z @ 4883 NONAME ; QtConcurrent::ResultStoreBase::~ResultStoreBase(unsigned int) + ?contains@ResultStoreBase@QtConcurrent@@QBE_NH@Z @ 4884 NONAME ; bool QtConcurrent::ResultStoreBase::contains(int) const + ?updateInsertIndex@ResultStoreBase@QtConcurrent@@IAEHHH@Z @ 4885 NONAME ; int QtConcurrent::ResultStoreBase::updateInsertIndex(int, int) + ??_EException@QtConcurrent@@UAE@I@Z @ 4886 NONAME ; QtConcurrent::Exception::~Exception(unsigned int) + ?qt_metacall@QFutureWatcherBase@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 4887 NONAME ; int QFutureWatcherBase::qt_metacall(enum QMetaObject::Call, int, void * *) + ?isStarted@QFutureInterfaceBase@@QBE_NXZ @ 4888 NONAME ; bool QFutureInterfaceBase::isStarted(void) const + ??0QFutureInterfaceBase@@QAE@ABV0@@Z @ 4889 NONAME ; QFutureInterfaceBase::QFutureInterfaceBase(class QFutureInterfaceBase const &) + ??_EUnhandledException@QtConcurrent@@UAE@I@Z @ 4890 NONAME ; QtConcurrent::UnhandledException::~UnhandledException(unsigned int) + ?progressValue@QFutureWatcherBase@@QBEHXZ @ 4891 NONAME ; int QFutureWatcherBase::progressValue(void) const + ??8ResultIteratorBase@QtConcurrent@@QBE_NABV01@@Z @ 4892 NONAME ; bool QtConcurrent::ResultIteratorBase::operator==(class QtConcurrent::ResultIteratorBase const &) const + ?tr@QFutureWatcherBase@@SA?AVQString@@PBD0@Z @ 4893 NONAME ; class QString QFutureWatcherBase::tr(char const *, char const *) + ?startBlocking@ThreadEngineBase@QtConcurrent@@QAEXXZ @ 4894 NONAME ; void QtConcurrent::ThreadEngineBase::startBlocking(void) + ?threadThrottleExit@ThreadEngineBase@QtConcurrent@@AAE_NXZ @ 4895 NONAME ; bool QtConcurrent::ThreadEngineBase::threadThrottleExit(void) + ?isFinished@QFutureWatcherBase@@QBE_NXZ @ 4896 NONAME ; bool QFutureWatcherBase::isFinished(void) const + ?resultsReadyAt@QFutureWatcherBase@@IAEXHH@Z @ 4897 NONAME ; void QFutureWatcherBase::resultsReadyAt(int, int) + ?start@ThreadEngineBase@QtConcurrent@@MAEXXZ @ 4898 NONAME ; void QtConcurrent::ThreadEngineBase::start(void) + ?runningAnimationCount@QUnifiedTimer@@QAEHXZ @ 4899 NONAME ; int QUnifiedTimer::runningAnimationCount(void) + ??9ResultIteratorBase@QtConcurrent@@QBE_NABV01@@Z @ 4900 NONAME ; bool QtConcurrent::ResultIteratorBase::operator!=(class QtConcurrent::ResultIteratorBase const &) const + ??1UnhandledException@QtConcurrent@@UAE@XZ @ 4901 NONAME ; QtConcurrent::UnhandledException::~UnhandledException(void) + ?shouldStartThread@ThreadEngineBase@QtConcurrent@@MAE_NXZ @ 4902 NONAME ; bool QtConcurrent::ThreadEngineBase::shouldStartThread(void) + ?d_func@QFutureWatcherBase@@AAEPAVQFutureWatcherBasePrivate@@XZ @ 4903 NONAME ; class QFutureWatcherBasePrivate * QFutureWatcherBase::d_func(void) + ?startThread@ThreadEngineBase@QtConcurrent@@QAEXXZ @ 4904 NONAME ; void QtConcurrent::ThreadEngineBase::startThread(void) + ?threadFunction@ThreadEngineBase@QtConcurrent@@MAE?AW4ThreadFunctionResult@2@XZ @ 4905 NONAME ; enum QtConcurrent::ThreadFunctionResult QtConcurrent::ThreadEngineBase::threadFunction(void) + ?count@ResultStoreBase@QtConcurrent@@QBEHXZ @ 4906 NONAME ; int QtConcurrent::ResultStoreBase::count(void) const + ?isThrottled@QFutureInterfaceBase@@QBE_NXZ @ 4907 NONAME ; bool QFutureInterfaceBase::isThrottled(void) const + ?waitForResume@ThreadEngineBase@QtConcurrent@@QAEXXZ @ 4908 NONAME ; void QtConcurrent::ThreadEngineBase::waitForResume(void) + ?progressMinimum@QFutureWatcherBase@@QBEHXZ @ 4909 NONAME ; int QFutureWatcherBase::progressMinimum(void) const + ??1ThreadEngineBase@QtConcurrent@@UAE@XZ @ 4910 NONAME ; QtConcurrent::ThreadEngineBase::~ThreadEngineBase(void) + ?finished@QFutureWatcherBase@@IAEXXZ @ 4911 NONAME ; void QFutureWatcherBase::finished(void) + ?progressMaximum@QFutureInterfaceBase@@QBEHXZ @ 4912 NONAME ; int QFutureInterfaceBase::progressMaximum(void) const + ?pause@QFutureWatcherBase@@QAEXXZ @ 4913 NONAME ; void QFutureWatcherBase::pause(void) + ?isProgressReportingEnabled@ThreadEngineBase@QtConcurrent@@QAE_NXZ @ 4914 NONAME ; bool QtConcurrent::ThreadEngineBase::isProgressReportingEnabled(void) + ?blockSizeMaxed@BlockSizeManager@QtConcurrent@@AAE_NXZ @ 4915 NONAME ; bool QtConcurrent::BlockSizeManager::blockSizeMaxed(void) + ?isCanceled@QFutureInterfaceBase@@QBE_NXZ @ 4916 NONAME ; bool QFutureInterfaceBase::isCanceled(void) const + ?cancel@QFutureInterfaceBase@@QAEXXZ @ 4917 NONAME ; void QFutureInterfaceBase::cancel(void) + ?setFilterMode@QFutureInterfaceBase@@QAEX_N@Z @ 4918 NONAME ; void QFutureInterfaceBase::setFilterMode(bool) + ?setProgressValueAndText@QFutureInterfaceBase@@QAEXHABVQString@@@Z @ 4919 NONAME ; void QFutureInterfaceBase::setProgressValueAndText(int, class QString const &) + ?setRunnable@QFutureInterfaceBase@@QAEXPAVQRunnable@@@Z @ 4920 NONAME ; void QFutureInterfaceBase::setRunnable(class QRunnable *) + ?trUtf8@QFutureWatcherBase@@SA?AVQString@@PBD0H@Z @ 4921 NONAME ; class QString QFutureWatcherBase::trUtf8(char const *, char const *, int) + ?paused@QFutureWatcherBase@@IAEXXZ @ 4922 NONAME ; void QFutureWatcherBase::paused(void) + ?disconnectOutputInterface@QFutureWatcherBase@@IAEX_N@Z @ 4923 NONAME ; void QFutureWatcherBase::disconnectOutputInterface(bool) + ?isCanceled@QFutureWatcherBase@@QBE_NXZ @ 4924 NONAME ; bool QFutureWatcherBase::isCanceled(void) const + ?expectedResultCount@QFutureInterfaceBase@@QAEHXZ @ 4925 NONAME ; int QFutureInterfaceBase::expectedResultCount(void) + ??_EQFutureInterfaceBase@@UAE@I@Z @ 4926 NONAME ; QFutureInterfaceBase::~QFutureInterfaceBase(unsigned int) + ?waitForResult@QFutureInterfaceBase@@QAEXH@Z @ 4927 NONAME ; void QFutureInterfaceBase::waitForResult(int) + ?d_func@QFutureWatcherBase@@ABEPBVQFutureWatcherBasePrivate@@XZ @ 4928 NONAME ; class QFutureWatcherBasePrivate const * QFutureWatcherBase::d_func(void) const + ?setPaused@QFutureInterfaceBase@@QAEX_N@Z @ 4929 NONAME ; void QFutureInterfaceBase::setPaused(bool) + ??_EThreadEngineBase@QtConcurrent@@UAE@I@Z @ 4930 NONAME ; QtConcurrent::ThreadEngineBase::~ThreadEngineBase(unsigned int) + ??0Exception@QtConcurrent@@QAE@ABV01@@Z @ 4931 NONAME ; QtConcurrent::Exception::Exception(class QtConcurrent::Exception const &) + ?referenceCountIsOne@QFutureInterfaceBase@@IBE_NXZ @ 4932 NONAME ; bool QFutureInterfaceBase::referenceCountIsOne(void) const + ?progressText@QFutureInterfaceBase@@QBE?AVQString@@XZ @ 4933 NONAME ; class QString QFutureInterfaceBase::progressText(void) const + ?startThreadInternal@ThreadEngineBase@QtConcurrent@@AAE_NXZ @ 4934 NONAME ; bool QtConcurrent::ThreadEngineBase::startThreadInternal(void) + ?addResult@ResultStoreBase@QtConcurrent@@QAEHHPBX@Z @ 4935 NONAME ; int QtConcurrent::ResultStoreBase::addResult(int, void const *) + ?waitForFinished@QFutureWatcherBase@@QAEXXZ @ 4936 NONAME ; void QFutureWatcherBase::waitForFinished(void) + ?togglePaused@QFutureInterfaceBase@@QAEXXZ @ 4937 NONAME ; void QFutureInterfaceBase::togglePaused(void) + ?isProgressUpdateNeeded@QFutureInterfaceBase@@QBE_NXZ @ 4938 NONAME ; bool QFutureInterfaceBase::isProgressUpdateNeeded(void) const + ?resultReadyAt@QFutureWatcherBase@@IAEXH@Z @ 4939 NONAME ; void QFutureWatcherBase::resultReadyAt(int) + ?waitForNextResult@QFutureInterfaceBase@@QAE_NXZ @ 4940 NONAME ; bool QFutureInterfaceBase::waitForNextResult(void) + ?raise@UnhandledException@QtConcurrent@@UBEXXZ @ 4941 NONAME ; void QtConcurrent::UnhandledException::raise(void) const + ?setProgressValue@QFutureInterfaceBase@@QAEXH@Z @ 4942 NONAME ; void QFutureInterfaceBase::setProgressValue(int) + ?startThreads@ThreadEngineBase@QtConcurrent@@AAEXXZ @ 4943 NONAME ; void QtConcurrent::ThreadEngineBase::startThreads(void) + ?isPaused@QFutureInterfaceBase@@QBE_NXZ @ 4944 NONAME ; bool QFutureInterfaceBase::isPaused(void) const + ?resultStoreBase@QFutureInterfaceBase@@QAEAAVResultStoreBase@QtConcurrent@@XZ @ 4945 NONAME ; class QtConcurrent::ResultStoreBase & QFutureInterfaceBase::resultStoreBase(void) + ?isRunning@QFutureInterfaceBase@@QBE_NXZ @ 4946 NONAME ; bool QFutureInterfaceBase::isRunning(void) const + ?begin@ResultStoreBase@QtConcurrent@@QBE?AVResultIteratorBase@2@XZ @ 4947 NONAME ; class QtConcurrent::ResultIteratorBase QtConcurrent::ResultStoreBase::begin(void) const + ?resultStoreBase@QFutureInterfaceBase@@QBEABVResultStoreBase@QtConcurrent@@XZ @ 4948 NONAME ; class QtConcurrent::ResultStoreBase const & QFutureInterfaceBase::resultStoreBase(void) const + ?setExpectedResultCount@QFutureInterfaceBase@@QAEXH@Z @ 4949 NONAME ; void QFutureInterfaceBase::setExpectedResultCount(int) + ?progressMaximum@QFutureWatcherBase@@QBEHXZ @ 4950 NONAME ; int QFutureWatcherBase::progressMaximum(void) const + ??0ResultStoreBase@QtConcurrent@@QAE@XZ @ 4951 NONAME ; QtConcurrent::ResultStoreBase::ResultStoreBase(void) + ?setProgressRange@QFutureInterfaceBase@@QAEXHH@Z @ 4952 NONAME ; void QFutureInterfaceBase::setProgressRange(int, int) + ?canIncrementVectorIndex@ResultIteratorBase@QtConcurrent@@QBE_NXZ @ 4953 NONAME ; bool QtConcurrent::ResultIteratorBase::canIncrementVectorIndex(void) const + ?progressValue@QFutureInterfaceBase@@QBEHXZ @ 4954 NONAME ; int QFutureInterfaceBase::progressValue(void) const + ?cancel@QFutureWatcherBase@@QAEXXZ @ 4955 NONAME ; void QFutureWatcherBase::cancel(void) + ?trolltechConf@QCoreApplicationPrivate@@SAPAVQSettings@@XZ @ 4956 NONAME ; class QSettings * QCoreApplicationPrivate::trolltechConf(void) + ?trUtf8@QFutureWatcherBase@@SA?AVQString@@PBD0@Z @ 4957 NONAME ; class QString QFutureWatcherBase::trUtf8(char const *, char const *) + ?getStaticMetaObject@QFutureWatcherBase@@SAABUQMetaObject@@XZ @ 4958 NONAME ; struct QMetaObject const & QFutureWatcherBase::getStaticMetaObject(void) + ?vectorIndex@ResultIteratorBase@QtConcurrent@@QBEHXZ @ 4959 NONAME ; int QtConcurrent::ResultIteratorBase::vectorIndex(void) const + ?syncPendingResults@ResultStoreBase@QtConcurrent@@IAEXXZ @ 4960 NONAME ; void QtConcurrent::ResultStoreBase::syncPendingResults(void) + ?progressText@QFutureWatcherBase@@QBE?AVQString@@XZ @ 4961 NONAME ; class QString QFutureWatcherBase::progressText(void) const + ??1QFutureWatcherBase@@UAE@XZ @ 4962 NONAME ; QFutureWatcherBase::~QFutureWatcherBase(void) + ?togglePaused@QFutureWatcherBase@@QAEXXZ @ 4963 NONAME ; void QFutureWatcherBase::togglePaused(void) + ?acquireBarrierSemaphore@ThreadEngineBase@QtConcurrent@@QAEXXZ @ 4964 NONAME ; void QtConcurrent::ThreadEngineBase::acquireBarrierSemaphore(void) + ?setFilterMode@ResultStoreBase@QtConcurrent@@QAEX_N@Z @ 4965 NONAME ; void QtConcurrent::ResultStoreBase::setFilterMode(bool) + ?disconnectNotify@QFutureWatcherBase@@MAEXPBD@Z @ 4966 NONAME ; void QFutureWatcherBase::disconnectNotify(char const *) + ?handleException@ThreadEngineBase@QtConcurrent@@AAEXABVException@2@@Z @ 4967 NONAME ; void QtConcurrent::ThreadEngineBase::handleException(class QtConcurrent::Exception const &) + ?setThrottled@QFutureInterfaceBase@@QAEX_N@Z @ 4968 NONAME ; void QFutureInterfaceBase::setThrottled(bool) + ?setProgressValue@ThreadEngineBase@QtConcurrent@@QAEXH@Z @ 4969 NONAME ; void QtConcurrent::ThreadEngineBase::setProgressValue(int) + ??4QFutureInterfaceBase@@QAEAAV0@ABV0@@Z @ 4970 NONAME ; class QFutureInterfaceBase & QFutureInterfaceBase::operator=(class QFutureInterfaceBase const &) + ?isFinished@QFutureInterfaceBase@@QBE_NXZ @ 4971 NONAME ; bool QFutureInterfaceBase::isFinished(void) const + ?progressRangeChanged@QFutureWatcherBase@@IAEXHH@Z @ 4972 NONAME ; void QFutureWatcherBase::progressRangeChanged(int, int) + ?finish@ThreadEngineBase@QtConcurrent@@MAEXXZ @ 4973 NONAME ; void QtConcurrent::ThreadEngineBase::finish(void) + ?isRunning@QFutureWatcherBase@@QBE_NXZ @ 4974 NONAME ; bool QFutureWatcherBase::isRunning(void) const + ?reportResultsReady@QFutureInterfaceBase@@QAEXHH@Z @ 4975 NONAME ; void QFutureInterfaceBase::reportResultsReady(int, int) + ?qt_static_metacall@QFutureWatcherBase@@CAXPAVQObject@@W4Call@QMetaObject@@HPAPAX@Z @ 4976 NONAME ; void QFutureWatcherBase::qt_static_metacall(class QObject *, enum QMetaObject::Call, int, void * *) + ?blockSize@BlockSizeManager@QtConcurrent@@QAEHXZ @ 4977 NONAME ; int QtConcurrent::BlockSizeManager::blockSize(void) + ??0BlockSizeManager@QtConcurrent@@QAE@H@Z @ 4978 NONAME ; QtConcurrent::BlockSizeManager::BlockSizeManager(int) + ?batchSize@ResultIteratorBase@QtConcurrent@@QBEHXZ @ 4979 NONAME ; int QtConcurrent::ResultIteratorBase::batchSize(void) const + ?started@QFutureWatcherBase@@IAEXXZ @ 4980 NONAME ; void QFutureWatcherBase::started(void) + ?metaObject@QFutureWatcherBase@@UBEPBUQMetaObject@@XZ @ 4981 NONAME ; struct QMetaObject const * QFutureWatcherBase::metaObject(void) const + ?resumed@QFutureWatcherBase@@IAEXXZ @ 4982 NONAME ; void QFutureWatcherBase::resumed(void) + ??0UnhandledException@QtConcurrent@@QAE@ABV01@@Z @ 4983 NONAME ; QtConcurrent::UnhandledException::UnhandledException(class QtConcurrent::UnhandledException const &) + ?timeBeforeUser@BlockSizeManager@QtConcurrent@@QAEXXZ @ 4984 NONAME ; void QtConcurrent::BlockSizeManager::timeBeforeUser(void) + ??EResultIteratorBase@QtConcurrent@@QAE?AV01@XZ @ 4985 NONAME ; class QtConcurrent::ResultIteratorBase QtConcurrent::ResultIteratorBase::operator++(void) + ?isResultReadyAt@QFutureInterfaceBase@@QBE_NH@Z @ 4986 NONAME ; bool QFutureInterfaceBase::isResultReadyAt(int) const + ?throwPossibleException@ExceptionStore@internal@QtConcurrent@@QAEXXZ @ 4987 NONAME ; void QtConcurrent::internal::ExceptionStore::throwPossibleException(void) + ?setPendingResultsLimit@QFutureWatcherBase@@QAEXH@Z @ 4988 NONAME ; void QFutureWatcherBase::setPendingResultsLimit(int) + ?resultCount@QFutureInterfaceBase@@QBEHXZ @ 4989 NONAME ; int QFutureInterfaceBase::resultCount(void) const + ?event@QFutureWatcherBase@@UAE_NPAVQEvent@@@Z @ 4990 NONAME ; bool QFutureWatcherBase::event(class QEvent *) + ?isPaused@QFutureWatcherBase@@QBE_NXZ @ 4991 NONAME ; bool QFutureWatcherBase::isPaused(void) const + ?clone@Exception@QtConcurrent@@UBEPAV12@XZ @ 4992 NONAME ; class QtConcurrent::Exception * QtConcurrent::Exception::clone(void) const + ?insertResultItemIfValid@ResultStoreBase@QtConcurrent@@IAEXHAAVResultItem@2@@Z @ 4993 NONAME ; void QtConcurrent::ResultStoreBase::insertResultItemIfValid(int, class QtConcurrent::ResultItem &) + ?reportException@QFutureInterfaceBase@@QAEXABVException@QtConcurrent@@@Z @ 4994 NONAME ; void QFutureInterfaceBase::reportException(class QtConcurrent::Exception const &) + ?waitForFinished@QFutureInterfaceBase@@QAEXXZ @ 4995 NONAME ; void QFutureInterfaceBase::waitForFinished(void) + ??0ResultIteratorBase@QtConcurrent@@QAE@Vconst_iterator@?$QMap@HVResultItem@QtConcurrent@@@@H@Z @ 4996 NONAME ; QtConcurrent::ResultIteratorBase::ResultIteratorBase(class QMap::const_iterator, int) + ?reportStarted@QFutureInterfaceBase@@QAEXXZ @ 4997 NONAME ; void QFutureInterfaceBase::reportStarted(void) + ??8QFutureInterfaceBase@@QBE_NABV0@@Z @ 4998 NONAME ; bool QFutureInterfaceBase::operator==(class QFutureInterfaceBase const &) const + ?addResults@ResultStoreBase@QtConcurrent@@QAEHHPBXHH@Z @ 4999 NONAME ; int QtConcurrent::ResultStoreBase::addResults(int, void const *, int, int) + ?shouldThrottleThread@ThreadEngineBase@QtConcurrent@@MAE_NXZ @ 5000 NONAME ; bool QtConcurrent::ThreadEngineBase::shouldThrottleThread(void) + ?reportFinished@QFutureInterfaceBase@@QAEXXZ @ 5001 NONAME ; void QFutureInterfaceBase::reportFinished(void) + ??0ThreadEngineBase@QtConcurrent@@QAE@XZ @ 5002 NONAME ; QtConcurrent::ThreadEngineBase::ThreadEngineBase(void) + ??1Exception@QtConcurrent@@UAE@XZ @ 5003 NONAME ; QtConcurrent::Exception::~Exception(void) + ?filterMode@ResultStoreBase@QtConcurrent@@QBE_NXZ @ 5004 NONAME ; bool QtConcurrent::ResultStoreBase::filterMode(void) const + ?raise@Exception@QtConcurrent@@UBEXXZ @ 5005 NONAME ; void QtConcurrent::Exception::raise(void) const + ?batchedAdvance@ResultIteratorBase@QtConcurrent@@QAEXXZ @ 5006 NONAME ; void QtConcurrent::ResultIteratorBase::batchedAdvance(void) + ?exceptionStore@QFutureInterfaceBase@@QAEAAVExceptionStore@internal@QtConcurrent@@XZ @ 5007 NONAME ; class QtConcurrent::internal::ExceptionStore & QFutureInterfaceBase::exceptionStore(void) + ?reportCanceled@QFutureInterfaceBase@@QAEXXZ @ 5008 NONAME ; void QFutureInterfaceBase::reportCanceled(void) + ?connectNotify@QFutureWatcherBase@@MAEXPBD@Z @ 5009 NONAME ; void QFutureWatcherBase::connectNotify(char const *) + ??1ResultStoreBase@QtConcurrent@@UAE@XZ @ 5010 NONAME ; QtConcurrent::ResultStoreBase::~ResultStoreBase(void) + ?isCanceled@ThreadEngineBase@QtConcurrent@@QAE_NXZ @ 5011 NONAME ; bool QtConcurrent::ThreadEngineBase::isCanceled(void) + ?canceled@QFutureWatcherBase@@IAEXXZ @ 5012 NONAME ; void QFutureWatcherBase::canceled(void) + ?clone@UnhandledException@QtConcurrent@@UBEPAVException@2@XZ @ 5013 NONAME ; class QtConcurrent::Exception * QtConcurrent::UnhandledException::clone(void) const diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def index 813bbf868a..d37006556e 100644 --- a/src/s60installs/bwins/QtGuiu.def +++ b/src/s60installs/bwins/QtGuiu.def @@ -12855,7 +12855,7 @@ EXPORTS ?populate@QTextureGlyphCache@@QAEXPAVQFontEngine@@HPBIPBUQFixedPoint@@@Z @ 12854 NONAME ABSENT ; void QTextureGlyphCache::populate(class QFontEngine *, int, unsigned int const *, struct QFixedPoint const *) ?hasPartialUpdateSupport@QWindowSurface@@UBE_NXZ @ 12855 NONAME ABSENT ; bool QWindowSurface::hasPartialUpdateSupport(void) const ?scroll@QRuntimePixmapData@@UAE_NHHABVQRect@@@Z @ 12856 NONAME ; bool QRuntimePixmapData::scroll(int, int, class QRect const &) - ?qt_draw_glyphs@@YAXPAVQPainter@@PBIPBVQPointF@@H@Z @ 12857 NONAME ; void qt_draw_glyphs(class QPainter *, unsigned int const *, class QPointF const *, int) + ?qt_draw_glyphs@@YAXPAVQPainter@@PBIPBVQPointF@@H@Z @ 12857 NONAME ABSENT ; void qt_draw_glyphs(class QPainter *, unsigned int const *, class QPointF const *, int) ?nativeDisplay@QEgl@@YAHXZ @ 12858 NONAME ; int QEgl::nativeDisplay(void) ?PreDocConstructL@QS60MainApplication@@UAEXXZ @ 12859 NONAME ; void QS60MainApplication::PreDocConstructL(void) ?detach@QStaticText@@AAEXXZ @ 12860 NONAME ; void QStaticText::detach(void) @@ -13213,7 +13213,7 @@ EXPORTS ??0QRasterWindowSurface@@QAE@PAVQWidget@@_N@Z @ 13212 NONAME ; QRasterWindowSurface::QRasterWindowSurface(class QWidget *, bool) ?brushChanged@QBlitterPaintEngine@@UAEXXZ @ 13213 NONAME ; void QBlitterPaintEngine::brushChanged(void) ?clip@QBlitterPaintEngine@@UAEXABVQRect@@W4ClipOperation@Qt@@@Z @ 13214 NONAME ; void QBlitterPaintEngine::clip(class QRect const &, enum Qt::ClipOperation) - ?detach@QGlyphs@@AAEXXZ @ 13215 NONAME ; void QGlyphs::detach(void) + ?detach@QGlyphs@@AAEXXZ @ 13215 NONAME ABSENT ; void QGlyphs::detach(void) ?trUtf8@QInternalMimeData@@SA?AVQString@@PBD0@Z @ 13216 NONAME ; class QString QInternalMimeData::trUtf8(char const *, char const *) ??0QShowEvent@@QAE@ABV0@@Z @ 13217 NONAME ABSENT ; QShowEvent::QShowEvent(class QShowEvent const &) ??0QMouseEvent@@QAE@ABV0@@Z @ 13218 NONAME ABSENT ; QMouseEvent::QMouseEvent(class QMouseEvent const &) @@ -13260,7 +13260,7 @@ EXPORTS ?trUtf8@QFlickGesture@@SA?AVQString@@PBD0@Z @ 13259 NONAME ; class QString QFlickGesture::trUtf8(char const *, char const *) ?stop@QScroller@@QAEXXZ @ 13260 NONAME ; void QScroller::stop(void) ?retrieveData@QInternalMimeData@@MBE?AVQVariant@@ABVQString@@W4Type@2@@Z @ 13261 NONAME ; class QVariant QInternalMimeData::retrieveData(class QString const &, enum QVariant::Type) const - ??8QGlyphs@@QBE_NABV0@@Z @ 13262 NONAME ; bool QGlyphs::operator==(class QGlyphs const &) const + ??8QGlyphs@@QBE_NABV0@@Z @ 13262 NONAME ABSENT ; bool QGlyphs::operator==(class QGlyphs const &) const ?drawImage@QBlitterPaintEngine@@UAEXABVQRectF@@ABVQImage@@0V?$QFlags@W4ImageConversionFlag@Qt@@@@@Z @ 13263 NONAME ; void QBlitterPaintEngine::drawImage(class QRectF const &, class QImage const &, class QRectF const &, class QFlags) ?contentPos@QScrollEvent@@QBE?AVQPointF@@XZ @ 13264 NONAME ; class QPointF QScrollEvent::contentPos(void) const ?mimeTypes@QAbstractProxyModel@@UBE?AVQStringList@@XZ @ 13265 NONAME ; class QStringList QAbstractProxyModel::mimeTypes(void) const @@ -13286,7 +13286,7 @@ EXPORTS ?canFetchMore@QAbstractProxyModel@@UBE_NABVQModelIndex@@@Z @ 13285 NONAME ; bool QAbstractProxyModel::canFetchMore(class QModelIndex const &) const ??4QStyleOptionProgressBarV2@@QAEAAV0@ABV0@@Z @ 13286 NONAME ABSENT ; class QStyleOptionProgressBarV2 & QStyleOptionProgressBarV2::operator=(class QStyleOptionProgressBarV2 const &) ??1QScroller@@EAE@XZ @ 13287 NONAME ; QScroller::~QScroller(void) - ?setFont@QGlyphs@@QAEXABVQFont@@@Z @ 13288 NONAME ; void QGlyphs::setFont(class QFont const &) + ?setFont@QGlyphs@@QAEXABVQFont@@@Z @ 13288 NONAME ABSENT ; void QGlyphs::setFont(class QFont const &) ?startPos@QScrollPrepareEvent@@QBE?AVQPointF@@XZ @ 13289 NONAME ; class QPointF QScrollPrepareEvent::startPos(void) const ?resize@QBlittablePixmapData@@UAEXHH@Z @ 13290 NONAME ; void QBlittablePixmapData::resize(int, int) ?setTabsClosable@QMdiArea@@QAEX_N@Z @ 13291 NONAME ; void QMdiArea::setTabsClosable(bool) @@ -13304,14 +13304,14 @@ EXPORTS ?opacityChanged@QBlitterPaintEngine@@UAEXXZ @ 13303 NONAME ; void QBlitterPaintEngine::opacityChanged(void) ?tr@QFlickGesture@@SA?AVQString@@PBD0H@Z @ 13304 NONAME ; class QString QFlickGesture::tr(char const *, char const *, int) ??_EQTextCursor@@QAE@I@Z @ 13305 NONAME ABSENT ; QTextCursor::~QTextCursor(unsigned int) - ?createExplicitFontWithName@QFontEngine@@IBE?AVQFont@@ABVQString@@@Z @ 13306 NONAME ; class QFont QFontEngine::createExplicitFontWithName(class QString const &) const + ?createExplicitFontWithName@QFontEngine@@IBE?AVQFont@@ABVQString@@@Z @ 13306 NONAME ABSENT ; class QFont QFontEngine::createExplicitFontWithName(class QString const &) const ?setState@QBlitterPaintEngine@@UAEXPAVQPainterState@@@Z @ 13307 NONAME ; void QBlitterPaintEngine::setState(class QPainterState *) ?clip@QBlitterPaintEngine@@UAEXABVQRegion@@W4ClipOperation@Qt@@@Z @ 13308 NONAME ; void QBlitterPaintEngine::clip(class QRegion const &, enum Qt::ClipOperation) ?subPixelPositionForX@QTextureGlyphCache@@QBE?AUQFixed@@U2@@Z @ 13309 NONAME ; struct QFixed QTextureGlyphCache::subPixelPositionForX(struct QFixed) const ?hasAlphaChannel@QBlittablePixmapData@@UBE_NXZ @ 13310 NONAME ; bool QBlittablePixmapData::hasAlphaChannel(void) const ?setSnapPositionsX@QScroller@@QAEXABV?$QList@M@@@Z @ 13311 NONAME ; void QScroller::setSnapPositionsX(class QList const &) ?numberSuffix@QTextListFormat@@QBE?AVQString@@XZ @ 13312 NONAME ; class QString QTextListFormat::numberSuffix(void) const - ??HQGlyphs@@ABE?AV0@ABV0@@Z @ 13313 NONAME ; class QGlyphs QGlyphs::operator+(class QGlyphs const &) const + ??HQGlyphs@@ABE?AV0@ABV0@@Z @ 13313 NONAME ABSENT ; class QGlyphs QGlyphs::operator+(class QGlyphs const &) const ??0QGradient@@QAE@ABV0@@Z @ 13314 NONAME ABSENT ; QGradient::QGradient(class QGradient const &) ?tabsMovable@QMdiArea@@QBE_NXZ @ 13315 NONAME ; bool QMdiArea::tabsMovable(void) const ??4QInputMethodEvent@@QAEAAV0@ABV0@@Z @ 13316 NONAME ABSENT ; class QInputMethodEvent & QInputMethodEvent::operator=(class QInputMethodEvent const &) @@ -13329,7 +13329,7 @@ EXPORTS ??_EQKeySequence@@QAE@I@Z @ 13328 NONAME ABSENT ; QKeySequence::~QKeySequence(unsigned int) ?tr@QInternalMimeData@@SA?AVQString@@PBD0H@Z @ 13329 NONAME ; class QString QInternalMimeData::tr(char const *, char const *, int) ?velocity@QScroller@@QBE?AVQPointF@@XZ @ 13330 NONAME ; class QPointF QScroller::velocity(void) const - ?glyphIndexes@QGlyphs@@QBE?AV?$QVector@I@@XZ @ 13331 NONAME ; class QVector QGlyphs::glyphIndexes(void) const + ?glyphIndexes@QGlyphs@@QBE?AV?$QVector@I@@XZ @ 13331 NONAME ABSENT ; class QVector QGlyphs::glyphIndexes(void) const ?get@QFontPrivate@@SAPAV1@ABVQFont@@@Z @ 13332 NONAME ; class QFontPrivate * QFontPrivate::get(class QFont const &) ?setScrollMetric@QScrollerProperties@@QAEXW4ScrollMetric@1@ABVQVariant@@@Z @ 13333 NONAME ; void QScrollerProperties::setScrollMetric(enum QScrollerProperties::ScrollMetric, class QVariant const &) ??4QGradient@@QAEAAV0@ABV0@@Z @ 13334 NONAME ABSENT ; class QGradient & QGradient::operator=(class QGradient const &) @@ -13339,7 +13339,7 @@ EXPORTS ??0QTextTableFormat@@QAE@ABV0@@Z @ 13338 NONAME ABSENT ; QTextTableFormat::QTextTableFormat(class QTextTableFormat const &) ??_EQImagePixmapCleanupHooks@@QAE@I@Z @ 13339 NONAME ABSENT ; QImagePixmapCleanupHooks::~QImagePixmapCleanupHooks(unsigned int) ?fetchMore@QAbstractProxyModel@@UAEXABVQModelIndex@@@Z @ 13340 NONAME ; void QAbstractProxyModel::fetchMore(class QModelIndex const &) - ?glyphs@QTextLine@@ABE?AV?$QList@VQGlyphs@@@@HH@Z @ 13341 NONAME ; class QList QTextLine::glyphs(int, int) const + ?glyphs@QTextLine@@ABE?AV?$QList@VQGlyphs@@@@HH@Z @ 13341 NONAME ABSENT ; class QList QTextLine::glyphs(int, int) const ?getStaticMetaObject@QFlickGesture@@SAABUQMetaObject@@XZ @ 13342 NONAME ; struct QMetaObject const & QFlickGesture::getStaticMetaObject(void) ?setViewportSize@QScrollPrepareEvent@@QAEXABVQSizeF@@@Z @ 13343 NONAME ; void QScrollPrepareEvent::setViewportSize(class QSizeF const &) ??0QStatusTipEvent@@QAE@ABV0@@Z @ 13344 NONAME ABSENT ; QStatusTipEvent::QStatusTipEvent(class QStatusTipEvent const &) @@ -13374,7 +13374,7 @@ EXPORTS ??4QStyleOptionQ3DockWindow@@QAEAAV0@ABV0@@Z @ 13373 NONAME ABSENT ; class QStyleOptionQ3DockWindow & QStyleOptionQ3DockWindow::operator=(class QStyleOptionQ3DockWindow const &) ?qt_metacast@QFlickGesture@@UAEPAXPBD@Z @ 13374 NONAME ; void * QFlickGesture::qt_metacast(char const *) ??_EQFont@@QAE@I@Z @ 13375 NONAME ABSENT ; QFont::~QFont(unsigned int) - ?setPositions@QGlyphs@@QAEXABV?$QVector@VQPointF@@@@@Z @ 13376 NONAME ; void QGlyphs::setPositions(class QVector const &) + ?setPositions@QGlyphs@@QAEXABV?$QVector@VQPointF@@@@@Z @ 13376 NONAME ABSENT ; void QGlyphs::setPositions(class QVector const &) ??4QStyleOptionDockWidget@@QAEAAV0@ABV0@@Z @ 13377 NONAME ABSENT ; class QStyleOptionDockWidget & QStyleOptionDockWidget::operator=(class QStyleOptionDockWidget const &) ??0QPainterState@@QAE@ABV0@@Z @ 13378 NONAME ABSENT ; QPainterState::QPainterState(class QPainterState const &) ??4QStyleOptionFrame@@QAEAAV0@ABV0@@Z @ 13379 NONAME ABSENT ; class QStyleOptionFrame & QStyleOptionFrame::operator=(class QStyleOptionFrame const &) @@ -13384,7 +13384,7 @@ EXPORTS ?renderHintsChanged@QBlitterPaintEngine@@UAEXXZ @ 13383 NONAME ; void QBlitterPaintEngine::renderHintsChanged(void) ?supportedDropActions@QAbstractProxyModel@@UBE?AV?$QFlags@W4DropAction@Qt@@@@XZ @ 13384 NONAME ; class QFlags QAbstractProxyModel::supportedDropActions(void) const ?fillRect@QBlitterPaintEngine@@UAEXABVQRectF@@ABVQBrush@@@Z @ 13385 NONAME ; void QBlitterPaintEngine::fillRect(class QRectF const &, class QBrush const &) - ?setGlyphIndexes@QGlyphs@@QAEXABV?$QVector@I@@@Z @ 13386 NONAME ; void QGlyphs::setGlyphIndexes(class QVector const &) + ?setGlyphIndexes@QGlyphs@@QAEXABV?$QVector@I@@@Z @ 13386 NONAME ABSENT ; void QGlyphs::setGlyphIndexes(class QVector const &) ?alphaMapBoundingBox@QFontEngine@@UAE?AUglyph_metrics_t@@IABVQTransform@@W4GlyphFormat@1@@Z @ 13387 NONAME ABSENT ; struct glyph_metrics_t QFontEngine::alphaMapBoundingBox(unsigned int, class QTransform const &, enum QFontEngine::GlyphFormat) ?resendPrepareEvent@QScroller@@QAEXXZ @ 13388 NONAME ; void QScroller::resendPrepareEvent(void) ??4QTextLength@@QAEAAV0@ABV0@@Z @ 13389 NONAME ABSENT ; class QTextLength & QTextLength::operator=(class QTextLength const &) @@ -13399,12 +13399,12 @@ EXPORTS ?scrollTo@QScroller@@QAEXABVQPointF@@H@Z @ 13398 NONAME ; void QScroller::scrollTo(class QPointF const &, int) ?ungrabGesture@QScroller@@SAXPAVQObject@@@Z @ 13399 NONAME ; void QScroller::ungrabGesture(class QObject *) ??4QItemSelectionRange@@QAEAAV0@ABV0@@Z @ 13400 NONAME ABSENT ; class QItemSelectionRange & QItemSelectionRange::operator=(class QItemSelectionRange const &) - ?clear@QGlyphs@@QAEXXZ @ 13401 NONAME ; void QGlyphs::clear(void) + ?clear@QGlyphs@@QAEXXZ @ 13401 NONAME ABSENT ; void QGlyphs::clear(void) ??_EQStyleOptionViewItemV4@@QAE@I@Z @ 13402 NONAME ABSENT ; QStyleOptionViewItemV4::~QStyleOptionViewItemV4(unsigned int) ??1QBlittablePixmapData@@UAE@XZ @ 13403 NONAME ; QBlittablePixmapData::~QBlittablePixmapData(void) ?formatsHelper@QInternalMimeData@@SA?AVQStringList@@PBVQMimeData@@@Z @ 13404 NONAME ; class QStringList QInternalMimeData::formatsHelper(class QMimeData const *) ?qt_metacast@QInternalMimeData@@UAEPAXPBD@Z @ 13405 NONAME ; void * QInternalMimeData::qt_metacast(char const *) - ?font@QGlyphs@@QBE?AVQFont@@XZ @ 13406 NONAME ; class QFont QGlyphs::font(void) const + ?font@QGlyphs@@QBE?AVQFont@@XZ @ 13406 NONAME ABSENT ; class QFont QGlyphs::font(void) const ?paintEngine@QBlittablePixmapData@@UBEPAVQPaintEngine@@XZ @ 13407 NONAME ; class QPaintEngine * QBlittablePixmapData::paintEngine(void) const ?unsetDefaultScrollerProperties@QScrollerProperties@@SAXXZ @ 13408 NONAME ; void QScrollerProperties::unsetDefaultScrollerProperties(void) ?hasChildren@QAbstractProxyModel@@UBE_NABVQModelIndex@@@Z @ 13409 NONAME ; bool QAbstractProxyModel::hasChildren(class QModelIndex const &) const @@ -13422,7 +13422,7 @@ EXPORTS ?qt_metacall@QInternalMimeData@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 13421 NONAME ; int QInternalMimeData::qt_metacall(enum QMetaObject::Call, int, void * *) ?lineHeightType@QTextBlockFormat@@QBEHXZ @ 13422 NONAME ; int QTextBlockFormat::lineHeightType(void) const ?hintingPreference@QFont@@QBE?AW4HintingPreference@1@XZ @ 13423 NONAME ; enum QFont::HintingPreference QFont::hintingPreference(void) const - ??0QGlyphs@@QAE@XZ @ 13424 NONAME ; QGlyphs::QGlyphs(void) + ??0QGlyphs@@QAE@XZ @ 13424 NONAME ABSENT ; QGlyphs::QGlyphs(void) ?trUtf8@QInternalMimeData@@SA?AVQString@@PBD0H@Z @ 13425 NONAME ; class QString QInternalMimeData::trUtf8(char const *, char const *, int) ??0QImageIOHandlerFactoryInterface@@QAE@XZ @ 13426 NONAME ABSENT ; QImageIOHandlerFactoryInterface::QImageIOHandlerFactoryInterface(void) ??_EQRegion@@QAE@I@Z @ 13427 NONAME ABSENT ; QRegion::~QRegion(unsigned int) @@ -13442,10 +13442,10 @@ EXPORTS ?clip@QBlitterPaintEngine@@UAEXABVQVectorPath@@W4ClipOperation@Qt@@@Z @ 13441 NONAME ; void QBlitterPaintEngine::clip(class QVectorPath const &, enum Qt::ClipOperation) ??1QScrollEvent@@UAE@XZ @ 13442 NONAME ; QScrollEvent::~QScrollEvent(void) ?state@QScroller@@QBE?AW4State@1@XZ @ 13443 NONAME ; enum QScroller::State QScroller::state(void) const - ?positions@QGlyphs@@QBE?AV?$QVector@VQPointF@@@@XZ @ 13444 NONAME ; class QVector QGlyphs::positions(void) const + ?positions@QGlyphs@@QBE?AV?$QVector@VQPointF@@@@XZ @ 13444 NONAME ABSENT ; class QVector QGlyphs::positions(void) const ?tr@QScroller@@SA?AVQString@@PBD0@Z @ 13445 NONAME ; class QString QScroller::tr(char const *, char const *) ?canReadData@QInternalMimeData@@SA_NABVQString@@@Z @ 13446 NONAME ; bool QInternalMimeData::canReadData(class QString const &) - ?glyphs@QTextLayout@@QBE?AV?$QList@VQGlyphs@@@@XZ @ 13447 NONAME ; class QList QTextLayout::glyphs(void) const + ?glyphs@QTextLayout@@QBE?AV?$QList@VQGlyphs@@@@XZ @ 13447 NONAME ABSENT ; class QList QTextLayout::glyphs(void) const ?leadingSpaceWidth@QTextEngine@@QAE?AUQFixed@@ABUQScriptLine@@@Z @ 13448 NONAME ; struct QFixed QTextEngine::leadingSpaceWidth(struct QScriptLine const &) ??_EQTextFormat@@QAE@I@Z @ 13449 NONAME ABSENT ; QTextFormat::~QTextFormat(unsigned int) ??4QStyleOptionTabWidgetFrame@@QAEAAV0@ABV0@@Z @ 13450 NONAME ABSENT ; class QStyleOptionTabWidgetFrame & QStyleOptionTabWidgetFrame::operator=(class QStyleOptionTabWidgetFrame const &) @@ -13463,7 +13463,7 @@ EXPORTS ??0QInternalMimeData@@QAE@XZ @ 13462 NONAME ; QInternalMimeData::QInternalMimeData(void) ??_EQScrollEvent@@UAE@I@Z @ 13463 NONAME ; QScrollEvent::~QScrollEvent(unsigned int) ?features@QRasterWindowSurface@@UBE?AV?$QFlags@W4WindowSurfaceFeature@QWindowSurface@@@@XZ @ 13464 NONAME ; class QFlags QRasterWindowSurface::features(void) const - ??4QGlyphs@@QAEAAV0@ABV0@@Z @ 13465 NONAME ; class QGlyphs & QGlyphs::operator=(class QGlyphs const &) + ??4QGlyphs@@QAEAAV0@ABV0@@Z @ 13465 NONAME ABSENT ; class QGlyphs & QGlyphs::operator=(class QGlyphs const &) ??4QQuaternion@@QAEAAV0@ABV0@@Z @ 13466 NONAME ABSENT ; class QQuaternion & QQuaternion::operator=(class QQuaternion const &) ??4Symbol@QCss@@QAEAAU01@ABU01@@Z @ 13467 NONAME ABSENT ; struct QCss::Symbol & QCss::Symbol::operator=(struct QCss::Symbol const &) ??0QBlittable@@QAE@ABVQSize@@V?$QFlags@W4Capability@QBlittable@@@@@Z @ 13468 NONAME ; QBlittable::QBlittable(class QSize const &, class QFlags) @@ -13480,10 +13480,10 @@ EXPORTS ?calculateSubPixelPositionCount@QTextureGlyphCache@@IBEHI@Z @ 13479 NONAME ; int QTextureGlyphCache::calculateSubPixelPositionCount(unsigned int) const ??0QTextImageFormat@@QAE@ABV0@@Z @ 13480 NONAME ABSENT ; QTextImageFormat::QTextImageFormat(class QTextImageFormat const &) ??0QMoveEvent@@QAE@ABV0@@Z @ 13481 NONAME ABSENT ; QMoveEvent::QMoveEvent(class QMoveEvent const &) - ?glyphs@QTextFragment@@QBE?AV?$QList@VQGlyphs@@@@XZ @ 13482 NONAME ; class QList QTextFragment::glyphs(void) const + ?glyphs@QTextFragment@@QBE?AV?$QList@VQGlyphs@@@@XZ @ 13482 NONAME ABSENT ; class QList QTextFragment::glyphs(void) const ??0QInputContextFactoryInterface@@QAE@XZ @ 13483 NONAME ABSENT ; QInputContextFactoryInterface::QInputContextFactoryInterface(void) ??0QTextFrameFormat@@QAE@ABV0@@Z @ 13484 NONAME ABSENT ; QTextFrameFormat::QTextFrameFormat(class QTextFrameFormat const &) - ?resetInternalData@QAbstractProxyModel@@IAEXXZ @ 13485 NONAME ; void QAbstractProxyModel::resetInternalData(void) + ?resetInternalData@QAbstractProxyModel@@IAEXXZ @ 13485 NONAME ABSENT ; void QAbstractProxyModel::resetInternalData(void) ??0Symbol@QCss@@QAE@ABU01@@Z @ 13486 NONAME ABSENT ; QCss::Symbol::Symbol(struct QCss::Symbol const &) ?features@QWindowSurface@@UBE?AV?$QFlags@W4WindowSurfaceFeature@QWindowSurface@@@@XZ @ 13487 NONAME ; class QFlags QWindowSurface::features(void) const ?markRasterOverlay@QBlittablePixmapData@@QAEXABVQVectorPath@@@Z @ 13488 NONAME ; void QBlittablePixmapData::markRasterOverlay(class QVectorPath const &) @@ -13499,7 +13499,7 @@ EXPORTS ?swap@QPainterPath@@QAEXAAV1@@Z @ 13498 NONAME ; void QPainterPath::swap(class QPainterPath &) ??4QStyleOptionRubberBand@@QAEAAV0@ABV0@@Z @ 13499 NONAME ABSENT ; class QStyleOptionRubberBand & QStyleOptionRubberBand::operator=(class QStyleOptionRubberBand const &) ?minimumSizeHint@QCheckBox@@UBE?AVQSize@@XZ @ 13500 NONAME ; class QSize QCheckBox::minimumSizeHint(void) const - ?createExplicitFont@QFontEngine@@UBE?AVQFont@@XZ @ 13501 NONAME ; class QFont QFontEngine::createExplicitFont(void) const + ?createExplicitFont@QFontEngine@@UBE?AVQFont@@XZ @ 13501 NONAME ABSENT ; class QFont QFontEngine::createExplicitFont(void) const ?alphaMapForGlyph@QFontEngine@@UAE?AVQImage@@IUQFixed@@@Z @ 13502 NONAME ; class QImage QFontEngine::alphaMapForGlyph(unsigned int, struct QFixed) ?fillTexture@QImageTextureGlyphCache@@UAEXABUCoord@QTextureGlyphCache@@IUQFixed@@@Z @ 13503 NONAME ; void QImageTextureGlyphCache::fillTexture(struct QTextureGlyphCache::Coord const &, unsigned int, struct QFixed) ?swap@QIcon@@QAEXAAV1@@Z @ 13504 NONAME ; void QIcon::swap(class QIcon &) @@ -13532,11 +13532,11 @@ EXPORTS ?pixelPerMeter@QScroller@@QBE?AVQPointF@@XZ @ 13531 NONAME ; class QPointF QScroller::pixelPerMeter(void) const ?target@QScroller@@QBEPAVQObject@@XZ @ 13532 NONAME ; class QObject * QScroller::target(void) const ?swap@QKeySequence@@QAEXAAV1@@Z @ 13533 NONAME ; void QKeySequence::swap(class QKeySequence &) - ??1QGlyphs@@QAE@XZ @ 13534 NONAME ; QGlyphs::~QGlyphs(void) + ??1QGlyphs@@QAE@XZ @ 13534 NONAME ABSENT ; QGlyphs::~QGlyphs(void) ?lineHeight@QTextBlockFormat@@QBEMXZ @ 13535 NONAME ; float QTextBlockFormat::lineHeight(void) const ?stroke@QBlitterPaintEngine@@UAEXABVQVectorPath@@ABVQPen@@@Z @ 13536 NONAME ; void QBlitterPaintEngine::stroke(class QVectorPath const &, class QPen const &) ?tr@QInternalMimeData@@SA?AVQString@@PBD0@Z @ 13537 NONAME ; class QString QInternalMimeData::tr(char const *, char const *) - ??9QGlyphs@@QBE_NABV0@@Z @ 13538 NONAME ; bool QGlyphs::operator!=(class QGlyphs const &) const + ??9QGlyphs@@QBE_NABV0@@Z @ 13538 NONAME ABSENT ; bool QGlyphs::operator!=(class QGlyphs const &) const ??1QBlittable@@UAE@XZ @ 13539 NONAME ; QBlittable::~QBlittable(void) ??_EQBlitterPaintEngine@@UAE@I@Z @ 13540 NONAME ; QBlitterPaintEngine::~QBlitterPaintEngine(unsigned int) ??0QCloseEvent@@QAE@ABV0@@Z @ 13541 NONAME ABSENT ; QCloseEvent::QCloseEvent(class QCloseEvent const &) @@ -13547,7 +13547,7 @@ EXPORTS ?finalPosition@QScroller@@QBE?AVQPointF@@XZ @ 13546 NONAME ; class QPointF QScroller::finalPosition(void) const ??4QStyleOptionTabWidgetFrameV2@@QAEAAV0@ABV0@@Z @ 13547 NONAME ABSENT ; class QStyleOptionTabWidgetFrameV2 & QStyleOptionTabWidgetFrameV2::operator=(class QStyleOptionTabWidgetFrameV2 const &) ?drawStaticTextItem@QBlitterPaintEngine@@UAEXPAVQStaticTextItem@@@Z @ 13548 NONAME ; void QBlitterPaintEngine::drawStaticTextItem(class QStaticTextItem *) - ??0QGlyphs@@QAE@ABV0@@Z @ 13549 NONAME ; QGlyphs::QGlyphs(class QGlyphs const &) + ??0QGlyphs@@QAE@ABV0@@Z @ 13549 NONAME ABSENT ; QGlyphs::QGlyphs(class QGlyphs const &) ?lock@QBlittable@@QAEPAVQImage@@XZ @ 13550 NONAME ; class QImage * QBlittable::lock(void) ?setFontHintingPreference@QTextCharFormat@@QAEXW4HintingPreference@QFont@@@Z @ 13551 NONAME ; void QTextCharFormat::setFontHintingPreference(enum QFont::HintingPreference) ??4QStyleOptionTabV2@@QAEAAV0@ABV0@@Z @ 13552 NONAME ABSENT ; class QStyleOptionTabV2 & QStyleOptionTabV2::operator=(class QStyleOptionTabV2 const &) @@ -13559,7 +13559,7 @@ EXPORTS ?markRasterOverlay@QBlittablePixmapData@@QAEXABVQPointF@@ABVQTextItem@@@Z @ 13558 NONAME ; void QBlittablePixmapData::markRasterOverlay(class QPointF const &, class QTextItem const &) ?trUtf8@QScroller@@SA?AVQString@@PBD0@Z @ 13559 NONAME ; class QString QScroller::trUtf8(char const *, char const *) ??_EQIcon@@QAE@I@Z @ 13560 NONAME ABSENT ; QIcon::~QIcon(unsigned int) - ??YQGlyphs@@AAEAAV0@ABV0@@Z @ 13561 NONAME ; class QGlyphs & QGlyphs::operator+=(class QGlyphs const &) + ??YQGlyphs@@AAEAAV0@ABV0@@Z @ 13561 NONAME ABSENT ; class QGlyphs & QGlyphs::operator+=(class QGlyphs const &) ??9QScrollerProperties@@QBE_NABV0@@Z @ 13562 NONAME ; bool QScrollerProperties::operator!=(class QScrollerProperties const &) const ??0QTextListFormat@@QAE@ABV0@@Z @ 13563 NONAME ABSENT ; QTextListFormat::QTextListFormat(class QTextListFormat const &) ?drawEllipse@QBlitterPaintEngine@@UAEXABVQRectF@@@Z @ 13564 NONAME ; void QBlitterPaintEngine::drawEllipse(class QRectF const &) @@ -13590,7 +13590,7 @@ EXPORTS ?qt_addBitmapToPath@@YAXMMPBEHHHPAVQPainterPath@@@Z @ 13589 NONAME ; void qt_addBitmapToPath(float, float, unsigned char const *, int, int, int, class QPainterPath *) ?staticMetaObject@QInternalMimeData@@2UQMetaObject@@B @ 13590 NONAME ; struct QMetaObject const QInternalMimeData::staticMetaObject ?activeScrollers@QScroller@@SA?AV?$QList@PAVQScroller@@@@XZ @ 13591 NONAME ; class QList QScroller::activeScrollers(void) - ?drawGlyphs@QPainter@@QAEXABVQPointF@@ABVQGlyphs@@@Z @ 13592 NONAME ; void QPainter::drawGlyphs(class QPointF const &, class QGlyphs const &) + ?drawGlyphs@QPainter@@QAEXABVQPointF@@ABVQGlyphs@@@Z @ 13592 NONAME ABSENT ; void QPainter::drawGlyphs(class QPointF const &, class QGlyphs const &) ??4QTextFrameFormat@@QAEAAV0@ABV0@@Z @ 13593 NONAME ABSENT ; class QTextFrameFormat & QTextFrameFormat::operator=(class QTextFrameFormat const &) ?staticMetaObjectExtraData@QStylePlugin@@0UQMetaObjectExtraData@@B @ 13594 NONAME ; struct QMetaObjectExtraData const QStylePlugin::staticMetaObjectExtraData ?staticMetaObjectExtraData@QToolBar@@0UQMetaObjectExtraData@@B @ 13595 NONAME ; struct QMetaObjectExtraData const QToolBar::staticMetaObjectExtraData @@ -13953,4 +13953,71 @@ EXPORTS ?staticMetaObjectExtraData@QWorkspace@@0UQMetaObjectExtraData@@B @ 13952 NONAME ; struct QMetaObjectExtraData const QWorkspace::staticMetaObjectExtraData ?staticMetaObjectExtraData@QSessionManager@@0UQMetaObjectExtraData@@B @ 13953 NONAME ; struct QMetaObjectExtraData const QSessionManager::staticMetaObjectExtraData ?qt_static_metacall@QGraphicsItemAnimation@@CAXPAVQObject@@W4Call@QMetaObject@@HPAPAX@Z @ 13954 NONAME ; void QGraphicsItemAnimation::qt_static_metacall(class QObject *, enum QMetaObject::Call, int, void * *) + ?cursorMoveStyle@QLineEdit@@QBE?AW4MoveStyle@QTextCursor@@XZ @ 13955 NONAME ; enum QTextCursor::MoveStyle QLineEdit::cursorMoveStyle(void) const + ?focalRadius@QRadialGradient@@QBEMXZ @ 13956 NONAME ; float QRadialGradient::focalRadius(void) const + ?alignLine@QTextEngine@@QAE?AUQFixed@@ABUQScriptLine@@@Z @ 13957 NONAME ; struct QFixed QTextEngine::alignLine(struct QScriptLine const &) + ?match@QIdentityProxyModel@@UBE?AV?$QList@VQModelIndex@@@@ABVQModelIndex@@HABVQVariant@@HV?$QFlags@W4MatchFlag@Qt@@@@@Z @ 13958 NONAME ; class QList QIdentityProxyModel::match(class QModelIndex const &, int, class QVariant const &, int, class QFlags) const + ?positionAfterVisualMovement@QTextEngine@@QAEHHW4MoveOperation@QTextCursor@@@Z @ 13959 NONAME ; int QTextEngine::positionAfterVisualMovement(int, enum QTextCursor::MoveOperation) + ?qt_painterPathFromVectorPath@@YA?AVQPainterPath@@ABVQVectorPath@@@Z @ 13960 NONAME ; class QPainterPath qt_painterPathFromVectorPath(class QVectorPath const &) + ?metaObject@QIdentityProxyModel@@UBEPBUQMetaObject@@XZ @ 13961 NONAME ; struct QMetaObject const * QIdentityProxyModel::metaObject(void) const + ?qt_static_metacall@QIdentityProxyModel@@CAXPAVQObject@@W4Call@QMetaObject@@HPAPAX@Z @ 13962 NONAME ; void QIdentityProxyModel::qt_static_metacall(class QObject *, enum QMetaObject::Call, int, void * *) + ?setCursorMoveStyle@QLineControl@@QAEXW4MoveStyle@QTextCursor@@@Z @ 13963 NONAME ; void QLineControl::setCursorMoveStyle(enum QTextCursor::MoveStyle) + ?visualCursorMovement@QTextEngine@@QBE_NXZ @ 13964 NONAME ; bool QTextEngine::visualCursorMovement(void) const + ?setFocalRadius@QRadialGradient@@QAEXM@Z @ 13965 NONAME ; void QRadialGradient::setFocalRadius(float) + ??_EQIdentityProxyModel@@UAE@I@Z @ 13966 NONAME ; QIdentityProxyModel::~QIdentityProxyModel(unsigned int) + ??1QIdentityProxyModel@@UAE@XZ @ 13967 NONAME ; QIdentityProxyModel::~QIdentityProxyModel(void) + ?d_func@QIdentityProxyModel@@AAEPAVQIdentityProxyModelPrivate@@XZ @ 13968 NONAME ; class QIdentityProxyModelPrivate * QIdentityProxyModel::d_func(void) + ?rowCount@QIdentityProxyModel@@UBEHABVQModelIndex@@@Z @ 13969 NONAME ; int QIdentityProxyModel::rowCount(class QModelIndex const &) const + ?previousLogicalPosition@QTextEngine@@QBEHH@Z @ 13970 NONAME ; int QTextEngine::previousLogicalPosition(int) const + ?endOfLine@QTextEngine@@AAEHH@Z @ 13971 NONAME ; int QTextEngine::endOfLine(int) + ?lineNumberForTextPosition@QTextEngine@@QAEHH@Z @ 13972 NONAME ; int QTextEngine::lineNumberForTextPosition(int) + ?mapToSource@QIdentityProxyModel@@UBE?AVQModelIndex@@ABV2@@Z @ 13973 NONAME ; class QModelIndex QIdentityProxyModel::mapToSource(class QModelIndex const &) const + ?setCursorMoveStyle@QTextLayout@@QAEXW4MoveStyle@QTextCursor@@@Z @ 13974 NONAME ; void QTextLayout::setCursorMoveStyle(enum QTextCursor::MoveStyle) + ?dropMimeData@QIdentityProxyModel@@UAE_NPBVQMimeData@@W4DropAction@Qt@@HHABVQModelIndex@@@Z @ 13975 NONAME ; bool QIdentityProxyModel::dropMimeData(class QMimeData const *, enum Qt::DropAction, int, int, class QModelIndex const &) + ?mapSelectionFromSource@QIdentityProxyModel@@UBE?AVQItemSelection@@ABV2@@Z @ 13976 NONAME ; class QItemSelection QIdentityProxyModel::mapSelectionFromSource(class QItemSelection const &) const + ?setInstantInvalidatePropagation@QGraphicsLayout@@SAX_N@Z @ 13977 NONAME ; void QGraphicsLayout::setInstantInvalidatePropagation(bool) + ?mapFromSource@QIdentityProxyModel@@UBE?AVQModelIndex@@ABV2@@Z @ 13978 NONAME ; class QModelIndex QIdentityProxyModel::mapFromSource(class QModelIndex const &) const + ?centerRadius@QRadialGradient@@QBEMXZ @ 13979 NONAME ; float QRadialGradient::centerRadius(void) const + ?mapSelectionToSource@QIdentityProxyModel@@UBE?AVQItemSelection@@ABV2@@Z @ 13980 NONAME ; class QItemSelection QIdentityProxyModel::mapSelectionToSource(class QItemSelection const &) const + ?tr@QIdentityProxyModel@@SA?AVQString@@PBD0H@Z @ 13981 NONAME ; class QString QIdentityProxyModel::tr(char const *, char const *, int) + ?cursorMoveStyle@QTextLayout@@QBE?AW4MoveStyle@QTextCursor@@XZ @ 13982 NONAME ; enum QTextCursor::MoveStyle QTextLayout::cursorMoveStyle(void) const + ?index@QIdentityProxyModel@@UBE?AVQModelIndex@@HHABV2@@Z @ 13983 NONAME ; class QModelIndex QIdentityProxyModel::index(int, int, class QModelIndex const &) const + ?qt_draw_decoration_for_glyphs@@YAXPAVQPainter@@PBIPBUQFixedPoint@@HPAVQFontEngine@@ABVQFont@@ABVQTextCharFormat@@@Z @ 13984 NONAME ; void qt_draw_decoration_for_glyphs(class QPainter *, unsigned int const *, struct QFixedPoint const *, int, class QFontEngine *, class QFont const &, class QTextCharFormat const &) + ?defaultCursorMoveStyle@QTextDocument@@QBE?AW4MoveStyle@QTextCursor@@XZ @ 13985 NONAME ; enum QTextCursor::MoveStyle QTextDocument::defaultCursorMoveStyle(void) const + ?insertRows@QIdentityProxyModel@@UAE_NHHABVQModelIndex@@@Z @ 13986 NONAME ; bool QIdentityProxyModel::insertRows(int, int, class QModelIndex const &) + ?qt_isExtendedRadialGradient@@YA_NABVQBrush@@@Z @ 13987 NONAME ; bool qt_isExtendedRadialGradient(class QBrush const &) + ?trUtf8@QIdentityProxyModel@@SA?AVQString@@PBD0H@Z @ 13988 NONAME ; class QString QIdentityProxyModel::trUtf8(char const *, char const *, int) + ?instantInvalidatePropagation@QGraphicsLayout@@SA_NXZ @ 13989 NONAME ; bool QGraphicsLayout::instantInvalidatePropagation(void) + ?trUtf8@QIdentityProxyModel@@SA?AVQString@@PBD0@Z @ 13990 NONAME ; class QString QIdentityProxyModel::trUtf8(char const *, char const *) + ??0QIdentityProxyModel@@QAE@PAVQObject@@@Z @ 13991 NONAME ; QIdentityProxyModel::QIdentityProxyModel(class QObject *) + ?removeColumns@QIdentityProxyModel@@UAE_NHHABVQModelIndex@@@Z @ 13992 NONAME ; bool QIdentityProxyModel::removeColumns(int, int, class QModelIndex const &) + ??0QIdentityProxyModel@@IAE@AAVQIdentityProxyModelPrivate@@PAVQObject@@@Z @ 13993 NONAME ; QIdentityProxyModel::QIdentityProxyModel(class QIdentityProxyModelPrivate &, class QObject *) + ?tr@QIdentityProxyModel@@SA?AVQString@@PBD0@Z @ 13994 NONAME ; class QString QIdentityProxyModel::tr(char const *, char const *) + ?columnCount@QIdentityProxyModel@@UBEHABVQModelIndex@@@Z @ 13995 NONAME ; int QIdentityProxyModel::columnCount(class QModelIndex const &) const + ??0QRadialGradient@@QAE@MMMMMM@Z @ 13996 NONAME ; QRadialGradient::QRadialGradient(float, float, float, float, float, float) + ?offsetInLigature@QTextEngine@@QAE?AUQFixed@@PBUQScriptItem@@HHH@Z @ 13997 NONAME ; struct QFixed QTextEngine::offsetInLigature(struct QScriptItem const *, int, int, int) + ?cursorMoveStyle@QLineControl@@QBE?AW4MoveStyle@QTextCursor@@XZ @ 13998 NONAME ; enum QTextCursor::MoveStyle QLineControl::cursorMoveStyle(void) const + ?beginningOfLine@QTextEngine@@AAEHH@Z @ 13999 NONAME ; int QTextEngine::beginningOfLine(int) + ?setCenterRadius@QRadialGradient@@QAEXM@Z @ 14000 NONAME ; void QRadialGradient::setCenterRadius(float) + ?setCursorMoveStyle@QLineEdit@@QAEXW4MoveStyle@QTextCursor@@@Z @ 14001 NONAME ; void QLineEdit::setCursorMoveStyle(enum QTextCursor::MoveStyle) + ??0QRadialGradient@@QAE@ABVQPointF@@M0M@Z @ 14002 NONAME ; QRadialGradient::QRadialGradient(class QPointF const &, float, class QPointF const &, float) + ?actionText@QUndoCommand@@QBE?AVQString@@XZ @ 14003 NONAME ; class QString QUndoCommand::actionText(void) const + ?insertionPointsForLine@QTextEngine@@QAEXHAAV?$QVector@H@@@Z @ 14004 NONAME ; void QTextEngine::insertionPointsForLine(int, class QVector &) + ?rightCursorPosition@QTextLayout@@QBEHH@Z @ 14005 NONAME ; int QTextLayout::rightCursorPosition(int) const + ?insertColumns@QIdentityProxyModel@@UAE_NHHABVQModelIndex@@@Z @ 14006 NONAME ; bool QIdentityProxyModel::insertColumns(int, int, class QModelIndex const &) + ?setDefaultCursorMoveStyle@QTextDocument@@QAEXW4MoveStyle@QTextCursor@@@Z @ 14007 NONAME ; void QTextDocument::setDefaultCursorMoveStyle(enum QTextCursor::MoveStyle) + ?doItemsLayout@QTableView@@UAEXXZ @ 14008 NONAME ; void QTableView::doItemsLayout(void) + ?qt_metacast@QIdentityProxyModel@@UAEPAXPBD@Z @ 14009 NONAME ; void * QIdentityProxyModel::qt_metacast(char const *) + ?setSourceModel@QIdentityProxyModel@@UAEXPAVQAbstractItemModel@@@Z @ 14010 NONAME ; void QIdentityProxyModel::setSourceModel(class QAbstractItemModel *) + ?d_func@QIdentityProxyModel@@ABEPBVQIdentityProxyModelPrivate@@XZ @ 14011 NONAME ; class QIdentityProxyModelPrivate const * QIdentityProxyModel::d_func(void) const + ?cloneWithSize@QFontEngine@@UBEPAV1@M@Z @ 14012 NONAME ; class QFontEngine * QFontEngine::cloneWithSize(float) const + ?leftCursorPosition@QTextLayout@@QBEHH@Z @ 14013 NONAME ; int QTextLayout::leftCursorPosition(int) const + ?paintingActive@QVolatileImage@@QBE_NXZ @ 14014 NONAME ; bool QVolatileImage::paintingActive(void) const + ?parent@QIdentityProxyModel@@UBE?AVQModelIndex@@ABV2@@Z @ 14015 NONAME ; class QModelIndex QIdentityProxyModel::parent(class QModelIndex const &) const + ?nextLogicalPosition@QTextEngine@@QBEHH@Z @ 14016 NONAME ; int QTextEngine::nextLogicalPosition(int) const + ?qt_metacall@QIdentityProxyModel@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 14017 NONAME ; int QIdentityProxyModel::qt_metacall(enum QMetaObject::Call, int, void * *) + ?staticMetaObject@QIdentityProxyModel@@2UQMetaObject@@B @ 14018 NONAME ; struct QMetaObject const QIdentityProxyModel::staticMetaObject + ?staticMetaObjectExtraData@QIdentityProxyModel@@0UQMetaObjectExtraData@@B @ 14019 NONAME ; struct QMetaObjectExtraData const QIdentityProxyModel::staticMetaObjectExtraData + ?getStaticMetaObject@QIdentityProxyModel@@SAABUQMetaObject@@XZ @ 14020 NONAME ; struct QMetaObject const & QIdentityProxyModel::getStaticMetaObject(void) + ?removeRows@QIdentityProxyModel@@UAE_NHHABVQModelIndex@@@Z @ 14021 NONAME ; bool QIdentityProxyModel::removeRows(int, int, class QModelIndex const &) diff --git a/src/s60installs/bwins/QtNetworku.def b/src/s60installs/bwins/QtNetworku.def index 49538efb1f..dd9dfaeaf5 100644 --- a/src/s60installs/bwins/QtNetworku.def +++ b/src/s60installs/bwins/QtNetworku.def @@ -1237,4 +1237,9 @@ EXPORTS ?qt_static_metacall@QBearerEnginePlugin@@CAXPAVQObject@@W4Call@QMetaObject@@HPAPAX@Z @ 1236 NONAME ; void QBearerEnginePlugin::qt_static_metacall(class QObject *, enum QMetaObject::Call, int, void * *) ?staticMetaObjectExtraData@QNetworkConfigurationManager@@0UQMetaObjectExtraData@@B @ 1237 NONAME ; struct QMetaObjectExtraData const QNetworkConfigurationManager::staticMetaObjectExtraData ?qt_static_metacall@QTcpSocket@@CAXPAVQObject@@W4Call@QMetaObject@@HPAPAX@Z @ 1238 NONAME ; void QTcpSocket::qt_static_metacall(class QObject *, enum QMetaObject::Call, int, void * *) + ??0QNetworkProxyQuery@@QAE@ABVQNetworkConfiguration@@GABVQString@@W4QueryType@0@@Z @ 1239 NONAME ; QNetworkProxyQuery::QNetworkProxyQuery(class QNetworkConfiguration const &, unsigned short, class QString const &, enum QNetworkProxyQuery::QueryType) + ??0QNetworkProxyQuery@@QAE@ABVQNetworkConfiguration@@ABVQString@@H1W4QueryType@0@@Z @ 1240 NONAME ; QNetworkProxyQuery::QNetworkProxyQuery(class QNetworkConfiguration const &, class QString const &, int, class QString const &, enum QNetworkProxyQuery::QueryType) + ?networkConfiguration@QNetworkProxyQuery@@QBE?AVQNetworkConfiguration@@XZ @ 1241 NONAME ; class QNetworkConfiguration QNetworkProxyQuery::networkConfiguration(void) const + ?setNetworkConfiguration@QNetworkProxyQuery@@QAEXABVQNetworkConfiguration@@@Z @ 1242 NONAME ; void QNetworkProxyQuery::setNetworkConfiguration(class QNetworkConfiguration const &) + ??0QNetworkProxyQuery@@QAE@ABVQNetworkConfiguration@@ABVQUrl@@W4QueryType@0@@Z @ 1243 NONAME ; QNetworkProxyQuery::QNetworkProxyQuery(class QNetworkConfiguration const &, class QUrl const &, enum QNetworkProxyQuery::QueryType) diff --git a/src/s60installs/eabi/QtCoreu.def b/src/s60installs/eabi/QtCoreu.def index 81b5267863..6c4e837e8d 100644 --- a/src/s60installs/eabi/QtCoreu.def +++ b/src/s60installs/eabi/QtCoreu.def @@ -3992,4 +3992,166 @@ EXPORTS _ZNK7QLocale9bcp47NameEv @ 3991 NONAME _ZTI13QActiveObject @ 3992 NONAME _ZTV13QActiveObject @ 3993 NONAME + _ZN23QCoreApplicationPrivate13trolltechConfEv @ 3994 NONAME + _ZN12QtConcurrent15ResultStoreBase10addResultsEiPKvii @ 3995 NONAME + _ZN12QtConcurrent15ResultStoreBase13setFilterModeEb @ 3996 NONAME + _ZN12QtConcurrent15ResultStoreBase15syncResultCountEv @ 3997 NONAME + _ZN12QtConcurrent15ResultStoreBase16insertResultItemEiRNS_10ResultItemE @ 3998 NONAME + _ZN12QtConcurrent15ResultStoreBase17updateInsertIndexEii @ 3999 NONAME + _ZN12QtConcurrent15ResultStoreBase18syncPendingResultsEv @ 4000 NONAME + _ZN12QtConcurrent15ResultStoreBase23insertResultItemIfValidEiRNS_10ResultItemE @ 4001 NONAME + _ZN12QtConcurrent15ResultStoreBase9addResultEiPKv @ 4002 NONAME + _ZN12QtConcurrent15ResultStoreBaseC1Ev @ 4003 NONAME + _ZN12QtConcurrent15ResultStoreBaseC2Ev @ 4004 NONAME + _ZN12QtConcurrent16BlockSizeManager13timeAfterUserEv @ 4005 NONAME + _ZN12QtConcurrent16BlockSizeManager14timeBeforeUserEv @ 4006 NONAME + _ZN12QtConcurrent16BlockSizeManager9blockSizeEv @ 4007 NONAME + _ZN12QtConcurrent16BlockSizeManagerC1Ei @ 4008 NONAME + _ZN12QtConcurrent16BlockSizeManagerC2Ei @ 4009 NONAME + _ZN12QtConcurrent16ThreadEngineBase10isCanceledEv @ 4010 NONAME + _ZN12QtConcurrent16ThreadEngineBase10threadExitEv @ 4011 NONAME + _ZN12QtConcurrent16ThreadEngineBase11startThreadEv @ 4012 NONAME + _ZN12QtConcurrent16ThreadEngineBase12startThreadsEv @ 4013 NONAME + _ZN12QtConcurrent16ThreadEngineBase13startBlockingEv @ 4014 NONAME + _ZN12QtConcurrent16ThreadEngineBase13waitForResumeEv @ 4015 NONAME + _ZN12QtConcurrent16ThreadEngineBase15handleExceptionERKNS_9ExceptionE @ 4016 NONAME + _ZN12QtConcurrent16ThreadEngineBase16setProgressRangeEii @ 4017 NONAME + _ZN12QtConcurrent16ThreadEngineBase16setProgressValueEi @ 4018 NONAME + _ZN12QtConcurrent16ThreadEngineBase18threadThrottleExitEv @ 4019 NONAME + _ZN12QtConcurrent16ThreadEngineBase19startSingleThreadedEv @ 4020 NONAME + _ZN12QtConcurrent16ThreadEngineBase19startThreadInternalEv @ 4021 NONAME + _ZN12QtConcurrent16ThreadEngineBase23acquireBarrierSemaphoreEv @ 4022 NONAME + _ZN12QtConcurrent16ThreadEngineBase26isProgressReportingEnabledEv @ 4023 NONAME + _ZN12QtConcurrent16ThreadEngineBase3runEv @ 4024 NONAME + _ZN12QtConcurrent16ThreadEngineBaseC2Ev @ 4025 NONAME + _ZN12QtConcurrent16ThreadEngineBaseD0Ev @ 4026 NONAME + _ZN12QtConcurrent16ThreadEngineBaseD1Ev @ 4027 NONAME + _ZN12QtConcurrent16ThreadEngineBaseD2Ev @ 4028 NONAME + _ZN12QtConcurrent18ResultIteratorBase14batchedAdvanceEv @ 4029 NONAME + _ZN12QtConcurrent18ResultIteratorBaseC1EN4QMapIiNS_10ResultItemEE14const_iteratorEi @ 4030 NONAME + _ZN12QtConcurrent18ResultIteratorBaseC1Ev @ 4031 NONAME + _ZN12QtConcurrent18ResultIteratorBaseC2EN4QMapIiNS_10ResultItemEE14const_iteratorEi @ 4032 NONAME + _ZN12QtConcurrent18ResultIteratorBaseC2Ev @ 4033 NONAME + _ZN12QtConcurrent18ResultIteratorBaseppEv @ 4034 NONAME + _ZN12QtConcurrent8internal14ExceptionStore12setExceptionERKNS_9ExceptionE @ 4035 NONAME + _ZN12QtConcurrent8internal14ExceptionStore22throwPossibleExceptionEv @ 4036 NONAME + _ZN12QtConcurrent8internal14ExceptionStore9exceptionEv @ 4037 NONAME + _ZN18QFutureWatcherBase11qt_metacallEN11QMetaObject4CallEiPPv @ 4038 NONAME + _ZN18QFutureWatcherBase11qt_metacastEPKc @ 4039 NONAME + _ZN18QFutureWatcherBase12togglePausedEv @ 4040 NONAME + _ZN18QFutureWatcherBase13connectNotifyEPKc @ 4041 NONAME + _ZN18QFutureWatcherBase13resultReadyAtEi @ 4042 NONAME + _ZN18QFutureWatcherBase14resultsReadyAtEii @ 4043 NONAME + _ZN18QFutureWatcherBase15waitForFinishedEv @ 4044 NONAME + _ZN18QFutureWatcherBase16disconnectNotifyEPKc @ 4045 NONAME + _ZN18QFutureWatcherBase16staticMetaObjectE @ 4046 NONAME DATA 16 + _ZN18QFutureWatcherBase18qt_static_metacallEP7QObjectN11QMetaObject4CallEiPPv @ 4047 NONAME + _ZN18QFutureWatcherBase19getStaticMetaObjectEv @ 4048 NONAME + _ZN18QFutureWatcherBase19progressTextChangedERK7QString @ 4049 NONAME + _ZN18QFutureWatcherBase20progressRangeChangedEii @ 4050 NONAME + _ZN18QFutureWatcherBase20progressValueChangedEi @ 4051 NONAME + _ZN18QFutureWatcherBase22connectOutputInterfaceEv @ 4052 NONAME + _ZN18QFutureWatcherBase22setPendingResultsLimitEi @ 4053 NONAME + _ZN18QFutureWatcherBase25disconnectOutputInterfaceEb @ 4054 NONAME + _ZN18QFutureWatcherBase25staticMetaObjectExtraDataE @ 4055 NONAME DATA 8 + _ZN18QFutureWatcherBase5eventEP6QEvent @ 4056 NONAME + _ZN18QFutureWatcherBase5pauseEv @ 4057 NONAME + _ZN18QFutureWatcherBase6cancelEv @ 4058 NONAME + _ZN18QFutureWatcherBase6pausedEv @ 4059 NONAME + _ZN18QFutureWatcherBase6resumeEv @ 4060 NONAME + _ZN18QFutureWatcherBase7resumedEv @ 4061 NONAME + _ZN18QFutureWatcherBase7startedEv @ 4062 NONAME + _ZN18QFutureWatcherBase8canceledEv @ 4063 NONAME + _ZN18QFutureWatcherBase8finishedEv @ 4064 NONAME + _ZN18QFutureWatcherBase9setPausedEb @ 4065 NONAME + _ZN18QFutureWatcherBaseC2EP7QObject @ 4066 NONAME + _ZN20QFutureInterfaceBase11setRunnableEP9QRunnable @ 4067 NONAME + _ZN20QFutureInterfaceBase12setThrottledEb @ 4068 NONAME + _ZN20QFutureInterfaceBase12togglePausedEv @ 4069 NONAME + _ZN20QFutureInterfaceBase13reportStartedEv @ 4070 NONAME + _ZN20QFutureInterfaceBase13setFilterModeEb @ 4071 NONAME + _ZN20QFutureInterfaceBase13waitForResultEi @ 4072 NONAME + _ZN20QFutureInterfaceBase13waitForResumeEv @ 4073 NONAME + _ZN20QFutureInterfaceBase14exceptionStoreEv @ 4074 NONAME + _ZN20QFutureInterfaceBase14reportCanceledEv @ 4075 NONAME + _ZN20QFutureInterfaceBase14reportFinishedEv @ 4076 NONAME + _ZN20QFutureInterfaceBase15reportExceptionERKN12QtConcurrent9ExceptionE @ 4077 NONAME + _ZN20QFutureInterfaceBase15resultStoreBaseEv @ 4078 NONAME + _ZN20QFutureInterfaceBase15waitForFinishedEv @ 4079 NONAME + _ZN20QFutureInterfaceBase16setProgressRangeEii @ 4080 NONAME + _ZN20QFutureInterfaceBase16setProgressValueEi @ 4081 NONAME + _ZN20QFutureInterfaceBase17waitForNextResultEv @ 4082 NONAME + _ZN20QFutureInterfaceBase18reportResultsReadyEii @ 4083 NONAME + _ZN20QFutureInterfaceBase19expectedResultCountEv @ 4084 NONAME + _ZN20QFutureInterfaceBase22setExpectedResultCountEi @ 4085 NONAME + _ZN20QFutureInterfaceBase23setProgressValueAndTextEiRK7QString @ 4086 NONAME + _ZN20QFutureInterfaceBase6cancelEv @ 4087 NONAME + _ZN20QFutureInterfaceBase9setPausedEb @ 4088 NONAME + _ZN20QFutureInterfaceBaseC1ENS_5StateE @ 4089 NONAME + _ZN20QFutureInterfaceBaseC1ERKS_ @ 4090 NONAME + _ZN20QFutureInterfaceBaseC2ENS_5StateE @ 4091 NONAME + _ZN20QFutureInterfaceBaseC2ERKS_ @ 4092 NONAME + _ZN20QFutureInterfaceBaseD0Ev @ 4093 NONAME + _ZN20QFutureInterfaceBaseD1Ev @ 4094 NONAME + _ZN20QFutureInterfaceBaseD2Ev @ 4095 NONAME + _ZN20QFutureInterfaceBaseaSERKS_ @ 4096 NONAME + _ZNK12QtConcurrent15ResultStoreBase10filterModeEv @ 4097 NONAME + _ZNK12QtConcurrent15ResultStoreBase13hasNextResultEv @ 4098 NONAME + _ZNK12QtConcurrent15ResultStoreBase3endEv @ 4099 NONAME + _ZNK12QtConcurrent15ResultStoreBase5beginEv @ 4100 NONAME + _ZNK12QtConcurrent15ResultStoreBase5countEv @ 4101 NONAME + _ZNK12QtConcurrent15ResultStoreBase8containsEi @ 4102 NONAME + _ZNK12QtConcurrent15ResultStoreBase8resultAtEi @ 4103 NONAME + _ZNK12QtConcurrent18ResultIteratorBase11resultIndexEv @ 4104 NONAME + _ZNK12QtConcurrent18ResultIteratorBase11vectorIndexEv @ 4105 NONAME + _ZNK12QtConcurrent18ResultIteratorBase23canIncrementVectorIndexEv @ 4106 NONAME + _ZNK12QtConcurrent18ResultIteratorBase8isVectorEv @ 4107 NONAME + _ZNK12QtConcurrent18ResultIteratorBase9batchSizeEv @ 4108 NONAME + _ZNK12QtConcurrent18ResultIteratorBaseeqERKS0_ @ 4109 NONAME + _ZNK12QtConcurrent18ResultIteratorBaseneERKS0_ @ 4110 NONAME + _ZNK12QtConcurrent18UnhandledException5cloneEv @ 4111 NONAME + _ZNK12QtConcurrent18UnhandledException5raiseEv @ 4112 NONAME + _ZNK12QtConcurrent8internal14ExceptionStore12hasExceptionEv @ 4113 NONAME + _ZNK12QtConcurrent8internal14ExceptionStore9hasThrownEv @ 4114 NONAME + _ZNK12QtConcurrent9Exception5cloneEv @ 4115 NONAME + _ZNK12QtConcurrent9Exception5raiseEv @ 4116 NONAME + _ZNK18QFutureWatcherBase10isCanceledEv @ 4117 NONAME + _ZNK18QFutureWatcherBase10isFinishedEv @ 4118 NONAME + _ZNK18QFutureWatcherBase10metaObjectEv @ 4119 NONAME + _ZNK18QFutureWatcherBase12progressTextEv @ 4120 NONAME + _ZNK18QFutureWatcherBase13progressValueEv @ 4121 NONAME + _ZNK18QFutureWatcherBase15progressMaximumEv @ 4122 NONAME + _ZNK18QFutureWatcherBase15progressMinimumEv @ 4123 NONAME + _ZNK18QFutureWatcherBase8isPausedEv @ 4124 NONAME + _ZNK18QFutureWatcherBase9isRunningEv @ 4125 NONAME + _ZNK18QFutureWatcherBase9isStartedEv @ 4126 NONAME + _ZNK20QFutureInterfaceBase10isCanceledEv @ 4127 NONAME + _ZNK20QFutureInterfaceBase10isFinishedEv @ 4128 NONAME + _ZNK20QFutureInterfaceBase10queryStateENS_5StateE @ 4129 NONAME + _ZNK20QFutureInterfaceBase11isThrottledEv @ 4130 NONAME + _ZNK20QFutureInterfaceBase11resultCountEv @ 4131 NONAME + _ZNK20QFutureInterfaceBase12progressTextEv @ 4132 NONAME + _ZNK20QFutureInterfaceBase13progressValueEv @ 4133 NONAME + _ZNK20QFutureInterfaceBase15isResultReadyAtEi @ 4134 NONAME + _ZNK20QFutureInterfaceBase15progressMaximumEv @ 4135 NONAME + _ZNK20QFutureInterfaceBase15progressMinimumEv @ 4136 NONAME + _ZNK20QFutureInterfaceBase15resultStoreBaseEv @ 4137 NONAME + _ZNK20QFutureInterfaceBase19referenceCountIsOneEv @ 4138 NONAME + _ZNK20QFutureInterfaceBase22isProgressUpdateNeededEv @ 4139 NONAME + _ZNK20QFutureInterfaceBase5mutexEv @ 4140 NONAME + _ZNK20QFutureInterfaceBase8isPausedEv @ 4141 NONAME + _ZNK20QFutureInterfaceBase9isRunningEv @ 4142 NONAME + _ZNK20QFutureInterfaceBase9isStartedEv @ 4143 NONAME + _ZTI18QFutureWatcherBase @ 4144 NONAME + _ZTI20QFutureInterfaceBase @ 4145 NONAME + _ZTIN12QtConcurrent15ResultStoreBaseE @ 4146 NONAME + _ZTIN12QtConcurrent16ThreadEngineBaseE @ 4147 NONAME + _ZTIN12QtConcurrent18UnhandledExceptionE @ 4148 NONAME + _ZTIN12QtConcurrent9ExceptionE @ 4149 NONAME + _ZTV18QFutureWatcherBase @ 4150 NONAME + _ZTV20QFutureInterfaceBase @ 4151 NONAME + _ZTVN12QtConcurrent15ResultStoreBaseE @ 4152 NONAME + _ZTVN12QtConcurrent16ThreadEngineBaseE @ 4153 NONAME + _ZTVN12QtConcurrent18UnhandledExceptionE @ 4154 NONAME + _ZTVN12QtConcurrent9ExceptionE @ 4155 NONAME diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def index 66464010e0..aec683199f 100644 --- a/src/s60installs/eabi/QtGuiu.def +++ b/src/s60installs/eabi/QtGuiu.def @@ -11820,7 +11820,7 @@ EXPORTS _ZN20QGraphicsItemPrivate16clearFocusHelperEb @ 11819 NONAME _ZN24QImagePixmapCleanupHooks13isImageCachedERK6QImage @ 11820 NONAME _ZN24QImagePixmapCleanupHooks14isPixmapCachedERK7QPixmap @ 11821 NONAME - _Z14qt_draw_glyphsP8QPainterPKjPK7QPointFi @ 11822 NONAME + _Z14qt_draw_glyphsP8QPainterPKjPK7QPointFi @ 11822 NONAME ABSENT _ZN10QImageData14convertInPlaceEN6QImage6FormatE6QFlagsIN2Qt19ImageConversionFlagEE @ 11823 NONAME _ZN10QZipReader5closeEv @ 11824 NONAME _ZN10QZipReader8FileInfoC1ERKS0_ @ 11825 NONAME @@ -12230,7 +12230,7 @@ EXPORTS _ZN17QInternalMimeDataD2Ev @ 12229 NONAME _ZN18QTextureGlyphCache19fillInPendingGlyphsEv @ 12230 NONAME _ZN19QAbstractProxyModel11setItemDataERK11QModelIndexRK4QMapIi8QVariantE @ 12231 NONAME - _ZN19QAbstractProxyModel17resetInternalDataEv @ 12232 NONAME + _ZN19QAbstractProxyModel17resetInternalDataEv @ 12232 NONAME ABSENT _ZN19QAbstractProxyModel4sortEiN2Qt9SortOrderE @ 12233 NONAME _ZN19QAbstractProxyModel9fetchMoreERK11QModelIndex @ 12234 NONAME _ZN19QApplicationPrivateC1ERiPPcN12QApplication4TypeEi @ 12235 NONAME @@ -12302,22 +12302,22 @@ EXPORTS _ZN5QFont20setHintingPreferenceENS_17HintingPreferenceE @ 12301 NONAME _ZN6QImage4fillEN2Qt11GlobalColorE @ 12302 NONAME _ZN6QImage4fillERK6QColor @ 12303 NONAME - _ZN7QGlyphs12setPositionsERK7QVectorI7QPointFE @ 12304 NONAME - _ZN7QGlyphs15setGlyphIndexesERK7QVectorIjE @ 12305 NONAME - _ZN7QGlyphs5clearEv @ 12306 NONAME - _ZN7QGlyphs6detachEv @ 12307 NONAME - _ZN7QGlyphs7setFontERK5QFont @ 12308 NONAME - _ZN7QGlyphsC1ERKS_ @ 12309 NONAME - _ZN7QGlyphsC1Ev @ 12310 NONAME - _ZN7QGlyphsC2ERKS_ @ 12311 NONAME - _ZN7QGlyphsC2Ev @ 12312 NONAME - _ZN7QGlyphsD1Ev @ 12313 NONAME - _ZN7QGlyphsD2Ev @ 12314 NONAME - _ZN7QGlyphsaSERKS_ @ 12315 NONAME - _ZN7QGlyphspLERKS_ @ 12316 NONAME + _ZN7QGlyphs12setPositionsERK7QVectorI7QPointFE @ 12304 NONAME ABSENT + _ZN7QGlyphs15setGlyphIndexesERK7QVectorIjE @ 12305 NONAME ABSENT + _ZN7QGlyphs5clearEv @ 12306 NONAME ABSENT + _ZN7QGlyphs6detachEv @ 12307 NONAME ABSENT + _ZN7QGlyphs7setFontERK5QFont @ 12308 NONAME ABSENT + _ZN7QGlyphsC1ERKS_ @ 12309 NONAME ABSENT + _ZN7QGlyphsC1Ev @ 12310 NONAME ABSENT + _ZN7QGlyphsC2ERKS_ @ 12311 NONAME ABSENT + _ZN7QGlyphsC2Ev @ 12312 NONAME ABSENT + _ZN7QGlyphsD1Ev @ 12313 NONAME ABSENT + _ZN7QGlyphsD2Ev @ 12314 NONAME ABSENT + _ZN7QGlyphsaSERKS_ @ 12315 NONAME ABSENT + _ZN7QGlyphspLERKS_ @ 12316 NONAME ABSENT _ZN8QMdiArea14setTabsMovableEb @ 12317 NONAME _ZN8QMdiArea15setTabsClosableEb @ 12318 NONAME - _ZN8QPainter10drawGlyphsERK7QPointFRK7QGlyphs @ 12319 NONAME + _ZN8QPainter10drawGlyphsERK7QPointFRK7QGlyphs @ 12319 NONAME ABSENT _ZN9QScroller11grabGestureEP7QObjectNS_19ScrollerGestureTypeE @ 12320 NONAME _ZN9QScroller11handleInputENS_5InputERK7QPointFx @ 12321 NONAME _ZN9QScroller11hasScrollerEP7QObject @ 12322 NONAME @@ -12351,9 +12351,9 @@ EXPORTS _ZNK10QBlittable12capabilitiesEv @ 12350 NONAME _ZNK10QBlittable4sizeEv @ 12351 NONAME _ZNK10QTabWidget14heightForWidthEi @ 12352 NONAME - _ZNK11QFontEngine18createExplicitFontEv @ 12353 NONAME - _ZNK11QFontEngine26createExplicitFontWithNameERK7QString @ 12354 NONAME - _ZNK11QTextLayout6glyphsEv @ 12355 NONAME + _ZNK11QFontEngine18createExplicitFontEv @ 12353 NONAME ABSENT + _ZNK11QFontEngine26createExplicitFontWithNameERK7QString @ 12354 NONAME ABSENT + _ZNK11QTextLayout6glyphsEv @ 12355 NONAME ABSENT _ZNK12QFontMetrics10inFontUcs4Ej @ 12356 NONAME _ZNK12QRadioButton15minimumSizeHintEv @ 12357 NONAME _ZNK12QScrollEvent10contentPosEv @ 12358 NONAME @@ -12362,7 +12362,7 @@ EXPORTS _ZNK12QScrollEvent6d_funcEv @ 12361 NONAME _ZNK13QFlickGesture10metaObjectEv @ 12362 NONAME _ZNK13QFontMetricsF10inFontUcs4Ej @ 12363 NONAME - _ZNK13QTextFragment6glyphsEv @ 12364 NONAME + _ZNK13QTextFragment6glyphsEv @ 12364 NONAME ABSENT _ZNK14QFileOpenEvent8openFileER5QFile6QFlagsIN9QIODevice12OpenModeFlagEE @ 12365 NONAME _ZNK14QWidgetPrivate17hasHeightForWidthEv @ 12366 NONAME _ZNK16QFileSystemModel5rmdirERK11QModelIndex @ 12367 NONAME @@ -12396,12 +12396,12 @@ EXPORTS _ZNK20QBlittablePixmapData9blittableEv @ 12395 NONAME _ZNK20QRasterWindowSurface24hasStaticContentsSupportEv @ 12396 NONAME ABSENT _ZNK5QFont17hintingPreferenceEv @ 12397 NONAME - _ZNK7QGlyphs12glyphIndexesEv @ 12398 NONAME - _ZNK7QGlyphs4fontEv @ 12399 NONAME - _ZNK7QGlyphs9positionsEv @ 12400 NONAME - _ZNK7QGlyphseqERKS_ @ 12401 NONAME - _ZNK7QGlyphsneERKS_ @ 12402 NONAME - _ZNK7QGlyphsplERKS_ @ 12403 NONAME + _ZNK7QGlyphs12glyphIndexesEv @ 12398 NONAME ABSENT + _ZNK7QGlyphs4fontEv @ 12399 NONAME ABSENT + _ZNK7QGlyphs9positionsEv @ 12400 NONAME ABSENT + _ZNK7QGlyphseqERKS_ @ 12401 NONAME ABSENT + _ZNK7QGlyphsneERKS_ @ 12402 NONAME ABSENT + _ZNK7QGlyphsplERKS_ @ 12403 NONAME ABSENT _ZNK8QMdiArea11tabsMovableEv @ 12404 NONAME _ZNK8QMdiArea12tabsClosableEv @ 12405 NONAME _ZNK8QPainter16clipBoundingRectEv @ 12406 NONAME @@ -12413,7 +12413,7 @@ EXPORTS _ZNK9QScroller5stateEv @ 12412 NONAME _ZNK9QScroller6targetEv @ 12413 NONAME _ZNK9QScroller8velocityEv @ 12414 NONAME - _ZNK9QTextLine6glyphsEii @ 12415 NONAME + _ZNK9QTextLine6glyphsEii @ 12415 NONAME ABSENT _ZTI10QBlittable @ 12416 NONAME _ZTI12QScrollEvent @ 12417 NONAME _ZTI13QFlickGesture @ 12418 NONAME @@ -12799,4 +12799,69 @@ EXPORTS _ZNK10QZipWriter6deviceEv @ 12798 NONAME _ZNK10QZipWriter6existsEv @ 12799 NONAME _ZNK10QZipWriter6statusEv @ 12800 NONAME + _Z27qt_isExtendedRadialGradientRK6QBrush @ 12801 NONAME + _Z28qt_painterPathFromVectorPathRK11QVectorPath @ 12802 NONAME + _Z29qt_draw_decoration_for_glyphsP8QPainterPKjPK11QFixedPointiP11QFontEngineRK5QFontRK15QTextCharFormat @ 12803 NONAME + _ZN10QTableView13doItemsLayoutEv @ 12804 NONAME + _ZN11QTextEngine15beginningOfLineEi @ 12805 NONAME + _ZN11QTextEngine16offsetInLigatureEPK11QScriptItemiii @ 12806 NONAME + _ZN11QTextEngine22insertionPointsForLineEiR7QVectorIiE @ 12807 NONAME + _ZN11QTextEngine25lineNumberForTextPositionEi @ 12808 NONAME + _ZN11QTextEngine27positionAfterVisualMovementEiN11QTextCursor13MoveOperationE @ 12809 NONAME + _ZN11QTextEngine9alignLineERK11QScriptLine @ 12810 NONAME + _ZN11QTextEngine9endOfLineEi @ 12811 NONAME + _ZN11QTextLayout18setCursorMoveStyleEN11QTextCursor9MoveStyleE @ 12812 NONAME + _ZN13QTextDocument25setDefaultCursorMoveStyleEN11QTextCursor9MoveStyleE @ 12813 NONAME + _ZN15QGraphicsLayout28instantInvalidatePropagationEv @ 12814 NONAME + _ZN15QGraphicsLayout31setInstantInvalidatePropagationEb @ 12815 NONAME + _ZN15QRadialGradient14setFocalRadiusEf @ 12816 NONAME + _ZN15QRadialGradient15setCenterRadiusEf @ 12817 NONAME + _ZN15QRadialGradientC1ERK7QPointFfS2_f @ 12818 NONAME + _ZN15QRadialGradientC1Effffff @ 12819 NONAME + _ZN15QRadialGradientC2ERK7QPointFfS2_f @ 12820 NONAME + _ZN15QRadialGradientC2Effffff @ 12821 NONAME + _ZN19QIdentityProxyModel10insertRowsEiiRK11QModelIndex @ 12822 NONAME + _ZN19QIdentityProxyModel10removeRowsEiiRK11QModelIndex @ 12823 NONAME + _ZN19QIdentityProxyModel11qt_metacallEN11QMetaObject4CallEiPPv @ 12824 NONAME + _ZN19QIdentityProxyModel11qt_metacastEPKc @ 12825 NONAME + _ZN19QIdentityProxyModel12dropMimeDataEPK9QMimeDataN2Qt10DropActionEiiRK11QModelIndex @ 12826 NONAME + _ZN19QIdentityProxyModel13insertColumnsEiiRK11QModelIndex @ 12827 NONAME + _ZN19QIdentityProxyModel13removeColumnsEiiRK11QModelIndex @ 12828 NONAME + _ZN19QIdentityProxyModel14setSourceModelEP18QAbstractItemModel @ 12829 NONAME + _ZN19QIdentityProxyModel16staticMetaObjectE @ 12830 NONAME DATA 16 + _ZN19QIdentityProxyModel18qt_static_metacallEP7QObjectN11QMetaObject4CallEiPPv @ 12831 NONAME + _ZN19QIdentityProxyModel19getStaticMetaObjectEv @ 12832 NONAME + _ZN19QIdentityProxyModel25staticMetaObjectExtraDataE @ 12833 NONAME DATA 8 + _ZN19QIdentityProxyModelC1EP7QObject @ 12834 NONAME + _ZN19QIdentityProxyModelC1ER26QIdentityProxyModelPrivateP7QObject @ 12835 NONAME + _ZN19QIdentityProxyModelC2EP7QObject @ 12836 NONAME + _ZN19QIdentityProxyModelC2ER26QIdentityProxyModelPrivateP7QObject @ 12837 NONAME + _ZN19QIdentityProxyModelD0Ev @ 12838 NONAME + _ZN19QIdentityProxyModelD1Ev @ 12839 NONAME + _ZN19QIdentityProxyModelD2Ev @ 12840 NONAME + _ZN9QLineEdit18setCursorMoveStyleEN11QTextCursor9MoveStyleE @ 12841 NONAME + _ZNK10QTextBlock7isValidEv @ 12842 NONAME + _ZNK11QTextEngine19nextLogicalPositionEi @ 12843 NONAME + _ZNK11QTextEngine23previousLogicalPositionEi @ 12844 NONAME + _ZNK11QTextLayout15cursorMoveStyleEv @ 12845 NONAME + _ZNK11QTextLayout18leftCursorPositionEi @ 12846 NONAME + _ZNK11QTextLayout19rightCursorPositionEi @ 12847 NONAME + _ZNK12QUndoCommand10actionTextEv @ 12848 NONAME + _ZNK13QTextDocument22defaultCursorMoveStyleEv @ 12849 NONAME + _ZNK14QVolatileImage14paintingActiveEv @ 12850 NONAME + _ZNK15QRadialGradient11focalRadiusEv @ 12851 NONAME + _ZNK15QRadialGradient12centerRadiusEv @ 12852 NONAME + _ZNK19QIdentityProxyModel10metaObjectEv @ 12853 NONAME + _ZNK19QIdentityProxyModel11columnCountERK11QModelIndex @ 12854 NONAME + _ZNK19QIdentityProxyModel11mapToSourceERK11QModelIndex @ 12855 NONAME + _ZNK19QIdentityProxyModel13mapFromSourceERK11QModelIndex @ 12856 NONAME + _ZNK19QIdentityProxyModel20mapSelectionToSourceERK14QItemSelection @ 12857 NONAME + _ZNK19QIdentityProxyModel22mapSelectionFromSourceERK14QItemSelection @ 12858 NONAME + _ZNK19QIdentityProxyModel5indexEiiRK11QModelIndex @ 12859 NONAME + _ZNK19QIdentityProxyModel5matchERK11QModelIndexiRK8QVarianti6QFlagsIN2Qt9MatchFlagEE @ 12860 NONAME + _ZNK19QIdentityProxyModel6parentERK11QModelIndex @ 12861 NONAME + _ZNK19QIdentityProxyModel8rowCountERK11QModelIndex @ 12862 NONAME + _ZNK9QLineEdit15cursorMoveStyleEv @ 12863 NONAME + _ZTI19QIdentityProxyModel @ 12864 NONAME + _ZTV19QIdentityProxyModel @ 12865 NONAME diff --git a/src/s60installs/eabi/QtNetworku.def b/src/s60installs/eabi/QtNetworku.def index b0cbb38252..8e29c2de69 100644 --- a/src/s60installs/eabi/QtNetworku.def +++ b/src/s60installs/eabi/QtNetworku.def @@ -1260,4 +1260,12 @@ EXPORTS _ZN4QFtp25staticMetaObjectExtraDataE @ 1259 NONAME DATA 8 _ZN5QHttp18qt_static_metacallEP7QObjectN11QMetaObject4CallEiPPv @ 1260 NONAME _ZN5QHttp25staticMetaObjectExtraDataE @ 1261 NONAME DATA 8 + _ZN18QNetworkProxyQuery23setNetworkConfigurationERK21QNetworkConfiguration @ 1262 NONAME + _ZN18QNetworkProxyQueryC1ERK21QNetworkConfigurationRK4QUrlNS_9QueryTypeE @ 1263 NONAME + _ZN18QNetworkProxyQueryC1ERK21QNetworkConfigurationRK7QStringiS5_NS_9QueryTypeE @ 1264 NONAME + _ZN18QNetworkProxyQueryC1ERK21QNetworkConfigurationtRK7QStringNS_9QueryTypeE @ 1265 NONAME + _ZN18QNetworkProxyQueryC2ERK21QNetworkConfigurationRK4QUrlNS_9QueryTypeE @ 1266 NONAME + _ZN18QNetworkProxyQueryC2ERK21QNetworkConfigurationRK7QStringiS5_NS_9QueryTypeE @ 1267 NONAME + _ZN18QNetworkProxyQueryC2ERK21QNetworkConfigurationtRK7QStringNS_9QueryTypeE @ 1268 NONAME + _ZNK18QNetworkProxyQuery20networkConfigurationEv @ 1269 NONAME From d49c561b7374bf72684c6eaea6e65c71f69e0150 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Wed, 10 Nov 2010 11:21:53 +0100 Subject: [PATCH 25/27] Add the QIdentityProxyModel. Older commit history is in KDE svn: http://websvn.kde.org/trunk/KDE/kdelibs/kdeui/itemviews/kidentityproxymodel.cpp?view=log Ammended to update the license headers. Merge-request: 900 Reviewed-by: Gabriel de Dietrich Conflicts: doc/src/frameworks-technologies/model-view-programming.qdoc tests/auto/headers/tst_headers.cpp (cherry picked from b00089261eafbdf5f92ed94d7fb20b402bfcaeb2) --- .../src_gui_itemviews_qidentityproxymodel.cpp | 66 ++ src/corelib/kernel/qabstractitemmodel.h | 1 + src/gui/itemviews/itemviews.pri | 2 + src/gui/itemviews/qidentityproxymodel.cpp | 582 ++++++++++++++++++ src/gui/itemviews/qidentityproxymodel.h | 115 ++++ src/gui/itemviews/qsortfilterproxymodel.cpp | 2 +- tests/auto/gui.pro | 1 + .../qidentityproxymodel.pro | 6 + .../tst_qidentityproxymodel.cpp | 329 ++++++++++ 9 files changed, 1103 insertions(+), 1 deletion(-) create mode 100644 doc/src/snippets/code/src_gui_itemviews_qidentityproxymodel.cpp create mode 100644 src/gui/itemviews/qidentityproxymodel.cpp create mode 100644 src/gui/itemviews/qidentityproxymodel.h create mode 100644 tests/auto/qidentityproxymodel/qidentityproxymodel.pro create mode 100644 tests/auto/qidentityproxymodel/tst_qidentityproxymodel.cpp diff --git a/doc/src/snippets/code/src_gui_itemviews_qidentityproxymodel.cpp b/doc/src/snippets/code/src_gui_itemviews_qidentityproxymodel.cpp new file mode 100644 index 0000000000..8bd65208cb --- /dev/null +++ b/doc/src/snippets/code/src_gui_itemviews_qidentityproxymodel.cpp @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Klarälvdalens Datakonsult AB, +** a KDAB Group company, info@kdab.com, +** author Stephen Kelly +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +class DateFormatProxyModel : public QIdentityProxyModel +{ + // ... + + void setDateFormatString(const QString &formatString) + { + m_formatString = formatString; + } + + QVariant data(const QModelIndex &index, int role) + { + if (role != Qt::DisplayRole) + return QIdentityProxyModel::data(index, role); + + const QDateTime dateTime = sourceModel()->data(SourceClass::DateRole).toDateTime(); + + return dateTime.toString(m_formatString); + } + +private: + QString m_formatString; +}; +//! [0] diff --git a/src/corelib/kernel/qabstractitemmodel.h b/src/corelib/kernel/qabstractitemmodel.h index 6de3bf5e4f..7bed3a296e 100644 --- a/src/corelib/kernel/qabstractitemmodel.h +++ b/src/corelib/kernel/qabstractitemmodel.h @@ -162,6 +162,7 @@ class Q_CORE_EXPORT QAbstractItemModel : public QObject friend class QPersistentModelIndexData; friend class QAbstractItemViewPrivate; + friend class QIdentityProxyModel; public: explicit QAbstractItemModel(QObject *parent = 0); diff --git a/src/gui/itemviews/itemviews.pri b/src/gui/itemviews/itemviews.pri index bbc1e983ba..149bfd67b0 100644 --- a/src/gui/itemviews/itemviews.pri +++ b/src/gui/itemviews/itemviews.pri @@ -4,6 +4,7 @@ HEADERS += \ itemviews/qabstractitemview.h \ itemviews/qabstractitemview_p.h \ itemviews/qheaderview.h \ + itemviews/qidentityproxymodel.h \ itemviews/qlistview.h \ itemviews/qlistview_p.h \ itemviews/qbsptree_p.h \ @@ -44,6 +45,7 @@ HEADERS += \ SOURCES += \ itemviews/qabstractitemview.cpp \ itemviews/qheaderview.cpp \ + itemviews/qidentityproxymodel.cpp \ itemviews/qlistview.cpp \ itemviews/qbsptree.cpp \ itemviews/qtableview.cpp \ diff --git a/src/gui/itemviews/qidentityproxymodel.cpp b/src/gui/itemviews/qidentityproxymodel.cpp new file mode 100644 index 0000000000..9396e6199a --- /dev/null +++ b/src/gui/itemviews/qidentityproxymodel.cpp @@ -0,0 +1,582 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Klarälvdalens Datakonsult AB, +** a KDAB Group company, info@kdab.com, +** author Stephen Kelly +** All rights reserved. +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** 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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +****************************************************************************/ + +#include "qidentityproxymodel.h" + +#ifndef QT_NO_IDENTITYPROXYMODEL + +#include "qitemselectionmodel.h" +#include + +QT_BEGIN_NAMESPACE + +class QIdentityProxyModelPrivate : public QAbstractProxyModelPrivate +{ + QIdentityProxyModelPrivate() + : ignoreNextLayoutAboutToBeChanged(false), + ignoreNextLayoutChanged(false) + { + + } + + Q_DECLARE_PUBLIC(QIdentityProxyModel) + + bool ignoreNextLayoutAboutToBeChanged; + bool ignoreNextLayoutChanged; + QList layoutChangePersistentIndexes; + QModelIndexList proxyIndexes; + + void _q_sourceRowsAboutToBeInserted(const QModelIndex &parent, int start, int end); + void _q_sourceRowsInserted(const QModelIndex &parent, int start, int end); + void _q_sourceRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end); + void _q_sourceRowsRemoved(const QModelIndex &parent, int start, int end); + void _q_sourceRowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest); + void _q_sourceRowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest); + + void _q_sourceColumnsAboutToBeInserted(const QModelIndex &parent, int start, int end); + void _q_sourceColumnsInserted(const QModelIndex &parent, int start, int end); + void _q_sourceColumnsAboutToBeRemoved(const QModelIndex &parent, int start, int end); + void _q_sourceColumnsRemoved(const QModelIndex &parent, int start, int end); + void _q_sourceColumnsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest); + void _q_sourceColumnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest); + + void _q_sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); + void _q_sourceHeaderDataChanged(Qt::Orientation orientation, int first, int last); + + void _q_sourceLayoutAboutToBeChanged(); + void _q_sourceLayoutChanged(); + void _q_sourceModelAboutToBeReset(); + void _q_sourceModelReset(); + +}; + +/*! + \since 4.8 + \class QIdentityProxyModel + \brief The QIdentityProxyModel class proxies its source model unmodified + + \ingroup model-view + + QIdentityProxyModel can be used to forward the structure of a source model exactly, with no sorting, filtering or other transformation. + This is similar in concept to an identity matrix where A.I = A. + + Because it does no sorting or filtering, this class is most suitable to proxy models which transform the data() of the source model. + For example, a proxy model could be created to define the font used, or the background colour, or the tooltip etc. This removes the + need to implement all data handling in the same class that creates the structure of the model, and can also be used to create + re-usable components. + + This also provides a way to change the data in the case where a source model is supplied by a third party which can not be modified. + + \snippet doc/src/snippets/code/src_gui_itemviews_qidentityproxymodel.cpp 0 + + \sa QAbstractProxyModel, {Model/View Programming}, QAbstractItemModel + +*/ + +/*! + Constructs an identity model with the given \a parent. +*/ +QIdentityProxyModel::QIdentityProxyModel(QObject* parent) + : QAbstractProxyModel(*new QIdentityProxyModelPrivate, parent) +{ + +} + +/*! \internal + */ +QIdentityProxyModel::QIdentityProxyModel(QIdentityProxyModelPrivate &dd, QObject* parent) + : QAbstractProxyModel(dd, parent) +{ + +} + +/*! + Destroys this identity model. +*/ +QIdentityProxyModel::~QIdentityProxyModel() +{ +} + +/*! + \reimp + */ +int QIdentityProxyModel::columnCount(const QModelIndex& parent) const +{ + Q_ASSERT(parent.isValid() ? parent.model() == this : true); + Q_D(const QIdentityProxyModel); + return d->model->columnCount(mapToSource(parent)); +} + +/*! + \reimp + */ +bool QIdentityProxyModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) +{ + Q_ASSERT(parent.isValid() ? parent.model() == this : true); + Q_D(QIdentityProxyModel); + return d->model->dropMimeData(data, action, row, column, mapToSource(parent)); +} + +/*! + \reimp + */ +QModelIndex QIdentityProxyModel::index(int row, int column, const QModelIndex& parent) const +{ + Q_ASSERT(parent.isValid() ? parent.model() == this : true); + Q_D(const QIdentityProxyModel); + if (!hasIndex(row, column, parent)) + return QModelIndex(); + const QModelIndex sourceParent = mapToSource(parent); + const QModelIndex sourceIndex = d->model->index(row, column, sourceParent); + Q_ASSERT(sourceIndex.isValid()); + return mapFromSource(sourceIndex); +} + +/*! + \reimp + */ +bool QIdentityProxyModel::insertColumns(int column, int count, const QModelIndex& parent) +{ + Q_ASSERT(parent.isValid() ? parent.model() == this : true); + Q_D(QIdentityProxyModel); + return d->model->insertColumns(column, count, mapToSource(parent)); +} + +/*! + \reimp + */ +bool QIdentityProxyModel::insertRows(int row, int count, const QModelIndex& parent) +{ + Q_ASSERT(parent.isValid() ? parent.model() == this : true); + Q_D(QIdentityProxyModel); + return d->model->insertRows(row, count, mapToSource(parent)); +} + +/*! + \reimp + */ +QModelIndex QIdentityProxyModel::mapFromSource(const QModelIndex& sourceIndex) const +{ + Q_D(const QIdentityProxyModel); + if (!d->model || !sourceIndex.isValid()) + return QModelIndex(); + + Q_ASSERT(sourceIndex.model() == d->model); + return createIndex(sourceIndex.row(), sourceIndex.column(), sourceIndex.internalPointer()); +} + +/*! + \reimp + */ +QItemSelection QIdentityProxyModel::mapSelectionFromSource(const QItemSelection& selection) const +{ + Q_D(const QIdentityProxyModel); + QItemSelection proxySelection; + + if (!d->model) + return proxySelection; + + QItemSelection::const_iterator it = selection.constBegin(); + const QItemSelection::const_iterator end = selection.constEnd(); + for ( ; it != end; ++it) { + Q_ASSERT(it->model() == d->model); + const QItemSelectionRange range(mapFromSource(it->topLeft()), mapFromSource(it->bottomRight())); + proxySelection.append(range); + } + + return proxySelection; +} + +/*! + \reimp + */ +QItemSelection QIdentityProxyModel::mapSelectionToSource(const QItemSelection& selection) const +{ + Q_D(const QIdentityProxyModel); + QItemSelection sourceSelection; + + if (!d->model) + return sourceSelection; + + QItemSelection::const_iterator it = selection.constBegin(); + const QItemSelection::const_iterator end = selection.constEnd(); + for ( ; it != end; ++it) { + Q_ASSERT(it->model() == this); + const QItemSelectionRange range(mapToSource(it->topLeft()), mapToSource(it->bottomRight())); + sourceSelection.append(range); + } + + return sourceSelection; +} + +/*! + \reimp + */ +QModelIndex QIdentityProxyModel::mapToSource(const QModelIndex& proxyIndex) const +{ + Q_D(const QIdentityProxyModel); + if (!d->model || !proxyIndex.isValid()) + return QModelIndex(); + Q_ASSERT(proxyIndex.model() == this); + return d->model->createIndex(proxyIndex.row(), proxyIndex.column(), proxyIndex.internalPointer()); +} + +/*! + \reimp + */ +QModelIndexList QIdentityProxyModel::match(const QModelIndex& start, int role, const QVariant& value, int hits, Qt::MatchFlags flags) const +{ + Q_D(const QIdentityProxyModel); + Q_ASSERT(start.isValid() ? start.model() == this : true); + if (!d->model) + return QModelIndexList(); + + const QModelIndexList sourceList = d->model->match(mapToSource(start), role, value, hits, flags); + QModelIndexList::const_iterator it = sourceList.constBegin(); + const QModelIndexList::const_iterator end = sourceList.constEnd(); + QModelIndexList proxyList; + for ( ; it != end; ++it) + proxyList.append(mapFromSource(*it)); + return proxyList; +} + +/*! + \reimp + */ +QModelIndex QIdentityProxyModel::parent(const QModelIndex& child) const +{ + Q_ASSERT(child.isValid() ? child.model() == this : true); + const QModelIndex sourceIndex = mapToSource(child); + const QModelIndex sourceParent = sourceIndex.parent(); + return mapFromSource(sourceParent); +} + +/*! + \reimp + */ +bool QIdentityProxyModel::removeColumns(int column, int count, const QModelIndex& parent) +{ + Q_ASSERT(parent.isValid() ? parent.model() == this : true); + Q_D(QIdentityProxyModel); + return d->model->removeColumns(column, count, mapToSource(parent)); +} + +/*! + \reimp + */ +bool QIdentityProxyModel::removeRows(int row, int count, const QModelIndex& parent) +{ + Q_ASSERT(parent.isValid() ? parent.model() == this : true); + Q_D(QIdentityProxyModel); + return d->model->removeRows(row, count, mapToSource(parent)); +} + +/*! + \reimp + */ +int QIdentityProxyModel::rowCount(const QModelIndex& parent) const +{ + Q_ASSERT(parent.isValid() ? parent.model() == this : true); + Q_D(const QIdentityProxyModel); + return d->model->rowCount(mapToSource(parent)); +} + +/*! + \reimp + */ +void QIdentityProxyModel::setSourceModel(QAbstractItemModel* sourceModel) +{ + beginResetModel(); + + if (sourceModel) { + disconnect(sourceModel, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)), + this, SLOT(_q_sourceRowsAboutToBeInserted(const QModelIndex &, int, int))); + disconnect(sourceModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)), + this, SLOT(_q_sourceRowsInserted(const QModelIndex &, int, int))); + disconnect(sourceModel, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)), + this, SLOT(_q_sourceRowsAboutToBeRemoved(const QModelIndex &, int, int))); + disconnect(sourceModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), + this, SLOT(_q_sourceRowsRemoved(const QModelIndex &, int, int))); + disconnect(sourceModel, SIGNAL(rowsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)), + this, SLOT(_q_sourceRowsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int))); + disconnect(sourceModel, SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), + this, SLOT(_q_sourceRowsMoved(const QModelIndex &, int, int, const QModelIndex &, int))); + disconnect(sourceModel, SIGNAL(columnsAboutToBeInserted(const QModelIndex &, int, int)), + this, SLOT(_q_sourceColumnsAboutToBeInserted(const QModelIndex &, int, int))); + disconnect(sourceModel, SIGNAL(columnsInserted(const QModelIndex &, int, int)), + this, SLOT(_q_sourceColumnsInserted(const QModelIndex &, int, int))); + disconnect(sourceModel, SIGNAL(columnsAboutToBeRemoved(const QModelIndex &, int, int)), + this, SLOT(_q_sourceColumnsAboutToBeRemoved(const QModelIndex &, int, int))); + disconnect(sourceModel, SIGNAL(columnsRemoved(const QModelIndex &, int, int)), + this, SLOT(_q_sourceColumnsRemoved(const QModelIndex &, int, int))); + disconnect(sourceModel, SIGNAL(columnsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)), + this, SLOT(_q_sourceColumnsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int))); + disconnect(sourceModel, SIGNAL(columnsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), + this, SLOT(_q_sourceColumnsMoved(const QModelIndex &, int, int, const QModelIndex &, int))); + disconnect(sourceModel, SIGNAL(modelAboutToBeReset()), + this, SLOT(_q_sourceModelAboutToBeReset())); + disconnect(sourceModel, SIGNAL(modelReset()), + this, SLOT(_q_sourceModelReset())); + disconnect(sourceModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), + this, SLOT(_q_sourceDataChanged(const QModelIndex &, const QModelIndex &))); + disconnect(sourceModel, SIGNAL(headerDataChanged(Qt::Orientation,int,int)), + this, SLOT(_q_sourceHeaderDataChanged(Qt::Orientation,int,int))); + disconnect(sourceModel, SIGNAL(layoutAboutToBeChanged()), + this, SLOT(_q_sourceLayoutAboutToBeChanged())); + disconnect(sourceModel, SIGNAL(layoutChanged()), + this, SLOT(_q_sourceLayoutChanged())); + } + + QAbstractProxyModel::setSourceModel(sourceModel); + + if (sourceModel) { + connect(sourceModel, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)), + SLOT(_q_sourceRowsAboutToBeInserted(const QModelIndex &, int, int))); + connect(sourceModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)), + SLOT(_q_sourceRowsInserted(const QModelIndex &, int, int))); + connect(sourceModel, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)), + SLOT(_q_sourceRowsAboutToBeRemoved(const QModelIndex &, int, int))); + connect(sourceModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), + SLOT(_q_sourceRowsRemoved(const QModelIndex &, int, int))); + connect(sourceModel, SIGNAL(rowsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)), + SLOT(_q_sourceRowsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int))); + connect(sourceModel, SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), + SLOT(_q_sourceRowsMoved(const QModelIndex &, int, int, const QModelIndex &, int))); + connect(sourceModel, SIGNAL(columnsAboutToBeInserted(const QModelIndex &, int, int)), + SLOT(_q_sourceColumnsAboutToBeInserted(const QModelIndex &, int, int))); + connect(sourceModel, SIGNAL(columnsInserted(const QModelIndex &, int, int)), + SLOT(_q_sourceColumnsInserted(const QModelIndex &, int, int))); + connect(sourceModel, SIGNAL(columnsAboutToBeRemoved(const QModelIndex &, int, int)), + SLOT(_q_sourceColumnsAboutToBeRemoved(const QModelIndex &, int, int))); + connect(sourceModel, SIGNAL(columnsRemoved(const QModelIndex &, int, int)), + SLOT(_q_sourceColumnsRemoved(const QModelIndex &, int, int))); + connect(sourceModel, SIGNAL(columnsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)), + SLOT(_q_sourceColumnsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int))); + connect(sourceModel, SIGNAL(columnsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), + SLOT(_q_sourceColumnsMoved(const QModelIndex &, int, int, const QModelIndex &, int))); + connect(sourceModel, SIGNAL(modelAboutToBeReset()), + SLOT(_q_sourceModelAboutToBeReset())); + connect(sourceModel, SIGNAL(modelReset()), + SLOT(_q_sourceModelReset())); + connect(sourceModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), + SLOT(_q_sourceDataChanged(const QModelIndex &, const QModelIndex &))); + connect(sourceModel, SIGNAL(headerDataChanged(Qt::Orientation,int,int)), + SLOT(_q_sourceHeaderDataChanged(Qt::Orientation,int,int))); + connect(sourceModel, SIGNAL(layoutAboutToBeChanged()), + SLOT(_q_sourceLayoutAboutToBeChanged())); + connect(sourceModel, SIGNAL(layoutChanged()), + SLOT(_q_sourceLayoutChanged())); + } + + endResetModel(); +} + +void QIdentityProxyModelPrivate::_q_sourceColumnsAboutToBeInserted(const QModelIndex &parent, int start, int end) +{ + Q_ASSERT(parent.isValid() ? parent.model() == model : true); + Q_Q(QIdentityProxyModel); + q->beginInsertColumns(q->mapFromSource(parent), start, end); +} + +void QIdentityProxyModelPrivate::_q_sourceColumnsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest) +{ + Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == model : true); + Q_ASSERT(destParent.isValid() ? destParent.model() == model : true); + Q_Q(QIdentityProxyModel); + q->beginMoveColumns(q->mapFromSource(sourceParent), sourceStart, sourceEnd, q->mapFromSource(destParent), dest); +} + +void QIdentityProxyModelPrivate::_q_sourceColumnsAboutToBeRemoved(const QModelIndex &parent, int start, int end) +{ + Q_ASSERT(parent.isValid() ? parent.model() == model : true); + Q_Q(QIdentityProxyModel); + q->beginRemoveColumns(q->mapFromSource(parent), start, end); +} + +void QIdentityProxyModelPrivate::_q_sourceColumnsInserted(const QModelIndex &parent, int start, int end) +{ + Q_ASSERT(parent.isValid() ? parent.model() == model : true); + Q_Q(QIdentityProxyModel); + Q_UNUSED(parent) + Q_UNUSED(start) + Q_UNUSED(end) + q->endInsertColumns(); +} + +void QIdentityProxyModelPrivate::_q_sourceColumnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest) +{ + Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == model : true); + Q_ASSERT(destParent.isValid() ? destParent.model() == model : true); + Q_Q(QIdentityProxyModel); + Q_UNUSED(sourceParent) + Q_UNUSED(sourceStart) + Q_UNUSED(sourceEnd) + Q_UNUSED(destParent) + Q_UNUSED(dest) + q->endMoveColumns(); +} + +void QIdentityProxyModelPrivate::_q_sourceColumnsRemoved(const QModelIndex &parent, int start, int end) +{ + Q_ASSERT(parent.isValid() ? parent.model() == model : true); + Q_Q(QIdentityProxyModel); + Q_UNUSED(parent) + Q_UNUSED(start) + Q_UNUSED(end) + q->endRemoveColumns(); +} + +void QIdentityProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) +{ + Q_ASSERT(topLeft.isValid() ? topLeft.model() == model : true); + Q_ASSERT(bottomRight.isValid() ? bottomRight.model() == model : true); + Q_Q(QIdentityProxyModel); + q->dataChanged(q->mapFromSource(topLeft), q->mapFromSource(bottomRight)); +} + +void QIdentityProxyModelPrivate::_q_sourceHeaderDataChanged(Qt::Orientation orientation, int first, int last) +{ + Q_Q(QIdentityProxyModel); + q->headerDataChanged(orientation, first, last); +} + +void QIdentityProxyModelPrivate::_q_sourceLayoutAboutToBeChanged() +{ + if (ignoreNextLayoutAboutToBeChanged) + return; + + Q_Q(QIdentityProxyModel); + + foreach(const QPersistentModelIndex &proxyPersistentIndex, q->persistentIndexList()) { + proxyIndexes << proxyPersistentIndex; + Q_ASSERT(proxyPersistentIndex.isValid()); + const QPersistentModelIndex srcPersistentIndex = q->mapToSource(proxyPersistentIndex); + Q_ASSERT(srcPersistentIndex.isValid()); + layoutChangePersistentIndexes << srcPersistentIndex; + } + + q->layoutAboutToBeChanged(); +} + +void QIdentityProxyModelPrivate::_q_sourceLayoutChanged() +{ + if (ignoreNextLayoutChanged) + return; + + Q_Q(QIdentityProxyModel); + + for (int i = 0; i < proxyIndexes.size(); ++i) { + q->changePersistentIndex(proxyIndexes.at(i), q->mapFromSource(layoutChangePersistentIndexes.at(i))); + } + + layoutChangePersistentIndexes.clear(); + proxyIndexes.clear(); + + q->layoutChanged(); +} + +void QIdentityProxyModelPrivate::_q_sourceModelAboutToBeReset() +{ + Q_Q(QIdentityProxyModel); + q->beginResetModel(); +} + +void QIdentityProxyModelPrivate::_q_sourceModelReset() +{ + Q_Q(QIdentityProxyModel); + q->endResetModel(); +} + +void QIdentityProxyModelPrivate::_q_sourceRowsAboutToBeInserted(const QModelIndex &parent, int start, int end) +{ + Q_ASSERT(parent.isValid() ? parent.model() == model : true); + Q_Q(QIdentityProxyModel); + q->beginInsertRows(q->mapFromSource(parent), start, end); +} + +void QIdentityProxyModelPrivate::_q_sourceRowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest) +{ + Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == model : true); + Q_ASSERT(destParent.isValid() ? destParent.model() == model : true); + Q_Q(QIdentityProxyModel); + q->beginMoveRows(q->mapFromSource(sourceParent), sourceStart, sourceEnd, q->mapFromSource(destParent), dest); +} + +void QIdentityProxyModelPrivate::_q_sourceRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) +{ + Q_ASSERT(parent.isValid() ? parent.model() == model : true); + Q_Q(QIdentityProxyModel); + q->beginRemoveRows(q->mapFromSource(parent), start, end); +} + +void QIdentityProxyModelPrivate::_q_sourceRowsInserted(const QModelIndex &parent, int start, int end) +{ + Q_ASSERT(parent.isValid() ? parent.model() == model : true); + Q_Q(QIdentityProxyModel); + Q_UNUSED(parent) + Q_UNUSED(start) + Q_UNUSED(end) + q->endInsertRows(); +} + +void QIdentityProxyModelPrivate::_q_sourceRowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest) +{ + Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == model : true); + Q_ASSERT(destParent.isValid() ? destParent.model() == model : true); + Q_Q(QIdentityProxyModel); + Q_UNUSED(sourceParent) + Q_UNUSED(sourceStart) + Q_UNUSED(sourceEnd) + Q_UNUSED(destParent) + Q_UNUSED(dest) + q->endMoveRows(); +} + +void QIdentityProxyModelPrivate::_q_sourceRowsRemoved(const QModelIndex &parent, int start, int end) +{ + Q_ASSERT(parent.isValid() ? parent.model() == model : true); + Q_Q(QIdentityProxyModel); + Q_UNUSED(parent) + Q_UNUSED(start) + Q_UNUSED(end) + q->endRemoveRows(); +} + +QT_END_NAMESPACE + +#include "moc_qidentityproxymodel.cpp" + +#endif // QT_NO_IDENTITYPROXYMODEL diff --git a/src/gui/itemviews/qidentityproxymodel.h b/src/gui/itemviews/qidentityproxymodel.h new file mode 100644 index 0000000000..b60aa0b7c9 --- /dev/null +++ b/src/gui/itemviews/qidentityproxymodel.h @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Klarälvdalens Datakonsult AB, +** a KDAB Group company, info@kdab.com, +** author Stephen Kelly +** All rights reserved. +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** 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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +****************************************************************************/ + + +#ifndef QIDENTITYPROXYMODEL_H +#define QIDENTITYPROXYMODEL_H + +#include + +#ifndef QT_NO_IDENTITYPROXYMODEL + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +class QIdentityProxyModelPrivate; + +class Q_GUI_EXPORT QIdentityProxyModel : public QAbstractProxyModel +{ + Q_OBJECT +public: + explicit QIdentityProxyModel(QObject* parent = 0); + ~QIdentityProxyModel(); + + int columnCount(const QModelIndex& parent = QModelIndex()) const; + QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const; + QModelIndex mapFromSource(const QModelIndex& sourceIndex) const; + QModelIndex mapToSource(const QModelIndex& proxyIndex) const; + QModelIndex parent(const QModelIndex& child) const; + int rowCount(const QModelIndex& parent = QModelIndex()) const; + bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent); + + QItemSelection mapSelectionFromSource(const QItemSelection& selection) const; + QItemSelection mapSelectionToSource(const QItemSelection& selection) const; + QModelIndexList match(const QModelIndex& start, int role, const QVariant& value, int hits = 1, Qt::MatchFlags flags = Qt::MatchFlags(Qt::MatchStartsWith|Qt::MatchWrap)) const; + void setSourceModel(QAbstractItemModel* sourceModel); + + bool insertColumns(int column, int count, const QModelIndex& parent = QModelIndex()); + bool insertRows(int row, int count, const QModelIndex& parent = QModelIndex()); + bool removeColumns(int column, int count, const QModelIndex& parent = QModelIndex()); + bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex()); + +protected: + QIdentityProxyModel(QIdentityProxyModelPrivate &dd, QObject* parent); + +private: + Q_DECLARE_PRIVATE(QIdentityProxyModel) + Q_DISABLE_COPY(QIdentityProxyModel) + + Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeInserted(QModelIndex,int,int)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsInserted(QModelIndex,int,int)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeRemoved(QModelIndex,int,int)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsRemoved(QModelIndex,int,int)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsMoved(QModelIndex,int,int,QModelIndex,int)) + + Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeInserted(QModelIndex,int,int)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsInserted(QModelIndex,int,int)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeRemoved(QModelIndex,int,int)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsRemoved(QModelIndex,int,int)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsMoved(QModelIndex,int,int,QModelIndex,int)) + + Q_PRIVATE_SLOT(d_func(), void _q_sourceDataChanged(QModelIndex,QModelIndex)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceHeaderDataChanged(Qt::Orientation orientation, int first, int last)) + + Q_PRIVATE_SLOT(d_func(), void _q_sourceLayoutAboutToBeChanged()) + Q_PRIVATE_SLOT(d_func(), void _q_sourceLayoutChanged()) + Q_PRIVATE_SLOT(d_func(), void _q_sourceModelAboutToBeReset()) + Q_PRIVATE_SLOT(d_func(), void _q_sourceModelReset()) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QT_NO_IDENTITYPROXYMODEL + +#endif // QIDENTITYPROXYMODEL_H + diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp index eb56f56ed4..f73607ba8d 100644 --- a/src/gui/itemviews/qsortfilterproxymodel.cpp +++ b/src/gui/itemviews/qsortfilterproxymodel.cpp @@ -1502,7 +1502,7 @@ void QSortFilterProxyModelPrivate::_q_sourceColumnsRemoved( \l{Model Subclassing Reference}. \sa QAbstractProxyModel, QAbstractItemModel, {Model/View Programming}, - {Basic Sort/Filter Model Example}, {Custom Sort/Filter Model Example} + {Basic Sort/Filter Model Example}, {Custom Sort/Filter Model Example}, QIdentityProxyModel */ /*! diff --git a/tests/auto/gui.pro b/tests/auto/gui.pro index d016f91fea..afa6ad3a55 100644 --- a/tests/auto/gui.pro +++ b/tests/auto/gui.pro @@ -84,6 +84,7 @@ SUBDIRS=\ qheaderview \ qicoimageformat \ qicon \ + qidentityproxymodel \ qimageiohandler \ qimagereader \ qimagewriter \ diff --git a/tests/auto/qidentityproxymodel/qidentityproxymodel.pro b/tests/auto/qidentityproxymodel/qidentityproxymodel.pro new file mode 100644 index 0000000000..f529e20c7f --- /dev/null +++ b/tests/auto/qidentityproxymodel/qidentityproxymodel.pro @@ -0,0 +1,6 @@ +load(qttest_p4) + +INCLUDEPATH += $$PWD/../modeltest + +SOURCES += tst_qidentityproxymodel.cpp ../modeltest/dynamictreemodel.cpp ../modeltest/modeltest.cpp +HEADERS += ../modeltest/dynamictreemodel.h ../modeltest/modeltest.h diff --git a/tests/auto/qidentityproxymodel/tst_qidentityproxymodel.cpp b/tests/auto/qidentityproxymodel/tst_qidentityproxymodel.cpp new file mode 100644 index 0000000000..bbcdb4c0a7 --- /dev/null +++ b/tests/auto/qidentityproxymodel/tst_qidentityproxymodel.cpp @@ -0,0 +1,329 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Klarälvdalens Datakonsult AB, +** a KDAB Group company, info@kdab.com, +** author Stephen Kelly +** All rights reserved. +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** 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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +****************************************************************************/ + + +#include +#include "../../shared/util.h" + +#include +#include + +#include "dynamictreemodel.h" +#include "qidentityproxymodel.h" + +//TESTED CLASS= +//TESTED_FILES= + +Q_DECLARE_METATYPE(QModelIndex) + +class tst_QIdentityProxyModel : public QObject +{ + Q_OBJECT + +public: + + tst_QIdentityProxyModel(); + virtual ~tst_QIdentityProxyModel(); + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void insertRows(); + void removeRows(); + void moveRows(); + void reset(); + +protected: + void verifyIdentity(QAbstractItemModel *model, const QModelIndex &parent = QModelIndex()); + +private: + QStandardItemModel *m_model; + QIdentityProxyModel *m_proxy; +}; + +tst_QIdentityProxyModel::tst_QIdentityProxyModel() + : m_model(0), m_proxy(0) +{ + +} + +tst_QIdentityProxyModel::~tst_QIdentityProxyModel() +{ + +} + +void tst_QIdentityProxyModel::initTestCase() +{ + qRegisterMetaType("QModelIndex"); + + m_model = new QStandardItemModel(0, 1); + m_proxy = new QIdentityProxyModel(); +} + +void tst_QIdentityProxyModel::cleanupTestCase() +{ + delete m_proxy; + delete m_model; +} + +void tst_QIdentityProxyModel::init() +{ +} + +void tst_QIdentityProxyModel::cleanup() +{ + m_model->clear(); + m_model->insertColumns(0, 1); +} + +void tst_QIdentityProxyModel::verifyIdentity(QAbstractItemModel *model, const QModelIndex &parent) +{ + const int rows = model->rowCount(parent); + const int columns = model->columnCount(parent); + const QModelIndex proxyParent = m_proxy->mapFromSource(parent); + + QVERIFY(m_proxy->mapToSource(proxyParent) == parent); + QVERIFY(rows == m_proxy->rowCount(proxyParent)); + QVERIFY(columns == m_proxy->columnCount(proxyParent)); + + for (int row = 0; row < rows; ++row) { + for (int column = 0; column < columns; ++column) { + const QModelIndex idx = model->index(row, column, parent); + const QModelIndex proxyIdx = m_proxy->mapFromSource(idx); + QVERIFY(proxyIdx.model() == m_proxy); + QVERIFY(m_proxy->mapToSource(proxyIdx) == idx); + QVERIFY(proxyIdx.isValid()); + QVERIFY(proxyIdx.row() == row); + QVERIFY(proxyIdx.column() == column); + QVERIFY(proxyIdx.parent() == proxyParent); + QVERIFY(proxyIdx.data() == idx.data()); + QVERIFY(proxyIdx.flags() == idx.flags()); + const int childCount = m_proxy->rowCount(proxyIdx); + const bool hasChildren = m_proxy->hasChildren(proxyIdx); + QVERIFY(model->hasChildren(idx) == hasChildren); + QVERIFY((childCount > 0) == hasChildren); + + if (hasChildren) + verifyIdentity(model, idx); + } + } +} + +/* + tests +*/ + +void tst_QIdentityProxyModel::insertRows() +{ + QStandardItem *parentItem = m_model->invisibleRootItem(); + for (int i = 0; i < 4; ++i) { + QStandardItem *item = new QStandardItem(QString("item %0").arg(i)); + parentItem->appendRow(item); + parentItem = item; + } + + m_proxy->setSourceModel(m_model); + + verifyIdentity(m_model); + + QSignalSpy modelBeforeSpy(m_model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int))); + QSignalSpy modelAfterSpy(m_model, SIGNAL(rowsInserted(QModelIndex,int,int))); + QSignalSpy proxyBeforeSpy(m_proxy, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int))); + QSignalSpy proxyAfterSpy(m_proxy, SIGNAL(rowsInserted(QModelIndex,int,int))); + + QStandardItem *item = new QStandardItem(QString("new item")); + parentItem->appendRow(item); + + QVERIFY(modelBeforeSpy.size() == 1 && 1 == proxyBeforeSpy.size()); + QVERIFY(modelAfterSpy.size() == 1 && 1 == proxyAfterSpy.size()); + + QVERIFY(modelBeforeSpy.first().first().value() == m_proxy->mapToSource(proxyBeforeSpy.first().first().value())); + QVERIFY(modelBeforeSpy.first().at(1) == proxyBeforeSpy.first().at(1)); + QVERIFY(modelBeforeSpy.first().at(2) == proxyBeforeSpy.first().at(2)); + + QVERIFY(modelAfterSpy.first().first().value() == m_proxy->mapToSource(proxyAfterSpy.first().first().value())); + QVERIFY(modelAfterSpy.first().at(1) == proxyAfterSpy.first().at(1)); + QVERIFY(modelAfterSpy.first().at(2) == proxyAfterSpy.first().at(2)); + + verifyIdentity(m_model); + +} + +void tst_QIdentityProxyModel::removeRows() +{ + QStandardItem *parentItem = m_model->invisibleRootItem(); + for (int i = 0; i < 4; ++i) { + QStandardItem *item = new QStandardItem(QString("item %0").arg(i)); + parentItem->appendRow(item); + parentItem = item; + } + + m_proxy->setSourceModel(m_model); + + verifyIdentity(m_model); + + QSignalSpy modelBeforeSpy(m_model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int))); + QSignalSpy modelAfterSpy(m_model, SIGNAL(rowsRemoved(QModelIndex,int,int))); + QSignalSpy proxyBeforeSpy(m_proxy, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int))); + QSignalSpy proxyAfterSpy(m_proxy, SIGNAL(rowsRemoved(QModelIndex,int,int))); + + const QModelIndex topLevel = m_model->index(0, 0, QModelIndex()); + const QModelIndex secondLevel = m_model->index(0, 0, topLevel); + const QModelIndex thirdLevel = m_model->index(0, 0, secondLevel); + + QVERIFY(thirdLevel.isValid()); + + m_model->removeRow(0, secondLevel); + + QVERIFY(modelBeforeSpy.size() == 1 && 1 == proxyBeforeSpy.size()); + QVERIFY(modelAfterSpy.size() == 1 && 1 == proxyAfterSpy.size()); + + QVERIFY(modelBeforeSpy.first().first().value() == m_proxy->mapToSource(proxyBeforeSpy.first().first().value())); + QVERIFY(modelBeforeSpy.first().at(1) == proxyBeforeSpy.first().at(1)); + QVERIFY(modelBeforeSpy.first().at(2) == proxyBeforeSpy.first().at(2)); + + QVERIFY(modelAfterSpy.first().first().value() == m_proxy->mapToSource(proxyAfterSpy.first().first().value())); + QVERIFY(modelAfterSpy.first().at(1) == proxyAfterSpy.first().at(1)); + QVERIFY(modelAfterSpy.first().at(2) == proxyAfterSpy.first().at(2)); + + verifyIdentity(m_model); +} + +void tst_QIdentityProxyModel::moveRows() +{ + DynamicTreeModel model; + + { + ModelInsertCommand insertCommand(&model); + insertCommand.setStartRow(0); + insertCommand.setEndRow(9); + insertCommand.doCommand(); + } + { + ModelInsertCommand insertCommand(&model); + insertCommand.setAncestorRowNumbers(QList() << 5); + insertCommand.setStartRow(0); + insertCommand.setEndRow(9); + insertCommand.doCommand(); + } + + m_proxy->setSourceModel(&model); + + verifyIdentity(&model); + + QSignalSpy modelBeforeSpy(&model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); + QSignalSpy modelAfterSpy(&model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int))); + QSignalSpy proxyBeforeSpy(m_proxy, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); + QSignalSpy proxyAfterSpy(m_proxy, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int))); + + { + ModelMoveCommand moveCommand(&model, 0); + moveCommand.setAncestorRowNumbers(QList() << 5); + moveCommand.setStartRow(3); + moveCommand.setEndRow(4); + moveCommand.setDestRow(1); + moveCommand.doCommand(); + } + + QVERIFY(modelBeforeSpy.size() == 1 && 1 == proxyBeforeSpy.size()); + QVERIFY(modelAfterSpy.size() == 1 && 1 == proxyAfterSpy.size()); + + QVERIFY(modelBeforeSpy.first().first().value() == m_proxy->mapToSource(proxyBeforeSpy.first().first().value())); + QVERIFY(modelBeforeSpy.first().at(1) == proxyBeforeSpy.first().at(1)); + QVERIFY(modelBeforeSpy.first().at(2) == proxyBeforeSpy.first().at(2)); + QVERIFY(modelBeforeSpy.first().at(3).value() == m_proxy->mapToSource(proxyBeforeSpy.first().at(3).value())); + QVERIFY(modelBeforeSpy.first().at(4) == proxyBeforeSpy.first().at(4)); + + QVERIFY(modelAfterSpy.first().first().value() == m_proxy->mapToSource(proxyAfterSpy.first().first().value())); + QVERIFY(modelAfterSpy.first().at(1) == proxyAfterSpy.first().at(1)); + QVERIFY(modelAfterSpy.first().at(2) == proxyAfterSpy.first().at(2)); + QVERIFY(modelAfterSpy.first().at(3).value() == m_proxy->mapToSource(proxyAfterSpy.first().at(3).value())); + QVERIFY(modelAfterSpy.first().at(4) == proxyAfterSpy.first().at(4)); + + verifyIdentity(&model); + + m_proxy->setSourceModel(0); +} + +void tst_QIdentityProxyModel::reset() +{ + DynamicTreeModel model; + + { + ModelInsertCommand insertCommand(&model); + insertCommand.setStartRow(0); + insertCommand.setEndRow(9); + insertCommand.doCommand(); + } + { + ModelInsertCommand insertCommand(&model); + insertCommand.setAncestorRowNumbers(QList() << 5); + insertCommand.setStartRow(0); + insertCommand.setEndRow(9); + insertCommand.doCommand(); + } + + m_proxy->setSourceModel(&model); + + verifyIdentity(&model); + + QSignalSpy modelBeforeSpy(&model, SIGNAL(modelAboutToBeReset())); + QSignalSpy modelAfterSpy(&model, SIGNAL(modelReset())); + QSignalSpy proxyBeforeSpy(m_proxy, SIGNAL(modelAboutToBeReset())); + QSignalSpy proxyAfterSpy(m_proxy, SIGNAL(modelReset())); + + { + ModelResetCommandFixed resetCommand(&model, 0); + resetCommand.setAncestorRowNumbers(QList() << 5); + resetCommand.setStartRow(3); + resetCommand.setEndRow(4); + resetCommand.setDestRow(1); + resetCommand.doCommand(); + } + + QVERIFY(modelBeforeSpy.size() == 1 && 1 == proxyBeforeSpy.size()); + QVERIFY(modelAfterSpy.size() == 1 && 1 == proxyAfterSpy.size()); + + verifyIdentity(&model); + m_proxy->setSourceModel(0); +} + +QTEST_MAIN(tst_QIdentityProxyModel) +#include "tst_qidentityproxymodel.moc" From e40443f7dfaa77e1295390385ef76f9b4e87c59b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 11 May 2011 17:34:12 +0200 Subject: [PATCH 26/27] Prevent crash in OpenGL engine when scaling images / pixmaps. Make sure the resulting image / pixmap is valid if the source was valid. Task-number: QTBUG-19157 Reviewed-by: Kim Reviewed-by: Benjamin Poulain (cherry picked from commit 1c5da7207a21cc44a4a08d291c290ffcd9b958fd) --- src/gui/image/qimage.cpp | 2 ++ src/gui/image/qpixmap.cpp | 2 ++ tests/auto/qimage/tst_qimage.cpp | 8 ++++++++ tests/auto/qpixmap/tst_qpixmap.cpp | 8 ++++++++ 4 files changed, 20 insertions(+) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 50b372ea63..25f6295b71 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -4449,6 +4449,8 @@ QImage QImage::scaled(const QSize& s, Qt::AspectRatioMode aspectMode, Qt::Transf QSize newSize = size(); newSize.scale(s, aspectMode); + newSize.rwidth() = qMax(newSize.width(), 1); + newSize.rheight() = qMax(newSize.height(), 1); if (newSize == size()) return *this; diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index c34f6ac1b2..640864d7dc 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -1514,6 +1514,8 @@ QPixmap QPixmap::scaled(const QSize& s, Qt::AspectRatioMode aspectMode, Qt::Tran QSize newSize = size(); newSize.scale(s, aspectMode); + newSize.rwidth() = qMax(newSize.width(), 1); + newSize.rheight() = qMax(newSize.height(), 1); if (newSize == size()) return *this; diff --git a/tests/auto/qimage/tst_qimage.cpp b/tests/auto/qimage/tst_qimage.cpp index c5ded0d158..ad85bf5cce 100644 --- a/tests/auto/qimage/tst_qimage.cpp +++ b/tests/auto/qimage/tst_qimage.cpp @@ -151,6 +151,7 @@ private slots: void rgbSwapped(); void deepCopyWhenPaintingActive(); + void scaled_QTBUG19157(); }; tst_QImage::tst_QImage() @@ -2029,5 +2030,12 @@ void tst_QImage::deepCopyWhenPaintingActive() QVERIFY(copy != image); } +void tst_QImage::scaled_QTBUG19157() +{ + QImage foo(5000, 1, QImage::Format_RGB32); + foo = foo.scaled(1024, 1024, Qt::KeepAspectRatio); + QVERIFY(!foo.isNull()); +} + QTEST_MAIN(tst_QImage) #include "tst_qimage.moc" diff --git a/tests/auto/qpixmap/tst_qpixmap.cpp b/tests/auto/qpixmap/tst_qpixmap.cpp index 4ba51de7e5..1f1ee88b23 100644 --- a/tests/auto/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/qpixmap/tst_qpixmap.cpp @@ -196,6 +196,7 @@ private slots: #if defined(Q_OS_SYMBIAN) && !defined(QT_NO_OPENVG) void vgImageReadBack(); #endif + void scaled_QTBUG19157(); }; static bool lenientCompare(const QPixmap &actual, const QPixmap &expected) @@ -1897,5 +1898,12 @@ void tst_QPixmap::vgImageReadBack() } #endif // Symbian & OpenVG +void tst_QPixmap::scaled_QTBUG19157() +{ + QPixmap foo(5000, 1); + foo = foo.scaled(1024, 1024, Qt::KeepAspectRatio); + QVERIFY(!foo.isNull()); +} + QTEST_MAIN(tst_QPixmap) #include "tst_qpixmap.moc" From 1f806aa1b40db276dad359863d018171080d93f9 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 14 Apr 2011 21:38:45 +0200 Subject: [PATCH 27/27] New algorithm for drawing thin lines Added a new QCosmeticStroker class for drawing thin lines. The class can handle both aliased and antialiased lines. The code replaces all the midpoint line drawing algorithms in the raster paintengine and gives correct subpixel positioning for lines. It gives around 30% to 50% speedup against the midpoint algorithm. If we missed that fast path, the speedup is around between a factor of 6 to 8 for lines and aliased paths and 100 and 400 for antialiased paths. Reviewed-by: Kim (cherry picked from commit 37c329a3e35fabc88fbcad824a69f37c671d2132) --- src/gui/painting/painting.pri | 4 +- src/gui/painting/qcosmeticstroker.cpp | 954 ++++++++++++++ src/gui/painting/qcosmeticstroker_p.h | 101 ++ src/gui/painting/qpaintengine_raster.cpp | 1524 ++-------------------- src/gui/painting/qpaintengine_raster_p.h | 5 - src/gui/painting/qpaintengineex.cpp | 2 +- 6 files changed, 1139 insertions(+), 1451 deletions(-) create mode 100644 src/gui/painting/qcosmeticstroker.cpp create mode 100644 src/gui/painting/qcosmeticstroker_p.h diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index 65e7af4742..13a9ba1c73 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -6,6 +6,7 @@ HEADERS += \ painting/qcolor.h \ painting/qcolor_p.h \ painting/qcolormap.h \ + painting/qcosmeticstroker_p.h \ painting/qdrawutil.h \ painting/qemulationpaintengine_p.h \ painting/qgraphicssystem_p.h \ @@ -14,7 +15,7 @@ HEADERS += \ painting/qoutlinemapper_p.h \ painting/qpaintdevice.h \ painting/qpaintengine.h \ - painting/qpaintengine_p.h \ + painting/qpaintengine_p.h \ painting/qpaintengine_alpha_p.h \ painting/qpaintengine_preview_p.h \ painting/qpaintengineex_p.h \ @@ -53,6 +54,7 @@ SOURCES += \ painting/qbrush.cpp \ painting/qcolor.cpp \ painting/qcolor_p.cpp \ + painting/qcosmeticstroker.cpp \ painting/qcssutil.cpp \ painting/qdrawutil.cpp \ painting/qemulationpaintengine.cpp \ diff --git a/src/gui/painting/qcosmeticstroker.cpp b/src/gui/painting/qcosmeticstroker.cpp new file mode 100644 index 0000000000..498b1546e2 --- /dev/null +++ b/src/gui/painting/qcosmeticstroker.cpp @@ -0,0 +1,954 @@ +#include "qcosmeticstroker_p.h" +#include "private/qpainterpath_p.h" +#include +#include + +#if 0 +inline QString capString(int caps) +{ + QString str; + if (caps & QCosmeticStroker::CapBegin) { + str += "CapBegin "; + } + if (caps & QCosmeticStroker::CapEnd) { + str += "CapEnd "; + } + return str; +} +#endif + +#define toF26Dot6(x) ((int)((x)*64.)) + +static inline uint sourceOver(uint d, uint color) +{ + return color + BYTE_MUL(d, qAlpha(~color)); +} + +inline static int F16Dot16FixedDiv(int x, int y) +{ + if (qAbs(x) > 0x7fff) + return (((qlonglong)x) << 16) / y; + return (x << 16) / y; +} + +typedef void (*DrawPixel)(QCosmeticStroker *stroker, int x, int y, int coverage); + +namespace { + +struct Dasher { + QCosmeticStroker *stroker; + int *pattern; + int offset; + int dashIndex; + int dashOn; + + Dasher(QCosmeticStroker *s, bool reverse, int start, int stop) + : stroker(s) + { + int delta = stop - start; + if (reverse) { + pattern = stroker->reversePattern; + offset = stroker->patternLength - stroker->patternOffset - delta - ((start & 63) - 32); + dashOn = 0; + } else { + pattern = stroker->pattern; + offset = stroker->patternOffset - ((start & 63) - 32); + dashOn = 1; + } + offset %= stroker->patternLength; + if (offset < 0) + offset += stroker->patternLength; + + dashIndex = 0; + while (offset>= pattern[dashIndex]) + ++dashIndex; + +// qDebug() << " dasher" << offset/64. << reverse << dashIndex; + stroker->patternOffset += delta; + stroker->patternOffset %= stroker->patternLength; + } + + bool on() const { + return (dashIndex + dashOn) & 1; + } + void adjust() { + offset += 64; + if (offset >= pattern[dashIndex]) { + ++dashIndex; + dashIndex %= stroker->patternSize; + } + offset %= stroker->patternLength; +// qDebug() << "dasher.adjust" << offset/64. << dashIndex; + } +}; + +struct NoDasher { + NoDasher(QCosmeticStroker *, bool, int, int) {} + bool on() const { return true; } + void adjust(int = 0) {} +}; + +}; + +template +static void drawLine(QCosmeticStroker *stroker, qreal x1, qreal y1, qreal x2, qreal y2, int caps); +template +static void drawLineAA(QCosmeticStroker *stroker, qreal x1, qreal y1, qreal x2, qreal y2, int caps); + +inline void drawPixel(QCosmeticStroker *stroker, int x, int y, int coverage) +{ + int lastx = stroker->spans[stroker->current_span-1].x + stroker->spans[stroker->current_span-1].len ; + int lasty = stroker->spans[stroker->current_span-1].y; + + if (stroker->current_span == QCosmeticStroker::NSPANS || y < lasty || (y == lasty && x < lastx)) { + stroker->blend(stroker->current_span, stroker->spans, &stroker->state->penData); + stroker->current_span = 0; + } + + stroker->spans[stroker->current_span].x = ushort(x); + stroker->spans[stroker->current_span].len = 1; + stroker->spans[stroker->current_span].y = y; + stroker->spans[stroker->current_span].coverage = coverage*stroker->opacity >> 8; + ++stroker->current_span; +} + +inline void drawPixelARGB32(QCosmeticStroker *stroker, int x, int y, int coverage) +{ + const QRect &cl = stroker->clip; + if (x < cl.x() || x > cl.right() || y < cl.y() || y > cl.bottom()) + return; + + int offset = x + stroker->ppl*y; + uint c = BYTE_MUL(stroker->color, coverage); + stroker->pixels[offset] = sourceOver(stroker->pixels[offset], c); +} + +inline void drawPixelARGB32Opaque(QCosmeticStroker *stroker, int x, int y, int) +{ + const QRect &cl = stroker->clip; + if (x < cl.x() || x > cl.right() || y < cl.y() || y > cl.bottom()) + return; + + int offset = x + stroker->ppl*y; + stroker->pixels[offset] = sourceOver(stroker->pixels[offset], stroker->color); +} + +enum StrokeSelection { + Aliased = 0, + AntiAliased = 1, + Solid = 0, + Dashed = 2, + RegularDraw = 0, + FastDraw = 4 +}; + +static StrokeLine strokeLine(int strokeSelection) +{ + StrokeLine stroke; + + switch (strokeSelection) { + case Aliased|Solid|RegularDraw: + stroke = &::drawLine; + break; + case Aliased|Solid|FastDraw: + stroke = &::drawLine; + break; + case Aliased|Dashed|RegularDraw: + stroke = &::drawLine; + break; + case Aliased|Dashed|FastDraw: + stroke = &::drawLine; + break; + case AntiAliased|Solid|RegularDraw: + stroke = &drawLineAA; + break; + case AntiAliased|Solid|FastDraw: + stroke = &drawLineAA; + break; + case AntiAliased|Dashed|RegularDraw: + stroke = &drawLineAA; + break; + case AntiAliased|Dashed|FastDraw: + stroke = &drawLineAA; + break; + default: + Q_ASSERT(false); + stroke = 0; + } + return stroke; +} + +void QCosmeticStroker::setup() +{ + blend = state->penData.blend; + if (state->clip && state->clip->enabled && state->clip->hasRectClip && !state->clip->clipRect.isEmpty()) { + clip &= state->clip->clipRect; + blend = state->penData.unclipped_blend; + } + + int strokeSelection = 0; + if (blend == state->penData.unclipped_blend + && state->penData.type == QSpanData::Solid + && (state->penData.rasterBuffer->format == QImage::Format_ARGB32_Premultiplied + || state->penData.rasterBuffer->format == QImage::Format_RGB32) + && state->compositionMode() == QPainter::CompositionMode_SourceOver) + strokeSelection |= FastDraw; + + if (state->renderHints & QPainter::Antialiasing) + strokeSelection |= AntiAliased; + + const QVector &penPattern = state->lastPen.dashPattern(); + if (penPattern.isEmpty()) { + Q_ASSERT(!pattern && !reversePattern); + pattern = 0; + reversePattern = 0; + patternLength = 0; + patternSize = 0; + } else { + pattern = (int *)malloc(penPattern.size()*sizeof(int)); + reversePattern = (int *)malloc(penPattern.size()*sizeof(int)); + patternSize = penPattern.size(); + + patternLength = 0; + for (int i = 0; i < patternSize; ++i) { + patternLength += (int) qMax(1. , penPattern.at(i)*64.); + pattern[i] = patternLength; + } + patternLength = 0; + for (int i = 0; i < patternSize; ++i) { + patternLength += (int) qMax(1., penPattern.at(patternSize - 1 - i)*64.); + reversePattern[i] = patternLength; + } + strokeSelection |= Dashed; +// qDebug() << "setup: size=" << patternSize << "length=" << patternLength/64.; + } + + stroke = strokeLine(strokeSelection); + + qreal width = state->lastPen.widthF(); + if (width == 0) + opacity = 256; + else if (state->lastPen.isCosmetic()) + opacity = (int) 256*width; + else + opacity = (int) 256*width*state->txscale; + opacity = qBound(0, opacity, 256); + + drawCaps = state->lastPen.capStyle() != Qt::FlatCap; + + if (strokeSelection & FastDraw) { + color = INTERPOLATE_PIXEL_256(state->penData.solid.color, opacity, 0, 0); + QRasterBuffer *buffer = state->penData.rasterBuffer; + pixels = (uint *)buffer->buffer(); + ppl = buffer->bytesPerLine()>>2; + } + + // setup FP clip bounds + xmin = clip.left() - 1; + xmax = clip.right() + 2; + ymin = clip.top() - 1; + ymax = clip.bottom() + 2; + + lastPixel.x = -1; +} + +// returns true if the whole line gets clipped away +bool QCosmeticStroker::clipLine(qreal &x1, qreal &y1, qreal &x2, qreal &y2) +{ + // basic/rough clipping is done in floating point coordinates to avoid + // integer overflow problems. + if (x1 < xmin) { + if (x2 <= xmin) + goto clipped; + y1 += (y2 - y1)/(x2 - x1) * (xmin - x1); + x1 = xmin; + } else if (x1 > xmax) { + if (x2 >= xmax) + goto clipped; + y1 += (y2 - y1)/(x2 - x1) * (xmax - x1); + x1 = xmax; + } + if (x2 < xmin) { + lastPixel.x = -1; + y2 += (y2 - y1)/(x2 - x1) * (xmin - x2); + x2 = xmin; + } else if (x2 > xmax) { + lastPixel.x = -1; + y2 += (y2 - y1)/(x2 - x1) * (xmax - x2); + x2 = xmax; + } + + if (y1 < ymin) { + if (y2 <= ymin) + goto clipped; + x1 += (x2 - x1)/(y2 - y1) * (ymin - y1); + y1 = ymin; + } else if (y1 > ymax) { + if (y2 >= ymax) + goto clipped; + x1 += (x2 - x1)/(y2 - y1) * (ymax - y1); + y1 = ymax; + } + if (y2 < ymin) { + lastPixel.x = -1; + x2 += (x2 - x1)/(y2 - y1) * (ymin - y2); + y2 = ymin; + } else if (y2 > ymax) { + lastPixel.x = -1; + x2 += (x2 - x1)/(y2 - y1) * (ymax - y2); + y2 = ymax; + } + + return false; + + clipped: + lastPixel.x = -1; + return true; +} + + +void QCosmeticStroker::drawLine(const QPointF &p1, const QPointF &p2) +{ + QPointF start = p1 * state->matrix; + QPointF end = p2 * state->matrix; + + patternOffset = state->lastPen.dashOffset()*64; + lastPixel.x = -1; + + stroke(this, start.x(), start.y(), end.x(), end.y(), drawCaps ? CapBegin|CapEnd : 0); + + blend(current_span, spans, &state->penData); + current_span = 0; +} + +void QCosmeticStroker::drawPoints(const QPoint *points, int num) +{ + const QPoint *end = points + num; + while (points < end) { + QPointF p = QPointF(*points) * state->matrix; + drawPixel(this, qRound(p.x()), qRound(p.y()), 255); + ++points; + } + + blend(current_span, spans, &state->penData); + current_span = 0; +} + +void QCosmeticStroker::drawPoints(const QPointF *points, int num) +{ + const QPointF *end = points + num; + while (points < end) { + QPointF p = (*points) * state->matrix; + drawPixel(this, qRound(p.x()), qRound(p.y()), 255); + ++points; + } + + blend(current_span, spans, &state->penData); + current_span = 0; +} + +void QCosmeticStroker::calculateLastPoint(qreal rx1, qreal ry1, qreal rx2, qreal ry2) +{ + // this is basically the same code as used in the aliased stroke method, + // but it only determines the direction and last point of a line + // + // This is being used to have proper dropout control for closed contours + // by calculating the direction and last pixel of the last segment in the contour. + // the info is then used to perform dropout control when drawing the first line segment + // of the contour + lastPixel.x = -1; + lastPixel.y = -1; + + if (clipLine(rx1, ry1, rx2, ry2)) + return; + + int x1 = toF26Dot6(rx1); + int y1 = toF26Dot6(ry1); + int x2 = toF26Dot6(rx2); + int y2 = toF26Dot6(ry2); + + int dx = qAbs(x2 - x1); + int dy = qAbs(y2 - y1); + + if (dx < dy) { + // vertical + bool swapped = false; + if (y1 > y2) { + swapped = true; + qSwap(y1, y2); + qSwap(x1, x2); + } + int xinc = F16Dot16FixedDiv(x2 - x1, y2 - y1); + int x = x1 << 10; + + int y = (y1+32) >> 6; + int ys = (y2+32) >> 6; + + if (y != ys) { + x += ( ((((y << 6) + 32 - y1))) * xinc ) >> 6; + + if (swapped) { + lastPixel.x = x >> 16; + lastPixel.y = y; + lastDir = QCosmeticStroker::BottomToTop; + } else { + lastPixel.x = (x + (ys - y - 1)*xinc) >> 16; + lastPixel.y = ys - 1; + lastDir = QCosmeticStroker::TopToBottom; + } + lastAxisAligned = qAbs(xinc) < (1 << 14); + } + } else { + // horizontal + if (!dx) + return; + + bool swapped = false; + if (x1 > x2) { + swapped = true; + qSwap(x1, x2); + qSwap(y1, y2); + } + int yinc = F16Dot16FixedDiv(y2 - y1, x2 - x1); + int y = y1 << 10; + + int x = (x1+32) >> 6; + int xs = (x2+32) >> 6; + + if (x != xs) { + y += ( ((((x << 6) + 32 - x1))) * yinc ) >> 6; + + if (swapped) { + lastPixel.x = x; + lastPixel.y = y >> 16; + lastDir = QCosmeticStroker::RightToLeft; + } else { + lastPixel.x = xs - 1; + lastPixel.y = (y + (xs - x - 1)*yinc) >> 16; + lastDir = QCosmeticStroker::LeftToRight; + } + lastAxisAligned = qAbs(yinc) < (1 << 14); + } + } +// qDebug() << " moveTo: setting last pixel to x/y dir" << lastPixel.x << lastPixel.y << lastDir; +} + +static inline const QPainterPath::ElementType *subPath(const QPainterPath::ElementType *t, const QPainterPath::ElementType *end, + const qreal *points, bool *closed) +{ + const QPainterPath::ElementType *start = t; + ++t; + + // find out if the subpath is closed + while (t < end) { + if (*t == QPainterPath::MoveToElement) + break; + ++t; + } + + int offset = t - start - 1; +// qDebug() << "subpath" << offset << points[0] << points[1] << points[2*offset] << points[2*offset+1]; + *closed = (points[0] == points[2*offset] && points[1] == points[2*offset + 1]); + + return t; +} + +void QCosmeticStroker::drawPath(const QVectorPath &path) +{ +// qDebug() << ">>>> drawpath" << path.convertToPainterPath() +// << "antialiasing:" << (bool)(state->renderHints & QPainter::Antialiasing) << " implicit close:" << path.hasImplicitClose(); + if (path.isEmpty()) + return; + + const qreal *points = path.points(); + const QPainterPath::ElementType *type = path.elements(); + + if (type) { + const QPainterPath::ElementType *end = type + path.elementCount(); + + while (type < end) { + Q_ASSERT(type == path.elements() || *type == QPainterPath::MoveToElement); + + QPointF p = QPointF(points[0], points[1]) * state->matrix; + QPointF movedTo = p; + patternOffset = state->lastPen.dashOffset()*64; + lastPixel.x = -1; + + bool closed; + const QPainterPath::ElementType *e = subPath(type, end, points, &closed); + if (closed) { + const qreal *p = points + 2*(e-type); + calculateLastPoint(p[-4], p[-3], p[-2], p[-1]); + } + int caps = (!closed & drawCaps) ? CapBegin : NoCaps; +// qDebug() << "closed =" << closed << capString(caps); + + points += 2; + ++type; + + while (type < e) { + QPointF p2 = QPointF(points[0], points[1]) * state->matrix; + switch (*type) { + case QPainterPath::MoveToElement: + Q_ASSERT(!"Logic error"); + break; + + case QPainterPath::LineToElement: + if (!closed && drawCaps && type == e - 1) + caps |= CapEnd; + stroke(this, p.x(), p.y(), p2.x(), p2.y(), caps); + p = p2; + points += 2; + ++type; + break; + + case QPainterPath::CurveToElement: { + if (!closed && drawCaps && type == e - 3) + caps |= CapEnd; + QPointF p3 = QPointF(points[2], points[3]) * state->matrix; + QPointF p4 = QPointF(points[4], points[5]) * state->matrix; + renderCubic(p, p2, p3, p4, caps); + p = p4; + type += 3; + points += 6; + break; + } + case QPainterPath::CurveToDataElement: + Q_ASSERT(!"QPainterPath::toSubpathPolygons(), bad element type"); + break; + } + caps = NoCaps; + } + } + } else { // !type, simple polygon + QPointF p = QPointF(points[0], points[1]) * state->matrix; + QPointF movedTo = p; + patternOffset = state->lastPen.dashOffset()*64; + lastPixel.x = -1; + + const qreal *end = points + 2*path.elementCount(); + // handle closed path case + bool closed = path.hasImplicitClose() || (points[0] == end[-2] && points[1] == end[-1]); + int caps = (!closed & drawCaps) ? CapBegin : NoCaps; + if (closed) + calculateLastPoint(end[-2], end[-1], points[0], points[1]); + + points += 2; + while (points < end) { + QPointF p2 = QPointF(points[0], points[1]) * state->matrix; + + if (!closed && drawCaps && points == end - 2) + caps |= CapEnd; + + stroke(this, p.x(), p.y(), p2.x(), p2.y(), caps); + + p = p2; + points += 2; + caps = NoCaps; + } + if (path.hasImplicitClose()) + stroke(this, p.x(), p.y(), movedTo.x(), movedTo.y(), NoCaps); + } + + + blend(current_span, spans, &state->penData); + current_span = 0; +} + +void QCosmeticStroker::renderCubic(const QPointF &p1, const QPointF &p2, const QPointF &p3, const QPointF &p4, int caps) +{ +// qDebug() << ">>>> renderCubic" << p1 << p2 << p3 << p4 << capString(caps); + const int maxSubDivisions = 6; + PointF points[3*maxSubDivisions + 4]; + + points[3].x = p1.x(); + points[3].y = p1.y(); + points[2].x = p2.x(); + points[2].y = p2.y(); + points[1].x = p3.x(); + points[1].y = p3.y(); + points[0].x = p4.x(); + points[0].y = p4.y(); + + PointF *p = points; + int level = maxSubDivisions; + + renderCubicSubdivision(p, level, caps); +} + +static void splitCubic(QCosmeticStroker::PointF *points) +{ + const qreal half = .5; + qreal a, b, c, d; + + points[6].x = points[3].x; + c = points[1].x; + d = points[2].x; + points[1].x = a = ( points[0].x + c ) * half; + points[5].x = b = ( points[3].x + d ) * half; + c = ( c + d ) * half; + points[2].x = a = ( a + c ) * half; + points[4].x = b = ( b + c ) * half; + points[3].x = ( a + b ) * half; + + points[6].y = points[3].y; + c = points[1].y; + d = points[2].y; + points[1].y = a = ( points[0].y + c ) * half; + points[5].y = b = ( points[3].y + d ) * half; + c = ( c + d ) * half; + points[2].y = a = ( a + c ) * half; + points[4].y = b = ( b + c ) * half; + points[3].y = ( a + b ) * half; +} + +void QCosmeticStroker::renderCubicSubdivision(QCosmeticStroker::PointF *points, int level, int caps) +{ + if (level) { + qreal dx = points[3].x - points[0].x; + qreal dy = points[3].y - points[0].y; + qreal len = ((qreal).25) * (qAbs(dx) + qAbs(dy)); + + if (qAbs(dx * (points[0].y - points[2].y) - dy * (points[0].x - points[2].x)) > len || + qAbs(dx * (points[0].y - points[1].y) - dy * (points[0].x - points[1].x)) > len) { + splitCubic(points); + + --level; + renderCubicSubdivision(points + 3, level, caps & CapBegin); + renderCubicSubdivision(points, level, caps & CapEnd); + return; + } + } + + stroke(this, points[3].x, points[3].y, points[0].x, points[0].y, caps); +} + +static inline int swapCaps(int caps) +{ + return ((caps & QCosmeticStroker::CapBegin) << 1) | + ((caps & QCosmeticStroker::CapEnd) >> 1); +} + +// adjust line by half a pixel +static inline void capAdjust(int caps, int &x1, int &x2, int &y, int yinc) +{ + if (caps & QCosmeticStroker::CapBegin) { + x1 -= 32; + y -= yinc >> 1; + } + if (caps & QCosmeticStroker::CapEnd) { + x2 += 32; + } +} + +/* + The hard part about this is dropout control and avoiding douple drawing of points when + the drawing shifts from horizontal to vertical or back. + */ +template +static void drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2, qreal ry2, int caps) +{ + if (stroker->clipLine(rx1, ry1, rx2, ry2)) + return; + + static const int half = 32; + int x1 = toF26Dot6(rx1) + half; + int y1 = toF26Dot6(ry1) + half; + int x2 = toF26Dot6(rx2) + half; + int y2 = toF26Dot6(ry2) + half; + + int dx = qAbs(x2 - x1); + int dy = qAbs(y2 - y1); + + QCosmeticStroker::Point last = stroker->lastPixel; + +// qDebug() << "stroke" << x1/64. << y1/64. << x2/64. << y2/64. << capString(caps); + + if (dx < dy) { + // vertical + + bool swapped = false; + if (y1 > y2) { + swapped = true; + qSwap(y1, y2); + qSwap(x1, x2); + caps = swapCaps(caps); + --x1; --x2; --y1; --y2; + } + int xinc = F16Dot16FixedDiv(x2 - x1, y2 - y1); + int x = x1 << 10; + + capAdjust(caps, y1, y2, x, xinc); + + int y = (y1+32) >> 6; + int ys = (y2+32) >> 6; + + if (y != ys) { + x += ( ((((y << 6) + 32 - y1))) * xinc ) >> 6; + + // calculate first and last pixel and perform dropout control + QCosmeticStroker::Direction dir = QCosmeticStroker::TopToBottom; + QCosmeticStroker::Point first; + first.x = x >> 16; + first.y = y; + last.x = (x + (ys - y - 1)*xinc) >> 16; + last.y = ys - 1; + if (swapped) { + qSwap(first, last); + dir = QCosmeticStroker::BottomToTop; + } + bool axisAligned = qAbs(xinc) < (1 << 14); + if (stroker->lastPixel.x >= 0) { + if (first.x == stroker->lastPixel.x && + first.y == stroker->lastPixel.y) { + // remove duplicated pixel + if (swapped) { + --ys; + } else { + ++y; + x += xinc; + } + } else if (stroker->lastDir != dir && + (((axisAligned && stroker->lastAxisAligned) && + stroker->lastPixel.x != first.x && stroker->lastPixel.y != first.y) || + (qAbs(stroker->lastPixel.x - first.x) > 1 && + qAbs(stroker->lastPixel.y - first.y) > 1))) { + // have a missing pixel, insert it + if (swapped) { + ++ys; + } else { + --y; + x -= xinc; + } + } + } + stroker->lastDir = dir; + stroker->lastAxisAligned = axisAligned; + + Dasher dasher(stroker, swapped, y << 6, ys << 6); + + do { + if (dasher.on()) + drawPixel(stroker, x >> 16, y, 255); + dasher.adjust(); + x += xinc; + } while (++y < ys); + } + } else { + // horizontal + if (!dx) + return; + + bool swapped = false; + if (x1 > x2) { + swapped = true; + qSwap(x1, x2); + qSwap(y1, y2); + caps = swapCaps(caps); + --x1; --x2; --y1; --y2; + } + int yinc = F16Dot16FixedDiv(y2 - y1, x2 - x1); + int y = y1 << 10; + + capAdjust(caps, x1, x2, y, yinc); + + int x = (x1+32) >> 6; + int xs = (x2+32) >> 6; + + + if (x != xs) { + y += ( ((((x << 6) + 32 - x1))) * yinc ) >> 6; + + // calculate first and last pixel to perform dropout control + QCosmeticStroker::Direction dir = QCosmeticStroker::LeftToRight; + QCosmeticStroker::Point first; + first.x = x; + first.y = y >> 16; + last.x = xs - 1; + last.y = (y + (xs - x - 1)*yinc) >> 16; + if (swapped) { + qSwap(first, last); + dir = QCosmeticStroker::RightToLeft; + } + bool axisAligned = qAbs(yinc) < (1 << 14); + if (stroker->lastPixel.x >= 0) { + if (first.x == stroker->lastPixel.x && first.y == stroker->lastPixel.y) { + // remove duplicated pixel + if (swapped) { + --xs; + } else { + ++x; + y += yinc; + } + } else if (stroker->lastDir != dir && + (((axisAligned && stroker->lastAxisAligned) && + stroker->lastPixel.x != first.x && stroker->lastPixel.y != first.y) || + (qAbs(stroker->lastPixel.x - first.x) > 1 && + qAbs(stroker->lastPixel.y - first.y) > 1))) { + // have a missing pixel, insert it + if (swapped) { + ++xs; + } else { + --x; + y -= yinc; + } + } + } + stroker->lastDir = dir; + stroker->lastAxisAligned = axisAligned; + + Dasher dasher(stroker, swapped, x << 6, xs << 6); + + do { + if (dasher.on()) + drawPixel(stroker, x, y >> 16, 255); + dasher.adjust(); + y += yinc; + } while (++x < xs); + } + } + stroker->lastPixel = last; +} + + +template +static void drawLineAA(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2, qreal ry2, int caps) +{ + if (stroker->clipLine(rx1, ry1, rx2, ry2)) + return; + + int x1 = toF26Dot6(rx1); + int y1 = toF26Dot6(ry1); + int x2 = toF26Dot6(rx2); + int y2 = toF26Dot6(ry2); + + int dx = x2 - x1; + int dy = y2 - y1; + + if (qAbs(dx) < qAbs(dy)) { + // vertical + + int xinc = F16Dot16FixedDiv(dx, dy); + + bool swapped = false; + if (y1 > y2) { + qSwap(y1, y2); + qSwap(x1, x2); + swapped = true; + caps = swapCaps(caps); + } + + int x = (x1 - 32) << 10; + x -= ( ((y1 & 63) - 32) * xinc ) >> 6; + + capAdjust(caps, y1, y2, x, xinc); + + Dasher dasher(stroker, swapped, y1, y2); + + int y = y1 >> 6; + int ys = y2 >> 6; + + int alphaStart, alphaEnd; + if (y == ys) { + alphaStart = y2 - y1; + Q_ASSERT(alphaStart >= 0 && alphaStart < 64); + alphaEnd = 0; + } else { + alphaStart = 64 - (y1 & 63); + alphaEnd = (y2 & 63); + } +// qDebug() << "vertical" << x1/64. << y1/64. << x2/64. << y2/64.; +// qDebug() << " x=" << x << "dx=" << dx << "xi=" << (x>>16) << "xsi=" << ((x+(ys-y)*dx)>>16) << "y=" << y << "ys=" << ys; + + // draw first pixel + if (dasher.on()) { + uint alpha = (quint8)(x >> 8); + drawPixel(stroker, x>>16, y, (255-alpha) * alphaStart >> 6); + drawPixel(stroker, (x>>16) + 1, y, alpha * alphaStart >> 6); + } + dasher.adjust(); + x += xinc; + ++y; + if (y < ys) { + do { + if (dasher.on()) { + uint alpha = (quint8)(x >> 8); + drawPixel(stroker, x>>16, y, (255-alpha)); + drawPixel(stroker, (x>>16) + 1, y, alpha); + } + dasher.adjust(); + x += xinc; + } while (++y < ys); + } + // draw last pixel + if (alphaEnd && dasher.on()) { + uint alpha = (quint8)(x >> 8); + drawPixel(stroker, x>>16, y, (255-alpha) * alphaEnd >> 6); + drawPixel(stroker, (x>>16) + 1, y, alpha * alphaEnd >> 6); + } + } else { + // horizontal + if (!dx) + return; + + int yinc = F16Dot16FixedDiv(dy, dx); + + bool swapped = false; + if (x1 > x2) { + qSwap(x1, x2); + qSwap(y1, y2); + swapped = true; + caps = swapCaps(caps); + } + + int y = (y1 - 32) << 10; + y -= ( ((x1 & 63) - 32) * yinc ) >> 6; + + capAdjust(caps, x1, x2, y, yinc); + + Dasher dasher(stroker, swapped, x1, x2); + + int x = x1 >> 6; + int xs = x2 >> 6; + +// qDebug() << "horizontal" << x1/64. << y1/64. << x2/64. << y2/64.; +// qDebug() << " y=" << y << "dy=" << dy << "x=" << x << "xs=" << xs << "yi=" << (y>>16) << "ysi=" << ((y+(xs-x)*dy)>>16); + int alphaStart, alphaEnd; + if (x == xs) { + alphaStart = x2 - x1; + Q_ASSERT(alphaStart >= 0 && alphaStart < 64); + alphaEnd = 0; + } else { + alphaStart = 64 - (x1 & 63); + alphaEnd = (x2 & 63); + } + + // draw first pixel + if (dasher.on()) { + uint alpha = (quint8)(y >> 8); + drawPixel(stroker, x, y>>16, (255-alpha) * alphaStart >> 6); + drawPixel(stroker, x, (y>>16) + 1, alpha * alphaStart >> 6); + } + dasher.adjust(); + y += yinc; + ++x; + // draw line + if (x < xs) { + do { + if (dasher.on()) { + uint alpha = (quint8)(y >> 8); + drawPixel(stroker, x, y>>16, (255-alpha)); + drawPixel(stroker, x, (y>>16) + 1, alpha); + } + dasher.adjust(); + y += yinc; + } while (++x < xs); + } + // draw last pixel + if (alphaEnd && dasher.on()) { + uint alpha = (quint8)(y >> 8); + drawPixel(stroker, x, y>>16, (255-alpha) * alphaEnd >> 6); + drawPixel(stroker, x, (y>>16) + 1, alpha * alphaEnd >> 6); + } + } +} diff --git a/src/gui/painting/qcosmeticstroker_p.h b/src/gui/painting/qcosmeticstroker_p.h new file mode 100644 index 0000000000..bc6dd76829 --- /dev/null +++ b/src/gui/painting/qcosmeticstroker_p.h @@ -0,0 +1,101 @@ +#ifndef QCOSMETICSTROKER_P_H +#define QCOSMETICSTROKER_P_H + +#include +#include +#include +#include + +class QCosmeticStroker; + + +typedef void (*StrokeLine)(QCosmeticStroker *stroker, qreal x1, qreal y1, qreal x2, qreal y2, int caps); + +class QCosmeticStroker +{ +public: + struct Point { + int x; + int y; + }; + struct PointF { + qreal x; + qreal y; + }; + + enum Caps { + NoCaps = 0, + CapBegin = 0x1, + CapEnd = 0x2, + }; + + // used to avoid drop outs or duplicated points + enum Direction { + TopToBottom, + BottomToTop, + LeftToRight, + RightToLeft + }; + + QCosmeticStroker(QRasterPaintEngineState *s, const QRect &dr) + : state(s), + clip(dr), + pattern(0), + reversePattern(0), + patternSize(0), + patternLength(0), + patternOffset(0), + current_span(0), + lastDir(LeftToRight), + lastAxisAligned(false) + { setup(); } + ~QCosmeticStroker() { free(pattern); free(reversePattern); } + void drawLine(const QPointF &p1, const QPointF &p2); + void drawPath(const QVectorPath &path); + void drawPoints(const QPoint *points, int num); + void drawPoints(const QPointF *points, int num); + + + QRasterPaintEngineState *state; + QRect clip; + // clip bounds in real + qreal xmin, xmax; + qreal ymin, ymax; + + StrokeLine stroke; + bool drawCaps; + + int *pattern; + int *reversePattern; + int patternSize; + int patternLength; + int patternOffset; + + enum { NSPANS = 255 }; + QT_FT_Span spans[NSPANS]; + int current_span; + ProcessSpans blend; + + int opacity; + + uint color; + uint *pixels; + int ppl; + + Direction lastDir; + Point lastPixel; + bool lastAxisAligned; + +private: + void setup(); + + void renderCubic(const QPointF &p1, const QPointF &p2, const QPointF &p3, const QPointF &p4, int caps); + void renderCubicSubdivision(PointF *points, int level, int caps); + // used for closed subpaths + void calculateLastPoint(qreal rx1, qreal ry1, qreal rx2, qreal ry2); + +public: + bool clipLine(qreal &x1, qreal &y1, qreal &x2, qreal &y2); +}; + +#endif // QCOSMETICLINE_H diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 2119e307d7..f0bc0d6027 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -69,6 +69,7 @@ // #include #include #include +#include #include "qmemrotate_p.h" #include "qpaintengine_raster_p.h" @@ -156,20 +157,6 @@ enum LineDrawMode { LineDrawIncludeLastPixel }; -static void drawLine_midpoint_i(int x1, int y1, int x2, int y2, ProcessSpans span_func, QSpanData *data, - LineDrawMode style, const QIntRect &rect); -static void drawLine_midpoint_dashed_i(int x1, int y1, int x2, int y2, - QPen *pen, ProcessSpans span_func, QSpanData *data, - LineDrawMode style, const QIntRect &devRect, - int *patternOffset); -// static void drawLine_midpoint_f(qreal x1, qreal y1, qreal x2, qreal y2, -// ProcessSpans span_func, QSpanData *data, -// LineDrawMode style, const QRect &devRect); - -static void drawEllipse_midpoint_i(const QRect &rect, const QRect &clip, - ProcessSpans pen_func, ProcessSpans brush_func, - QSpanData *pen_data, QSpanData *brush_data); - struct QRasterFloatPoint { qreal x; qreal y; @@ -789,14 +776,12 @@ void QRasterPaintEngine::updatePen(const QPen &pen) s->stroker = 0; } - s->flags.fast_pen = pen_style > Qt::NoPen - && s->penData.blend - && !s->flags.antialiased - && (penWidth == 0 || (penWidth <= 1 - && (s->matrix.type() <= QTransform::TxTranslate - || pen.isCosmetic()))); - ensureState(); // needed because of tx_noshear... + s->flags.fast_pen = pen_style > Qt::NoPen + && s->penData.blend + && ((pen.isCosmetic() && penWidth <= 1) + || (s->flags.tx_noshear && penWidth * s->txscale <= 1)); + s->flags.non_complex_pen = qpen_capStyle(s->lastPen) <= Qt::SquareCap && s->flags.tx_noshear; s->strokeFlags = 0; @@ -1513,6 +1498,7 @@ void QRasterPaintEngine::drawRects(const QRect *rects, int rectCount) qDebug(" - QRasterPaintEngine::drawRect(), rectCount=%d", rectCount); #endif Q_D(QRasterPaintEngine); + ensureState(); QRasterPaintEngineState *s = state(); // Fill @@ -1541,32 +1527,14 @@ void QRasterPaintEngine::drawRects(const QRect *rects, int rectCount) ensurePen(); if (s->penData.blend) { - if (s->flags.fast_pen && s->lastPen.brush().isOpaque()) { - const QRect *r = rects; - const QRect *lastRect = rects + rectCount; - while (r < lastRect) { - int left = r->x(); - int right = r->x() + r->width(); - int top = r->y(); - int bottom = r->y() + r->height(); - -#ifdef Q_WS_MAC - int pts[] = { top, left, - top, right, - bottom, right, - bottom, left }; -#else - int pts[] = { left, top, - right, top, - right, bottom, - left, bottom }; -#endif - - strokePolygonCosmetic((QPoint *) pts, 4, WindingMode); - ++r; + QRectVectorPath path; + if (s->flags.fast_pen) { + QCosmeticStroker stroker(s, d->deviceRect); + for (int i = 0; i < rectCount; ++i) { + path.set(rects[i]); + stroker.drawPath(path); } } else { - QRectVectorPath path; for (int i = 0; i < rectCount; ++i) { path.set(rects[i]); stroke(path, s->pen); @@ -1581,13 +1549,13 @@ void QRasterPaintEngine::drawRects(const QRect *rects, int rectCount) void QRasterPaintEngine::drawRects(const QRectF *rects, int rectCount) { #ifdef QT_DEBUG_DRAW - qDebug(" - QRasterPaintEngine::drawRect(), rectCount=%d", rectCount); + qDebug(" - QRasterPaintEngine::drawRect(QRectF*), rectCount=%d", rectCount); #endif #ifdef QT_FAST_SPANS Q_D(QRasterPaintEngine); + ensureState(); QRasterPaintEngineState *s = state(); - ensureState(); if (s->flags.tx_noshear) { ensureBrush(); @@ -1605,59 +1573,17 @@ void QRasterPaintEngine::drawRects(const QRectF *rects, int rectCount) ensurePen(); if (s->penData.blend) { - qreal width = s->pen.isCosmetic() - ? (s->lastPen.widthF() == 0 ? 1 : s->lastPen.widthF()) - : s->lastPen.widthF() * s->txscale; - - if (s->flags.fast_pen && s->lastPen.brush().isOpaque()) { + QRectVectorPath path; + if (s->flags.fast_pen) { + QCosmeticStroker stroker(s, d->deviceRect); for (int i = 0; i < rectCount; ++i) { - const QRectF &r = rects[i]; - qreal left = r.x(); - qreal right = r.x() + r.width(); - qreal top = r.y(); - qreal bottom = r.y() + r.height(); - qreal pts[] = { left, top, - right, top, - right, bottom, - left, bottom }; - strokePolygonCosmetic((QPointF *) pts, 4, WindingMode); - } - } else if (width <= 1 && qpen_style(s->lastPen) == Qt::SolidLine) { - d->initializeRasterizer(&s->penData); - - for (int i = 0; i < rectCount; ++i) { - const QRectF &rect = rects[i].normalized(); - if (rect.isEmpty()) { - qreal pts[] = { rect.left(), rect.top(), rect.right(), rect.bottom() }; - QVectorPath vp(pts, 2, 0, QVectorPath::LinesHint); - QPaintEngineEx::stroke(vp, s->lastPen); - } else { - const QPointF tl = s->matrix.map(rect.topLeft()); - const QPointF tr = s->matrix.map(rect.topRight()); - const QPointF bl = s->matrix.map(rect.bottomLeft()); - const QPointF br = s->matrix.map(rect.bottomRight()); - const qreal w = width / (rect.width() * s->txscale); - const qreal h = width / (rect.height() * s->txscale); - d->rasterizer->rasterizeLine(tl, tr, w); // top - d->rasterizer->rasterizeLine(bl, br, w); // bottom - d->rasterizer->rasterizeLine(bl, tl, h); // left - d->rasterizer->rasterizeLine(br, tr, h); // right - } + path.set(rects[i]); + stroker.drawPath(path); } } else { for (int i = 0; i < rectCount; ++i) { - const QRectF &r = rects[i]; - qreal left = r.x(); - qreal right = r.x() + r.width(); - qreal top = r.y(); - qreal bottom = r.y() + r.height(); - qreal pts[] = { left, top, - right, top, - right, bottom, - left, bottom, - left, top }; - QVectorPath vp(pts, 5, 0, QVectorPath::RectangleHint); - QPaintEngineEx::stroke(vp, s->lastPen); + path.set(rects[i]); + QPaintEngineEx::stroke(path, s->lastPen); } } } @@ -1674,36 +1600,16 @@ void QRasterPaintEngine::drawRects(const QRectF *rects, int rectCount) */ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen) { + Q_D(QRasterPaintEngine); QRasterPaintEngineState *s = state(); + ensurePen(pen); if (!s->penData.blend) return; - if (s->flags.fast_pen && !path.isCurved() - && s->lastPen.brush().isOpaque()) { - int count = path.elementCount(); - QPointF *points = (QPointF *) path.points(); - const QPainterPath::ElementType *types = path.elements(); - if (types) { - int first = 0; - int last; - while (first < count) { - while (first < count && types[first] != QPainterPath::MoveToElement) ++first; - last = first + 1; - while (last < count && types[last] == QPainterPath::LineToElement) ++last; - strokePolygonCosmetic(points + first, last - first, - path.hasImplicitClose() && last == count // only close last one.. - ? WindingMode - : PolylineMode); - first = last; - } - } else { - strokePolygonCosmetic(points, count, - path.hasImplicitClose() - ? WindingMode - : PolylineMode); - } - + if (s->flags.fast_pen) { + QCosmeticStroker stroker(s, d->deviceRect); + stroker.drawPath(path); } else if (s->flags.non_complex_pen && path.shape() == QVectorPath::LinesHint) { qreal width = s->lastPen.isCosmetic() ? (qpen_widthf(s->lastPen) == 0 ? 1 : qpen_widthf(s->lastPen)) @@ -1818,26 +1724,6 @@ void QRasterPaintEngine::fill(const QVectorPath &path, const QBrush &brush) } } - if (path.shape() == QVectorPath::EllipseHint) { - if (!s->flags.antialiased && s->matrix.type() <= QTransform::TxScale) { - const qreal *p = path.points(); - QPointF tl = QPointF(p[0], p[1]) * s->matrix; - QPointF br = QPointF(p[4], p[5]) * s->matrix; - QRectF r = s->matrix.mapRect(QRectF(tl, br)); - - ProcessSpans penBlend = d->getPenFunc(r, &s->penData); - ProcessSpans brushBlend = d->getBrushFunc(r, &s->brushData); - const QRect brect = QRect(int(r.x()), int(r.y()), - int_dim(r.x(), r.width()), - int_dim(r.y(), r.height())); - if (brect == r) { - drawEllipse_midpoint_i(brect, d->deviceRect, penBlend, brushBlend, - &s->penData, &s->brushData); - return; - } - } - } - // ### Optimize for non transformed ellipses and rectangles... QRectF cpRect = path.controlPointRect(); const QRect deviceRect = s->matrix.mapRect(cpRect).toRect(); @@ -2032,6 +1918,7 @@ void QRasterPaintEngine::fillPolygon(const QPointF *points, int pointCount, Poly */ void QRasterPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) { + Q_D(QRasterPaintEngine); QRasterPaintEngineState *s = state(); #ifdef QT_DEBUG_DRAW @@ -2048,9 +1935,9 @@ void QRasterPaintEngine::drawPolygon(const QPointF *points, int pointCount, Poly } ensurePen(); - ensureBrush(); if (mode != PolylineMode) { // Do the fill... + ensureBrush(); if (s->brushData.blend) { fillPolygon(points, pointCount, mode); } @@ -2058,10 +1945,11 @@ void QRasterPaintEngine::drawPolygon(const QPointF *points, int pointCount, Poly // Do the outline... if (s->penData.blend) { - if (s->flags.fast_pen && s->lastPen.brush().isOpaque()) - strokePolygonCosmetic(points, pointCount, mode); - else { - QVectorPath vp((qreal *) points, pointCount, 0, QVectorPath::polygonFlags(mode)); + QVectorPath vp((qreal *) points, pointCount, 0, QVectorPath::polygonFlags(mode)); + if (s->flags.fast_pen) { + QCosmeticStroker stroker(s, d->deviceRect); + stroker.drawPath(vp); + } else { QPaintEngineEx::stroke(vp, s->lastPen); } } @@ -2090,13 +1978,7 @@ void QRasterPaintEngine::drawPolygon(const QPoint *points, int pointCount, Polyg return; } - ensureState(); ensurePen(); - if (!(s->flags.int_xform && s->flags.fast_pen && (!s->penData.blend || s->pen.brush().isOpaque()))) { - // this calls the float version - QPaintEngineEx::drawPolygon(points, pointCount, mode); - return; - } // Do the fill if (mode != PolylineMode) { @@ -2122,234 +2004,28 @@ void QRasterPaintEngine::drawPolygon(const QPoint *points, int pointCount, Polyg // Do the outline... if (s->penData.blend) { - if (s->flags.fast_pen && s->lastPen.brush().isOpaque()) - strokePolygonCosmetic(points, pointCount, mode); - else { - int count = pointCount * 2; - QVarLengthArray fpoints(count); -#ifdef Q_WS_MAC - for (int i=0; i fpoints(count); + #ifdef Q_WS_MAC + for (int i=0; iflags.fast_pen) { + QCosmeticStroker stroker(s, d->deviceRect); + stroker.drawPath(vp); + } else { QPaintEngineEx::stroke(vp, s->lastPen); } } } -/*! - \internal -*/ -void QRasterPaintEngine::strokePolygonCosmetic(const QPointF *points, int pointCount, PolygonDrawMode mode) -{ - Q_D(QRasterPaintEngine); - QRasterPaintEngineState *s = state(); - - Q_ASSERT(s->penData.blend); - Q_ASSERT(s->flags.fast_pen); - - bool needs_closing = mode != PolylineMode && points[0] != points[pointCount-1]; - - // Use fast path for 0 width / trivial pens. - QIntRect devRect; - devRect.set(d->deviceRect); - - LineDrawMode mode_for_last = (s->lastPen.capStyle() != Qt::FlatCap - ? LineDrawIncludeLastPixel - : LineDrawNormal); - int dashOffset = int(s->lastPen.dashOffset()); - - // Draw all the line segments. - for (int i=1; imatrix; - QPointF lp2 = points[i] * s->matrix; - - const QRectF brect(lp1, lp2); - ProcessSpans penBlend = d->getPenFunc(brect, &s->penData); - if (qpen_style(s->lastPen) == Qt::SolidLine) { - drawLine_midpoint_i(qFloor(lp1.x()), qFloor(lp1.y()), - qFloor(lp2.x()), qFloor(lp2.y()), - penBlend, &s->penData, - i == pointCount - 1 ? mode_for_last : LineDrawIncludeLastPixel, - devRect); - } else { - drawLine_midpoint_dashed_i(qFloor(lp1.x()), qFloor(lp1.y()), - qFloor(lp2.x()), qFloor(lp2.y()), - &s->lastPen, - penBlend, &s->penData, - i == pointCount - 1 ? mode_for_last : LineDrawIncludeLastPixel, - devRect, &dashOffset); - } - } - - // Polygons are implicitly closed. - if (needs_closing) { - QPointF lp1 = points[pointCount-1] * s->matrix; - QPointF lp2 = points[0] * s->matrix; - - const QRectF brect(lp1, lp2); - ProcessSpans penBlend = d->getPenFunc(brect, &s->penData); - if (qpen_style(s->lastPen) == Qt::SolidLine) { - drawLine_midpoint_i(qFloor(lp1.x()), qFloor(lp1.y()), - qFloor(lp2.x()), qFloor(lp2.y()), - penBlend, &s->penData, - LineDrawIncludeLastPixel, - devRect); - } else { - drawLine_midpoint_dashed_i(qFloor(lp1.x()), qFloor(lp1.y()), - qFloor(lp2.x()), qFloor(lp2.y()), - &s->lastPen, - penBlend, &s->penData, - LineDrawIncludeLastPixel, - devRect, &dashOffset); - } - } - -} - -/*! - \internal -*/ -void QRasterPaintEngine::strokePolygonCosmetic(const QPoint *points, int pointCount, PolygonDrawMode mode) -{ - Q_D(QRasterPaintEngine); - QRasterPaintEngineState *s = state(); - - // We assert here because this function is called from drawRects - // and drawPolygon and they already do ensurePen(), so we skip that - // here to avoid duplicate checks.. - Q_ASSERT(s->penData.blend); - - bool needs_closing = mode != PolylineMode && points[0] != points[pointCount-1]; - - QIntRect devRect; - devRect.set(d->deviceRect); - - LineDrawMode mode_for_last = (s->lastPen.capStyle() != Qt::FlatCap - ? LineDrawIncludeLastPixel - : LineDrawNormal); - - int m11 = int(s->matrix.m11()); - int m22 = int(s->matrix.m22()); - int dx = int(s->matrix.dx()); - int dy = int(s->matrix.dy()); - int m13 = int(s->matrix.m13()); - int m23 = int(s->matrix.m23()); - bool affine = !m13 && !m23; - - int dashOffset = int(s->lastPen.dashOffset()); - - if (affine) { - // Draw all the line segments. - for (int i=1; imatrix; - const QPoint lp2 = points[i] * s->matrix; - const QRect brect(lp1, lp2); - ProcessSpans penBlend = d->getPenFunc(brect, &s->penData); - - if (qpen_style(s->lastPen) == Qt::SolidLine) - drawLine_midpoint_i(lp1.x(), lp1.y(), - lp2.x(), lp2.y(), - penBlend, &s->penData, - i == pointCount - 1 ? mode_for_last : LineDrawIncludeLastPixel, - devRect); - else - drawLine_midpoint_dashed_i(lp1.x(), lp1.y(), - lp2.x(), lp2.y(), - &s->lastPen, - penBlend, &s->penData, - i == pointCount - 1 ? mode_for_last : LineDrawIncludeLastPixel, - devRect, &dashOffset); - - } - - // Polygons are implicitly closed. - if (needs_closing) { - const QPoint lp1 = points[pointCount - 1] * s->matrix; - const QPoint lp2 = points[0] * s->matrix; - const QRect brect(lp1, lp2); - ProcessSpans penBlend = d->getPenFunc(brect, &s->penData); - - if (qpen_style(s->lastPen) == Qt::SolidLine) - drawLine_midpoint_i(lp1.x(), lp1.y(), - lp2.x(), lp2.y(), - penBlend, &s->penData, LineDrawIncludeLastPixel, - devRect); - else - drawLine_midpoint_dashed_i(lp1.x(), lp1.y(), - lp2.x(), lp2.y(), - &s->lastPen, - penBlend, &s->penData, LineDrawIncludeLastPixel, - devRect, &dashOffset); - } - } else { - // Draw all the line segments. - for (int i=1; igetPenFunc(brect, &s->penData); - if (qpen_style(s->lastPen) == Qt::SolidLine) - drawLine_midpoint_i(x1, y1, x2, y2, - penBlend, &s->penData, - i == pointCount - 1 ? mode_for_last : LineDrawIncludeLastPixel, - devRect); - else - drawLine_midpoint_dashed_i(x1, y1, x2, y2, - &s->lastPen, - penBlend, &s->penData, - i == pointCount - 1 ? mode_for_last : LineDrawIncludeLastPixel, - devRect, &dashOffset); - - } - - int x1 = points[pointCount-1].x() * m11 + dx; - int y1 = points[pointCount-1].y() * m22 + dy; - qreal w = m13*points[pointCount-1].x() + m23*points[pointCount-1].y() + 1.; - w = 1/w; - x1 = int(x1*w); - y1 = int(y1*w); - int x2 = points[0].x() * m11 + dx; - int y2 = points[0].y() * m22 + dy; - w = m13*points[0].x() + m23*points[0].y() + 1.; - w = 1/w; - x2 = int(x2 * w); - y2 = int(y2 * w); - // Polygons are implicitly closed. - - if (needs_closing) { - const QRect brect(x1, y1, x2 - x1 + 1, y2 - y1 + 1); - ProcessSpans penBlend = d->getPenFunc(brect, &s->penData); - if (qpen_style(s->lastPen) == Qt::SolidLine) - drawLine_midpoint_i(x1, y1, x2, y2, - penBlend, &s->penData, LineDrawIncludeLastPixel, - devRect); - else - drawLine_midpoint_dashed_i(x1, y1, x2, y2, - &s->lastPen, - penBlend, &s->penData, LineDrawIncludeLastPixel, - devRect, &dashOffset); - } - } -} - /*! \internal */ @@ -3345,32 +3021,6 @@ QRasterPaintEnginePrivate::getBrushFunc(const QRectF &rect, return isUnclipped(rect, 0) ? data->unclipped_blend : data->blend; } -inline ProcessSpans -QRasterPaintEnginePrivate::getPenFunc(const QRect &rect, - const QSpanData *data) const -{ - Q_Q(const QRasterPaintEngine); - const QRasterPaintEngineState *s = q->state(); - - if (!s->flags.fast_pen && s->matrix.type() > QTransform::TxTranslate) - return data->blend; - const int penWidth = s->flags.fast_pen ? 1 : qCeil(s->pen.widthF()); - return isUnclipped(rect, penWidth) ? data->unclipped_blend : data->blend; -} - -inline ProcessSpans -QRasterPaintEnginePrivate::getPenFunc(const QRectF &rect, - const QSpanData *data) const -{ - Q_Q(const QRasterPaintEngine); - const QRasterPaintEngineState *s = q->state(); - - if (!s->flags.fast_pen && s->matrix.type() > QTransform::TxTranslate) - return data->blend; - const int penWidth = s->flags.fast_pen ? 1 : qCeil(s->lastPen.widthF()); - return isUnclipped(rect, penWidth) ? data->unclipped_blend : data->blend; -} - /*! \reimp */ @@ -3544,48 +3194,16 @@ void QRasterPaintEngine::drawPoints(const QPointF *points, int pointCount) QRasterPaintEngineState *s = state(); ensurePen(); - qreal pw = s->lastPen.widthF(); - if (!s->flags.fast_pen && (s->matrix.type() > QTransform::TxTranslate || pw > 1)) { + if (!s->penData.blend) + return; + + if (!s->flags.fast_pen) { QPaintEngineEx::drawPoints(points, pointCount); - - } else { - if (!s->penData.blend) - return; - - QVarLengthArray array(pointCount); - QT_FT_Span span = { 0, 1, 0, 255 }; - const QPointF *end = points + pointCount; - qreal trans_x, trans_y; - int x, y; - int left = d->deviceRect.x(); - int right = left + d->deviceRect.width(); - int top = d->deviceRect.y(); - int bottom = top + d->deviceRect.height(); - int count = 0; - while (points < end) { - s->matrix.map(points->x(), points->y(), &trans_x, &trans_y); - x = qFloor(trans_x); - y = qFloor(trans_y); - if (x >= left && x < right && y >= top && y < bottom) { - if (count > 0) { - const QT_FT_Span &last = array[count - 1]; - // spans must be sorted on y (primary) and x (secondary) - if (y < last.y || (y == last.y && x < last.x)) { - s->penData.blend(count, array.constData(), &s->penData); - count = 0; - } - } - - span.x = x; - span.y = y; - array[count++] = span; - } - ++points; - } - - if (count > 0) - s->penData.blend(count, array.constData(), &s->penData); + return; } + + QCosmeticStroker stroker(s, d->deviceRect); + stroker.drawPoints(points, pointCount); } @@ -3595,48 +3213,16 @@ void QRasterPaintEngine::drawPoints(const QPoint *points, int pointCount) QRasterPaintEngineState *s = state(); ensurePen(); - double pw = s->lastPen.widthF(); - if (!s->flags.fast_pen && (s->matrix.type() > QTransform::TxTranslate || pw > 1)) { + if (!s->penData.blend) + return; + + if (!s->flags.fast_pen) { QPaintEngineEx::drawPoints(points, pointCount); - - } else { - if (!s->penData.blend) - return; - - QVarLengthArray array(pointCount); - QT_FT_Span span = { 0, 1, 0, 255 }; - const QPoint *end = points + pointCount; - qreal trans_x, trans_y; - int x, y; - int left = d->deviceRect.x(); - int right = left + d->deviceRect.width(); - int top = d->deviceRect.y(); - int bottom = top + d->deviceRect.height(); - int count = 0; - while (points < end) { - s->matrix.map(points->x(), points->y(), &trans_x, &trans_y); - x = qFloor(trans_x); - y = qFloor(trans_y); - if (x >= left && x < right && y >= top && y < bottom) { - if (count > 0) { - const QT_FT_Span &last = array[count - 1]; - // spans must be sorted on y (primary) and x (secondary) - if (y < last.y || (y == last.y && x < last.x)) { - s->penData.blend(count, array.constData(), &s->penData); - count = 0; - } - } - - span.x = x; - span.y = y; - array[count++] = span; - } - ++points; - } - - if (count > 0) - s->penData.blend(count, array.constData(), &s->penData); + return; } + + QCosmeticStroker stroker(s, d->deviceRect); + stroker.drawPoints(points, pointCount); } /*! @@ -3645,59 +3231,22 @@ void QRasterPaintEngine::drawPoints(const QPoint *points, int pointCount) void QRasterPaintEngine::drawLines(const QLine *lines, int lineCount) { #ifdef QT_DEBUG_DRAW - qDebug() << " - QRasterPaintEngine::drawLine()"; + qDebug() << " - QRasterPaintEngine::drawLines(QLine*)" << lineCount; #endif Q_D(QRasterPaintEngine); QRasterPaintEngineState *s = state(); ensurePen(); + if (!s->penData.blend) + return; + if (s->flags.fast_pen) { - QIntRect bounds; bounds.set(d->deviceRect); - LineDrawMode mode = s->lastPen.capStyle() == Qt::FlatCap - ? LineDrawNormal - : LineDrawIncludeLastPixel; - - int m11 = int(s->matrix.m11()); - int m22 = int(s->matrix.m22()); - int dx = qFloor(s->matrix.dx()); - int dy = qFloor(s->matrix.dy()); + QCosmeticStroker stroker(s, d->deviceRect); for (int i=0; ilastPen.dashOffset()); - if (s->flags.int_xform) { - const QLine &l = lines[i]; - int x1 = l.x1() * m11 + dx; - int y1 = l.y1() * m22 + dy; - int x2 = l.x2() * m11 + dx; - int y2 = l.y2() * m22 + dy; - - const QRect brect(QPoint(x1, y1), QPoint(x2, y2)); - ProcessSpans penBlend = d->getPenFunc(brect, &s->penData); - if (qpen_style(s->lastPen) == Qt::SolidLine) - drawLine_midpoint_i(x1, y1, x2, y2, - penBlend, &s->penData, mode, bounds); - else - drawLine_midpoint_dashed_i(x1, y1, x2, y2, - &s->lastPen, penBlend, - &s->penData, mode, bounds, - &dashOffset); - } else { - QLineF line = lines[i] * s->matrix; - const QRectF brect(QPointF(line.x1(), line.y1()), - QPointF(line.x2(), line.y2())); - ProcessSpans penBlend = d->getPenFunc(brect, &s->penData); - if (qpen_style(s->lastPen) == Qt::SolidLine) - drawLine_midpoint_i(int(line.x1()), int(line.y1()), - int(line.x2()), int(line.y2()), - penBlend, &s->penData, mode, bounds); - else - drawLine_midpoint_dashed_i(int(line.x1()), int(line.y1()), - int(line.x2()), int(line.y2()), - &s->lastPen, penBlend, - &s->penData, mode, bounds, - &dashOffset); - } + const QLine &l = lines[i]; + stroker.drawLine(l.p1(), l.p2()); } - } else if (s->penData.blend) { + } else { QPaintEngineEx::drawLines(lines, lineCount); } } @@ -3754,7 +3303,7 @@ void QRasterPaintEnginePrivate::rasterizeLine_dashed(QLineF line, void QRasterPaintEngine::drawLines(const QLineF *lines, int lineCount) { #ifdef QT_DEBUG_DRAW - qDebug() << " - QRasterPaintEngine::drawLine()"; + qDebug() << " - QRasterPaintEngine::drawLines(QLineF *)" << lineCount; #endif Q_D(QRasterPaintEngine); QRasterPaintEngineState *s = state(); @@ -3763,28 +3312,10 @@ void QRasterPaintEngine::drawLines(const QLineF *lines, int lineCount) if (!s->penData.blend) return; if (s->flags.fast_pen) { - QIntRect bounds; - bounds.set(d->deviceRect); - LineDrawMode mode = s->lastPen.capStyle() == Qt::FlatCap - ? LineDrawNormal - : LineDrawIncludeLastPixel; - + QCosmeticStroker stroker(s, d->deviceRect); for (int i=0; ilastPen.dashOffset()); - QLineF line = lines[i] * s->matrix; - const QRectF brect(QPointF(line.x1(), line.y1()), - QPointF(line.x2(), line.y2())); - ProcessSpans penBlend = d->getPenFunc(brect, &s->penData); - if (qpen_style(s->lastPen) == Qt::SolidLine) - drawLine_midpoint_i(int(line.x1()), int(line.y1()), - int(line.x2()), int(line.y2()), - penBlend, &s->penData, mode, bounds); - else - drawLine_midpoint_dashed_i(int(line.x1()), int(line.y1()), - int(line.x2()), int(line.y2()), - &s->lastPen, - penBlend, &s->penData, mode, - bounds, &dashOffset); + QLineF line = lines[i]; + stroker.drawLine(line.p1(), line.p2()); } } else { QPaintEngineEx::drawLines(lines, lineCount); @@ -3797,29 +3328,6 @@ void QRasterPaintEngine::drawLines(const QLineF *lines, int lineCount) */ void QRasterPaintEngine::drawEllipse(const QRectF &rect) { - Q_D(QRasterPaintEngine); - QRasterPaintEngineState *s = state(); - - ensurePen(); - if (((qpen_style(s->lastPen) == Qt::SolidLine && s->flags.fast_pen) - || (qpen_style(s->lastPen) == Qt::NoPen && !s->flags.antialiased)) - && qMax(rect.width(), rect.height()) < QT_RASTER_COORD_LIMIT - && !rect.isEmpty() - && s->matrix.type() <= QTransform::TxScale) // no shear - { - ensureBrush(); - const QRectF r = s->matrix.mapRect(rect); - ProcessSpans penBlend = d->getPenFunc(r, &s->penData); - ProcessSpans brushBlend = d->getBrushFunc(r, &s->brushData); - const QRect brect = QRect(int(r.x()), int(r.y()), - int_dim(r.x(), r.width()), - int_dim(r.y(), r.height())); - if (brect == r) { - drawEllipse_midpoint_i(brect, d->deviceRect, penBlend, brushBlend, - &s->penData, &s->brushData); - return; - } - } QPaintEngineEx::drawEllipse(rect); } @@ -4821,7 +4329,7 @@ static void qt_span_fill_clipped(int spanCount, const QSpan *spans, void *userDa while (spans < end) { QSpan *clipped = cspans; spans = qt_intersect_spans(fillData->clip, ¤tClip, spans, end, &clipped, NSPANS); -// qDebug() << "processed " << processed << "clipped" << clipped-cspans +// qDebug() << "processed " << spanCount - (end - spans) << "clipped" << clipped-cspans // << "span:" << cspans->x << cspans->y << cspans->len << spans->coverage; if (clipped - cspans) @@ -5473,878 +4981,6 @@ void QSpanData::initTexture(const QImage *image, int alpha, QTextureData::Type _ adjustSpanMethods(); } -#ifdef Q_WS_WIN - - -#endif - - -/*! - \internal - - Draws a line using the floating point midpoint algorithm. The line - \a line is already in device coords at this point. -*/ - -static void drawLine_midpoint_i(int x1, int y1, int x2, int y2, ProcessSpans span_func, QSpanData *data, - LineDrawMode style, const QIntRect &devRect) -{ -#ifdef QT_DEBUG_DRAW - qDebug() << " - drawLine_midpoint_i" << QLine(QPoint(x1, y1), QPoint(x2, y2)); -#endif - - int x, y; - int dx, dy, d, incrE, incrNE; - - dx = x2 - x1; - dy = y2 - y1; - - const int NSPANS = 256; - QT_FT_Span spans[NSPANS]; - int current = 0; - bool ordered = true; - - if (dy == 0) { - // specialcase horizontal lines - if (y1 >= devRect.y1 && y1 < devRect.y2) { - int start = qMax(devRect.x1, qMin(x1, x2)); - int stop = qMax(x1, x2) + 1; - int stop_clipped = qMin(devRect.x2, stop); - int len = stop_clipped - start; - if (style == LineDrawNormal && stop == stop_clipped) - len--; - if (len > 0) { - spans[0].x = ushort(start); - spans[0].len = ushort(len); - spans[0].y = y1; - spans[0].coverage = 255; - span_func(1, spans, data); - } - } - return; - } else if (dx == 0) { - // specialcase vertical lines - if (x1 >= devRect.x1 && x1 < devRect.x2) { - int start = qMax(devRect.y1, qMin(y1, y2)); - int stop = qMax(y1, y2) + 1; - int stop_clipped = qMin(devRect.y2, stop); - int len = stop_clipped - start; - if (style == LineDrawNormal && stop == stop_clipped) - len--; - // hw: create spans directly instead to possibly avoid clipping - if (len > 0) - fillRect_normalized(QRect(x1, start, 1, len).normalized(), data, 0); - } - return; - } - - - if (qAbs(dx) >= qAbs(dy)) { /* if x is the major axis: */ - - if (x2 < x1) { /* if coordinates are out of order */ - qt_swap_int(x1, x2); - dx = -dx; - - qt_swap_int(y1, y2); - dy = -dy; - } - - int x_lower_limit = - 128; - if (x1 < x_lower_limit) { - int cy = dy * (x_lower_limit - x1) / dx + y1; - drawLine_midpoint_i(x_lower_limit, cy, x2, y2, span_func, data, style, devRect); - return; - } - - if (style == LineDrawNormal) - --x2; - - // In the loops below we increment before call the span function so - // we need to stop one pixel before - x2 = qMin(x2, devRect.x2 - 1); - - // completely clipped, so abort - if (x2 <= x1) { - return; - } - - int x = x1; - int y = y1; - - if (y2 <= y1) - ordered = false; - - { - const int index = (ordered ? current : NSPANS - 1 - current); - spans[index].coverage = 255; - spans[index].x = x; - spans[index].y = y; - - if (x >= devRect.x1 && y >= devRect.y1 && y < devRect.y2) - spans[index].len = 1; - else - spans[index].len = 0; - } - - if (y2 > y1) { // 315 -> 360 and 135 -> 180 (unit circle degrees) - y2 = qMin(y2, devRect.y2 - 1); - - incrE = dy * 2; - d = incrE - dx; - incrNE = (dy - dx) * 2; - - if (y > y2) - goto flush_and_return; - - while (x < x2) { - ++x; - if (d > 0) { - if (spans[current].len > 0) - ++current; - if (current == NSPANS) { - span_func(NSPANS, spans, data); - current = 0; - } - - ++y; - d += incrNE; - if (y > y2) - goto flush_and_return; - - spans[current].len = 0; - spans[current].coverage = 255; - spans[current].x = x; - spans[current].y = y; - } else { - d += incrE; - if (x == devRect.x1) - spans[current].x = devRect.x1; - } - - if (x < devRect.x1 || y < devRect.y1) - continue; - - Q_ASSERT(x 0) { - ++current; - } - } else { // 0-45 and 180->225 (unit circle degrees) - - y1 = qMin(y1, devRect.y2 - 1); - - incrE = dy * 2; - d = incrE + dx; - incrNE = (dy + dx) * 2; - - if (y < devRect.y1) - goto flush_and_return; - - while (x < x2) { - ++x; - if (d < 0) { - if (spans[NSPANS - 1 - current].len > 0) - ++current; - if (current == NSPANS) { - span_func(NSPANS, spans, data); - current = 0; - } - - --y; - d += incrNE; - if (y < devRect.y1) - goto flush_and_return; - - const int index = NSPANS - 1 - current; - spans[index].len = 0; - spans[index].coverage = 255; - spans[index].x = x; - spans[index].y = y; - } else { - d += incrE; - if (x == devRect.x1) - spans[NSPANS - 1 - current].x = devRect.x1; - } - - if (x < devRect.x1 || y > y1) - continue; - - Q_ASSERT(x 0) { - ++current; - } - } - - } else { - - // if y is the major axis: - - if (y2 < y1) { /* if coordinates are out of order */ - qt_swap_int(y1, y2); - dy = -dy; - - qt_swap_int(x1, x2); - dx = -dx; - } - - int y_lower_limit = - 128; - if (y1 < y_lower_limit) { - int cx = dx * (y_lower_limit - y1) / dy + x1; - drawLine_midpoint_i(cx, y_lower_limit, x2, y2, span_func, data, style, devRect); - return; - } - - if (style == LineDrawNormal) - --y2; - - // In the loops below we increment before call the span function so - // we need to stop one pixel before - y2 = qMin(y2, devRect.y2 - 1); - - // completely clipped, so abort - if (y2 <= y1) { - return; - } - - x = x1; - y = y1; - - if (x>=devRect.x1 && y>=devRect.y1 && x < devRect.x2) { - Q_ASSERT(x >= devRect.x1 && y >= devRect.y1 && x < devRect.x2 && y < devRect.y2); - if (current == NSPANS) { - span_func(NSPANS, spans, data); - current = 0; - } - spans[current].len = 1; - spans[current].coverage = 255; - spans[current].x = x; - spans[current].y = y; - ++current; - } - - if (x2 > x1) { // 90 -> 135 and 270 -> 315 (unit circle degrees) - x2 = qMin(x2, devRect.x2 - 1); - incrE = dx * 2; - d = incrE - dy; - incrNE = (dx - dy) * 2; - - if (x > x2) - goto flush_and_return; - - while (y < y2) { - if (d > 0) { - ++x; - d += incrNE; - if (x > x2) - goto flush_and_return; - } else { - d += incrE; - } - ++y; - if (x < devRect.x1 || y < devRect.y1) - continue; - Q_ASSERT(x 90 and 225 -> 270 (unit circle degrees) - x1 = qMin(x1, devRect.x2 - 1); - incrE = dx * 2; - d = incrE + dy; - incrNE = (dx + dy) * 2; - - if (x < devRect.x1) - goto flush_and_return; - - while (y < y2) { - if (d < 0) { - --x; - d += incrNE; - if (x < devRect.x1) - goto flush_and_return; - } else { - d += incrE; - } - ++y; - if (y < devRect.y1 || x > x1) - continue; - Q_ASSERT(x>=devRect.x1 && x=devRect.y1 && y 0) - span_func(current, ordered ? spans : spans + (NSPANS - current), data); -} - -static void offset_pattern(int offset, bool *inDash, int *dashIndex, int *currentOffset, const QVarLengthArray &pattern) -{ - while (offset--) { - if (--*currentOffset == 0) { - *inDash = !*inDash; - *dashIndex = ((*dashIndex + 1) % pattern.size()); - *currentOffset = int(pattern[*dashIndex]); - } - } -} - -static void drawLine_midpoint_dashed_i(int x1, int y1, int x2, int y2, - QPen *pen, - ProcessSpans span_func, QSpanData *data, - LineDrawMode style, const QIntRect &devRect, - int *patternOffset) -{ -#ifdef QT_DEBUG_DRAW - qDebug() << " - drawLine_midpoint_dashed_i" << x1 << y1 << x2 << y2 << *patternOffset; -#endif - - int x, y; - int dx, dy, d, incrE, incrNE; - - dx = x2 - x1; - dy = y2 - y1; - - Q_ASSERT(*patternOffset >= 0); - - const QVector penPattern = pen->dashPattern(); - QVarLengthArray pattern(penPattern.size()); - - int patternLength = 0; - for (int i = 0; i < penPattern.size(); ++i) - patternLength += qMax(1.0, (penPattern.at(i))); - - // pattern must be reversed if coordinates are out of order - int reverseLength = -1; - if (dy == 0 && x1 > x2) - reverseLength = x1 - x2; - else if (dx == 0 && y1 > y2) - reverseLength = y1 - y2; - else if (qAbs(dx) >= qAbs(dy) && x2 < x1) // x major axis - reverseLength = qAbs(dx); - else if (qAbs(dy) >= qAbs(dx) && y2 < y1) // y major axis - reverseLength = qAbs(dy); - - const bool reversed = (reverseLength > -1); - if (reversed) { // reverse pattern - for (int i = 0; i < penPattern.size(); ++i) - pattern[penPattern.size() - 1 - i] = qMax(1.0, penPattern.at(i)); - - *patternOffset = (patternLength - 1 - *patternOffset); - *patternOffset += patternLength - (reverseLength % patternLength); - *patternOffset = *patternOffset % patternLength; - } else { - for (int i = 0; i < penPattern.size(); ++i) - pattern[i] = qMax(1.0, penPattern.at(i)); - } - - int dashIndex = 0; - bool inDash = !reversed; - int currPattern = int(pattern[dashIndex]); - - // adjust pattern for offset - offset_pattern(*patternOffset, &inDash, &dashIndex, &currPattern, pattern); - - const int NSPANS = 256; - QT_FT_Span spans[NSPANS]; - int current = 0; - bool ordered = true; - - if (dy == 0) { - // specialcase horizontal lines - if (y1 >= devRect.y1 && y1 < devRect.y2) { - int start_unclipped = qMin(x1, x2); - int start = qMax(devRect.x1, start_unclipped); - int stop = qMax(x1, x2) + 1; - int stop_clipped = qMin(devRect.x2, stop); - int len = stop_clipped - start; - if (style == LineDrawNormal && stop == stop_clipped) - len--; - - // adjust pattern for starting offset - offset_pattern(start - start_unclipped, &inDash, &dashIndex, &currPattern, pattern); - - if (len > 0) { - int x = start; - while (x < stop_clipped) { - if (current == NSPANS) { - span_func(NSPANS, spans, data); - current = 0; - } - const int dash = qMin(currPattern, stop_clipped - x); - if (inDash) { - spans[current].x = ushort(x); - spans[current].len = ushort(dash); - spans[current].y = y1; - spans[current].coverage = 255; - ++current; - } - if (dash < currPattern) { - currPattern -= dash; - } else { - dashIndex = (dashIndex + 1) % pattern.size(); - currPattern = int(pattern[dashIndex]); - inDash = !inDash; - } - x += dash; - } - } - } - goto flush_and_return; - } else if (dx == 0) { - if (x1 >= devRect.x1 && x1 < devRect.x2) { - int start_unclipped = qMin(y1, y2); - int start = qMax(devRect.y1, start_unclipped); - int stop = qMax(y1, y2) + 1; - int stop_clipped = qMin(devRect.y2, stop); - if (style == LineDrawNormal && stop == stop_clipped) - --stop; - else - stop = stop_clipped; - - // adjust pattern for starting offset - offset_pattern(start - start_unclipped, &inDash, &dashIndex, &currPattern, pattern); - - // loop over dashes - int y = start; - while (y < stop) { - const int dash = qMin(currPattern, stop - y); - if (inDash) { - for (int i = 0; i < dash; ++i) { - if (current == NSPANS) { - span_func(NSPANS, spans, data); - current = 0; - } - spans[current].x = x1; - spans[current].len = 1; - spans[current].coverage = 255; - spans[current].y = ushort(y + i); - ++current; - } - } - if (dash < currPattern) { - currPattern -= dash; - } else { - dashIndex = (dashIndex + 1) % pattern.size(); - currPattern = int(pattern[dashIndex]); - inDash = !inDash; - } - y += dash; - } - } - goto flush_and_return; - } - - if (qAbs(dx) >= qAbs(dy)) { /* if x is the major axis: */ - - if (x2 < x1) { /* if coordinates are out of order */ - qt_swap_int(x1, x2); - dx = -dx; - - qt_swap_int(y1, y2); - dy = -dy; - } - - if (style == LineDrawNormal) - --x2; - - // In the loops below we increment before call the span function so - // we need to stop one pixel before - x2 = qMin(x2, devRect.x2 - 1); - - // completely clipped, so abort - if (x2 <= x1) - goto flush_and_return; - - int x = x1; - int y = y1; - - if (x >= devRect.x1 && y >= devRect.y1 && y < devRect.y2) { - Q_ASSERT(x < devRect.x2); - if (inDash) { - if (current == NSPANS) { - span_func(NSPANS, spans, data); - current = 0; - } - spans[current].len = 1; - spans[current].coverage = 255; - spans[current].x = x; - spans[current].y = y; - ++current; - } - if (--currPattern <= 0) { - inDash = !inDash; - dashIndex = (dashIndex + 1) % pattern.size(); - currPattern = int(pattern[dashIndex]); - } - } - - if (y2 > y1) { // 315 -> 360 and 135 -> 180 (unit circle degrees) - y2 = qMin(y2, devRect.y2 - 1); - - incrE = dy * 2; - d = incrE - dx; - incrNE = (dy - dx) * 2; - - if (y > y2) - goto flush_and_return; - - while (x < x2) { - if (d > 0) { - ++y; - d += incrNE; - if (y > y2) - goto flush_and_return; - } else { - d += incrE; - } - ++x; - - const bool skip = x < devRect.x1 || y < devRect.y1; - Q_ASSERT(skip || (x < devRect.x2 && y < devRect.y2)); - if (inDash && !skip) { - if (current == NSPANS) { - span_func(NSPANS, spans, data); - current = 0; - } - spans[current].len = 1; - spans[current].coverage = 255; - spans[current].x = x; - spans[current].y = y; - ++current; - } - if (--currPattern <= 0) { - inDash = !inDash; - dashIndex = (dashIndex + 1) % pattern.size(); - currPattern = int(pattern[dashIndex]); - } - } - } else { // 0-45 and 180->225 (unit circle degrees) - y1 = qMin(y1, devRect.y2 - 1); - - incrE = dy * 2; - d = incrE + dx; - incrNE = (dy + dx) * 2; - - if (y < devRect.y1) - goto flush_and_return; - - while (x < x2) { - if (d < 0) { - if (current > 0) { - span_func(current, spans, data); - current = 0; - } - - --y; - d += incrNE; - if (y < devRect.y1) - goto flush_and_return; - } else { - d += incrE; - } - ++x; - - const bool skip = x < devRect.x1 || y > y1; - Q_ASSERT(skip || (x < devRect.x2 && y < devRect.y2)); - if (inDash && !skip) { - if (current == NSPANS) { - span_func(NSPANS, spans, data); - current = 0; - } - spans[current].len = 1; - spans[current].coverage = 255; - spans[current].x = x; - spans[current].y = y; - ++current; - } - if (--currPattern <= 0) { - inDash = !inDash; - dashIndex = (dashIndex + 1) % pattern.size(); - currPattern = int(pattern[dashIndex]); - } - } - } - } else { - - // if y is the major axis: - - if (y2 < y1) { /* if coordinates are out of order */ - qt_swap_int(y1, y2); - dy = -dy; - - qt_swap_int(x1, x2); - dx = -dx; - } - - if (style == LineDrawNormal) - --y2; - - // In the loops below we increment before call the span function so - // we need to stop one pixel before - y2 = qMin(y2, devRect.y2 - 1); - - // completely clipped, so abort - if (y2 <= y1) - goto flush_and_return; - - x = x1; - y = y1; - - if (x>=devRect.x1 && y>=devRect.y1 && x < devRect.x2) { - Q_ASSERT(x < devRect.x2); - if (inDash) { - if (current == NSPANS) { - span_func(NSPANS, spans, data); - current = 0; - } - spans[current].len = 1; - spans[current].coverage = 255; - spans[current].x = x; - spans[current].y = y; - ++current; - } - if (--currPattern <= 0) { - inDash = !inDash; - dashIndex = (dashIndex + 1) % pattern.size(); - currPattern = int(pattern[dashIndex]); - } - } - - if (x2 > x1) { // 90 -> 135 and 270 -> 315 (unit circle degrees) - x2 = qMin(x2, devRect.x2 - 1); - incrE = dx * 2; - d = incrE - dy; - incrNE = (dx - dy) * 2; - - if (x > x2) - goto flush_and_return; - - while (y < y2) { - if (d > 0) { - ++x; - d += incrNE; - if (x > x2) - goto flush_and_return; - } else { - d += incrE; - } - ++y; - const bool skip = x < devRect.x1 || y < devRect.y1; - Q_ASSERT(skip || (x < devRect.x2 && y < devRect.y2)); - if (inDash && !skip) { - if (current == NSPANS) { - span_func(NSPANS, spans, data); - current = 0; - } - spans[current].len = 1; - spans[current].coverage = 255; - spans[current].x = x; - spans[current].y = y; - ++current; - } - if (--currPattern <= 0) { - inDash = !inDash; - dashIndex = (dashIndex + 1) % pattern.size(); - currPattern = int(pattern[dashIndex]); - } - } - } else { // 45 -> 90 and 225 -> 270 (unit circle degrees) - x1 = qMin(x1, devRect.x2 - 1); - incrE = dx * 2; - d = incrE + dy; - incrNE = (dx + dy) * 2; - - if (x < devRect.x1) - goto flush_and_return; - - while (y < y2) { - if (d < 0) { - --x; - d += incrNE; - if (x < devRect.x1) - goto flush_and_return; - } else { - d += incrE; - } - ++y; - const bool skip = y < devRect.y1 || x > x1; - Q_ASSERT(skip || (x >= devRect.x1 && x < devRect.x2 && y < devRect.y2)); - if (inDash && !skip) { - if (current == NSPANS) { - span_func(NSPANS, spans, data); - current = 0; - } - spans[current].len = 1; - spans[current].coverage = 255; - spans[current].x = x; - spans[current].y = y; - ++current; - } - if (--currPattern <= 0) { - inDash = !inDash; - dashIndex = (dashIndex + 1) % pattern.size(); - currPattern = int(pattern[dashIndex]); - } - } - } - } -flush_and_return: - if (current > 0) - span_func(current, ordered ? spans : spans + (NSPANS - current), data); - - // adjust offset - if (reversed) { - *patternOffset = (patternLength - 1 - *patternOffset); - } else { - *patternOffset = 0; - for (int i = 0; i <= dashIndex; ++i) - *patternOffset += int(pattern[i]); - *patternOffset += patternLength - currPattern - 1; - *patternOffset = (*patternOffset % patternLength); - } -} - -/*! - \internal - \a x and \a y is relative to the midpoint of \a rect. -*/ -static inline void drawEllipsePoints(int x, int y, int length, - const QRect &rect, - const QRect &clip, - ProcessSpans pen_func, ProcessSpans brush_func, - QSpanData *pen_data, QSpanData *brush_data) -{ - if (length == 0) - return; - - QT_FT_Span outline[4]; - const int midx = rect.x() + (rect.width() + 1) / 2; - const int midy = rect.y() + (rect.height() + 1) / 2; - - x = x + midx; - y = midy - y; - - // topleft - outline[0].x = midx + (midx - x) - (length - 1) - (rect.width() & 0x1); - outline[0].len = qMin(length, x - outline[0].x); - outline[0].y = y; - outline[0].coverage = 255; - - // topright - outline[1].x = x; - outline[1].len = length; - outline[1].y = y; - outline[1].coverage = 255; - - // bottomleft - outline[2].x = outline[0].x; - outline[2].len = outline[0].len; - outline[2].y = midy + (midy - y) - (rect.height() & 0x1); - outline[2].coverage = 255; - - // bottomright - outline[3].x = x; - outline[3].len = length; - outline[3].y = outline[2].y; - outline[3].coverage = 255; - - if (brush_func && outline[0].x + outline[0].len < outline[1].x) { - QT_FT_Span fill[2]; - - // top fill - fill[0].x = outline[0].x + outline[0].len - 1; - fill[0].len = qMax(0, outline[1].x - fill[0].x); - fill[0].y = outline[1].y; - fill[0].coverage = 255; - - // bottom fill - fill[1].x = outline[2].x + outline[2].len - 1; - fill[1].len = qMax(0, outline[3].x - fill[1].x); - fill[1].y = outline[3].y; - fill[1].coverage = 255; - - int n = (fill[0].y >= fill[1].y ? 1 : 2); - n = qt_intersect_spans(fill, n, clip); - if (n > 0) - brush_func(n, fill, brush_data); - } - if (pen_func) { - int n = (outline[1].y >= outline[2].y ? 2 : 4); - n = qt_intersect_spans(outline, n, clip); - if (n > 0) - pen_func(n, outline, pen_data); - } -} - -/*! - \internal - Draws an ellipse using the integer point midpoint algorithm. -*/ -static void drawEllipse_midpoint_i(const QRect &rect, const QRect &clip, - ProcessSpans pen_func, ProcessSpans brush_func, - QSpanData *pen_data, QSpanData *brush_data) -{ - const qreal a = qreal(rect.width()) / 2; - const qreal b = qreal(rect.height()) / 2; - qreal d = b*b - (a*a*b) + 0.25*a*a; - - int x = 0; - int y = (rect.height() + 1) / 2; - int startx = x; - - // region 1 - while (a*a*(2*y - 1) > 2*b*b*(x + 1)) { - if (d < 0) { // select E - d += b*b*(2*x + 3); - ++x; - } else { // select SE - d += b*b*(2*x + 3) + a*a*(-2*y + 2); - drawEllipsePoints(startx, y, x - startx + 1, rect, clip, - pen_func, brush_func, pen_data, brush_data); - startx = ++x; - --y; - } - } - drawEllipsePoints(startx, y, x - startx + 1, rect, clip, - pen_func, brush_func, pen_data, brush_data); - - // region 2 - d = b*b*(x + 0.5)*(x + 0.5) + a*a*((y - 1)*(y - 1) - b*b); - const int miny = rect.height() & 0x1; - while (y > miny) { - if (d < 0) { // select SE - d += b*b*(2*x + 2) + a*a*(-2*y + 3); - ++x; - } else { // select S - d += a*a*(-2*y + 3); - } - --y; - drawEllipsePoints(x, y, 1, rect, clip, - pen_func, brush_func, pen_data, brush_data); - } -} /*! \fn void QRasterPaintEngine::drawPoints(const QPoint *points, int pointCount) diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h index 52f51fab16..122c2b868a 100644 --- a/src/gui/painting/qpaintengine_raster_p.h +++ b/src/gui/painting/qpaintengine_raster_p.h @@ -196,9 +196,6 @@ public: void stroke(const QVectorPath &path, const QPen &pen); void fill(const QVectorPath &path, const QBrush &brush); - void strokePolygonCosmetic(const QPoint *pts, int pointCount, PolygonDrawMode mode); - void strokePolygonCosmetic(const QPointF *pt, int pointCount, PolygonDrawMode mode); - void clip(const QVectorPath &path, Qt::ClipOperation op); void clip(const QRect &rect, Qt::ClipOperation op); void clip(const QRegion ®ion, Qt::ClipOperation op); @@ -328,8 +325,6 @@ public: bool isUnclipped_normalized(const QRect &rect) const; bool isUnclipped(const QRect &rect, int penWidth) const; bool isUnclipped(const QRectF &rect, int penWidth) const; - ProcessSpans getPenFunc(const QRect &rect, const QSpanData *data) const; - ProcessSpans getPenFunc(const QRectF &rect, const QSpanData *data) const; ProcessSpans getBrushFunc(const QRect &rect, const QSpanData *data) const; ProcessSpans getBrushFunc(const QRectF &rect, const QSpanData *data) const; diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 7f601eb755..bbdf76f0c0 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -831,7 +831,7 @@ void QPaintEngineEx::drawEllipse(const QRectF &r) int point_count = 0; x.points[0] = qt_curves_for_arc(r, 0, -360, x.points + 1, &point_count); - QVectorPath vp((qreal *) pts, point_count, qpaintengineex_ellipse_types, QVectorPath::EllipseHint); + QVectorPath vp((qreal *) pts, point_count + 1, qpaintengineex_ellipse_types, QVectorPath::EllipseHint); draw(vp); }