From 2aa55af392f527b9357ca227d853a2ee5e340f35 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Fri, 4 Feb 2011 13:49:09 +1000 Subject: Only ask for name when the user goes on the high score list. Task-number: QTBUG-14714 --- .../declarative/samegame/SamegameCore/samegame.js | 41 +++++++++++++++++++--- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/demos/declarative/samegame/SamegameCore/samegame.js b/demos/declarative/samegame/SamegameCore/samegame.js index e618a10..16c48c4 100755 --- a/demos/declarative/samegame/SamegameCore/samegame.js +++ b/demos/declarative/samegame/SamegameCore/samegame.js @@ -8,6 +8,7 @@ var blockSrc = "SamegameCore/BoomBlock.qml"; var scoresURL = ""; var gameDuration; var component = Qt.createComponent(blockSrc); +var highScoreBar = 0; // Index function used instead of a 2D array function index(column, row) @@ -152,11 +153,15 @@ function victoryCheck() // Checks for game over if (deservesBonus || !(floodMoveCheck(0, maxRow - 1, -1))) { gameDuration = new Date() - gameDuration; - nameInputDialog.show("You won! Please enter your name: "); - nameInputDialog.initialWidth = nameInputDialog.text.width + 20; - if (nameInputDialog.name == "") - nameInputDialog.width = nameInputDialog.initialWidth; - nameInputDialog.text.opacity = 0; // Just a spacer + if(gameCanvas.score > highScoreBar){ + nameInputDialog.show("You won! Please enter your name: "); + nameInputDialog.initialWidth = nameInputDialog.text.width + 20; + if (nameInputDialog.name == "") + nameInputDialog.width = nameInputDialog.initialWidth; + nameInputDialog.text.opacity = 0; // Just a spacer + }else{ + dialog.show("You won!"); + } } } @@ -202,6 +207,30 @@ function createBlock(column,row) return true; } +function initHighScoreBar() +{ + if(scoresURL != "") + return true;//don't query remote scores + var db = openDatabaseSync( + "SameGameScores", + "1.0", + "Local SameGame High Scores", + 100 + ); + db.transaction( + function(tx) { + tx.executeSql('CREATE TABLE IF NOT EXISTS Scores(name TEXT, score NUMBER, gridSize TEXT, time NUMBER)'); + // Only show results for the current grid size + var rs = tx.executeSql('SELECT * FROM Scores WHERE gridSize = "' + + maxColumn + "x" + maxRow + '" ORDER BY score desc LIMIT 10'); + if(rs.rows.length < 10) + highScoreBar = 0; + else + highScoreBar = rs.rows.item(rs.rows.length - 1).score; + } + ); +} + function saveHighScore(name) { if (scoresURL != "") @@ -234,6 +263,8 @@ function saveHighScore(name) + rs.rows.item(i).score + ' points in ' + rs.rows.item(i).time + ' seconds.\n'; } + if(rs.rows.length == 10) + highScoreBar = rs.rows.item(9).score; dialog.show(r); } ); -- cgit v0.12 From b82332fec19ee977eceaf2d533ee027020a474e0 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Fri, 4 Feb 2011 14:02:21 +1000 Subject: Make -no-opengl exist on other platforms Task-Number: QTBUG-15830 --- tools/qml/main.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp index 5846ff0..67154dd 100644 --- a/tools/qml/main.cpp +++ b/tools/qml/main.cpp @@ -161,7 +161,9 @@ void usage() qWarning(" -P ........................... prepend to the plugin search path"); #if defined(Q_WS_MAC) qWarning(" -no-opengl ............................... don't use a QGLWidget for the viewport"); + qWarning(" -opengl .................................. use a QGLWidget for the viewport (default)"); #else + qWarning(" -no-opengl ............................... don't use a QGLWidget for the viewport (default)"); qWarning(" -opengl .................................. use a QGLWidget for the viewport"); #endif qWarning(" -script ........................... set the script to use"); @@ -380,13 +382,10 @@ static void parseCommandLineOptions(const QStringList &arguments) } else if (arg == "-translation") { if (lastArg) usage(); opts.translationFile = arguments.at(++i); -#if defined(Q_WS_MAC) } else if (arg == "-no-opengl") { opts.useGL = false; -#else } else if (arg == "-opengl") { opts.useGL = true; -#endif } else if (arg == "-qmlbrowser") { opts.useNativeFileBrowser = false; } else if (arg == "-warnings") { -- cgit v0.12 From ca03f39224fb64775ed7150685df96c6b5b83b23 Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Fri, 25 Feb 2011 14:50:38 +0100 Subject: Fixed QML TextEdit docs Removed non-existent enumeration value from docs. Signed-off-by: Thiago Marcos P. Santos Reviewed-by: Leonardo Sobral Cunha --- src/declarative/graphicsitems/qdeclarativetextedit.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp index e2f6265..42ce404 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp @@ -271,7 +271,6 @@ void QDeclarativeTextEdit::setText(const QString &text) \o TextEdit.AutoText \o TextEdit.PlainText \o TextEdit.RichText - \o TextEdit.StyledText \endlist The default is TextEdit.AutoText. If the text format is TextEdit.AutoText the text edit -- cgit v0.12 From 19d11751da73fded31605bb80f70642faf4095c5 Mon Sep 17 00:00:00 2001 From: Perttu Pohjonen Date: Mon, 7 Mar 2011 08:49:00 +0200 Subject: Unsuccessful unlocking of QNetworkConfigurationPrivate mutex Above mentioned mutex is locked twice: first in caller function and second time in called function. Called function unlocks mutex and emits signal clearly unaware that the mutex is actually still locked. I changed the mutex to be unlocked before the function is called. Task-number: QTBUG-15108 Reviewed-by: Ville Pernu (cherry picked from commit c15560fbe2a1762117395c5ecaaecfa5ab8dce6f) --- src/plugins/bearer/symbian/symbianengine.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/bearer/symbian/symbianengine.cpp b/src/plugins/bearer/symbian/symbianengine.cpp index bcf7dd9..edf4b89 100644 --- a/src/plugins/bearer/symbian/symbianengine.cpp +++ b/src/plugins/bearer/symbian/symbianengine.cpp @@ -829,6 +829,7 @@ void SymbianEngine::updateStatesToSnaps() discovered = true; } } + snapConfigLocker.unlock(); if (active) { changeConfigurationStateTo(ptr, QNetworkConfiguration::Active); } else if (discovered) { -- cgit v0.12 From 0e32d0575aa92b6d92999fa661d36fd40c1fee66 Mon Sep 17 00:00:00 2001 From: Jani Hautakangas Date: Thu, 10 Mar 2011 17:50:12 +0200 Subject: Fix for major regression in OpenVG clipping OpenVG paint engine didn't reset it's mask fallback state correctly when engine was resetted. Task-number: QTBUG-17966 Reviewed-by: Jason Barron (cherry picked from commit 2ecb0ea77c04424f6f557ca8a13c1d86666763df) --- src/openvg/qpaintengine_vg.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index c2a4c9b..ec2936e 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -2333,6 +2333,7 @@ bool QVGPaintEngine::isDefaultClipRect(const QRect& rect) void QVGPaintEngine::clipEnabledChanged() { #if defined(QVG_SCISSOR_CLIP) + vgSeti(VG_MASKING, VG_FALSE); // disable mask fallback updateScissor(); #else Q_D(QVGPaintEngine); -- cgit v0.12 From 71acbd0ff1c926c9a508b879f0ca365d17cc4987 Mon Sep 17 00:00:00 2001 From: Cristiano di Flora Date: Thu, 24 Feb 2011 03:23:28 +0200 Subject: Fix QTBUG-17627: build break in mobility bearer applications Task-Number: QTBUG-17627 (cherry picked from commit f86e014bb6f2754bfed33106021a809ca8c2ce73) --- src/network/bearer/qnetworksession.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/network/bearer/qnetworksession.h b/src/network/bearer/qnetworksession.h index 52db88f..e491d50 100644 --- a/src/network/bearer/qnetworksession.h +++ b/src/network/bearer/qnetworksession.h @@ -141,13 +141,12 @@ private: #ifndef QT_MOBILITY_BEARER QT_END_NAMESPACE +Q_DECLARE_METATYPE(QNetworkSession::State) +Q_DECLARE_METATYPE(QNetworkSession::SessionError) #else QTM_END_NAMESPACE #endif -Q_DECLARE_METATYPE(QNetworkSession::State) -Q_DECLARE_METATYPE(QNetworkSession::SessionError) - QT_END_HEADER #endif // QT_NO_BEARERMANAGEMENT -- cgit v0.12 From e733cce50b5c49b3ace52b8b5a2266e57ad769e5 Mon Sep 17 00:00:00 2001 From: Timo Turunen Date: Fri, 11 Mar 2011 16:38:58 +0200 Subject: Bump Qt version to 4.7.3 Reviewed-by: Trust Me (cherry picked from commit e90cff53cdd7bf0bdfed1f2e8efb90539c6f33ba) Conflicts: tools/qdoc3/test/qt-project.qdocconf --- dist/changes-4.7.3 | 0 src/3rdparty/webkit/WebKit/qt/qt_webkit_version.pri | 4 ++-- src/corelib/global/qglobal.h | 4 ++-- src/plugins/qpluginbase.pri | 2 +- src/qbase.pri | 2 +- tests/auto/mediaobject/dummy/dummy.pro | 2 +- tests/auto/selftests/expected_cmptest.txt | 2 +- tests/auto/selftests/expected_crashes_3.txt | 2 +- tests/auto/selftests/expected_longstring.txt | 2 +- tests/auto/selftests/expected_maxwarnings.txt | 2 +- tests/auto/selftests/expected_skip.txt | 2 +- tools/assistant/tools/assistant/doc/assistant.qdocconf | 4 ++-- tools/qdoc3/doc/files/qt.qdocconf | 8 ++++---- tools/qdoc3/test/assistant.qdocconf | 4 ++-- tools/qdoc3/test/designer.qdocconf | 4 ++-- tools/qdoc3/test/linguist.qdocconf | 4 ++-- tools/qdoc3/test/qdeclarative.qdocconf | 8 ++++---- tools/qdoc3/test/qmake.qdocconf | 4 ++-- tools/qdoc3/test/qt-build-docs_ja_JP.qdocconf | 8 ++++---- tools/qdoc3/test/qt-build-docs_zh_CN.qdocconf | 8 ++++---- 20 files changed, 38 insertions(+), 38 deletions(-) create mode 100644 dist/changes-4.7.3 diff --git a/dist/changes-4.7.3 b/dist/changes-4.7.3 new file mode 100644 index 0000000..e69de29 diff --git a/src/3rdparty/webkit/WebKit/qt/qt_webkit_version.pri b/src/3rdparty/webkit/WebKit/qt/qt_webkit_version.pri index b98617f..07754a7 100644 --- a/src/3rdparty/webkit/WebKit/qt/qt_webkit_version.pri +++ b/src/3rdparty/webkit/WebKit/qt/qt_webkit_version.pri @@ -1,5 +1,5 @@ -QT_WEBKIT_VERSION = 4.7.2 +QT_WEBKIT_VERSION = 4.7.3 QT_WEBKIT_MAJOR_VERSION = 4 QT_WEBKIT_MINOR_VERSION = 7 -QT_WEBKIT_PATCH_VERSION = 2 +QT_WEBKIT_PATCH_VERSION = 3 QT_CONFIG += webkit diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index e13a0fc..d374f09 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -44,11 +44,11 @@ #include -#define QT_VERSION_STR "4.7.2" +#define QT_VERSION_STR "4.7.3" /* QT_VERSION is (major << 16) + (minor << 8) + patch. */ -#define QT_VERSION 0x040702 +#define QT_VERSION 0x040703 /* can be used like #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) */ diff --git a/src/plugins/qpluginbase.pri b/src/plugins/qpluginbase.pri index 7cbffe0..3de5fdf 100644 --- a/src/plugins/qpluginbase.pri +++ b/src/plugins/qpluginbase.pri @@ -1,6 +1,6 @@ TEMPLATE = lib isEmpty(QT_MAJOR_VERSION) { - VERSION=4.7.2 + VERSION=4.7.3 } else { VERSION=$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION} } diff --git a/src/qbase.pri b/src/qbase.pri index 75da3dc..babea56 100644 --- a/src/qbase.pri +++ b/src/qbase.pri @@ -4,7 +4,7 @@ INCLUDEPATH *= $$QMAKE_INCDIR_QT/$$TARGET #just for today to have some compat isEmpty(QT_ARCH):!isEmpty(ARCH):QT_ARCH=$$ARCH #another compat that will rot for change #215700 TEMPLATE = lib isEmpty(QT_MAJOR_VERSION) { - VERSION=4.7.2 + VERSION=4.7.3 } else { VERSION=$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION} } diff --git a/tests/auto/mediaobject/dummy/dummy.pro b/tests/auto/mediaobject/dummy/dummy.pro index 88b864b..c81411c 100644 --- a/tests/auto/mediaobject/dummy/dummy.pro +++ b/tests/auto/mediaobject/dummy/dummy.pro @@ -1,7 +1,7 @@ TEMPLATE = lib isEmpty(QT_MAJOR_VERSION) { - VERSION=4.6.4 + VERSION=4.7.3 } else { VERSION=$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION} } diff --git a/tests/auto/selftests/expected_cmptest.txt b/tests/auto/selftests/expected_cmptest.txt index fccaca3..d70815d 100644 --- a/tests/auto/selftests/expected_cmptest.txt +++ b/tests/auto/selftests/expected_cmptest.txt @@ -1,5 +1,5 @@ ********* Start testing of tst_Cmptest ********* -Config: Using QTest library 4.7.2, Qt 4.7.2 +Config: Using QTest library 4.7.3, Qt 4.7.3 PASS : tst_Cmptest::initTestCase() PASS : tst_Cmptest::compare_boolfuncs() PASS : tst_Cmptest::compare_pointerfuncs() diff --git a/tests/auto/selftests/expected_crashes_3.txt b/tests/auto/selftests/expected_crashes_3.txt index 2558f68..2aea62c 100644 --- a/tests/auto/selftests/expected_crashes_3.txt +++ b/tests/auto/selftests/expected_crashes_3.txt @@ -1,5 +1,5 @@ ********* Start testing of tst_Crashes ********* -Config: Using QTest library 4.7.2, Qt 4.7.2 +Config: Using QTest library 4.7.3, Qt 4.7.3 PASS : tst_Crashes::initTestCase() QFATAL : tst_Crashes::crash() Received signal 11 FAIL! : tst_Crashes::crash() Received a fatal error. diff --git a/tests/auto/selftests/expected_longstring.txt b/tests/auto/selftests/expected_longstring.txt index c56244b..1fe012f 100644 --- a/tests/auto/selftests/expected_longstring.txt +++ b/tests/auto/selftests/expected_longstring.txt @@ -1,5 +1,5 @@ ********* Start testing of tst_LongString ********* -Config: Using QTest library 4.7.2, Qt 4.7.2 +Config: Using QTest library 4.7.3, Qt 4.7.3 PASS : tst_LongString::initTestCase() FAIL! : tst_LongString::failWithLongString() Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. diff --git a/tests/auto/selftests/expected_maxwarnings.txt b/tests/auto/selftests/expected_maxwarnings.txt index 7846435..cdd6ee8 100644 --- a/tests/auto/selftests/expected_maxwarnings.txt +++ b/tests/auto/selftests/expected_maxwarnings.txt @@ -1,5 +1,5 @@ ********* Start testing of MaxWarnings ********* -Config: Using QTest library 4.7.2, Qt 4.7.2 +Config: Using QTest library 4.7.3, Qt 4.7.3 PASS : MaxWarnings::initTestCase() QWARN : MaxWarnings::warn() 0 QWARN : MaxWarnings::warn() 1 diff --git a/tests/auto/selftests/expected_skip.txt b/tests/auto/selftests/expected_skip.txt index 5c9e497..490c140 100644 --- a/tests/auto/selftests/expected_skip.txt +++ b/tests/auto/selftests/expected_skip.txt @@ -1,5 +1,5 @@ ********* Start testing of tst_Skip ********* -Config: Using QTest library 4.7.2, Qt 4.7.2 +Config: Using QTest library 4.7.3, Qt 4.7.3 PASS : tst_Skip::initTestCase() SKIP : tst_Skip::test() skipping all Loc: [/home/user/depot/qt-git/mainline/tests/auto/selftests/skip/tst_skip.cpp(68)] diff --git a/tools/assistant/tools/assistant/doc/assistant.qdocconf b/tools/assistant/tools/assistant/doc/assistant.qdocconf index 57abeae..575b1e5 100644 --- a/tools/assistant/tools/assistant/doc/assistant.qdocconf +++ b/tools/assistant/tools/assistant/doc/assistant.qdocconf @@ -10,7 +10,7 @@ description = "Qt Assistant" HTML.{postheader,address} = "" HTML.footer = "


\n" \ "\n" \ - "\n" \ + "\n" \ "\n" \ - "\n" \ + "\n" \ "
Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)Copyright © 2011 Nokia Corporation and/or its subsidiary(-ies)Trademarks
Qt 4.7.2
Qt 4.7.3
" diff --git a/tools/qdoc3/doc/files/qt.qdocconf b/tools/qdoc3/doc/files/qt.qdocconf index 44cfbc1..9b16233 100644 --- a/tools/qdoc3/doc/files/qt.qdocconf +++ b/tools/qdoc3/doc/files/qt.qdocconf @@ -22,7 +22,7 @@ edition.DesktopLight.groups = -graphicsview-api qhp.projects = Qt qhp.Qt.file = qt.qhp -qhp.Qt.namespace = com.trolltech.qt.472 +qhp.Qt.namespace = com.trolltech.qt.473 qhp.Qt.virtualFolder = qdoc qhp.Qt.indexTitle = Qt Reference Documentation qhp.Qt.indexRoot = @@ -36,9 +36,9 @@ qhp.Qt.extraFiles = classic.css \ images/dynamiclayouts-example.png \ images/stylesheet-coffee-plastique.png -qhp.Qt.filterAttributes = qt 4.7.2 qtrefdoc -qhp.Qt.customFilters.Qt.name = Qt 4.7.2 -qhp.Qt.customFilters.Qt.filterAttributes = qt 4.7.2 +qhp.Qt.filterAttributes = qt 4.7.3 qtrefdoc +qhp.Qt.customFilters.Qt.name = Qt 4.7.3 +qhp.Qt.customFilters.Qt.filterAttributes = qt 4.7.3 qhp.Qt.subprojects = classes overviews examples qhp.Qt.subprojects.classes.title = Classes qhp.Qt.subprojects.classes.indexTitle = Qt's Classes diff --git a/tools/qdoc3/test/assistant.qdocconf b/tools/qdoc3/test/assistant.qdocconf index 0e9a2a8..74ab67b 100644 --- a/tools/qdoc3/test/assistant.qdocconf +++ b/tools/qdoc3/test/assistant.qdocconf @@ -13,7 +13,7 @@ indexes = $QT_BUILD_TREE/doc-build/html-qt/qt.index qhp.projects = Assistant qhp.Assistant.file = assistant.qhp -qhp.Assistant.namespace = com.trolltech.assistant.472 +qhp.Assistant.namespace = com.trolltech.assistant.473 qhp.Assistant.virtualFolder = qdoc qhp.Assistant.indexTitle = Qt Assistant Manual qhp.Assistant.extraFiles = images/bg_l.png \ @@ -50,7 +50,7 @@ qhp.Assistant.extraFiles = images/bg_l.png \ style/style_ie8.css \ style/style.css -qhp.Assistant.filterAttributes = qt 4.7.2 tools assistant +qhp.Assistant.filterAttributes = qt 4.7.3 tools assistant qhp.Assistant.customFilters.Assistant.name = Qt Assistant Manual qhp.Assistant.customFilters.Assistant.filterAttributes = qt tools assistant qhp.Assistant.subprojects = manual examples diff --git a/tools/qdoc3/test/designer.qdocconf b/tools/qdoc3/test/designer.qdocconf index 637399b..42dbc20 100644 --- a/tools/qdoc3/test/designer.qdocconf +++ b/tools/qdoc3/test/designer.qdocconf @@ -13,7 +13,7 @@ indexes = $QT_BUILD_TREE/doc-build/html-qt/qt.index qhp.projects = Designer qhp.Designer.file = designer.qhp -qhp.Designer.namespace = com.trolltech.designer.472 +qhp.Designer.namespace = com.trolltech.designer.473 qhp.Designer.virtualFolder = qdoc qhp.Designer.indexTitle = Qt Designer Manual qhp.Designer.extraFiles = images/bg_l.png \ @@ -50,7 +50,7 @@ qhp.Designer.extraFiles = images/bg_l.png \ style/style_ie8.css \ style/style.css -qhp.Designer.filterAttributes = qt 4.7.2 tools designer +qhp.Designer.filterAttributes = qt 4.7.3 tools designer qhp.Designer.customFilters.Designer.name = Qt Designer Manual qhp.Designer.customFilters.Designer.filterAttributes = qt tools designer qhp.Designer.subprojects = manual examples diff --git a/tools/qdoc3/test/linguist.qdocconf b/tools/qdoc3/test/linguist.qdocconf index 8ee298e..7c01023 100644 --- a/tools/qdoc3/test/linguist.qdocconf +++ b/tools/qdoc3/test/linguist.qdocconf @@ -13,7 +13,7 @@ indexes = $QT_BUILD_TREE/doc-build/html-qt/qt.index qhp.projects = Linguist qhp.Linguist.file = linguist.qhp -qhp.Linguist.namespace = com.trolltech.linguist.472 +qhp.Linguist.namespace = com.trolltech.linguist.473 qhp.Linguist.virtualFolder = qdoc qhp.Linguist.indexTitle = Qt Linguist Manual qhp.Linguist.extraFiles = images/bg_l.png \ @@ -50,7 +50,7 @@ qhp.Linguist.extraFiles = images/bg_l.png \ style/style_ie8.css \ style/style.css -qhp.Linguist.filterAttributes = qt 4.7.2 tools linguist +qhp.Linguist.filterAttributes = qt 4.7.3 tools linguist qhp.Linguist.customFilters.Linguist.name = Qt Linguist Manual qhp.Linguist.customFilters.Linguist.filterAttributes = qt tools linguist qhp.Linguist.subprojects = manual examples diff --git a/tools/qdoc3/test/qdeclarative.qdocconf b/tools/qdoc3/test/qdeclarative.qdocconf index e68a935..12c939c 100644 --- a/tools/qdoc3/test/qdeclarative.qdocconf +++ b/tools/qdoc3/test/qdeclarative.qdocconf @@ -21,7 +21,7 @@ edition.DesktopLight.groups = -graphicsview-api qhp.projects = Qml qhp.Qml.file = qml.qhp -qhp.Qml.namespace = com.trolltech.qml.472 +qhp.Qml.namespace = com.trolltech.qml.473 qhp.Qml.virtualFolder = qdoc qhp.Qml.indexTitle = Qml Reference @@ -61,9 +61,9 @@ qhp.Qml.extraFiles = images/bg_l.png \ style/style_ie8.css \ style/style.css -qhp.Qml.filterAttributes = qt 4.7.2 qtrefdoc -qhp.Qml.customFilters.Qt.name = Qt 4.7.2 -qhp.Qml.customFilters.Qt.filterAttributes = qt 4.7.2 +qhp.Qml.filterAttributes = qt 4.7.3 qtrefdoc +qhp.Qml.customFilters.Qt.name = Qt 4.7.3 +qhp.Qml.customFilters.Qt.filterAttributes = qt 4.7.3 qhp.Qml.subprojects = classes qhp.Qml.subprojects.classes.title = Elements qhp.Qml.subprojects.classes.indexTitle = Qml Elements diff --git a/tools/qdoc3/test/qmake.qdocconf b/tools/qdoc3/test/qmake.qdocconf index b5bc96c..b7d1299 100644 --- a/tools/qdoc3/test/qmake.qdocconf +++ b/tools/qdoc3/test/qmake.qdocconf @@ -13,7 +13,7 @@ indexes = $QT_BUILD_TREE/doc-build/html-qt/qt.index qhp.projects = qmake qhp.qmake.file = qmake.qhp -qhp.qmake.namespace = com.trolltech.qmake.472 +qhp.qmake.namespace = com.trolltech.qmake.473 qhp.qmake.virtualFolder = qdoc qhp.qmake.indexTitle = QMake Manual qhp.qmake.extraFiles = images/bg_l.png \ @@ -50,7 +50,7 @@ qhp.qmake.extraFiles = images/bg_l.png \ style/style_ie8.css \ style/style.css -qhp.qmake.filterAttributes = qt 4.7.2 tools qmake +qhp.qmake.filterAttributes = qt 4.7.3 tools qmake qhp.qmake.customFilters.qmake.name = qmake Manual qhp.qmake.customFilters.qmake.filterAttributes = qt tools qmake qhp.qmake.subprojects = manual diff --git a/tools/qdoc3/test/qt-build-docs_ja_JP.qdocconf b/tools/qdoc3/test/qt-build-docs_ja_JP.qdocconf index 24696d5..a4d0653 100644 --- a/tools/qdoc3/test/qt-build-docs_ja_JP.qdocconf +++ b/tools/qdoc3/test/qt-build-docs_ja_JP.qdocconf @@ -17,15 +17,15 @@ indexes = $QT_BUILD_TREE/doc-build/html-qt/qt.index qhp.projects = Qt qhp.Qt.file = qt.qhp -qhp.Qt.namespace = com.trolltech.qt.472 +qhp.Qt.namespace = com.trolltech.qt.473 qhp.Qt.virtualFolder = qdoc qhp.Qt.title = Qt qhp.Qt.indexTitle = Qt qhp.Qt.selectors = fake:example -qhp.Qt.filterAttributes = qt 4.7.2 qtrefdoc ja_JP -qhp.Qt.customFilters.Qt.name = Qt 4.7.2 -qhp.Qt.customFilters.Qt.filterAttributes = qt 4.7.2 +qhp.Qt.filterAttributes = qt 4.7.3 qtrefdoc ja_JP +qhp.Qt.customFilters.Qt.name = Qt 4.7.3 +qhp.Qt.customFilters.Qt.filterAttributes = qt 4.7.3 # Files not referenced in any qdoc file (last four are needed by qtdemo) # See also extraimages.HTML diff --git a/tools/qdoc3/test/qt-build-docs_zh_CN.qdocconf b/tools/qdoc3/test/qt-build-docs_zh_CN.qdocconf index 7789bf7..818b5c5 100644 --- a/tools/qdoc3/test/qt-build-docs_zh_CN.qdocconf +++ b/tools/qdoc3/test/qt-build-docs_zh_CN.qdocconf @@ -17,15 +17,15 @@ indexes = $QT_BUILD_TREE/doc-build/html-qt/qt.index qhp.projects = Qt qhp.Qt.file = qt.qhp -qhp.Qt.namespace = com.trolltech.qt.472 +qhp.Qt.namespace = com.trolltech.qt.473 qhp.Qt.virtualFolder = qdoc qhp.Qt.title = 教程 qhp.Qt.indexTitle = 教程 qhp.Qt.selectors = fake:example -qhp.Qt.filterAttributes = qt 4.7.2 qtrefdoc zh_CN -qhp.Qt.customFilters.Qt.name = Qt 4.7.2 -qhp.Qt.customFilters.Qt.filterAttributes = qt 4.7.2 +qhp.Qt.filterAttributes = qt 4.7.3 qtrefdoc zh_CN +qhp.Qt.customFilters.Qt.name = Qt 4.7.3 +qhp.Qt.customFilters.Qt.filterAttributes = qt 4.7.3 # Files not referenced in any qdoc file (last four are needed by qtdemo) # See also extraimages.HTML -- cgit v0.12 From 9a5f3dd71a7c3bb4e777c92cca09100d077a736a Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Mon, 14 Mar 2011 14:36:52 +1000 Subject: Add Constant and Final flags to QMetaObjectBuilder Change-Id: I25090e833f7ce184bcbf2bc5b9281c27ab05aa2d Reviewed-by: Michael Brasser --- src/declarative/qml/qmetaobjectbuilder.cpp | 57 +++++++++++++++++++++- src/declarative/qml/qmetaobjectbuilder_p.h | 4 ++ .../qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp | 22 ++++++++- 3 files changed, 81 insertions(+), 2 deletions(-) diff --git a/src/declarative/qml/qmetaobjectbuilder.cpp b/src/declarative/qml/qmetaobjectbuilder.cpp index 6a0226f..448797b 100644 --- a/src/declarative/qml/qmetaobjectbuilder.cpp +++ b/src/declarative/qml/qmetaobjectbuilder.cpp @@ -101,7 +101,7 @@ bool isVariantType(const char* type) return qvariant_nameToType(type) != 0; } -// copied from qmetaobject.cpp +// copied from qmetaobject_p.h // do not touch without touching the moc as well enum PropertyFlags { Invalid = 0x00000000, @@ -111,6 +111,8 @@ enum PropertyFlags { EnumOrFlag = 0x00000008, StdCppSet = 0x00000100, // Override = 0x00000200, + Constant = 0x00000400, + Final = 0x00000800, Designable = 0x00001000, ResolveDesignable = 0x00002000, Scriptable = 0x00004000, @@ -618,6 +620,8 @@ QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QMetaProperty& protot property.setUser(prototype.isUser()); property.setStdCppSet(prototype.hasStdCppSet()); property.setEnumOrFlag(prototype.isEnumType()); + property.setConstant(prototype.isConstant()); + property.setFinal(prototype.isFinal()); if (prototype.hasNotifySignal()) { // Find an existing method for the notify signal, or add a new one. QMetaMethod method = prototype.notifySignal(); @@ -2278,6 +2282,32 @@ bool QMetaPropertyBuilder::isEnumOrFlag() const } /*! + Returns true if the property is constant; otherwise returns false. + The default value is false. +*/ +bool QMetaPropertyBuilder::isConstant() const +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + return d->flag(Constant); + else + return false; +} + +/*! + Returns true if the property is final; otherwise returns false. + The default value is false. +*/ +bool QMetaPropertyBuilder::isFinal() const +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + return d->flag(Final); + else + return false; +} + +/*! Sets this property to readable if \a value is true. \sa isReadable(), setWritable() @@ -2401,6 +2431,31 @@ void QMetaPropertyBuilder::setEnumOrFlag(bool value) } /*! + Sets the \c CONSTANT flag on this property to \a value. + + \sa isConstant() +*/ +void QMetaPropertyBuilder::setConstant(bool value) +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + d->setFlag(Constant, value); +} + +/*! + Sets the \c FINAL flag on this property to \a value. + + \sa isFinal() +*/ +void QMetaPropertyBuilder::setFinal(bool value) +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + d->setFlag(Final, value); +} + + +/*! \class QMetaEnumBuilder \internal \brief The QMetaEnumBuilder class enables modifications to an enumerator definition on a meta object builder. diff --git a/src/declarative/qml/qmetaobjectbuilder_p.h b/src/declarative/qml/qmetaobjectbuilder_p.h index 2678bff..392e13b 100644 --- a/src/declarative/qml/qmetaobjectbuilder_p.h +++ b/src/declarative/qml/qmetaobjectbuilder_p.h @@ -258,6 +258,8 @@ public: bool isUser() const; bool hasStdCppSet() const; bool isEnumOrFlag() const; + bool isConstant() const; + bool isFinal() const; void setReadable(bool value); void setWritable(bool value); @@ -269,6 +271,8 @@ public: void setUser(bool value); void setStdCppSet(bool value); void setEnumOrFlag(bool value); + void setConstant(bool value); + void setFinal(bool value); private: const QMetaObjectBuilder *_mobj; diff --git a/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp index 06baed8..ff72654 100644 --- a/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp +++ b/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp @@ -546,6 +546,8 @@ void tst_QMetaObjectBuilder::property() QVERIFY(!nullProp.isUser()); QVERIFY(!nullProp.hasStdCppSet()); QVERIFY(!nullProp.isEnumOrFlag()); + QVERIFY(!nullProp.isConstant()); + QVERIFY(!nullProp.isFinal()); QCOMPARE(nullProp.index(), 0); // Add a property and check its attributes. @@ -563,6 +565,8 @@ void tst_QMetaObjectBuilder::property() QVERIFY(!prop1.isUser()); QVERIFY(!prop1.hasStdCppSet()); QVERIFY(!prop1.isEnumOrFlag()); + QVERIFY(!prop1.isConstant()); + QVERIFY(!prop1.isFinal()); QCOMPARE(prop1.index(), 0); QCOMPARE(builder.propertyCount(), 1); @@ -581,6 +585,8 @@ void tst_QMetaObjectBuilder::property() QVERIFY(!prop2.isUser()); QVERIFY(!prop2.hasStdCppSet()); QVERIFY(!prop2.isEnumOrFlag()); + QVERIFY(!prop2.isConstant()); + QVERIFY(!prop2.isFinal()); QCOMPARE(prop2.index(), 1); QCOMPARE(builder.propertyCount(), 2); @@ -602,6 +608,8 @@ void tst_QMetaObjectBuilder::property() prop1.setUser(true); prop1.setStdCppSet(true); prop1.setEnumOrFlag(true); + prop1.setConstant(true); + prop1.setFinal(true); // Check that prop1 is changed, but prop2 is not. QCOMPARE(prop1.name(), QByteArray("foo")); @@ -616,6 +624,8 @@ void tst_QMetaObjectBuilder::property() QVERIFY(prop1.isUser()); QVERIFY(prop1.hasStdCppSet()); QVERIFY(prop1.isEnumOrFlag()); + QVERIFY(prop1.isConstant()); + QVERIFY(prop1.isFinal()); QVERIFY(prop2.isReadable()); QVERIFY(prop2.isWritable()); QCOMPARE(prop2.name(), QByteArray("bar")); @@ -628,6 +638,8 @@ void tst_QMetaObjectBuilder::property() QVERIFY(!prop2.isUser()); QVERIFY(!prop2.hasStdCppSet()); QVERIFY(!prop2.isEnumOrFlag()); + QVERIFY(!prop2.isConstant()); + QVERIFY(!prop2.isFinal()); // Remove prop1 and check that prop2 becomes index 0. builder.removeProperty(0); @@ -643,6 +655,8 @@ void tst_QMetaObjectBuilder::property() QVERIFY(!prop2.isUser()); QVERIFY(!prop2.hasStdCppSet()); QVERIFY(!prop2.isEnumOrFlag()); + QVERIFY(!prop2.isConstant()); + QVERIFY(!prop2.isFinal()); QCOMPARE(prop2.index(), 0); // Perform index-based lookup again. @@ -666,6 +680,8 @@ void tst_QMetaObjectBuilder::property() prop2.setUser(false); \ prop2.setStdCppSet(false); \ prop2.setEnumOrFlag(false); \ + prop2.setConstant(false); \ + prop2.setFinal(false); \ } while (0) #define COUNT_FLAGS() \ ((prop2.isReadable() ? 1 : 0) + \ @@ -677,7 +693,9 @@ void tst_QMetaObjectBuilder::property() (prop2.isEditable() ? 1 : 0) + \ (prop2.isUser() ? 1 : 0) + \ (prop2.hasStdCppSet() ? 1 : 0) + \ - (prop2.isEnumOrFlag() ? 1 : 0)) + (prop2.isEnumOrFlag() ? 1 : 0) + \ + (prop2.isConstant() ? 1 : 0) + \ + (prop2.isFinal() ? 1 : 0)) #define CHECK_FLAG(setFunc,isFunc) \ do { \ CLEAR_FLAGS(); \ @@ -696,6 +714,8 @@ void tst_QMetaObjectBuilder::property() CHECK_FLAG(setUser, isUser); CHECK_FLAG(setStdCppSet, hasStdCppSet); CHECK_FLAG(setEnumOrFlag, isEnumOrFlag); + CHECK_FLAG(setConstant, isConstant); + CHECK_FLAG(setFinal, isFinal); // Check that nothing else changed. QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Properties)); -- cgit v0.12 From 186096455ed3dd5bc27b272ff8959a5a38ec5100 Mon Sep 17 00:00:00 2001 From: Timo Turunen Date: Mon, 14 Mar 2011 13:26:53 +0200 Subject: QDeclarativeDebug: Export needed symbols on Symbian Allow applications to link against the QDeclarativeDebugService API. This is needed for on-device debugging of QML. (The removal of the symbols was a regression in 4.7.2). Task-number: QTBUG-17503 Reviewed-by: Tom Sutcliffe (cherry picked from commit fbf73dec65df9c27a3a09ca9b436f5f8cb9f1b0e) Conflicts: src/s60installs/bwins/QtDeclarativeu.def --- .../debugger/qdeclarativedebugservice_p.h | 2 +- src/s60installs/bwins/QtDeclarativeu.def | 48 +++++++++++----------- src/s60installs/eabi/QtDeclarativeu.def | 44 ++++++++++---------- 3 files changed, 47 insertions(+), 47 deletions(-) diff --git a/src/declarative/debugger/qdeclarativedebugservice_p.h b/src/declarative/debugger/qdeclarativedebugservice_p.h index 449cb65..271b3c9 100644 --- a/src/declarative/debugger/qdeclarativedebugservice_p.h +++ b/src/declarative/debugger/qdeclarativedebugservice_p.h @@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) class QDeclarativeDebugServicePrivate; -class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeDebugService : public QObject +class Q_DECLARATIVE_EXPORT QDeclarativeDebugService : public QObject { Q_OBJECT Q_DECLARE_PRIVATE(QDeclarativeDebugService) diff --git a/src/s60installs/bwins/QtDeclarativeu.def b/src/s60installs/bwins/QtDeclarativeu.def index b5da47d..6cc24d8 100644 --- a/src/s60installs/bwins/QtDeclarativeu.def +++ b/src/s60installs/bwins/QtDeclarativeu.def @@ -3,7 +3,7 @@ EXPORTS ?setStored@QMetaPropertyBuilder@@QAEX_N@Z @ 2 NONAME ABSENT ; void QMetaPropertyBuilder::setStored(bool) ?trUtf8@QDeclarativeExpression@@SA?AVQString@@PBD0H@Z @ 3 NONAME ; class QString QDeclarativeExpression::trUtf8(char const *, char const *, int) ?qt_metacast@QDeclarativeComponent@@UAEPAXPBD@Z @ 4 NONAME ; void * QDeclarativeComponent::qt_metacast(char const *) - ?name@QDeclarativeDebugService@@QBE?AVQString@@XZ @ 5 NONAME ABSENT ; class QString QDeclarativeDebugService::name(void) const + ?name@QDeclarativeDebugService@@QBE?AVQString@@XZ @ 5 NONAME ; class QString QDeclarativeDebugService::name(void) const ?debugId@QDeclarativeDebugObjectReference@@QBEHXZ @ 6 NONAME ABSENT ; int QDeclarativeDebugObjectReference::debugId(void) const ?addPluginPath@QDeclarativeEngine@@QAEXABVQString@@@Z @ 7 NONAME ; void QDeclarativeEngine::addPluginPath(class QString const &) ?name@QMetaPropertyBuilder@@QBE?AVQByteArray@@XZ @ 8 NONAME ABSENT ; class QByteArray QMetaPropertyBuilder::name(void) const @@ -11,7 +11,7 @@ EXPORTS ?propertyOffset@QDeclarativeOpenMetaObjectType@@QBEHXZ @ 10 NONAME ABSENT ; int QDeclarativeOpenMetaObjectType::propertyOffset(void) const ??0QDeclarativeText@@QAE@PAVQDeclarativeItem@@@Z @ 11 NONAME ABSENT ; QDeclarativeText::QDeclarativeText(class QDeclarativeItem *) ?propertyTypeName@QDeclarativeProperty@@QBEPBDXZ @ 12 NONAME ; char const * QDeclarativeProperty::propertyTypeName(void) const - ?getStaticMetaObject@QDeclarativeDebugService@@SAABUQMetaObject@@XZ @ 13 NONAME ABSENT ; struct QMetaObject const & QDeclarativeDebugService::getStaticMetaObject(void) + ?getStaticMetaObject@QDeclarativeDebugService@@SAABUQMetaObject@@XZ @ 13 NONAME ; struct QMetaObject const & QDeclarativeDebugService::getStaticMetaObject(void) ?setLeft@QDeclarativeAnchors@@QAEXABVQDeclarativeAnchorLine@@@Z @ 14 NONAME ABSENT ; void QDeclarativeAnchors::setLeft(class QDeclarativeAnchorLine const &) ?qt_metacall@QDeclarativeExpression@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 15 NONAME ; int QDeclarativeExpression::qt_metacall(enum QMetaObject::Call, int, void * *) ?staticMetaObject@QDeclarativePen@@2UQMetaObject@@B @ 16 NONAME ABSENT ; struct QMetaObject const QDeclarativePen::staticMetaObject @@ -145,7 +145,7 @@ EXPORTS ?isConnected@QDeclarativeDebugClient@@QBE_NXZ @ 144 NONAME ABSENT ; bool QDeclarativeDebugClient::isConnected(void) const ?enabled@QDeclarativeBinding@@QBE_NXZ @ 145 NONAME ABSENT ; bool QDeclarativeBinding::enabled(void) const ?setSource@QDeclarativeView@@QAEXABVQUrl@@@Z @ 146 NONAME ; void QDeclarativeView::setSource(class QUrl const &) - ??_EQDeclarativeDebugService@@UAE@I@Z @ 147 NONAME ABSENT ; QDeclarativeDebugService::~QDeclarativeDebugService(unsigned int) + ??_EQDeclarativeDebugService@@UAE@I@Z @ 147 NONAME ; QDeclarativeDebugService::~QDeclarativeDebugService(unsigned int) ??0QDeclarativeDomDynamicProperty@@QAE@ABV0@@Z @ 148 NONAME ABSENT ; QDeclarativeDomDynamicProperty::QDeclarativeDomDynamicProperty(class QDeclarativeDomDynamicProperty const &) ?className@QDeclarativeDebugObjectReference@@QBE?AVQString@@XZ @ 149 NONAME ABSENT ; class QString QDeclarativeDebugObjectReference::className(void) const ?indexOfSlot@QMetaObjectBuilder@@QAEHABVQByteArray@@@Z @ 150 NONAME ABSENT ; int QMetaObjectBuilder::indexOfSlot(class QByteArray const &) @@ -294,7 +294,7 @@ EXPORTS ?attachedPropertiesType@QDeclarativeType@@QBEPBUQMetaObject@@XZ @ 293 NONAME ABSENT ; struct QMetaObject const * QDeclarativeType::attachedPropertiesType(void) const ?setName@QDeclarativeState@@QAEXABVQString@@@Z @ 294 NONAME ; void QDeclarativeState::setName(class QString const &) ?setReversed@QDeclarativeTransition@@QAEX_N@Z @ 295 NONAME ; void QDeclarativeTransition::setReversed(bool) - ?idForObject@QDeclarativeDebugService@@SAHPAVQObject@@@Z @ 296 NONAME ABSENT ; int QDeclarativeDebugService::idForObject(class QObject *) + ?idForObject@QDeclarativeDebugService@@SAHPAVQObject@@@Z @ 296 NONAME ; int QDeclarativeDebugService::idForObject(class QObject *) ?qt_metacall@QDeclarativeDebugWatch@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 297 NONAME ABSENT ; int QDeclarativeDebugWatch::qt_metacall(enum QMetaObject::Call, int, void * *) ?fromState@QDeclarativeTransition@@QBE?AVQString@@XZ @ 298 NONAME ; class QString QDeclarativeTransition::fromState(void) const ??1QDeclarativeExpression@@UAE@XZ @ 299 NONAME ; QDeclarativeExpression::~QDeclarativeExpression(void) @@ -332,7 +332,7 @@ EXPORTS ??0QDeclarativeCustomParserNode@@QAE@ABV0@@Z @ 331 NONAME ; QDeclarativeCustomParserNode::QDeclarativeCustomParserNode(class QDeclarativeCustomParserNode const &) ??1QDeclarativeImageProvider@@UAE@XZ @ 332 NONAME ; QDeclarativeImageProvider::~QDeclarativeImageProvider(void) ?sync@QDeclarativeListModel@@QAEXXZ @ 333 NONAME ABSENT ; void QDeclarativeListModel::sync(void) - ?objectForId@QDeclarativeDebugService@@SAPAVQObject@@H@Z @ 334 NONAME ABSENT ; class QObject * QDeclarativeDebugService::objectForId(int) + ?objectForId@QDeclarativeDebugService@@SAPAVQObject@@H@Z @ 334 NONAME ; class QObject * QDeclarativeDebugService::objectForId(int) ?hasFocus@QDeclarativeItem@@QBE_NXZ @ 335 NONAME ; bool QDeclarativeItem::hasFocus(void) const ??1QDeclarativeExtensionPlugin@@UAE@XZ @ 336 NONAME ; QDeclarativeExtensionPlugin::~QDeclarativeExtensionPlugin(void) ?qt_metacall@QDeclarativeBehavior@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 337 NONAME ABSENT ; int QDeclarativeBehavior::qt_metacall(enum QMetaObject::Call, int, void * *) @@ -482,7 +482,7 @@ EXPORTS ?pluginPathList@QDeclarativeEngine@@QBE?AVQStringList@@XZ @ 481 NONAME ; class QStringList QDeclarativeEngine::pluginPathList(void) const ?parentContext@QDeclarativeContext@@QBEPAV1@XZ @ 482 NONAME ; class QDeclarativeContext * QDeclarativeContext::parentContext(void) const ?leftMarginChanged@QDeclarativeAnchors@@IAEXXZ @ 483 NONAME ABSENT ; void QDeclarativeAnchors::leftMarginChanged(void) - ?staticMetaObject@QDeclarativeDebugService@@2UQMetaObject@@B @ 484 NONAME ABSENT ; struct QMetaObject const QDeclarativeDebugService::staticMetaObject + ?staticMetaObject@QDeclarativeDebugService@@2UQMetaObject@@B @ 484 NONAME ; struct QMetaObject const QDeclarativeDebugService::staticMetaObject ?topMargin@QDeclarativeAnchors@@QBEMXZ @ 485 NONAME ABSENT ; float QDeclarativeAnchors::topMargin(void) const ??0QDeclarativeDebugExpressionQuery@@AAE@PAVQObject@@@Z @ 486 NONAME ABSENT ; QDeclarativeDebugExpressionQuery::QDeclarativeDebugExpressionQuery(class QObject *) ??0QPacket@@IAE@ABVQByteArray@@@Z @ 487 NONAME ABSENT ; QPacket::QPacket(class QByteArray const &) @@ -559,7 +559,7 @@ EXPORTS ?metaObject@QDeclarativeEngine@@UBEPBUQMetaObject@@XZ @ 558 NONAME ; struct QMetaObject const * QDeclarativeEngine::metaObject(void) const ??_EQDeclarativeDebugContextReference@@QAE@I@Z @ 559 NONAME ABSENT ; QDeclarativeDebugContextReference::~QDeclarativeDebugContextReference(unsigned int) ?propertyWrite@QDeclarativeOpenMetaObject@@MAEXH@Z @ 560 NONAME ABSENT ; void QDeclarativeOpenMetaObject::propertyWrite(int) - ?qt_metacall@QDeclarativeDebugService@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 561 NONAME ABSENT ; int QDeclarativeDebugService::qt_metacall(enum QMetaObject::Call, int, void * *) + ?qt_metacall@QDeclarativeDebugService@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 561 NONAME ; int QDeclarativeDebugService::qt_metacall(enum QMetaObject::Call, int, void * *) ?setVerticalCenterOffset@QDeclarativeAnchors@@QAEXM@Z @ 562 NONAME ABSENT ; void QDeclarativeAnchors::setVerticalCenterOffset(float) ??1QDeclarativeDebugWatch@@UAE@XZ @ 563 NONAME ABSENT ; QDeclarativeDebugWatch::~QDeclarativeDebugWatch(void) ??1QPacketAutoSend@@UAE@XZ @ 564 NONAME ABSENT ; QPacketAutoSend::~QPacketAutoSend(void) @@ -641,7 +641,7 @@ EXPORTS ?d_func@QDeclarativeItem@@AAEPAVQDeclarativeItemPrivate@@XZ @ 640 NONAME ; class QDeclarativeItemPrivate * QDeclarativeItem::d_func(void) ?binding@QDeclarativeDomValueBinding@@QBE?AVQString@@XZ @ 641 NONAME ABSENT ; class QString QDeclarativeDomValueBinding::binding(void) const ?updateAutoState@QDeclarativeStateGroup@@AAE_NXZ @ 642 NONAME ; bool QDeclarativeStateGroup::updateAutoState(void) - ?tr@QDeclarativeDebugService@@SA?AVQString@@PBD0@Z @ 643 NONAME ABSENT ; class QString QDeclarativeDebugService::tr(char const *, char const *) + ?tr@QDeclarativeDebugService@@SA?AVQString@@PBD0@Z @ 643 NONAME ; class QString QDeclarativeDebugService::tr(char const *, char const *) ?tr@QDeclarativeComponent@@SA?AVQString@@PBD0H@Z @ 644 NONAME ; class QString QDeclarativeComponent::tr(char const *, char const *, int) ??1QDeclarativeProperty@@QAE@XZ @ 645 NONAME ; QDeclarativeProperty::~QDeclarativeProperty(void) ?fontChanged@QDeclarativeText@@IAEXABVQFont@@@Z @ 646 NONAME ABSENT ; void QDeclarativeText::fontChanged(class QFont const &) @@ -667,14 +667,14 @@ EXPORTS ?getStaticMetaObject@QDeclarativeListModel@@SAABUQMetaObject@@XZ @ 666 NONAME ABSENT ; struct QMetaObject const & QDeclarativeListModel::getStaticMetaObject(void) ?setStdCppSet@QMetaPropertyBuilder@@QAEX_N@Z @ 667 NONAME ABSENT ; void QMetaPropertyBuilder::setStdCppSet(bool) ??0QDeclarativeItemPrivate@@QAE@XZ @ 668 NONAME ; QDeclarativeItemPrivate::QDeclarativeItemPrivate(void) - ??0QDeclarativeDebugService@@QAE@ABVQString@@PAVQObject@@@Z @ 669 NONAME ABSENT ; QDeclarativeDebugService::QDeclarativeDebugService(class QString const &, class QObject *) + ??0QDeclarativeDebugService@@QAE@ABVQString@@PAVQObject@@@Z @ 669 NONAME ; QDeclarativeDebugService::QDeclarativeDebugService(class QString const &, class QObject *) ?load@QDeclarativePixmap@@QAEXPAVQDeclarativeEngine@@ABVQUrl@@_N@Z @ 670 NONAME ; void QDeclarativePixmap::load(class QDeclarativeEngine *, class QUrl const &, bool) ??_EQPacketAutoSend@@UAE@I@Z @ 671 NONAME ABSENT ; QPacketAutoSend::~QPacketAutoSend(unsigned int) ?saveValueType@QDeclarativePropertyPrivate@@SA?AVQByteArray@@PBUQMetaObject@@H0H@Z @ 672 NONAME ABSENT ; class QByteArray QDeclarativePropertyPrivate::saveValueType(struct QMetaObject const *, int, struct QMetaObject const *, int) ?resetHeight@QDeclarativeItem@@QAEXXZ @ 673 NONAME ; void QDeclarativeItem::resetHeight(void) ?setVAlign@QDeclarativeText@@QAEXW4VAlignment@1@@Z @ 674 NONAME ABSENT ; void QDeclarativeText::setVAlign(enum QDeclarativeText::VAlignment) - ??1QDeclarativeDebugService@@UAE@XZ @ 675 NONAME ABSENT ; QDeclarativeDebugService::~QDeclarativeDebugService(void) - ?trUtf8@QDeclarativeDebugService@@SA?AVQString@@PBD0H@Z @ 676 NONAME ABSENT ; class QString QDeclarativeDebugService::trUtf8(char const *, char const *, int) + ??1QDeclarativeDebugService@@UAE@XZ @ 675 NONAME ; QDeclarativeDebugService::~QDeclarativeDebugService(void) + ?trUtf8@QDeclarativeDebugService@@SA?AVQString@@PBD0H@Z @ 676 NONAME ; class QString QDeclarativeDebugService::trUtf8(char const *, char const *, int) ?elideMode@QDeclarativeText@@QBE?AW4TextElideMode@1@XZ @ 677 NONAME ABSENT ; enum QDeclarativeText::TextElideMode QDeclarativeText::elideMode(void) const ?baseUrl@QDeclarativeContext@@QBE?AVQUrl@@XZ @ 678 NONAME ; class QUrl QDeclarativeContext::baseUrl(void) const ?qt_metacall@QDeclarativeDebugRootContextQuery@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 679 NONAME ABSENT ; int QDeclarativeDebugRootContextQuery::qt_metacall(enum QMetaObject::Call, int, void * *) @@ -849,7 +849,7 @@ EXPORTS ??1QDeclarativeBehavior@@UAE@XZ @ 848 NONAME ABSENT ; QDeclarativeBehavior::~QDeclarativeBehavior(void) ?qmlInfo@@YA?AVQDeclarativeInfo@@PBVQObject@@@Z @ 849 NONAME ; class QDeclarativeInfo qmlInfo(class QObject const *) ?qt_metacall@QDeclarativeDebugClient@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 850 NONAME ABSENT ; int QDeclarativeDebugClient::qt_metacall(enum QMetaObject::Call, int, void * *) - ?d_func@QDeclarativeDebugService@@ABEPBVQDeclarativeDebugServicePrivate@@XZ @ 851 NONAME ABSENT ; class QDeclarativeDebugServicePrivate const * QDeclarativeDebugService::d_func(void) const + ?d_func@QDeclarativeDebugService@@ABEPBVQDeclarativeDebugServicePrivate@@XZ @ 851 NONAME ; class QDeclarativeDebugServicePrivate const * QDeclarativeDebugService::d_func(void) const ??1QDeclarativeDebugQuery@@UAE@XZ @ 852 NONAME ABSENT ; QDeclarativeDebugQuery::~QDeclarativeDebugQuery(void) ?data_append@QDeclarativeItemPrivate@@SAXPAV?$QDeclarativeListProperty@VQObject@@@@PAVQObject@@@Z @ 853 NONAME ; void QDeclarativeItemPrivate::data_append(class QDeclarativeListProperty *, class QObject *) ?tr@QDeclarativeState@@SA?AVQString@@PBD0@Z @ 854 NONAME ; class QString QDeclarativeState::tr(char const *, char const *) @@ -1120,7 +1120,7 @@ EXPORTS ?expression@QDeclarativeDebugExpressionQuery@@QBE?AVQVariant@@XZ @ 1119 NONAME ABSENT ; class QVariant QDeclarativeDebugExpressionQuery::expression(void) const ??4QDeclarativeDomList@@QAEAAV0@ABV0@@Z @ 1120 NONAME ABSENT ; class QDeclarativeDomList & QDeclarativeDomList::operator=(class QDeclarativeDomList const &) ?qt_metacall@QDeclarativeComponent@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 1121 NONAME ; int QDeclarativeComponent::qt_metacall(enum QMetaObject::Call, int, void * *) - ?tr@QDeclarativeDebugService@@SA?AVQString@@PBD0H@Z @ 1122 NONAME ABSENT ; class QString QDeclarativeDebugService::tr(char const *, char const *, int) + ?tr@QDeclarativeDebugService@@SA?AVQString@@PBD0H@Z @ 1122 NONAME ; class QString QDeclarativeDebugService::tr(char const *, char const *, int) ?staticMetaObject@QDeclarativeEngine@@2UQMetaObject@@B @ 1123 NONAME ; struct QMetaObject const QDeclarativeEngine::staticMetaObject ?staticMetaObject@QDeclarativeStateOperation@@2UQMetaObject@@B @ 1124 NONAME ; struct QMetaObject const QDeclarativeStateOperation::staticMetaObject ?actions@QDeclarativeStateOperation@@UAE?AV?$QList@VQDeclarativeAction@@@@XZ @ 1125 NONAME ; class QList QDeclarativeStateOperation::actions(void) @@ -1145,7 +1145,7 @@ EXPORTS ?sourceFile@QDeclarativeExpression@@QBE?AVQString@@XZ @ 1144 NONAME ; class QString QDeclarativeExpression::sourceFile(void) const ??_EQDeclarativeAnchors@@UAE@I@Z @ 1145 NONAME ABSENT ; QDeclarativeAnchors::~QDeclarativeAnchors(unsigned int) ?removeNotifySignal@QMetaPropertyBuilder@@QAEXXZ @ 1146 NONAME ABSENT ; void QMetaPropertyBuilder::removeNotifySignal(void) - ?trUtf8@QDeclarativeDebugService@@SA?AVQString@@PBD0@Z @ 1147 NONAME ABSENT ; class QString QDeclarativeDebugService::trUtf8(char const *, char const *) + ?trUtf8@QDeclarativeDebugService@@SA?AVQString@@PBD0@Z @ 1147 NONAME ; class QString QDeclarativeDebugService::trUtf8(char const *, char const *) ?setImportPathList@QDeclarativeEngine@@QAEXABVQStringList@@@Z @ 1148 NONAME ; void QDeclarativeEngine::setImportPathList(class QStringList const &) ?enabledChanged@QDeclarativeDebugService@@MAEX_N@Z @ 1149 NONAME ABSENT ; void QDeclarativeDebugService::enabledChanged(bool) ?addWatch@QDeclarativeEngineDebug@@QAEPAVQDeclarativeDebugWatch@@ABVQDeclarativeDebugObjectReference@@PAVQObject@@@Z @ 1150 NONAME ABSENT ; class QDeclarativeDebugWatch * QDeclarativeEngineDebug::addWatch(class QDeclarativeDebugObjectReference const &, class QObject *) @@ -1176,7 +1176,7 @@ EXPORTS ?paint@QDeclarativeRectangle@@UAEXPAVQPainter@@PBVQStyleOptionGraphicsItem@@PAVQWidget@@@Z @ 1175 NONAME ABSENT ; void QDeclarativeRectangle::paint(class QPainter *, class QStyleOptionGraphicsItem const *, class QWidget *) ??6QDeclarativeState@@QAEAAV0@PAVQDeclarativeStateOperation@@@Z @ 1176 NONAME ; class QDeclarativeState & QDeclarativeState::operator<<(class QDeclarativeStateOperation *) ?destroy@QDeclarativeAbstractBinding@@UAEXXZ @ 1177 NONAME ABSENT ; void QDeclarativeAbstractBinding::destroy(void) - ?qt_metacast@QDeclarativeDebugService@@UAEPAXPBD@Z @ 1178 NONAME ABSENT ; void * QDeclarativeDebugService::qt_metacast(char const *) + ?qt_metacast@QDeclarativeDebugService@@UAEPAXPBD@Z @ 1178 NONAME ; void * QDeclarativeDebugService::qt_metacast(char const *) ?qt_metacast@QDeclarativeValueType@@UAEPAXPBD@Z @ 1179 NONAME ABSENT ; void * QDeclarativeValueType::qt_metacast(char const *) ?childAt@QDeclarativeItem@@QBEPAV1@MM@Z @ 1180 NONAME ; class QDeclarativeItem * QDeclarativeItem::childAt(float, float) const ?paintedWidth@QDeclarativeText@@QBEMXZ @ 1181 NONAME ABSENT ; float QDeclarativeText::paintedWidth(void) const @@ -1297,7 +1297,7 @@ EXPORTS ?value@QDeclarativeOpenMetaObject@@QBE?AVQVariant@@H@Z @ 1296 NONAME ABSENT ; class QVariant QDeclarativeOpenMetaObject::value(int) const ?tr@QDeclarativeDebugRootContextQuery@@SA?AVQString@@PBD0H@Z @ 1297 NONAME ABSENT ; class QString QDeclarativeDebugRootContextQuery::tr(char const *, char const *, int) ?setFromState@QDeclarativeTransition@@QAEXABVQString@@@Z @ 1298 NONAME ; void QDeclarativeTransition::setFromState(class QString const &) - ?metaObject@QDeclarativeDebugService@@UBEPBUQMetaObject@@XZ @ 1299 NONAME ABSENT ; struct QMetaObject const * QDeclarativeDebugService::metaObject(void) const + ?metaObject@QDeclarativeDebugService@@UBEPBUQMetaObject@@XZ @ 1299 NONAME ; struct QMetaObject const * QDeclarativeDebugService::metaObject(void) const ?state@QDeclarativeDebugQuery@@QBE?AW4State@1@XZ @ 1300 NONAME ABSENT ; enum QDeclarativeDebugQuery::State QDeclarativeDebugQuery::state(void) const ?setBottom@QDeclarativeScaleGrid@@QAEXH@Z @ 1301 NONAME ABSENT ; void QDeclarativeScaleGrid::setBottom(int) ?topMarginChanged@QDeclarativeAnchors@@IAEXXZ @ 1302 NONAME ABSENT ; void QDeclarativeAnchors::topMarginChanged(void) @@ -1305,7 +1305,7 @@ EXPORTS ?position@QDeclarativeDomObject@@QBEHXZ @ 1304 NONAME ABSENT ; int QDeclarativeDomObject::position(void) const ?update@QDeclarativeBinding@@UAEXV?$QFlags@W4WriteFlag@QDeclarativePropertyPrivate@@@@@Z @ 1305 NONAME ABSENT ; void QDeclarativeBinding::update(class QFlags) ?tr@QDeclarativeBehavior@@SA?AVQString@@PBD0@Z @ 1306 NONAME ABSENT ; class QString QDeclarativeBehavior::tr(char const *, char const *) - ?isDebuggingEnabled@QDeclarativeDebugService@@SA_NXZ @ 1307 NONAME ABSENT ; bool QDeclarativeDebugService::isDebuggingEnabled(void) + ?isDebuggingEnabled@QDeclarativeDebugService@@SA_NXZ @ 1307 NONAME ; bool QDeclarativeDebugService::isDebuggingEnabled(void) ?tr@QDeclarativeText@@SA?AVQString@@PBD0H@Z @ 1308 NONAME ABSENT ; class QString QDeclarativeText::tr(char const *, char const *, int) ?reset@QDeclarativeProperty@@QBE_NXZ @ 1309 NONAME ; bool QDeclarativeProperty::reset(void) const ?objectDebugId@QDeclarativeDebugWatch@@QBEHXZ @ 1310 NONAME ABSENT ; int QDeclarativeDebugWatch::objectDebugId(void) const @@ -1344,7 +1344,7 @@ EXPORTS ?maximumPacketSize@QPacketProtocol@@QBEHXZ @ 1343 NONAME ABSENT ; int QPacketProtocol::maximumPacketSize(void) const ??_EQDeclarativeDebuggerStatus@@UAE@I@Z @ 1344 NONAME ABSENT ; QDeclarativeDebuggerStatus::~QDeclarativeDebuggerStatus(unsigned int) ?error@QDeclarativeCustomParser@@IAEXABVQString@@@Z @ 1345 NONAME ; void QDeclarativeCustomParser::error(class QString const &) - ?messageReceived@QDeclarativeDebugService@@MAEXABVQByteArray@@@Z @ 1346 NONAME ABSENT ; void QDeclarativeDebugService::messageReceived(class QByteArray const &) + ?messageReceived@QDeclarativeDebugService@@MAEXABVQByteArray@@@Z @ 1346 NONAME ; void QDeclarativeDebugService::messageReceived(class QByteArray const &) ??0QDeclarativeParserStatus@@QAE@XZ @ 1347 NONAME ; QDeclarativeParserStatus::QDeclarativeParserStatus(void) ?isNumber@Variant@QDeclarativeParser@@QBE_NXZ @ 1348 NONAME ; bool QDeclarativeParser::Variant::isNumber(void) const ?getStaticMetaObject@QDeclarativeEngineDebug@@SAABUQMetaObject@@XZ @ 1349 NONAME ABSENT ; struct QMetaObject const & QDeclarativeEngineDebug::getStaticMetaObject(void) @@ -1475,7 +1475,7 @@ EXPORTS ?packetWritten@QPacketProtocol@@IAEXXZ @ 1474 NONAME ABSENT ; void QPacketProtocol::packetWritten(void) ?getStaticMetaObject@QDeclarativeDebugObjectQuery@@SAABUQMetaObject@@XZ @ 1475 NONAME ABSENT ; struct QMetaObject const & QDeclarativeDebugObjectQuery::getStaticMetaObject(void) ?isSignalProperty@QDeclarativeProperty@@QBE_NXZ @ 1476 NONAME ; bool QDeclarativeProperty::isSignalProperty(void) const - ?d_func@QDeclarativeDebugService@@AAEPAVQDeclarativeDebugServicePrivate@@XZ @ 1477 NONAME ABSENT ; class QDeclarativeDebugServicePrivate * QDeclarativeDebugService::d_func(void) + ?d_func@QDeclarativeDebugService@@AAEPAVQDeclarativeDebugServicePrivate@@XZ @ 1477 NONAME ; class QDeclarativeDebugServicePrivate * QDeclarativeDebugService::d_func(void) ?qmlTypeNames@QDeclarativeMetaType@@SA?AV?$QList@VQByteArray@@@@XZ @ 1478 NONAME ABSENT ; class QList QDeclarativeMetaType::qmlTypeNames(void) ?componentComplete@QDeclarativeItem@@MAEXXZ @ 1479 NONAME ; void QDeclarativeItem::componentComplete(void) ?creationContext@QDeclarativeComponent@@QBEPAVQDeclarativeContext@@XZ @ 1480 NONAME ; class QDeclarativeContext * QDeclarativeComponent::creationContext(void) const @@ -1575,7 +1575,7 @@ EXPORTS ?keyCount@QMetaEnumBuilder@@QBEHXZ @ 1574 NONAME ABSENT ; int QMetaEnumBuilder::keyCount(void) const ??1QDeclarativeDomProperty@@QAE@XZ @ 1575 NONAME ABSENT ; QDeclarativeDomProperty::~QDeclarativeDomProperty(void) ?url@QDeclarativePixmap@@QBEABVQUrl@@XZ @ 1576 NONAME ; class QUrl const & QDeclarativePixmap::url(void) const - ?sendMessage@QDeclarativeDebugService@@QAEXABVQByteArray@@@Z @ 1577 NONAME ABSENT ; void QDeclarativeDebugService::sendMessage(class QByteArray const &) + ?sendMessage@QDeclarativeDebugService@@QAEXABVQByteArray@@@Z @ 1577 NONAME ; void QDeclarativeDebugService::sendMessage(class QByteArray const &) ?context@QDeclarativeScriptString@@QBEPAVQDeclarativeContext@@XZ @ 1578 NONAME ; class QDeclarativeContext * QDeclarativeScriptString::context(void) const ?queryObject@QDeclarativeEngineDebug@@QAEPAVQDeclarativeDebugObjectQuery@@ABVQDeclarativeDebugObjectReference@@PAVQObject@@@Z @ 1579 NONAME ABSENT ; class QDeclarativeDebugObjectQuery * QDeclarativeEngineDebug::queryObject(class QDeclarativeDebugObjectReference const &, class QObject *) ?tr@QDeclarativePropertyMap@@SA?AVQString@@PBD0H@Z @ 1580 NONAME ; class QString QDeclarativePropertyMap::tr(char const *, char const *, int) @@ -1608,7 +1608,7 @@ EXPORTS ??_EQDeclarativeComponent@@UAE@I@Z @ 1607 NONAME ; QDeclarativeComponent::~QDeclarativeComponent(unsigned int) ?get@QDeclarativeItemPrivate@@SAPAV1@PAVQDeclarativeItem@@@Z @ 1608 NONAME ; class QDeclarativeItemPrivate * QDeclarativeItemPrivate::get(class QDeclarativeItem *) ?staticMetaObject@QDeclarativeView@@2UQMetaObject@@B @ 1609 NONAME ; struct QMetaObject const QDeclarativeView::staticMetaObject - ?objectToString@QDeclarativeDebugService@@SA?AVQString@@PAVQObject@@@Z @ 1610 NONAME ABSENT ; class QString QDeclarativeDebugService::objectToString(class QObject *) + ?objectToString@QDeclarativeDebugService@@SA?AVQString@@PAVQObject@@@Z @ 1610 NONAME ; class QString QDeclarativeDebugService::objectToString(class QObject *) ?defaultValue@QDeclarativeDomDynamicProperty@@QBE?AVQDeclarativeDomProperty@@XZ @ 1611 NONAME ABSENT ; class QDeclarativeDomProperty QDeclarativeDomDynamicProperty::defaultValue(void) const ?relatedMetaObject@QMetaObjectBuilder@@QBEPBUQMetaObject@@H@Z @ 1612 NONAME ABSENT ; struct QMetaObject const * QMetaObjectBuilder::relatedMetaObject(int) const ?addKey@QMetaEnumBuilder@@QAEHABVQByteArray@@H@Z @ 1613 NONAME ABSENT ; int QMetaEnumBuilder::addKey(class QByteArray const &, int) @@ -1633,7 +1633,7 @@ EXPORTS ?tr@QDeclarativeView@@SA?AVQString@@PBD0@Z @ 1632 NONAME ; class QString QDeclarativeView::tr(char const *, char const *) ?qt_metacall@QPacketProtocol@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 1633 NONAME ABSENT ; int QPacketProtocol::qt_metacall(enum QMetaObject::Call, int, void * *) ??0QDeclarativeItem@@QAE@PAV0@@Z @ 1634 NONAME ; QDeclarativeItem::QDeclarativeItem(class QDeclarativeItem *) - ?hasDebuggingClient@QDeclarativeDebugService@@SA_NXZ @ 1635 NONAME ABSENT ; bool QDeclarativeDebugService::hasDebuggingClient(void) + ?hasDebuggingClient@QDeclarativeDebugService@@SA_NXZ @ 1635 NONAME ; bool QDeclarativeDebugService::hasDebuggingClient(void) ?staticMetaObject@QDeclarativeContext@@2UQMetaObject@@B @ 1636 NONAME ; struct QMetaObject const QDeclarativeContext::staticMetaObject ?setContextForObject@QDeclarativeEngine@@SAXPAVQObject@@PAVQDeclarativeContext@@@Z @ 1637 NONAME ; void QDeclarativeEngine::setContextForObject(class QObject *, class QDeclarativeContext *) ?baselineOffsetChanged@QDeclarativeItem@@IAEXM@Z @ 1638 NONAME ; void QDeclarativeItem::baselineOffsetChanged(float) @@ -1733,7 +1733,7 @@ EXPORTS ?start@QDeclarativeTimer@@QAEXXZ @ 1732 NONAME ABSENT ; void QDeclarativeTimer::start(void) ?transition@QDeclarativeAbstractAnimation@@UAEXAAV?$QList@VQDeclarativeAction@@@@AAV?$QList@VQDeclarativeProperty@@@@W4TransitionDirection@1@@Z @ 1733 NONAME ABSENT ; void QDeclarativeAbstractAnimation::transition(class QList &, class QList &, enum QDeclarativeAbstractAnimation::TransitionDirection) ?componentComplete@QDeclarativeAbstractAnimation@@UAEXXZ @ 1734 NONAME ABSENT ; void QDeclarativeAbstractAnimation::componentComplete(void) - ?statusChanged@QDeclarativeDebugService@@MAEXW4Status@1@@Z @ 1735 NONAME ABSENT ; void QDeclarativeDebugService::statusChanged(enum QDeclarativeDebugService::Status) + ?statusChanged@QDeclarativeDebugService@@MAEXW4Status@1@@Z @ 1735 NONAME ; void QDeclarativeDebugService::statusChanged(enum QDeclarativeDebugService::Status) ?runningChanged@QDeclarativeAbstractAnimation@@IAEX_N@Z @ 1736 NONAME ABSENT ; void QDeclarativeAbstractAnimation::runningChanged(bool) ?trUtf8@QDeclarativeAbstractAnimation@@SA?AVQString@@PBD0H@Z @ 1737 NONAME ABSENT ; class QString QDeclarativeAbstractAnimation::trUtf8(char const *, char const *, int) ??_EQDeclarativeBasePositioner@@UAE@I@Z @ 1738 NONAME ABSENT ; QDeclarativeBasePositioner::~QDeclarativeBasePositioner(unsigned int) @@ -1813,7 +1813,7 @@ EXPORTS ?setTarget@QDeclarativeAbstractAnimation@@EAEXABVQDeclarativeProperty@@@Z @ 1812 NONAME ABSENT ; void QDeclarativeAbstractAnimation::setTarget(class QDeclarativeProperty const &) ?alwaysRunToEnd@QDeclarativeAbstractAnimation@@QBE_NXZ @ 1813 NONAME ABSENT ; bool QDeclarativeAbstractAnimation::alwaysRunToEnd(void) const ?tr@QDeclarativeTimer@@SA?AVQString@@PBD0H@Z @ 1814 NONAME ABSENT ; class QString QDeclarativeTimer::tr(char const *, char const *, int) - ?status@QDeclarativeDebugService@@QBE?AW4Status@1@XZ @ 1815 NONAME ABSENT ; enum QDeclarativeDebugService::Status QDeclarativeDebugService::status(void) const + ?status@QDeclarativeDebugService@@QBE?AW4Status@1@XZ @ 1815 NONAME ; enum QDeclarativeDebugService::Status QDeclarativeDebugService::status(void) const ?intervalChanged@QDeclarativeTimer@@IAEXXZ @ 1816 NONAME ABSENT ; void QDeclarativeTimer::intervalChanged(void) ?isPaused@QDeclarativeAbstractAnimation@@QBE_NXZ @ 1817 NONAME ABSENT ; bool QDeclarativeAbstractAnimation::isPaused(void) const ?getStaticMetaObject@QDeclarativeAbstractAnimation@@SAABUQMetaObject@@XZ @ 1818 NONAME ABSENT ; struct QMetaObject const & QDeclarativeAbstractAnimation::getStaticMetaObject(void) diff --git a/src/s60installs/eabi/QtDeclarativeu.def b/src/s60installs/eabi/QtDeclarativeu.def index 1ed68a8..b4f54d8 100644 --- a/src/s60installs/eabi/QtDeclarativeu.def +++ b/src/s60installs/eabi/QtDeclarativeu.def @@ -761,20 +761,20 @@ EXPORTS _ZN24QDeclarativeCustomParser5errorERK28QDeclarativeCustomParserNodeRK7QString @ 760 NONAME _ZN24QDeclarativeCustomParser5errorERK32QDeclarativeCustomParserPropertyRK7QString @ 761 NONAME _ZN24QDeclarativeCustomParser5errorERK7QString @ 762 NONAME - _ZN24QDeclarativeDebugService11idForObjectEP7QObject @ 763 NONAME ABSENT - _ZN24QDeclarativeDebugService11objectForIdEi @ 764 NONAME ABSENT - _ZN24QDeclarativeDebugService11qt_metacallEN11QMetaObject4CallEiPPv @ 765 NONAME ABSENT - _ZN24QDeclarativeDebugService11qt_metacastEPKc @ 766 NONAME ABSENT - _ZN24QDeclarativeDebugService11sendMessageERK10QByteArray @ 767 NONAME ABSENT + _ZN24QDeclarativeDebugService11idForObjectEP7QObject @ 763 NONAME + _ZN24QDeclarativeDebugService11objectForIdEi @ 764 NONAME + _ZN24QDeclarativeDebugService11qt_metacallEN11QMetaObject4CallEiPPv @ 765 NONAME + _ZN24QDeclarativeDebugService11qt_metacastEPKc @ 766 NONAME + _ZN24QDeclarativeDebugService11sendMessageERK10QByteArray @ 767 NONAME _ZN24QDeclarativeDebugService14enabledChangedEb @ 768 NONAME ABSENT - _ZN24QDeclarativeDebugService14objectToStringEP7QObject @ 769 NONAME ABSENT - _ZN24QDeclarativeDebugService15messageReceivedERK10QByteArray @ 770 NONAME ABSENT - _ZN24QDeclarativeDebugService16staticMetaObjectE @ 771 NONAME DATA 16 ABSENT - _ZN24QDeclarativeDebugService18hasDebuggingClientEv @ 772 NONAME ABSENT - _ZN24QDeclarativeDebugService18isDebuggingEnabledEv @ 773 NONAME ABSENT - _ZN24QDeclarativeDebugService19getStaticMetaObjectEv @ 774 NONAME ABSENT - _ZN24QDeclarativeDebugServiceC1ERK7QStringP7QObject @ 775 NONAME ABSENT - _ZN24QDeclarativeDebugServiceC2ERK7QStringP7QObject @ 776 NONAME ABSENT + _ZN24QDeclarativeDebugService14objectToStringEP7QObject @ 769 NONAME + _ZN24QDeclarativeDebugService15messageReceivedERK10QByteArray @ 770 NONAME + _ZN24QDeclarativeDebugService16staticMetaObjectE @ 771 NONAME DATA 16 + _ZN24QDeclarativeDebugService18hasDebuggingClientEv @ 772 NONAME + _ZN24QDeclarativeDebugService18isDebuggingEnabledEv @ 773 NONAME + _ZN24QDeclarativeDebugService19getStaticMetaObjectEv @ 774 NONAME + _ZN24QDeclarativeDebugServiceC1ERK7QStringP7QObject @ 775 NONAME + _ZN24QDeclarativeDebugServiceC2ERK7QStringP7QObject @ 776 NONAME _ZN24QDeclarativeDomComponentC1ERKS_ @ 777 NONAME ABSENT _ZN24QDeclarativeDomComponentC1Ev @ 778 NONAME ABSENT _ZN24QDeclarativeDomComponentC2ERKS_ @ 779 NONAME ABSENT @@ -1425,8 +1425,8 @@ EXPORTS _ZNK23QDeclarativePropertyMapixERK7QString @ 1424 NONAME _ZNK24QDeclarativeCustomParser11resolveTypeERK10QByteArray @ 1425 NONAME _ZNK24QDeclarativeCustomParser12evaluateEnumERK10QByteArray @ 1426 NONAME - _ZNK24QDeclarativeDebugService10metaObjectEv @ 1427 NONAME ABSENT - _ZNK24QDeclarativeDebugService4nameEv @ 1428 NONAME ABSENT + _ZNK24QDeclarativeDebugService10metaObjectEv @ 1427 NONAME + _ZNK24QDeclarativeDebugService4nameEv @ 1428 NONAME _ZNK24QDeclarativeDebugService9isEnabledEv @ 1429 NONAME ABSENT _ZNK24QDeclarativeDomComponent13componentRootEv @ 1430 NONAME ABSENT _ZNK24QDeclarativeScriptString11scopeObjectEv @ 1431 NONAME @@ -1554,7 +1554,7 @@ EXPORTS _ZTI23QDeclarativeItemPrivate @ 1553 NONAME _ZTI23QDeclarativePropertyMap @ 1554 NONAME _ZTI24QDeclarativeCustomParser @ 1555 NONAME - _ZTI24QDeclarativeDebugService @ 1556 NONAME ABSENT + _ZTI24QDeclarativeDebugService @ 1556 NONAME _ZTI24QDeclarativeParserStatus @ 1557 NONAME _ZTI25QDeclarativeImageProvider @ 1558 NONAME _ZTI26QDeclarativeDebuggerStatus @ 1559 NONAME ABSENT @@ -1604,7 +1604,7 @@ EXPORTS _ZTV23QDeclarativeItemPrivate @ 1603 NONAME _ZTV23QDeclarativePropertyMap @ 1604 NONAME _ZTV24QDeclarativeCustomParser @ 1605 NONAME - _ZTV24QDeclarativeDebugService @ 1606 NONAME ABSENT + _ZTV24QDeclarativeDebugService @ 1606 NONAME _ZTV24QDeclarativeParserStatus @ 1607 NONAME _ZTV25QDeclarativeImageProvider @ 1608 NONAME _ZTV26QDeclarativeDebuggerStatus @ 1609 NONAME ABSENT @@ -1777,10 +1777,10 @@ EXPORTS _ZN23QDeclarativeDebugClientD1Ev @ 1776 NONAME ABSENT _ZN23QDeclarativeDebugClientD2Ev @ 1777 NONAME ABSENT _ZN23QDeclarativeEngineDebug13statusChangedENS_6StatusE @ 1778 NONAME ABSENT - _ZN24QDeclarativeDebugService13statusChangedENS_6StatusE @ 1779 NONAME ABSENT - _ZN24QDeclarativeDebugServiceD0Ev @ 1780 NONAME ABSENT - _ZN24QDeclarativeDebugServiceD1Ev @ 1781 NONAME ABSENT - _ZN24QDeclarativeDebugServiceD2Ev @ 1782 NONAME ABSENT + _ZN24QDeclarativeDebugService13statusChangedENS_6StatusE @ 1779 NONAME + _ZN24QDeclarativeDebugServiceD0Ev @ 1780 NONAME + _ZN24QDeclarativeDebugServiceD1Ev @ 1781 NONAME + _ZN24QDeclarativeDebugServiceD2Ev @ 1782 NONAME _ZN26QDeclarativeBasePositioner10addChangedEv @ 1783 NONAME ABSENT _ZN26QDeclarativeBasePositioner10itemChangeEN13QGraphicsItem18GraphicsItemChangeERK8QVariant @ 1784 NONAME ABSENT _ZN26QDeclarativeBasePositioner10setSpacingEi @ 1785 NONAME ABSENT @@ -1851,7 +1851,7 @@ EXPORTS _ZNK17QDeclarativeTimer9isRunningEv @ 1850 NONAME ABSENT _ZNK23QDeclarativeDebugClient6statusEv @ 1851 NONAME ABSENT _ZNK23QDeclarativeEngineDebug6statusEv @ 1852 NONAME ABSENT - _ZNK24QDeclarativeDebugService6statusEv @ 1853 NONAME ABSENT + _ZNK24QDeclarativeDebugService6statusEv @ 1853 NONAME _ZNK26QDeclarativeBasePositioner10metaObjectEv @ 1854 NONAME ABSENT _ZNK26QDeclarativeBasePositioner3addEv @ 1855 NONAME ABSENT _ZNK26QDeclarativeBasePositioner4moveEv @ 1856 NONAME ABSENT -- cgit v0.12 From 99512251be8e5814238ec398854a8aa71fa8b25d Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 16 Mar 2011 10:23:06 +1000 Subject: Optimization and benchmark for setting object properties from QML. Change-Id: Ib923e5d3946e99001ef682a9dd8ca6d7788818a3 Reviewed-by: Aaron Kennedy --- .../qml/qdeclarativeobjectscriptclass.cpp | 27 ++++++++++++ .../qdeclarativeecmascript/data/realToInt.qml | 11 +++++ .../tst_qdeclarativeecmascript.cpp | 13 ++++++ tests/benchmarks/declarative/script/tst_script.cpp | 49 +++++++++++++++++++++- 4 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/realToInt.qml diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp index dc3ecca..e7ab9cd 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp @@ -395,6 +395,33 @@ void QDeclarativeObjectScriptClass::setProperty(QObject *obj, } else if (value.isFunction() && !value.isRegExp()) { // this is handled by the binding creation above } else { + //### expand optimization for other known types + if (lastData->propType == QMetaType::Int && value.isNumber()) { + int rawValue = qRound(value.toNumber()); + int status = -1; + int flags = 0; + void *a[] = { (void *)&rawValue, 0, &status, &flags }; + QMetaObject::metacall(obj, QMetaObject::WriteProperty, + lastData->coreIndex, a); + return; + } else if (lastData->propType == QMetaType::QReal && value.isNumber()) { + qreal rawValue = qreal(value.toNumber()); + int status = -1; + int flags = 0; + void *a[] = { (void *)&rawValue, 0, &status, &flags }; + QMetaObject::metacall(obj, QMetaObject::WriteProperty, + lastData->coreIndex, a); + return; + } else if (lastData->propType == QMetaType::QString && value.isString()) { + const QString &rawValue = value.toString(); + int status = -1; + int flags = 0; + void *a[] = { (void *)&rawValue, 0, &status, &flags }; + QMetaObject::metacall(obj, QMetaObject::WriteProperty, + lastData->coreIndex, a); + return; + } + QVariant v; if (lastData->flags & QDeclarativePropertyCache::Data::IsQList) v = enginePriv->scriptValueToVariant(value, qMetaTypeId >()); diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/realToInt.qml b/tests/auto/declarative/qdeclarativeecmascript/data/realToInt.qml new file mode 100644 index 0000000..cbbbbf9 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/realToInt.qml @@ -0,0 +1,11 @@ +import QtQuick 1.0 +import Qt.test 1.0 + +MyQmlObject { + function test1() { + value = 4.2 + } + function test2() { + value = 7.9 + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index 40b0e1b..2f5581a 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -176,6 +176,7 @@ private slots: void aliasBindingsOverrideTarget(); void aliasWritesOverrideBindings(); void pushCleanContext(); + void realToInt(); void include(); @@ -3055,6 +3056,18 @@ void tst_qdeclarativeecmascript::pushCleanContext() QCOMPARE(func2.call().toInt32(), 6); } +void tst_qdeclarativeecmascript::realToInt() +{ + QDeclarativeComponent component(&engine, TEST_FILE("realToInt.qml")); + MyQmlObject *object = qobject_cast(component.create()); + QVERIFY(object != 0); + + QMetaObject::invokeMethod(object, "test1"); + QCOMPARE(object->value(), int(4)); + QMetaObject::invokeMethod(object, "test2"); + QCOMPARE(object->value(), int(8)); +} + QTEST_MAIN(tst_qdeclarativeecmascript) #include "tst_qdeclarativeecmascript.moc" diff --git a/tests/benchmarks/declarative/script/tst_script.cpp b/tests/benchmarks/declarative/script/tst_script.cpp index 2020a18..b07ffa1 100644 --- a/tests/benchmarks/declarative/script/tst_script.cpp +++ b/tests/benchmarks/declarative/script/tst_script.cpp @@ -70,6 +70,9 @@ private slots: void property_qobject(); void property_qmlobject(); + void setproperty_js(); + void setproperty_qmlobject(); + void function_js(); void function_cpp(); void function_qobject(); @@ -108,12 +111,13 @@ inline QUrl TEST_FILE(const QString &filename) class TestObject : public QObject { Q_OBJECT - Q_PROPERTY(int x READ x) + Q_PROPERTY(int x READ x WRITE setX) public: TestObject(QObject *parent = 0); int x(); + void setX(int x) { m_x = x; } void emitMySignal() { emit mySignal(); } void emitMySignalWithArgs(int n) { emit mySignalWithArgs(n); } @@ -323,6 +327,49 @@ void tst_script::property_qmlobject() } } +#define SETPROPERTY_PROGRAM \ + "(function(testObject) { return (function() { " \ + " for (var ii = 0; ii < 10000; ++ii) { " \ + " testObject.x = ii; " \ + " } " \ + "}); })" + +void tst_script::setproperty_js() +{ + QScriptEngine engine; + + QScriptValue v = engine.newObject(); + v.setProperty(QLatin1String("x"), 0); + + QScriptValueList args; + args << v; + QScriptValue prog = engine.evaluate(SETPROPERTY_PROGRAM).call(engine.globalObject(), args); + prog.call(); + + QBENCHMARK { + prog.call(); + } +} + +void tst_script::setproperty_qmlobject() +{ + QDeclarativeEngine qmlengine; + + QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(&qmlengine); + TestObject to; + + QScriptValue v = QDeclarativeEnginePrivate::get(&qmlengine)->objectClass->newQObject(&to); + + QScriptValueList args; + args << v; + QScriptValue prog = engine->evaluate(SETPROPERTY_PROGRAM).call(engine->globalObject(), args); + prog.call(); + + QBENCHMARK { + prog.call(); + } +} + #define FUNCTION_PROGRAM \ "(function(testObject) { return (function() { " \ " var test = 0; " \ -- cgit v0.12 From b3f605aebb90dc651e73a252788a81cb530a74b9 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Fri, 18 Feb 2011 16:19:23 +1000 Subject: Stop the animation driver when there are no more animations. Change-Id: If03c9e4539e984db725f7e7d89e8b565890fcbed Reviewed-by: Gunnar Sletta --- src/corelib/animation/qabstractanimation.cpp | 3 ++- src/corelib/animation/qabstractanimation_p.h | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index 2d5cfab..a562542 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -254,7 +254,8 @@ void QUnifiedTimer::restartAnimationTimer() } else if (!driver->isRunning() || isPauseTimerActive) { driver->start(); isPauseTimerActive = false; - } + } else if (runningLeafAnimations == 0) + driver->stop(); } void QUnifiedTimer::setTimingInterval(int interval) diff --git a/src/corelib/animation/qabstractanimation_p.h b/src/corelib/animation/qabstractanimation_p.h index 1ab05cd..2c0eee7 100644 --- a/src/corelib/animation/qabstractanimation_p.h +++ b/src/corelib/animation/qabstractanimation_p.h @@ -184,6 +184,9 @@ public: void restartAnimationTimer(); void updateAnimationsTime(); + //useful for profiling/debugging + int runningAnimationCount() { return animations.count(); } + protected: void timerEvent(QTimerEvent *); -- cgit v0.12 From cc016cc9cfba9b35a852399603c6d3f99e31af58 Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Mon, 14 Mar 2011 12:06:04 +0200 Subject: QS60Style: QTreeView::indexRowSizeHint returns incorrect value Fix for http://bugreports.qt.nokia.com/browse/QTBUG-17786. QS60Style tries to work around the hardcoded margin that the QCommonStyle adds to menu items (line 4782 in my QCommonStyle.cpp). Unfortunately regular itemview items are handled in the same code branch in QS60Style, so the class incorrectly reduces the itemview height 8 pixels. The reduction should only happen with menu items. Task-number: QTBUG-17786 Reviewed-by: Laszlo Agocs (cherry picked from commit 8b7c98123eadf9263c6bde4b1263bd64fc388c8d) --- src/gui/styles/qs60style.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index c949326..d0ca407 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -2643,10 +2643,13 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt, sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget); //native items have small empty areas at the beginning and end of menu item sz.setWidth(sz.width() + 2 * pixelMetric(PM_MenuHMargin) + 2 * QS60StylePrivate::pixelMetric(PM_FrameCornerWidth)); - if (QS60StylePrivate::isTouchSupported()) + if (QS60StylePrivate::isTouchSupported()) { //Make itemview easier to use in touch devices + sz.setHeight(sz.height() + 2 * pixelMetric(PM_FocusFrameVMargin)); //QCommonStyle does not adjust height with horizontal margin, it only adjusts width - sz.setHeight(sz.height() + 2 * pixelMetric(PM_FocusFrameVMargin) - 8); //QCommonstyle adds 8 to height that this style handles through PM values + if (ct == CT_MenuItem) + sz.setHeight(sz.height() - 8); //QCommonstyle adds 8 to height that this style handles through PM values + } break; #ifndef QT_NO_COMBOBOX case CT_ComboBox: { -- cgit v0.12 From 3fa85afd04ba67c762ca7489c63b4bfc4a6deac0 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 14 Mar 2011 13:53:44 +0200 Subject: Fix qgraphicstransform autotest for Symbian, where qreal is float. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-17907 Reviewed-by: Samuel Rødal (cherry picked from commit 99aa67f649c44dda8c0da639b4925dbb0e4c9b70) --- tests/auto/qgraphicstransform/tst_qgraphicstransform.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/tests/auto/qgraphicstransform/tst_qgraphicstransform.cpp b/tests/auto/qgraphicstransform/tst_qgraphicstransform.cpp index fe66ffa..c8de7fd 100644 --- a/tests/auto/qgraphicstransform/tst_qgraphicstransform.cpp +++ b/tests/auto/qgraphicstransform/tst_qgraphicstransform.cpp @@ -163,10 +163,11 @@ static inline bool fuzzyCompare(qreal p1, qreal p2) { // increase delta on small machines using float instead of double if (sizeof(qreal) == sizeof(float)) - return (qAbs(p1 - p2) <= 0.00002f * qMin(qAbs(p1), qAbs(p2))); + return (qAbs(p1 - p2) <= 0.00003f * qMin(qAbs(p1), qAbs(p2))); else return (qAbs(p1 - p2) <= 0.00001f * qMin(qAbs(p1), qAbs(p2))); } + static bool fuzzyCompare(const QTransform& t1, const QTransform& t2) { return fuzzyCompare(t1.m11(), t2.m11()) && @@ -180,6 +181,15 @@ static bool fuzzyCompare(const QTransform& t1, const QTransform& t2) fuzzyCompare(t1.m33(), t2.m33()); } +static inline bool fuzzyCompare(const QMatrix4x4& m1, const QMatrix4x4& m2) +{ + bool ok = true; + for (int y = 0; y < 4; ++y) + for (int x = 0; x < 4; ++x) + ok &= fuzzyCompare(m1(y, x), m2(y, x)); + return ok; +} + void tst_QGraphicsTransform::rotation() { QGraphicsRotation rotation; @@ -267,7 +277,7 @@ void tst_QGraphicsTransform::rotation3d() // because the deg2rad value in QTransform is not accurate // enough to match what QMatrix4x4 is doing. } else { - QVERIFY(qFuzzyCompare(t, r)); + QVERIFY(fuzzyCompare(t, r)); } //now let's check that a null vector will not change the transform -- cgit v0.12 From a92f15eaae6981bf420477e4736f169b4224a6c4 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 16 Mar 2011 13:52:28 +0200 Subject: Fix for wrong dpi metrics for raster pixmaps on Symbian. The original implementation relied on SizeInTwips() for the underlying bitmap which unfortunately returns 0, leading to incorrect results from QPixmap::logicalDpiX/Y(). This caused issues in text rendering onto pixmaps (QTBUG-17628). This fix changes QS60PixmapData to use a slightly different metrics() implementation (the one VG and GL PixmapData are using). Task-number: QTBUG-18154 Reviewed-by: Jani Hautakangas (cherry picked from commit 48629ab39aa4e20b21a359dc251569a98606983d) --- src/gui/image/qpixmap_s60.cpp | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/src/gui/image/qpixmap_s60.cpp b/src/gui/image/qpixmap_s60.cpp index 2bde2e5..0de99f8 100644 --- a/src/gui/image/qpixmap_s60.cpp +++ b/src/gui/image/qpixmap_s60.cpp @@ -599,6 +599,9 @@ bool QS60PixmapData::scroll(int dx, int dy, const QRect &rect) return res; } +Q_GUI_EXPORT int qt_defaultDpiX(); +Q_GUI_EXPORT int qt_defaultDpiY(); + int QS60PixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const { if (!cfbsBitmap) @@ -609,28 +612,18 @@ int QS60PixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const return cfbsBitmap->SizeInPixels().iWidth; case QPaintDevice::PdmHeight: return cfbsBitmap->SizeInPixels().iHeight; - case QPaintDevice::PdmWidthMM: { - TInt twips = cfbsBitmap->SizeInTwips().iWidth; - return (int)(twips * (25.4/KTwipsPerInch)); - } - case QPaintDevice::PdmHeightMM: { - TInt twips = cfbsBitmap->SizeInTwips().iHeight; - return (int)(twips * (25.4/KTwipsPerInch)); - } + case QPaintDevice::PdmWidthMM: + return qRound(cfbsBitmap->SizeInPixels().iWidth * 25.4 / qt_defaultDpiX()); + case QPaintDevice::PdmHeightMM: + return qRound(cfbsBitmap->SizeInPixels().iHeight * 25.4 / qt_defaultDpiY()); case QPaintDevice::PdmNumColors: return TDisplayModeUtils::NumDisplayModeColors(cfbsBitmap->DisplayMode()); case QPaintDevice::PdmDpiX: - case QPaintDevice::PdmPhysicalDpiX: { - TReal inches = cfbsBitmap->SizeInTwips().iWidth / (TReal)KTwipsPerInch; - TInt pixels = cfbsBitmap->SizeInPixels().iWidth; - return pixels / inches; - } + case QPaintDevice::PdmPhysicalDpiX: + return qt_defaultDpiX(); case QPaintDevice::PdmDpiY: - case QPaintDevice::PdmPhysicalDpiY: { - TReal inches = cfbsBitmap->SizeInTwips().iHeight / (TReal)KTwipsPerInch; - TInt pixels = cfbsBitmap->SizeInPixels().iHeight; - return pixels / inches; - } + case QPaintDevice::PdmPhysicalDpiY: + return qt_defaultDpiY(); case QPaintDevice::PdmDepth: return TDisplayModeUtils::NumDisplayModeBitsPerPixel(cfbsBitmap->DisplayMode()); default: -- cgit v0.12 From 0f5feed7dc260eabe1c2784a168e0b2fcc85e1d8 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 16 Mar 2011 17:20:32 +1000 Subject: Fix QUnifiedTimer bug Pause animations (like Timer) could trigger a jump to the next tick, which meant that other pause animations would have missed the interval skipped by the pause. Change-Id: Idebe4cbe70b2a1536d684288fc1c5d65e4c5df84 Cherry-pick-of: 115d437efb25adc2262460e001c034ea3cd8ba14 Task-number: QTBUG-18126 Reviewed-by: Leo Cunha Reviewed-by: Michael Brasser --- src/corelib/animation/qabstractanimation.cpp | 8 +++++++- src/corelib/animation/qabstractanimation_p.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index a562542..55e511d 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -167,7 +167,7 @@ Q_GLOBAL_STATIC(QThreadStorage, unifiedTimer) QUnifiedTimer::QUnifiedTimer() : QObject(), defaultDriver(this), lastTick(0), timingInterval(DEFAULT_TIMER_INTERVAL), - currentAnimationIdx(0), consistentTiming(false), slowMode(false), + insideTick(false), currentAnimationIdx(0), consistentTiming(false), slowMode(false), slowdownFactor(5.0f), isPauseTimerActive(false), runningLeafAnimations(0) { time.invalidate(); @@ -206,6 +206,10 @@ void QUnifiedTimer::ensureTimerUpdate() void QUnifiedTimer::updateAnimationsTime() { + //setCurrentTime can get this called again while we're the for loop. At least with pauseAnimations + if(insideTick) + return; + qint64 totalElapsed = time.elapsed(); // ignore consistentTiming in case the pause timer is active int delta = (consistentTiming && !isPauseTimerActive) ? @@ -223,12 +227,14 @@ void QUnifiedTimer::updateAnimationsTime() //it might happen in some cases that the time doesn't change because events are delayed //when the CPU load is high if (delta) { + insideTick = true; for (currentAnimationIdx = 0; currentAnimationIdx < animations.count(); ++currentAnimationIdx) { QAbstractAnimation *animation = animations.at(currentAnimationIdx); int elapsed = QAbstractAnimationPrivate::get(animation)->totalCurrentTime + (animation->direction() == QAbstractAnimation::Forward ? delta : -delta); animation->setCurrentTime(elapsed); } + insideTick = false; currentAnimationIdx = 0; } } diff --git a/src/corelib/animation/qabstractanimation_p.h b/src/corelib/animation/qabstractanimation_p.h index 2c0eee7..0ccc502 100644 --- a/src/corelib/animation/qabstractanimation_p.h +++ b/src/corelib/animation/qabstractanimation_p.h @@ -205,6 +205,7 @@ private: qint64 lastTick; int timingInterval; int currentAnimationIdx; + bool insideTick; bool consistentTiming; bool slowMode; -- cgit v0.12 From 7f76be56573f47fc163fa5556061a890cf0c338f Mon Sep 17 00:00:00 2001 From: Timo Turunen Date: Tue, 22 Mar 2011 15:21:10 +0200 Subject: Changes for 4.7.3 Reviewed-by: Trust Me (cherry picked from commit 5054d7ecdb3bd3fc1c5bf77a99b1675c26ba9795) --- dist/changes-4.7.3 | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/dist/changes-4.7.3 b/dist/changes-4.7.3 index e69de29..fa8a71e 100644 --- a/dist/changes-4.7.3 +++ b/dist/changes-4.7.3 @@ -0,0 +1,47 @@ +Qt 4.7.3 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 4.7.0. For more details, +refer to the online documentation included in this distribution. The +documentation is also available online: + +http://qt.nokia.com/doc/4.7 + +The Qt version 4.7 series is binary compatible with the 4.6.x series. +Applications compiled for 4.6 will continue to run with 4.7. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker or the Merge Request queue +of the public source repository. + +Qt Bug Tracker: http://bugreports.qt.nokia.com +Merge Request: http://qt.gitorious.org + +**************************************************************************** +* Platform Specific Changes * +**************************************************************************** + +Qt for Symbian +-------------- + +- Bearer Management +* [QTBUG-15108] Deadlock between SymbianEngine mutex and +QNetworkConfigurationPrivate mutex in the symbian bearer code +* [QTBUG-17627] qnetworksession.h Q_DECLARE_METATYPE breaks building +QtMobility QtBearer depending applications + +- GraphicsView +* [QTBUG-17966] Major regression in QGraphicsView OpenVG backend + +- Declarative +* [QTBUG-17503] Export qml debugging symbols on Symbian + +- Widgets +* [QTBUG-17786] BC between Qt 4.7.3 and 4.6.3 QTreeView::indexRowSizeHint +doesn't return correct value on Symbian for row when QPushButton widget is +inserted in the treeview + +- Painting +* [QTBUG-17907] tst_QGraphicsTransform::rotation3d test case from +tests/auto/qgraphicstransfor is failed for some rotation angle on +Symbian^3 devices +* [QTBUG-18154] Symbian's QPixmap::logicalDpi[X\Y]() incorrectly +returns MAXINT -- cgit v0.12 From 6567653a003191508ee5561dcd9896cb97cf3ec3 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Thu, 24 Mar 2011 10:05:07 +1000 Subject: Remove compile warning Change-Id: If209db684878ab734b3265b479c59dfc27b18be1 --- src/corelib/animation/qabstractanimation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index 55e511d..0a1f5d7 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -167,7 +167,7 @@ Q_GLOBAL_STATIC(QThreadStorage, unifiedTimer) QUnifiedTimer::QUnifiedTimer() : QObject(), defaultDriver(this), lastTick(0), timingInterval(DEFAULT_TIMER_INTERVAL), - insideTick(false), currentAnimationIdx(0), consistentTiming(false), slowMode(false), + currentAnimationIdx(0), insideTick(false), consistentTiming(false), slowMode(false), slowdownFactor(5.0f), isPauseTimerActive(false), runningLeafAnimations(0) { time.invalidate(); -- cgit v0.12 From 1f6c02c290b3330c7c784c83b1c0f8a94155f9e5 Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Fri, 25 Mar 2011 15:17:16 +0100 Subject: QSslSocket: add test for blacklisted certificates Reviewed-by: Richard J. Moore Task-number: QTBUG-18338 (cherry picked from commit 764e060a389a18a5804d23c528abdaebcee3ca13) --- .../auto/qsslsocket/certs/fake-login.live.com.key | 15 ++++++++ .../auto/qsslsocket/certs/fake-login.live.com.pem | 19 ++++++++++ tests/auto/qsslsocket/tst_qsslsocket.cpp | 43 ++++++++++++++++++++-- 3 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 tests/auto/qsslsocket/certs/fake-login.live.com.key create mode 100644 tests/auto/qsslsocket/certs/fake-login.live.com.pem diff --git a/tests/auto/qsslsocket/certs/fake-login.live.com.key b/tests/auto/qsslsocket/certs/fake-login.live.com.key new file mode 100644 index 0000000..692a7bd --- /dev/null +++ b/tests/auto/qsslsocket/certs/fake-login.live.com.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQDOtxdvMa0VHUQYG5q7Tsi1Jj4qKEJppyZEkmuRXOi0fDbd1SwE +bwHrLGMvDO6OMrYBbq3WDNrtnIfF9CvzUOEch+gjr4hEVQqecU5fb45Wor7yNel3 +/C/gxfbzuXHrsj/gUjNghL2i10+c2NW+hUo/sWO6OusaBT6d6s7ee+YBcQIDAQAB +AoGAb8cVhu0HuLkgjyCuJMbPRRUu3ED02Iin6sB6JhplQuNAD+grayJTmUVhRJnr +jTziqhedLHe7Em1oBaSo92MutfMpXvWiccSlbNygI61VgmrJpVB+qIN5H9cQc9ql +Zymc+nIPa1+i5rsrOzlpUytTh7AsbZ27QG4tQXR/kQejEiECQQD6BgTxBeT8D7x9 +DuukoBaSCkLwx7U7P1NXx15EI3lA1nO51t6UHfvk/jGPp8Sl4wv4alJ7AQxr5uQ/ +vC3kzA/1AkEA06gNu10se8pe3n8qL2RRt+FmVjHkQdD9Mm2Dx9oWCs2A4wOSOrlo +6/nKYF1CaQNYn9HgsNbHVEUpnICVO18qDQJBALEw/uOJ1+TDikPfBSWgxx4s45Ad +GNWqZXh6NNZ5hX9r/IwiOZAjR9fcRmeW8IjYRi2BvH6sGY+HDRAWXzgdXtkCQCma +dOiJTf8fLjqp4E7kdzOfuI/kyqstOze4Uxjrgz2oW1dEEnA8laUcumzqp+0gXUE8 +7d+UuCWWWrGKjMrYz9kCQQDh5E5+b6Djn082Jo6gvyuXWC5eXju6IdmihlJ2SMzD +s2y3IDjOUtTeQQRDymLneteMz0ha79KeUp6VnAvZCOVe +-----END RSA PRIVATE KEY----- diff --git a/tests/auto/qsslsocket/certs/fake-login.live.com.pem b/tests/auto/qsslsocket/certs/fake-login.live.com.pem new file mode 100644 index 0000000..429f951 --- /dev/null +++ b/tests/auto/qsslsocket/certs/fake-login.live.com.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDjCCAnegAwIBAgIRALC3Ez7Qlvm1b66RyHS9OsAwDQYJKoZIhvcNAQEFBQAw +XjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGElu +dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEXMBUGA1UEAxMObG9naW4ubGl2ZS5jb20w +HhcNMTEwMzI1MTMyODUwWhcNMTEwNDI0MTMyODUwWjBeMQswCQYDVQQGEwJBVTET +MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ +dHkgTHRkMRcwFQYDVQQDEw5sb2dpbi5saXZlLmNvbTCBnzANBgkqhkiG9w0BAQEF +AAOBjQAwgYkCgYEAzrcXbzGtFR1EGBuau07ItSY+KihCaacmRJJrkVzotHw23dUs +BG8B6yxjLwzujjK2AW6t1gza7ZyHxfQr81DhHIfoI6+IRFUKnnFOX2+OVqK+8jXp +d/wv4MX287lx67I/4FIzYIS9otdPnNjVvoVKP7FjujrrGgU+nerO3nvmAXECAwEA +AaOByzCByDAdBgNVHQ4EFgQUpSOEcmtkQITvBdM2IDfcXnJ0FCAwgZgGA1UdIwSB +kDCBjYAUpSOEcmtkQITvBdM2IDfcXnJ0FCChYqRgMF4xCzAJBgNVBAYTAkFVMRMw +EQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0 +eSBMdGQxFzAVBgNVBAMTDmxvZ2luLmxpdmUuY29tghEAsLcTPtCW+bVvrpHIdL06 +wDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAD+2HT4GSHHKCdbl9VkX +zsl+D+drMm2b0ksxz9SgPihP7aW50EEIJDEEihNMTa27mhpeOXHc/sLqDi4ECUao +/0Ns/5uoVuAIrAKCydmtPsonVFh9XWjyrfUzPOHAc9p2bmJ1i9a3kTsLB6jlrVDO +VufGzsowHlHZ0TtKf5omojU5 +-----END CERTIFICATE----- diff --git a/tests/auto/qsslsocket/tst_qsslsocket.cpp b/tests/auto/qsslsocket/tst_qsslsocket.cpp index 569a593..aa695e7 100644 --- a/tests/auto/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/qsslsocket/tst_qsslsocket.cpp @@ -183,6 +183,7 @@ private slots: void ignoreSslErrorsListWithSlot(); void readFromClosedSocket(); void writeBigChunk(); + void blacklist(); void setEmptyDefaultConfiguration(); static void exitLoop() @@ -868,8 +869,13 @@ class SslServer : public QTcpServer { Q_OBJECT public: - SslServer() : socket(0) { } + SslServer(const QString &keyFile = SRCDIR "certs/fluke.key", const QString &certFile = SRCDIR "certs/fluke.cert") + : socket(0), + m_keyFile(keyFile), + m_certFile(certFile) { } QSslSocket *socket; + QString m_keyFile; + QString m_certFile; protected: void incomingConnection(int socketDescriptor) @@ -877,13 +883,13 @@ protected: socket = new QSslSocket(this); connect(socket, SIGNAL(sslErrors(const QList &)), this, SLOT(ignoreErrorSlot())); - QFile file(SRCDIR "certs/fluke.key"); + QFile file(m_keyFile); QVERIFY(file.open(QIODevice::ReadOnly)); QSslKey key(file.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey); QVERIFY(!key.isNull()); socket->setPrivateKey(key); - QList localCert = QSslCertificate::fromPath(SRCDIR "certs/fluke.cert"); + QList localCert = QSslCertificate::fromPath(m_certFile); QVERIFY(!localCert.isEmpty()); QVERIFY(localCert.first().handle()); socket->setLocalCertificate(localCert.first()); @@ -1837,6 +1843,37 @@ void tst_QSslSocket::writeBigChunk() socket->close(); } +void tst_QSslSocket::blacklist() +{ + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + return; + + SslServer server(SRCDIR "certs/fake-login.live.com.key", SRCDIR "certs/fake-login.live.com.pem"); + QSslSocket *receiver = new QSslSocket(this); + connect(receiver, SIGNAL(readyRead()), SLOT(exitLoop())); + + // connect two sockets to each other: + QVERIFY(server.listen(QHostAddress::LocalHost)); + receiver->connectToHost("127.0.0.1", server.serverPort()); + QVERIFY(receiver->waitForConnected(5000)); + QVERIFY(server.waitForNewConnection(0)); + + QSslSocket *sender = server.socket; + QVERIFY(sender); + QVERIFY(sender->state() == QAbstractSocket::ConnectedState); + receiver->setObjectName("receiver"); + sender->setObjectName("sender"); + receiver->ignoreSslErrors(); + receiver->startClientEncryption(); + + connect(receiver, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(exitLoop())); + connect(receiver, SIGNAL(encrypted()), SLOT(exitLoop())); + enterLoop(1); + QCOMPARE(receiver->error(), QAbstractSocket::SslHandshakeFailedError); + QCOMPARE(receiver->errorString(), QString("The peer certificate is blacklisted")); +} + void tst_QSslSocket::setEmptyDefaultConfiguration() { // used to produce a crash in QSslConfigurationPrivate::deepCopyDefaultConfiguration, QTBUG-13265 -- cgit v0.12 From b3f64f1b4eb949bd639c4a088121a4c5ad2eb743 Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Fri, 25 Mar 2011 13:45:24 +0100 Subject: QSslSocket internals: abort on encountering blacklisted certificates tested manually with "openssl s_server -cert blacklisted.pem -key key.pem" and connecting a QSslSocket. Reviewed-by: Markus Goetz Task-number: QTBUG-18338 (cherry picked from commit b87528a71b66e786c11804d7b79e408aae612748) --- src/network/ssl/qsslsocket_openssl.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 7395c0a..0024ee6 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -1183,6 +1183,13 @@ bool QSslSocketBackendPrivate::startHandshake() X509 *x509 = q_SSL_get_peer_certificate(ssl); configuration.peerCertificate = QSslCertificatePrivate::QSslCertificate_from_X509(x509); q_X509_free(x509); + if (QSslCertificatePrivate::isBlacklisted(configuration.peerCertificate)) { + q->setErrorString(QSslSocket::tr("The peer certificate is blacklisted")); + q->setSocketError(QAbstractSocket::SslHandshakeFailedError); + emit q->error(QAbstractSocket::SslHandshakeFailedError); + plainSocket->disconnectFromHost(); + return false; + } // Start translating errors. QList errors; -- cgit v0.12 From c9511d642e7ab38ad2a47ba834580cfbda43ab65 Mon Sep 17 00:00:00 2001 From: Timo Turunen Date: Mon, 28 Mar 2011 20:01:19 +0300 Subject: QSslCertificate: fix test for blacklisted certs on Windows Apparently the wildcard matching and the SRCDIR hack don't go well together. Reviewed-by: Markus Goetz Task-number: QTBUG-18338 (cherry picked from commit aeabe790203e7dcb1786e0dad7b4608f1e45b7d5) Conflicts: tests/auto/qsslcertificate/tst_qsslcertificate.cpp --- tests/auto/qsslcertificate/tst_qsslcertificate.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/auto/qsslcertificate/tst_qsslcertificate.cpp b/tests/auto/qsslcertificate/tst_qsslcertificate.cpp index ccc6af9..a8c5a4d 100644 --- a/tests/auto/qsslcertificate/tst_qsslcertificate.cpp +++ b/tests/auto/qsslcertificate/tst_qsslcertificate.cpp @@ -817,6 +817,15 @@ void tst_QSslCertificate::largeExpirationDate() // QTBUG-12489 QCOMPARE(cert.expiryDate().toUTC(), QDateTime(QDate(2051, 8, 29), QTime(9, 53, 41), Qt::UTC)); } +void tst_QSslCertificate::blacklistedCertificates() +{ + QList blacklistedCerts = QSslCertificate::fromPath("more-certificates/blacklisted*.pem", QSsl::Pem, QRegExp::Wildcard); + QVERIFY2(blacklistedCerts.count() > 0, "Please run this test from the source directory"); + for (int a = 0; a < blacklistedCerts.count(); a++) { + QVERIFY(! blacklistedCerts.at(a).isValid()); + } +} + #endif // QT_NO_OPENSSL QTEST_MAIN(tst_QSslCertificate) -- cgit v0.12 From 43a8e3115fc9d13c2da2f32c3d2aafcfe0c6e543 Mon Sep 17 00:00:00 2001 From: Timo Turunen Date: Mon, 28 Mar 2011 20:24:32 +0300 Subject: QSslCertificate: report fraudulent certificates as invalid There are some fraudulent certificates in the wild that are not valid; this patch introduces a blacklist of serial numbers of those certificates. Reviewed-by: Richard J. Moore Reviewed-by: Markus Goetz Task-number: QTBUG-18338 (cherry picked from commit 04e074e8d7c097295505e63565abdc7ca2b49f7b) Conflicts: tests/auto/qsslcertificate/tst_qsslcertificate.cpp --- src/network/ssl/qsslcertificate.cpp | 34 +++++++++++++++++++--- src/network/ssl/qsslcertificate_p.h | 1 + .../more-certificates/blacklisted1.pem | 19 ++++++++++++ .../more-certificates/blacklisted2.pem | 19 ++++++++++++ .../more-certificates/blacklisted3.pem | 19 ++++++++++++ .../more-certificates/blacklisted4.pem | 19 ++++++++++++ .../more-certificates/blacklisted5.pem | 19 ++++++++++++ .../more-certificates/blacklisted6.pem | 19 ++++++++++++ .../more-certificates/blacklisted7.pem | 19 ++++++++++++ .../more-certificates/blacklisted8.pem | 19 ++++++++++++ .../more-certificates/blacklisted9.pem | 19 ++++++++++++ tests/auto/qsslcertificate/tst_qsslcertificate.cpp | 2 ++ 12 files changed, 204 insertions(+), 4 deletions(-) create mode 100644 tests/auto/qsslcertificate/more-certificates/blacklisted1.pem create mode 100644 tests/auto/qsslcertificate/more-certificates/blacklisted2.pem create mode 100644 tests/auto/qsslcertificate/more-certificates/blacklisted3.pem create mode 100644 tests/auto/qsslcertificate/more-certificates/blacklisted4.pem create mode 100644 tests/auto/qsslcertificate/more-certificates/blacklisted5.pem create mode 100644 tests/auto/qsslcertificate/more-certificates/blacklisted6.pem create mode 100644 tests/auto/qsslcertificate/more-certificates/blacklisted7.pem create mode 100644 tests/auto/qsslcertificate/more-certificates/blacklisted8.pem create mode 100644 tests/auto/qsslcertificate/more-certificates/blacklisted9.pem diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index 3053351..1bcc3c9 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -219,17 +219,19 @@ bool QSslCertificate::isNull() const Returns true if this certificate is valid; otherwise returns false. - Note: Currently, this function only checks that the current + Note: Currently, this function checks that the current data-time is within the date-time range during which the - certificate is considered valid. No other checks are - currently performed. + certificate is considered valid, and checks that the + certificate is not in a blacklist of fraudulent certificates. \sa isNull() */ bool QSslCertificate::isValid() const { const QDateTime currentTime = QDateTime::currentDateTime(); - return currentTime >= d->notValidBefore && currentTime <= d->notValidAfter; + return currentTime >= d->notValidBefore && + currentTime <= d->notValidAfter && + ! QSslCertificatePrivate::isBlacklisted(*this); } /*! @@ -798,6 +800,30 @@ QList QSslCertificatePrivate::certificatesFromDer(const QByteAr return certificates; } +// These certificates are known to be fraudulent and were created during the comodo +// compromise. See http://www.comodo.com/Comodo-Fraud-Incident-2011-03-23.html +static const char *certificate_blacklist[] = { + "04:7e:cb:e9:fc:a5:5f:7b:d0:9e:ae:36:e1:0c:ae:1e", + "f5:c8:6a:f3:61:62:f1:3a:64:f5:4f:6d:c9:58:7c:06", + "d7:55:8f:da:f5:f1:10:5b:b2:13:28:2b:70:77:29:a3", + "39:2a:43:4f:0e:07:df:1f:8a:a3:05:de:34:e0:c2:29", + "3e:75:ce:d4:6b:69:30:21:21:88:30:ae:86:a8:2a:71", + "e9:02:8b:95:78:e4:15:dc:1a:71:0a:2b:88:15:44:47", + "92:39:d5:34:8f:40:d1:69:5a:74:54:70:e1:f2:3f:43", + "b0:b7:13:3e:d0:96:f9:b5:6f:ae:91:c8:74:bd:3a:c0", + "d8:f3:5f:4e:b7:87:2b:2d:ab:06:92:e3:15:38:2f:b0", + 0 +}; + +bool QSslCertificatePrivate::isBlacklisted(const QSslCertificate &certificate) +{ + for (int a = 0; certificate_blacklist[a] != 0; a++) { + if (certificate.serialNumber() == certificate_blacklist[a]) + return true; + } + return false; +} + #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug debug, const QSslCertificate &certificate) { diff --git a/src/network/ssl/qsslcertificate_p.h b/src/network/ssl/qsslcertificate_p.h index 1f99b09..4dd0e75 100644 --- a/src/network/ssl/qsslcertificate_p.h +++ b/src/network/ssl/qsslcertificate_p.h @@ -96,6 +96,7 @@ public: static QSslCertificate QSslCertificate_from_X509(X509 *x509); static QList certificatesFromPem(const QByteArray &pem, int count = -1); static QList certificatesFromDer(const QByteArray &der, int count = -1); + static bool isBlacklisted(const QSslCertificate &certificate); friend class QSslSocketBackendPrivate; diff --git a/tests/auto/qsslcertificate/more-certificates/blacklisted1.pem b/tests/auto/qsslcertificate/more-certificates/blacklisted1.pem new file mode 100644 index 0000000..3945aea --- /dev/null +++ b/tests/auto/qsslcertificate/more-certificates/blacklisted1.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDzCCAnigAwIBAgIQBH7L6fylX3vQnq424QyuHjANBgkqhkiG9w0BAQUFADBf +MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50 +ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRgwFgYDVQQDEw9tYWlsLmdvb2dsZS5jb20w +HhcNMTEwMzI0MTMwNjI1WhcNMTEwNDIzMTMwNjI1WjBfMQswCQYDVQQGEwJBVTET +MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ +dHkgTHRkMRgwFgYDVQQDEw9tYWlsLmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEB +BQADgY0AMIGJAoGBAOeAGV2FbGnT4rLjTvCNEEDjj0/iIUATa6RT8WKF2PVaOzbE +oceiODx6hTStvBnCgs+h/d3eVKgp+uAyBde5sW/HlOwHrNgKF3ZDvxegzIOEHaVI +ndNtBpFS3UyOEkO0NxfioBatNRYpeTRU/DVmazu3yvzgrV1V2mDsrNngVWxJAgMB +AAGjgcswgcgwHQYDVR0OBBYEFHcF1eqRpm7B78aY8ZjseN6zSYbvMIGYBgNVHSME +gZAwgY2AFHcF1eqRpm7B78aY8ZjseN6zSYbvoWOkYTBfMQswCQYDVQQGEwJBVTET +MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ +dHkgTHRkMRgwFgYDVQQDEw9tYWlsLmdvb2dsZS5jb22CEAR+y+n8pV970J6uNuEM +rh4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQBEb1iF+EbhAJli5Sj2 ++iEdJ5xMP8R6FtgqAYknqXD8+tyEyXxJXdN186qdAWuTD9N22AUqi61BPWxUkufW +xH8FYMEHdFCkitvYE0321+GT5pJz6ON/d5Co+wusumt7T5oSjzj8Ax9V+nmo3Nkb +dSANM4/Lnc6moijcpJZq+GC1ng== +-----END CERTIFICATE----- diff --git a/tests/auto/qsslcertificate/more-certificates/blacklisted2.pem b/tests/auto/qsslcertificate/more-certificates/blacklisted2.pem new file mode 100644 index 0000000..4b8d059 --- /dev/null +++ b/tests/auto/qsslcertificate/more-certificates/blacklisted2.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDjCCAnegAwIBAgIRAPXIavNhYvE6ZPVPbclYfAYwDQYJKoZIhvcNAQEFBQAw +XjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGElu +dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEXMBUGA1UEAxMOd3d3Lmdvb2dsZS5jb20w +HhcNMTEwMzI0MTMwNzExWhcNMTEwNDIzMTMwNzExWjBeMQswCQYDVQQGEwJBVTET +MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ +dHkgTHRkMRcwFQYDVQQDEw53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEF +AAOBjQAwgYkCgYEAy1fNDFl65Njfcd1EUJeaxvyiKln+JKlqUmk1x4mrE1BQoa0C +QZaiXAF21rDhivWejZWBiEQ4IWbg3b12ANY74G1KqAfLC4BNKS9UP94hy18vezRA +pFc+m/HAClwc8AdACpl8eZpQW8cMgdvnMBMZTrQkgV0JYykX+uDD9Tb+QNUCAwEA +AaOByzCByDAdBgNVHQ4EFgQUSelG6IVRj2ZQbp049zkQ0X/Po9wwgZgGA1UdIwSB +kDCBjYAUSelG6IVRj2ZQbp049zkQ0X/Po9yhYqRgMF4xCzAJBgNVBAYTAkFVMRMw +EQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0 +eSBMdGQxFzAVBgNVBAMTDnd3dy5nb29nbGUuY29tghEA9chq82Fi8Tpk9U9tyVh8 +BjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBALQyDC/AMQMNj2fa6E8L +umILCklWJwG1K1p/1bUAgm0CB8zm94n1xrh/ZK4+HS+k2a9OQmvLRbFyJn8Wua8p +3UU0267UNkCanA1FKHuO3Mo18wLvjMLWjjCQ4g1C9IvJx6P+8EFDQFG+MJBV/w2k +gJXXVl3q1T1dvahIgfav9QBL +-----END CERTIFICATE----- diff --git a/tests/auto/qsslcertificate/more-certificates/blacklisted3.pem b/tests/auto/qsslcertificate/more-certificates/blacklisted3.pem new file mode 100644 index 0000000..e47ece6 --- /dev/null +++ b/tests/auto/qsslcertificate/more-certificates/blacklisted3.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDETCCAnqgAwIBAgIRANdVj9r18RBbshMoK3B3KaMwDQYJKoZIhvcNAQEFBQAw +XzELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGElu +dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEYMBYGA1UEAxMPbG9naW4ueWFob28uY29t +MB4XDTExMDMyNDEzMDg0MloXDTExMDQyMzEzMDg0MlowXzELMAkGA1UEBhMCQVUx +EzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMg +UHR5IEx0ZDEYMBYGA1UEAxMPbG9naW4ueWFob28uY29tMIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQCosFLKRvGtxjvdAjWdEAHYycFTa4VtdpXmCNhNHf2xbeLn +xzde10KjEe44pQxNI+UUD1rJkyuH6wUfloyefn0D2Mu+MvusmvOEzFosa4EDbK9s +BAAlsSiyJgrp/GgbEPq/XOl4XJRBIVP1WC6LllduNbskFCipDqS+HQwifXmmwQID +AQABo4HMMIHJMB0GA1UdDgQWBBSEgWnsoYtd5GEx/MGJvKxuIuROJzCBmQYDVR0j +BIGRMIGOgBSEgWnsoYtd5GEx/MGJvKxuIuROJ6FjpGEwXzELMAkGA1UEBhMCQVUx +EzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMg +UHR5IEx0ZDEYMBYGA1UEAxMPbG9naW4ueWFob28uY29tghEA11WP2vXxEFuyEygr +cHcpozAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAKNpIrzTOxIykKZt +EE6HU2nW1lrWUkIMjwjL8ntw7QI4JLMDN1ADVIxWaGTeQ+U/eXFou6dDNAYVAijK +ONDXgOItxW2YvSw0wOZsZj6INX2x88/0yRH+19TqaL/r+Y1D1h/0zefkHgfXufnY +Ex7BHju/rGBTp6R1mr+Tlh1tewva +-----END CERTIFICATE----- diff --git a/tests/auto/qsslcertificate/more-certificates/blacklisted4.pem b/tests/auto/qsslcertificate/more-certificates/blacklisted4.pem new file mode 100644 index 0000000..64c7d41 --- /dev/null +++ b/tests/auto/qsslcertificate/more-certificates/blacklisted4.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDzCCAnigAwIBAgIQOSpDTw4H3x+KowXeNODCKTANBgkqhkiG9w0BAQUFADBf +MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50 +ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRgwFgYDVQQDEw9sb2dpbi55YWhvby5jb20w +HhcNMTEwMzI0MTMwOTE1WhcNMTEwNDIzMTMwOTE1WjBfMQswCQYDVQQGEwJBVTET +MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ +dHkgTHRkMRgwFgYDVQQDEw9sb2dpbi55YWhvby5jb20wgZ8wDQYJKoZIhvcNAQEB +BQADgY0AMIGJAoGBANO2gz9x2H92xz5OvZSEul9gHxqqd+kdjeoS2exyvjC9wzqb +gYXqNmAsbtNp4WmieEQFd0riCAEkIAn8JpHTCsMHN4rHhS+W+4D5a/drI2jfnZEF +orNYJG1PHSQV/rvh6d7wkVdT+0SYOjrFTAA2biGWaK3W9ztf2yX577w+uQtBAgMB +AAGjgcswgcgwHQYDVR0OBBYEFJjDp8Prs7oReRmskIeFixp0vDkGMIGYBgNVHSME +gZAwgY2AFJjDp8Prs7oReRmskIeFixp0vDkGoWOkYTBfMQswCQYDVQQGEwJBVTET +MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ +dHkgTHRkMRgwFgYDVQQDEw9sb2dpbi55YWhvby5jb22CEDkqQ08OB98fiqMF3jTg +wikwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQAZyo0Q3leeM1+lxeCd +Wp0ZYHMSW11ANc6nuMWOmJC+nIQGlyGiP3IqeUvIfekwboV638bahVPwcl2HYWsS +/l01Bgyd25Zn6VTQBfMK01dILyxscjVwdHuojzYBN05sl+qkVoqQr5EroQQbgDc9 +6I88p6Kjajv3IusCwfK6wlqISw== +-----END CERTIFICATE----- diff --git a/tests/auto/qsslcertificate/more-certificates/blacklisted5.pem b/tests/auto/qsslcertificate/more-certificates/blacklisted5.pem new file mode 100644 index 0000000..c7ddbf2 --- /dev/null +++ b/tests/auto/qsslcertificate/more-certificates/blacklisted5.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDzCCAnigAwIBAgIQPnXO1GtpMCEhiDCuhqgqcTANBgkqhkiG9w0BAQUFADBf +MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50 +ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRgwFgYDVQQDEw9sb2dpbi55YWhvby5jb20w +HhcNMTEwMzI0MTMwOTQ4WhcNMTEwNDIzMTMwOTQ4WjBfMQswCQYDVQQGEwJBVTET +MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ +dHkgTHRkMRgwFgYDVQQDEw9sb2dpbi55YWhvby5jb20wgZ8wDQYJKoZIhvcNAQEB +BQADgY0AMIGJAoGBALkiHG9TgTw/00CMW8D23NBDAa3331AL5kTkAaXbAWg2R/1o +yKQfXq3hgHbyWGPccUT+tU6FmaBf3bIndLK7iGx81RGzGgXeoQ5mpgnJ50iCeW73 +G99VlVwutPia7d9qqui84YdcG9t+P2Fuxv+xRqAB6lKOaa4qTPIbH50PgwOvAgMB +AAGjgcswgcgwHQYDVR0OBBYEFBWJrs8bnZ5fikfaLbTxK0ssj69MMIGYBgNVHSME +gZAwgY2AFBWJrs8bnZ5fikfaLbTxK0ssj69MoWOkYTBfMQswCQYDVQQGEwJBVTET +MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ +dHkgTHRkMRgwFgYDVQQDEw9sb2dpbi55YWhvby5jb22CED51ztRraTAhIYgwroao +KnEwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQCIfqqs1a7RzdmV8U00 +v/xAsxscKvQvmu6BK+HwvY5iL2pSwXTYgRLJLoj5QGOd3mmgOFsyW3BPSCP1+fVE +M1ROhU2u8wHub+hGGds18Fx6F4yZjdh8pNUoOUR9A0Ym+VDJr2p50oUNTTy0RbH8 +9ns/gbemx84cjF9DD2G5stQhYg== +-----END CERTIFICATE----- diff --git a/tests/auto/qsslcertificate/more-certificates/blacklisted6.pem b/tests/auto/qsslcertificate/more-certificates/blacklisted6.pem new file mode 100644 index 0000000..bc2be2a --- /dev/null +++ b/tests/auto/qsslcertificate/more-certificates/blacklisted6.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDETCCAnqgAwIBAgIRAOkCi5V45BXcGnEKK4gVREcwDQYJKoZIhvcNAQEFBQAw +XzELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGElu +dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEYMBYGA1UEAxMPbG9naW4uc2t5cGUuY29t +MB4XDTExMDMyNDEzMTAxNloXDTExMDQyMzEzMTAxNlowXzELMAkGA1UEBhMCQVUx +EzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMg +UHR5IEx0ZDEYMBYGA1UEAxMPbG9naW4uc2t5cGUuY29tMIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQDFq06qqRl86pP7GRX3m7FMMSaSU6zlNGAo+WPoRfYAzB6x +5KpvlfxMCo3T/nWtInX3Bw9TBWCZSweQ2GEjggO0irjw5UX3MiToLxK+rwzWztm9 +H3LBxTWR0cOOa78kRFvNQ1onvNHbs8fJzXjG7b2IJDOIwG1HAT1LK80oPXZc1wID +AQABo4HMMIHJMB0GA1UdDgQWBBTiGNxw0ImW/wfW0mD3eA65PY5CAzCBmQYDVR0j +BIGRMIGOgBTiGNxw0ImW/wfW0mD3eA65PY5CA6FjpGEwXzELMAkGA1UEBhMCQVUx +EzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMg +UHR5IEx0ZDEYMBYGA1UEAxMPbG9naW4uc2t5cGUuY29tghEA6QKLlXjkFdwacQor +iBVERzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAHdb1QY/oxuro/4x +GX9jbm930ysoeXkWZSKVtVxoxrPIferu8jVpb1SLRjGcMnmjJoNWNFpvnbZgoYei +f3wdSWun7ndyQBh61k8eM7UABDOUXUHOsHuHj7s1koMKtet4gykmMfd6VxBkwBvN +ZXOll4X+TKe8nrxbnGUByIwQaRM+ +-----END CERTIFICATE----- diff --git a/tests/auto/qsslcertificate/more-certificates/blacklisted7.pem b/tests/auto/qsslcertificate/more-certificates/blacklisted7.pem new file mode 100644 index 0000000..19d4353 --- /dev/null +++ b/tests/auto/qsslcertificate/more-certificates/blacklisted7.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDGjCCAoOgAwIBAgIRAJI51TSPQNFpWnRUcOHyP0MwDQYJKoZIhvcNAQEFBQAw +YjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGElu +dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEbMBkGA1UEAxMSYWRkb25zLm1vemlsbGEu +b3JnMB4XDTExMDMyNDEzMTA0NFoXDTExMDQyMzEzMTA0NFowYjELMAkGA1UEBhMC +QVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdp +dHMgUHR5IEx0ZDEbMBkGA1UEAxMSYWRkb25zLm1vemlsbGEub3JnMIGfMA0GCSqG +SIb3DQEBAQUAA4GNADCBiQKBgQC1lsoAcZTwF8Pf0E9do5avLdobB/O7EhhrCMs2 +/EMO07aIlrLwl3UP/Fmu/cAkKuX8Mx+Eif9x+XT3ZqGKGYKiqPTJcNfeZvgwbn0j +wXDtEo4DuURrwtBU9okS+v4dF6F4RtHQKAGcsXoOjhR7ah71kve+PG2GG0sJ167V +klK1xwIDAQABo4HPMIHMMB0GA1UdDgQWBBRgGDJ4Qp0WFyLIzm4Nz5wgqDSSxjCB +nAYDVR0jBIGUMIGRgBRgGDJ4Qp0WFyLIzm4Nz5wgqDSSxqFmpGQwYjELMAkGA1UE +BhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdp +ZGdpdHMgUHR5IEx0ZDEbMBkGA1UEAxMSYWRkb25zLm1vemlsbGEub3JnghEAkjnV +NI9A0WladFRw4fI/QzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBACeE +DHMQ+LWEuoa/6z2EgrgM1k9rvBbUtCR+rjTuyzVW4OLXdpiVwZPOAiKphpq7q8Sb +TQ3zwsCoPLLJk5VolwcPfcD8Y2/tYK3NCYl+HzGxxnzPDFVaZM5Jh8RI861Hc00D +hVoQaptPK/V/lr0KEevqjhusAdFZbwlWA923zASa +-----END CERTIFICATE----- diff --git a/tests/auto/qsslcertificate/more-certificates/blacklisted8.pem b/tests/auto/qsslcertificate/more-certificates/blacklisted8.pem new file mode 100644 index 0000000..aedf3f7 --- /dev/null +++ b/tests/auto/qsslcertificate/more-certificates/blacklisted8.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDjCCAnegAwIBAgIRALC3Ez7Qlvm1b66RyHS9OsAwDQYJKoZIhvcNAQEFBQAw +XjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGElu +dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEXMBUGA1UEAxMObG9naW4ubGl2ZS5jb20w +HhcNMTEwMzI0MTMxMTA2WhcNMTEwNDIzMTMxMTA2WjBeMQswCQYDVQQGEwJBVTET +MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ +dHkgTHRkMRcwFQYDVQQDEw5sb2dpbi5saXZlLmNvbTCBnzANBgkqhkiG9w0BAQEF +AAOBjQAwgYkCgYEA3OVNj9ijzMewvDeZYzgCWoKtyjclyIHxrQfHZpcexaKbxUap +1MtF6L0ayjtRWpiBYuPteUSy/Ja4Oh6zZz8K6z5rVgXhmy3xPIYuOoWaTKEOhb0Z +oHTBtGh8aWWai1XWw37HIm2FP8cmfgdH4lZwVvpTZIUxYidsyqyjB9IrhiMCAwEA +AaOByzCByDAdBgNVHQ4EFgQU4CcQcIvEhJC0tqHlNFMkv6MlDN4wgZgGA1UdIwSB +kDCBjYAU4CcQcIvEhJC0tqHlNFMkv6MlDN6hYqRgMF4xCzAJBgNVBAYTAkFVMRMw +EQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0 +eSBMdGQxFzAVBgNVBAMTDmxvZ2luLmxpdmUuY29tghEAsLcTPtCW+bVvrpHIdL06 +wDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAMNzIStXDNSNQ8ayxrcj +4RrUMsHWUG/6XPrgfYqCP5TfPGAa5qBfNb9LfUbiS4b0flJVN1RlHVwwRo0yf9v4 +LGg0dSuPQAOWlLeUR1GminO1jHZw7E4dYfR7QEmiiOgaQU+CbxLsf5vCaKInN9Gu +jv/5xytVCbMoLoZ4EBVb0tka +-----END CERTIFICATE----- diff --git a/tests/auto/qsslcertificate/more-certificates/blacklisted9.pem b/tests/auto/qsslcertificate/more-certificates/blacklisted9.pem new file mode 100644 index 0000000..d179b29 --- /dev/null +++ b/tests/auto/qsslcertificate/more-certificates/blacklisted9.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDjCCAnegAwIBAgIRANjzX063hystqwaS4xU4L7AwDQYJKoZIhvcNAQEFBQAw +XjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGElu +dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEXMBUGA1UEAxMOZ2xvYmFsIHRydXN0ZWUw +HhcNMTEwMzI0MTMxMTM3WhcNMTEwNDIzMTMxMTM3WjBeMQswCQYDVQQGEwJBVTET +MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ +dHkgTHRkMRcwFQYDVQQDEw5nbG9iYWwgdHJ1c3RlZTCBnzANBgkqhkiG9w0BAQEF +AAOBjQAwgYkCgYEArHCVym7AEZDBhDkrUSG3Q94a+caNcCk5fE6ltZHiZHv096xr +cixHYvSGvms780bkI+oot2xI/e9awwkV+7VjWNvr0HrajzBWeimwk+myjP+3ddMY +Kmr0eI6bmvmPHtOFJE5Ar8/62FwD0wlLogRIx56JtXcCpkiUQktJVPz2gtMCAwEA +AaOByzCByDAdBgNVHQ4EFgQUUJwC/qSGBmcB+DVrd43ovRLdLmQwgZgGA1UdIwSB +kDCBjYAUUJwC/qSGBmcB+DVrd43ovRLdLmShYqRgMF4xCzAJBgNVBAYTAkFVMRMw +EQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0 +eSBMdGQxFzAVBgNVBAMTDmdsb2JhbCB0cnVzdGVlghEA2PNfTreHKy2rBpLjFTgv +sDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBACAYxI+r3+JNelL6SBB0 +Pda3LkbCm+schP64NBYDdGl2Kus2b2QZ83T7xENBFEhyNoXvc6pRI4/Oh6JDxmG1 +7WmqOVStS/4JeAu6ygiyI1ImRKq2/MvJx/kaKh6IiXanB5nW1U+fhDV6kMOEfpwV +i6FBibpHboPQoqzPPRe7qHSL +-----END CERTIFICATE----- diff --git a/tests/auto/qsslcertificate/tst_qsslcertificate.cpp b/tests/auto/qsslcertificate/tst_qsslcertificate.cpp index a8c5a4d..aadfb5e 100644 --- a/tests/auto/qsslcertificate/tst_qsslcertificate.cpp +++ b/tests/auto/qsslcertificate/tst_qsslcertificate.cpp @@ -111,6 +111,8 @@ private slots: void nulInSan(); void largeSerialNumber(); void largeExpirationDate(); + void blacklistedCertificates(); + // ### add tests for certificate bundles (multiple certificates concatenated into a single // structure); both PEM and DER formatted #endif -- cgit v0.12 From abc6e08c72427feea29c9826f72990f2c4e2565f Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 28 Mar 2011 15:55:28 +0300 Subject: Show softkeys when opening a dialog that has a fullscreen parent. Now shows the CBA for each window that defines softkeys even if topmost parent is fullscreen. Task-number: QTBUG-4953 Reviewed-by: Sami Merila (cherry picked from commit 5a6acc0ba1ed3b056f4c7a9c37481f4cb347a352) --- src/gui/kernel/qapplication_s60.cpp | 39 ++++++++++++++++++++++++-------- src/gui/kernel/qwidget_s60.cpp | 44 ++++++++++++++++++++++++++++--------- 2 files changed, 64 insertions(+), 19 deletions(-) diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index dd403d8..57dc218 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -1243,15 +1243,36 @@ void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */) qwidget->d_func()->setWindowIcon_sys(true); qwidget->d_func()->setWindowTitle_sys(qwidget->windowTitle()); #ifdef Q_WS_S60 - // If widget is fullscreen/minimized, hide status pane and button container otherwise show them. - QWidget *const window = qwidget->window(); - if (!window->parentWidget()) { // Only top level native windows have control over cba/status pane - const bool decorationsVisible = !(window->windowState() & (Qt::WindowFullScreen | Qt::WindowMinimized)); - const bool statusPaneVisibility = decorationsVisible; - const bool isFullscreen = window->windowState() & Qt::WindowFullScreen; - const bool cbaVisibilityHint = window->windowFlags() & Qt::WindowSoftkeysVisibleHint; - const bool buttonGroupVisibility = (decorationsVisible || (isFullscreen && cbaVisibilityHint)); - S60->setStatusPaneAndButtonGroupVisibility(statusPaneVisibility, buttonGroupVisibility); + if (qwidget->isWindow()) { + QWidget *const window = qwidget->window(); + QWidget *parentWindow = window->parentWidget(); + if (parentWindow) { + while (parentWindow->parentWidget()) + parentWindow = parentWindow->parentWidget(); + } else { + parentWindow = window; + } + + const bool parentDecorationsVisible = !(parentWindow->windowState() & (Qt::WindowFullScreen | Qt::WindowMinimized)); + const bool parentIsFullscreen = parentWindow->windowState() & Qt::WindowFullScreen; + const bool parentCbaVisibilityHint = parentWindow->windowFlags() & Qt::WindowSoftkeysVisibleHint; + bool buttonGroupVisibility = (parentDecorationsVisible || (parentIsFullscreen && parentCbaVisibilityHint)); + + // For non-toplevel normal and maximized windows, show cba if window has softkey + // actions even if topmost parent is not showing cba. Do the same for fullscreen + // windows that request it. + if (!buttonGroupVisibility + && window->parentWidget() + && !(window->windowState() & Qt::WindowMinimized) + && ((window->windowFlags() & Qt::WindowSoftkeysVisibleHint) || !(window->windowState() & Qt::WindowFullScreen))) { + for (int i = 0; i < window->actions().size(); ++i) { + if (window->actions().at(i)->softKeyRole() != QAction::NoSoftKey) { + buttonGroupVisibility = true; + break; + } + } + } + S60->setStatusPaneAndButtonGroupVisibility(parentDecorationsVisible, buttonGroupVisibility); } #endif } else if (QApplication::activeWindow() == qwidget->window()) { diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 1e0f1c1..d2bd614 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -1184,17 +1184,41 @@ void QWidget::setWindowState(Qt::WindowStates newstate) } #ifdef Q_WS_S60 - bool decorationsVisible(false); - if (!parentWidget()) { // Only top level native windows have control over cba/status pane - // Hide window decoration when switching to fullscreen / minimized otherwise show decoration. - // The window decoration visibility has to be changed before doing actual window state - // change since in that order the availableGeometry will return directly the right size and - // we will avoid unnecessary redraws - decorationsVisible = !(newstate & (Qt::WindowFullScreen | Qt::WindowMinimized)); - const bool statusPaneVisibility = decorationsVisible; - const bool buttonGroupVisibility = (decorationsVisible || (isFullscreen && cbaRequested)); - S60->setStatusPaneAndButtonGroupVisibility(statusPaneVisibility, buttonGroupVisibility); + // Hide window decoration when switching to fullscreen / minimized otherwise show decoration. + // The window decoration visibility has to be changed before doing actual window state + // change since in that order the availableGeometry will return directly the right size and + // we will avoid unnecessary redraws + Qt::WindowStates comparisonState = newstate; + QWidget *parentWindow = parentWidget(); + if (parentWindow) { + while (parentWindow->parentWidget()) + parentWindow = parentWindow->parentWidget(); + comparisonState = parentWindow->windowState(); + } else { + parentWindow = this; + } + + const bool decorationsVisible = !(comparisonState & (Qt::WindowFullScreen | Qt::WindowMinimized)); + const bool parentIsFullscreen = comparisonState & Qt::WindowFullScreen; + const bool parentCbaVisibilityHint = parentWindow->windowFlags() & Qt::WindowSoftkeysVisibleHint; + bool buttonGroupVisibility = (decorationsVisible || (parentIsFullscreen && parentCbaVisibilityHint)); + + // For non-toplevel normal and maximized windows, show cba if window has softkey + // actions even if topmost parent is not showing cba. Do the same for fullscreen + // windows that request it. + if (!buttonGroupVisibility + && parentWidget() + && !(newstate & Qt::WindowMinimized) + && ((windowFlags() & Qt::WindowSoftkeysVisibleHint) || !(newstate & Qt::WindowFullScreen))) { + for (int i = 0; i < actions().size(); ++i) { + if (actions().at(i)->softKeyRole() != QAction::NoSoftKey) { + buttonGroupVisibility = true; + break; + } + } } + S60->setStatusPaneAndButtonGroupVisibility(decorationsVisible, buttonGroupVisibility); + #endif // Q_WS_S60 // Ensure the initial size is valid, since we store it as normalGeometry below. -- cgit v0.12 From a5f89cb5e52554b59b308ca0ceed76873f833c46 Mon Sep 17 00:00:00 2001 From: Timo Turunen Date: Mon, 28 Mar 2011 21:18:40 +0300 Subject: Update changes for 4.7.3 Reviewed-by: Trust Me (cherry picked from commit 45c4c792c48605de4cbc28637a39bce5a65b1613) --- dist/changes-4.7.3 | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/dist/changes-4.7.3 b/dist/changes-4.7.3 index fa8a71e..1ff23c6 100644 --- a/dist/changes-4.7.3 +++ b/dist/changes-4.7.3 @@ -16,6 +16,16 @@ Qt Bug Tracker: http://bugreports.qt.nokia.com Merge Request: http://qt.gitorious.org **************************************************************************** +* Library * +**************************************************************************** + +QtNetwork +--------- + +- SSL +* [QTBUG-18338] blacklist fraudulent SSL certificates + +**************************************************************************** * Platform Specific Changes * **************************************************************************** @@ -38,6 +48,8 @@ QtMobility QtBearer depending applications * [QTBUG-17786] BC between Qt 4.7.3 and 4.6.3 QTreeView::indexRowSizeHint doesn't return correct value on Symbian for row when QPushButton widget is inserted in the treeview +* [QTBUG-4953] QMessageBox can not be closed/dismissed on touch phones if any +widget is fullscreen - Painting * [QTBUG-17907] tst_QGraphicsTransform::rotation3d test case from -- cgit v0.12 From 30d7d4d990f9734ed8cdf418ee5c8361a1633b42 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Wed, 23 Mar 2011 14:51:17 +0100 Subject: QDeclarativeDebug: Handle case where client with ongoing queries is deleted Change-Id: I4be7080af1e7e8a834b927b6c6fc211db8bd90c0 Reviewed-by: Aaron Kennedy --- src/declarative/debugger/qdeclarativedebug.cpp | 46 ++++++++++++++++++++++ .../qdeclarativedebug/tst_qdeclarativedebug.cpp | 28 ++++++++++++- 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/src/declarative/debugger/qdeclarativedebug.cpp b/src/declarative/debugger/qdeclarativedebug.cpp index 62eb8fe..049e05e 100644 --- a/src/declarative/debugger/qdeclarativedebug.cpp +++ b/src/declarative/debugger/qdeclarativedebug.cpp @@ -84,6 +84,7 @@ public: static void remove(QDeclarativeEngineDebug *, QDeclarativeDebugRootContextQuery *); static void remove(QDeclarativeEngineDebug *, QDeclarativeDebugObjectQuery *); static void remove(QDeclarativeEngineDebug *, QDeclarativeDebugExpressionQuery *); + static void remove(QDeclarativeEngineDebug *, QDeclarativeDebugWatch *); QHash enginesQuery; QHash rootContextQuery; @@ -120,6 +121,41 @@ QDeclarativeEngineDebugPrivate::~QDeclarativeEngineDebugPrivate() { if (client) client->priv = 0; + delete client; + + QHash::iterator enginesIter = enginesQuery.begin(); + for (; enginesIter != enginesQuery.end(); ++enginesIter) { + enginesIter.value()->m_client = 0; + if (enginesIter.value()->state() == QDeclarativeDebugQuery::Waiting) + enginesIter.value()->setState(QDeclarativeDebugQuery::Error); + } + + QHash::iterator rootContextIter = rootContextQuery.begin(); + for (; rootContextIter != rootContextQuery.end(); ++rootContextIter) { + rootContextIter.value()->m_client = 0; + if (rootContextIter.value()->state() == QDeclarativeDebugQuery::Waiting) + rootContextIter.value()->setState(QDeclarativeDebugQuery::Error); + } + + QHash::iterator objectIter = objectQuery.begin(); + for (; objectIter != objectQuery.end(); ++objectIter) { + objectIter.value()->m_client = 0; + if (objectIter.value()->state() == QDeclarativeDebugQuery::Waiting) + objectIter.value()->setState(QDeclarativeDebugQuery::Error); + } + + QHash::iterator exprIter = expressionQuery.begin(); + for (; exprIter != expressionQuery.end(); ++exprIter) { + exprIter.value()->m_client = 0; + if (exprIter.value()->state() == QDeclarativeDebugQuery::Waiting) + exprIter.value()->setState(QDeclarativeDebugQuery::Error); + } + + QHash::iterator watchIter = watched.begin(); + for (; watchIter != watched.end(); ++watchIter) { + watchIter.value()->m_client = 0; + watchIter.value()->setState(QDeclarativeDebugWatch::Dead); + } } int QDeclarativeEngineDebugPrivate::getId() @@ -160,6 +196,14 @@ void QDeclarativeEngineDebugPrivate::remove(QDeclarativeEngineDebug *c, QDeclara } } +void QDeclarativeEngineDebugPrivate::remove(QDeclarativeEngineDebug *c, QDeclarativeDebugWatch *w) +{ + if (c && w) { + QDeclarativeEngineDebugPrivate *p = (QDeclarativeEngineDebugPrivate *)QObjectPrivate::get(c); + p->watched.remove(w->m_queryId); + } +} + void QDeclarativeEngineDebugPrivate::decode(QDataStream &ds, QDeclarativeDebugObjectReference &o, bool simple) { @@ -647,6 +691,8 @@ QDeclarativeDebugWatch::QDeclarativeDebugWatch(QObject *parent) QDeclarativeDebugWatch::~QDeclarativeDebugWatch() { + if (m_client && m_queryId != -1) + QDeclarativeEngineDebugPrivate::remove(m_client, this); } int QDeclarativeDebugWatch::queryId() const diff --git a/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp b/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp index 6bcb4eb..4597ab4 100644 --- a/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp +++ b/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp @@ -649,7 +649,13 @@ void tst_QDeclarativeDebug::queryAvailableEngines() QCOMPARE(e.name(), m_engine->objectName()); } + // Make query invalid by deleting client + q_engines = m_dbg->queryAvailableEngines(this); + QCOMPARE(q_engines->state(), QDeclarativeDebugQuery::Waiting); + delete m_dbg; + QCOMPARE(q_engines->state(), QDeclarativeDebugQuery::Error); delete q_engines; + m_dbg = new QDeclarativeEngineDebug(m_conn, this); } void tst_QDeclarativeDebug::queryRootContexts() @@ -657,6 +663,7 @@ void tst_QDeclarativeDebug::queryRootContexts() QDeclarativeDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); waitForQuery(q_engines); int engineId = q_engines->engines()[0].debugId(); + delete q_engines; QDeclarativeDebugRootContextQuery *q_context; @@ -688,8 +695,13 @@ void tst_QDeclarativeDebug::queryRootContexts() QVERIFY(context.contexts()[0].debugId() >= 0); QCOMPARE(context.contexts()[0].name(), QString("tst_QDeclarativeDebug_childContext")); - delete q_engines; + // Make query invalid by deleting client + q_context = m_dbg->queryRootContexts(engineId, this); + QCOMPARE(q_context->state(), QDeclarativeDebugQuery::Waiting); + delete m_dbg; + QCOMPARE(q_context->state(), QDeclarativeDebugQuery::Error); delete q_context; + m_dbg = new QDeclarativeEngineDebug(m_conn, this); } void tst_QDeclarativeDebug::queryObject() @@ -721,7 +733,14 @@ void tst_QDeclarativeDebug::queryObject() delete q_engines; delete q_context; + + // Make query invalid by deleting client + q_obj = recursive ? m_dbg->queryObjectRecursive(rootObject, this) : m_dbg->queryObject(rootObject, this); + QCOMPARE(q_obj->state(), QDeclarativeDebugQuery::Waiting); + delete m_dbg; + QCOMPARE(q_obj->state(), QDeclarativeDebugQuery::Error); delete q_obj; + m_dbg = new QDeclarativeEngineDebug(m_conn, this); // check source as defined in main() QDeclarativeDebugFileReference source = obj.source(); @@ -796,7 +815,14 @@ void tst_QDeclarativeDebug::queryExpressionResult() delete q_engines; delete q_context; + + // Make query invalid by deleting client + q_expr = m_dbg->queryExpressionResult(objectId, expr, this); + QCOMPARE(q_expr->state(), QDeclarativeDebugQuery::Waiting); + delete m_dbg; + QCOMPARE(q_expr->state(), QDeclarativeDebugQuery::Error); delete q_expr; + m_dbg = new QDeclarativeEngineDebug(m_conn, this); } void tst_QDeclarativeDebug::queryExpressionResult_data() -- cgit v0.12 From e442459e15100c2fcff0f101d8004213c2ce6960 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Wed, 30 Mar 2011 13:42:06 +0200 Subject: QDeclarativeDebug: Fix test case --- tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp b/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp index 4597ab4..d3c7032 100644 --- a/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp +++ b/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp @@ -1012,7 +1012,7 @@ void tst_QDeclarativeDebug::setBindingForObject() // set handler // rootObject = findRootObject(); - QCOMPARE(rootObject.children().size(), 3); + QCOMPARE(rootObject.children().size(), 4); // Rectangle, Text, MouseArea, QDeclarativeComponentAttached QDeclarativeDebugObjectReference mouseAreaObject = rootObject.children().at(2); QDeclarativeDebugObjectQuery *q_obj = m_dbg->queryObjectRecursive(mouseAreaObject, this); waitForQuery(q_obj); -- cgit v0.12 From 45f2e655b22cb6e845183a1090fb888c32c516b3 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 5 Apr 2011 20:11:00 +0200 Subject: Aim to fix Windows builds. --- doc/doc.pri | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/doc.pri b/doc/doc.pri index 68d729b..253e1b4 100644 --- a/doc/doc.pri +++ b/doc/doc.pri @@ -13,12 +13,14 @@ win32:!win32-g++* { unixstyle = true } +COPYWEBKITGUIDE = $$QT_SOURCE_TREE/examples/webkit/webkit-guide + $$unixstyle { QDOC = cd $$QT_SOURCE_TREE/tools/qdoc3/test && QT_BUILD_TREE=$$QT_BUILD_TREE QT_SOURCE_TREE=$$QT_SOURCE_TREE $$QT_BUILD_TREE/bin/qdoc3 $$DOCS_GENERATION_DEFINES - COPYWEBKITGUIDE = $$QT_SOURCE_TREE/examples/webkit/webkit-guide } else { QDOC = cd $$QT_SOURCE_TREE/tools/qdoc3/test && set QT_BUILD_TREE=$$QT_BUILD_TREE&& set QT_SOURCE_TREE=$$QT_SOURCE_TREE&& $$QT_BUILD_TREE/bin/qdoc3.exe $$DOCS_GENERATION_DEFINES QDOC = $$replace(QDOC, "/", "\\") + COPYWEBKITGUIDE = $$replace(COPYWEBKITGUIDE, "/", "\\") } ADP_DOCS_QDOCCONF_FILE = qt-build-docs-online.qdocconf QT_DOCUMENTATION = ($$QDOC qt-api-only.qdocconf assistant.qdocconf designer.qdocconf \ -- cgit v0.12 From f55d5a5a3c2842d4e5f66cc86219cea56f2a4612 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Wed, 6 Apr 2011 17:18:09 +1000 Subject: Fix missing equality and inequality operator docs for QPointer. Task-number: QTBUG-18565 Reviewed-by: Rohan McGovern --- src/corelib/kernel/qpointer.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/corelib/kernel/qpointer.cpp b/src/corelib/kernel/qpointer.cpp index 7d63088..73f695b 100644 --- a/src/corelib/kernel/qpointer.cpp +++ b/src/corelib/kernel/qpointer.cpp @@ -183,6 +183,7 @@ /*! \fn bool operator==(const T *o, const QPointer &p) + \relates QPointer Equality operator. Returns true if \a o and the guarded pointer \a p are pointing to the same object, otherwise @@ -191,6 +192,7 @@ */ /*! \fn bool operator==(const QPointer &p, const T *o) + \relates QPointer Equality operator. Returns true if \a o and the guarded pointer \a p are pointing to the same object, otherwise @@ -199,6 +201,7 @@ */ /*! \fn bool operator==(T *o, const QPointer &p) + \relates QPointer Equality operator. Returns true if \a o and the guarded pointer \a p are pointing to the same object, otherwise @@ -207,6 +210,7 @@ */ /*! \fn bool operator==(const QPointer &p, T *o) + \relates QPointer Equality operator. Returns true if \a o and the guarded pointer \a p are pointing to the same object, otherwise @@ -215,6 +219,7 @@ */ /*! \fn bool operator==(const QPointer &p1, const QPointer &p2) + \relates QPointer Equality operator. Returns true if the guarded pointers \a p1 and \a p2 are pointing to the same object, otherwise @@ -225,6 +230,7 @@ /*! \fn bool operator!=(const T *o, const QPointer &p) + \relates QPointer Inequality operator. Returns true if \a o and the guarded pointer \a p are not pointing to the same object, otherwise @@ -232,6 +238,7 @@ */ /*! \fn bool operator!=(const QPointer &p, const T *o) + \relates QPointer Inequality operator. Returns true if \a o and the guarded pointer \a p are not pointing to the same object, otherwise @@ -239,6 +246,7 @@ */ /*! \fn bool operator!=(T *o, const QPointer &p) + \relates QPointer Inequality operator. Returns true if \a o and the guarded pointer \a p are not pointing to the same object, otherwise @@ -246,6 +254,7 @@ */ /*! \fn bool operator!=(const QPointer &p, T *o) + \relates QPointer Inequality operator. Returns true if \a o and the guarded pointer \a p are not pointing to the same object, otherwise @@ -253,6 +262,7 @@ */ /*! \fn bool operator!=(const QPointer &p1, const QPointer &p2) + \relates QPointer Inequality operator. Returns true if the guarded pointers \a p1 and \a p2 are not pointing to the same object, otherwise -- cgit v0.12 From c772ab261c3a09fab786306c70796c3c5f0efb15 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Wed, 6 Apr 2011 10:09:46 +0200 Subject: qdoc: Fixed QTBUG-18591 --- tools/qdoc3/htmlgenerator.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index 114db26..88bc3e2 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -1494,8 +1494,10 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker) QString allQmlMembersLink = generateAllQmlMembersFile(qml_cn, marker); if (!allQmlMembersLink.isEmpty()) { + out() << "\n"; } s = sections.begin(); -- cgit v0.12 From 1db38c5ccb6188889bac1ae5e6f1d415a59ac444 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Wed, 6 Apr 2011 12:45:44 +0200 Subject: qdoc: Updated the QDoc manual. --- tools/qdoc3/ditaxmlgenerator.cpp | 24 ++++++++++++------------ tools/qdoc3/doc/corefeatures.qdoc | 8 ++++++++ tools/qdoc3/doc/qdoc-manual.qdoc | 15 +++------------ 3 files changed, 23 insertions(+), 24 deletions(-) create mode 100644 tools/qdoc3/doc/corefeatures.qdoc diff --git a/tools/qdoc3/ditaxmlgenerator.cpp b/tools/qdoc3/ditaxmlgenerator.cpp index 1bc4992..69afde9 100644 --- a/tools/qdoc3/ditaxmlgenerator.cpp +++ b/tools/qdoc3/ditaxmlgenerator.cpp @@ -5664,29 +5664,29 @@ QString DitaXmlGenerator::metadataDefault(DitaTag t) const \list \o * \o * - \o + \o not used \o * \o * \o * \o * - \o + \o not used \o * - \o - \o - \o + \o not used + \o not used + \o not used \o * - \o + \o * \o * - \o + \o not used \o * \o * \o * \o * - \o - \o - \o - \o - \o + \o not used + \o not used + \o not used + \o not used + \o not used \o * \o * \endlist diff --git a/tools/qdoc3/doc/corefeatures.qdoc b/tools/qdoc3/doc/corefeatures.qdoc new file mode 100644 index 0000000..50bd726 --- /dev/null +++ b/tools/qdoc3/doc/corefeatures.qdoc @@ -0,0 +1,8 @@ +/*! + \page corefeatures.html + \title Core Features + + \input examples/signalandslots.qdocinc + \input examples/objectmodel.qdocinc + \input examples/layoutmanagement.qdocinc +*/ diff --git a/tools/qdoc3/doc/qdoc-manual.qdoc b/tools/qdoc3/doc/qdoc-manual.qdoc index 0e4055b..5b15fca 100644 --- a/tools/qdoc3/doc/qdoc-manual.qdoc +++ b/tools/qdoc3/doc/qdoc-manual.qdoc @@ -3999,20 +3999,11 @@ Here are links to the \c .qdocinc files used above: \l{signalandslots.qdocinc}, \l{objectmodel.qdocinc}, - \l{layoutmanagement.qdocinc}. QDoc renders this page as: - - \quotation - \raw HTML -

Core Features

- \endraw - - \input examples/signalandslots.qdocinc - \input examples/objectmodel.qdocinc - \input examples/layoutmanagement.qdocinc - \endquotation + \l{layoutmanagement.qdocinc}. QDoc renders this page + \l{corefeatures.html} {as shown here}. \target 2-argument-form} - \section2 \\include filename snippet-identifier + \section2 \\include filename snippet-identifier \span {class="newStuff"} {(new)} It is kind of a pain to make a separate \c .qdocinc file for every QDoc include snippet you want to use in multiple places in the -- cgit v0.12 From 90de2bb100b2f4a23655b2e914b93c644f1a4841 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 7 Apr 2011 09:59:57 +0200 Subject: qdoc: Updated the QDoc manual. --- src/gui/kernel/qwidget.cpp | 2 +- tools/qdoc3/doc/qdoc-manual.qdoc | 165 ++++++++++++++++++++++++++++++--------- 2 files changed, 128 insertions(+), 39 deletions(-) diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index ac35d42..9d9cd75 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -598,7 +598,7 @@ void QWidget::setAutoFillBackground(bool enabled) \brief The QWidget class is the base class of all user interface objects. \ingroup basicwidgets - + The widget is the atom of the user interface: it receives mouse, keyboard and other events from the window system, and paints a representation of itself on the screen. Every widget is rectangular, and they are sorted in a diff --git a/tools/qdoc3/doc/qdoc-manual.qdoc b/tools/qdoc3/doc/qdoc-manual.qdoc index 5b15fca..31c56a1 100644 --- a/tools/qdoc3/doc/qdoc-manual.qdoc +++ b/tools/qdoc3/doc/qdoc-manual.qdoc @@ -66,6 +66,7 @@ \o \l {Compatibility Issues} \o \l {qt.qdocconf} \o \l {minimum.qdocconf} + \o \l {Generating DITA XML Output} \endlist \endlist @@ -4037,48 +4038,77 @@ sent to the QDoc input stream. You can even nest these snippets, although it's not clear why you would want to do that. - \target meta-command + \target meta-command \section1 \\meta - The \\meta command is the QDoc equivalent to the HTML - \c meta tag. + The \\meta command is mainly used for including metadata in DITA + XML files. It is also used when generating HTML output for specifying + the \e maintainer(s) of a C++ class. - The command accepts two arguments: The first argument (the - following word) is equivalent to the HTML meta tag's \e name - variable, and the second argument (the rest of the line) is - equivalent to the tag's \e contents variable. + The command has two arguments: The first argument is the name of the + metadata attribute you wish to set, and the second argument is the + value for the attribute. Each argument should be enclosed in curly + brackets, as shown in this example: - \code - / *! - \meta author Summerfield - - \section1 Automatic Dialogs - - \abstract - This article shows how to maintain sets of - "attributes" (QVariant values), and how to allow - users to view and edit them using dialogs that are - created dynamically based on the attributes and - their types. - \endabstract - - The Attributes class described in this article holds a - set of QVariants, and can create a dialog to present - the QVariants to the user in an appropriate way. - - ... - * / - \endcode - - QDoc renders this as: + \code + / *! + \class QWidget + \brief The QWidget class is the base class of all user interface objects. + + \ingroup basicwidgets + + \meta {technology} {User Interface} + \meta {platform} {OS X 10.6} + \meta {platform} {Symbian} + \meta {platform} {MeeGo} + \meta {audience} {user} + \meta {audience} {programmer} + \meta {audience} {designer} + * / + \endcode - \code - - ... - - ... - - \endcode + When running QDoc to generate HTML, the example above will have no + effect on the generated output, but if you run QDoc to generate + DITA XML, the example will generate the following: + + \code + + + + + QWidget + the QWidget class is the base class of all user interface objects. + + Qt Development Frameworks + Nokia + + + Nokia + + + + + + + Class reference + + Qt Reference Documentation + + + + QtGui + + + + + + + + \endcode + + In the example output, several values have been set using defualt + values obtained from the QDoc configuration file. See \l + {Generating DITA XML Output} for details. \target omit-command \section1 \\omit @@ -6923,7 +6953,7 @@ \page 21-1-minimum-qdocconf.html \previouspage qt.qdocconf \contentspage Table of Contents - \nextpage Table of Contents + \nextpage Generating DITA XML Output \title minimum.qdocconf @@ -6942,6 +6972,65 @@ */ /*! + \page 21-3-qt-dita-xml-output.html + \previouspage minimum.qdocconf + \contentspage Table of Contents + \nextpage Table of Contents + + \title Generating DITA XML Output + + QDoc can generate \l {http://dita.xml.org} {DITA XML output}. + + In your confifiguration file, set your \c {outputformats} variable + to \c {DITAXML}, and send the output to an appropriate directory: + + \code + outputdir = $QTDIR/doc/ditaxml + outputformats = DITAXML + \endcode + + And include these macros in your configuration file to prevent + QDoc from doing some escaping that doesn't validate in XML: + + \code + macro.aacute.DITAXML = "á" + macro.Aring.DITAXML = "Å" + macro.aring.DITAXML = "å" + macro.Auml.DITAXML = "Ä" + macro.br.DITAXML = " " + macro.BR.DITAXML = " " + macro.copyright.DITAXML = "©" + macro.eacute.DITAXML = "é" + macro.hr.DITAXML = " " + macro.iacute.DITAXML = "í" + macro.oslash.DITAXML = "ø" + macro.ouml.DITAXML = "ö" + macro.raisedaster.DITAXML = "*" + macro.rarrow.DITAXML = "→" + macro.reg.DITAXML = "®" + macro.uuml.DITAXML = "ü" + macro.mdash.DITAXML = "—" + macro.emptyspan.DITAXML = " " + \endcode + + You can also set default values for some of the tags in the DITA + \c {} and \c {} elements: + + \code + dita.metadata.default.author = Qt Development Frameworks + dita.metadata.default.permissions = all + dita.metadata.default.publisher = Nokia + dita.metadata.default.copyryear = 2011 + dita.metadata.default.copyrholder = Nokia + dita.metadata.default.audience = programmer + \endcode + + See the \l {12-0-qdoc-commands-miscellaneous.html#meta-command} + {\\meta} command for more details on DITA metadata. + +*/ + +/*! \page 22-qdoc-configuration-generalvariables.html \previouspage The QDoc Configuration File \contentspage Table of Contents -- cgit v0.12 From 58e28ff518ee983f6af0e8937bbd355a2587c4d3 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 7 Apr 2011 11:47:40 +0200 Subject: qdoc: Updated the QDoc manual. --- tools/qdoc3/doc/qdoc-manual.qdoc | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/tools/qdoc3/doc/qdoc-manual.qdoc b/tools/qdoc3/doc/qdoc-manual.qdoc index 31c56a1..9039296 100644 --- a/tools/qdoc3/doc/qdoc-manual.qdoc +++ b/tools/qdoc3/doc/qdoc-manual.qdoc @@ -7560,23 +7560,26 @@ \target macro-variable \section1 macro - The \c macro variable can be used to create your own QDoc - commands. - - The general syntax is \tt {macro.\e{command} = - "\e{definition}}". The definition can be described using QDoc - syntax. In addition it is possible to provide an HTML definition - by appending .HTML to the variable. + The \c macro variable is used to create your own simple QDoc + commands or to redefine existing QDoc commands. The syntax is \tt + {macro.\e{command} = \e{definition}}, where the definition is + written using QDoc syntax. - For example in \l qt.qdocconf: + A macro command can be restricted for use in one type of output + generation. By appending \c {.HTML} to the macro name, for + example, the macro is only used when generating HTML output. By + appending \c {.DITAXML} to the macro name, the macro is only used + when generating DITA XML. \code macro.gui = "\\bold" macro.raisedaster.HTML = "*" \endcode - makes sure that the \\gui command renders its argument using a - bold font, and that \\raisedaster renders a '*'. + The first macro defines the \\gui command to render its argument + using a bold font. The second macro defines the \\raisedaster + command to render a superscript asterisk, but only when generating + HTML. \target naturallanguage-variable \section1 naturallanguage -- cgit v0.12 From bd0f7729ad5371b3b0ba42976451b622b1209b45 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 7 Apr 2011 13:21:25 +0200 Subject: qdoc: Updated the QDoc manual. --- tools/qdoc3/doc/qdoc-manual.qdoc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tools/qdoc3/doc/qdoc-manual.qdoc b/tools/qdoc3/doc/qdoc-manual.qdoc index 9039296..da0646e 100644 --- a/tools/qdoc3/doc/qdoc-manual.qdoc +++ b/tools/qdoc3/doc/qdoc-manual.qdoc @@ -7061,7 +7061,7 @@ information see the \l {Compatibility Issues} {compatibility section}. - See also \l {macro-command} {macro}. + See also \l {macro-variable} {macro}. \target codeindent-variable \section1 codeindent @@ -7561,11 +7561,10 @@ \section1 macro The \c macro variable is used to create your own simple QDoc - commands or to redefine existing QDoc commands. The syntax is \tt - {macro.\e{command} = \e{definition}}, where the definition is - written using QDoc syntax. + commands. The syntax is \tt {macro.\e{command} = \e{definition}}, + where the definition is written using QDoc syntax. - A macro command can be restricted for use in one type of output + A macro variable can be restricted for use in one type of output generation. By appending \c {.HTML} to the macro name, for example, the macro is only used when generating HTML output. By appending \c {.DITAXML} to the macro name, the macro is only used @@ -7581,6 +7580,8 @@ command to render a superscript asterisk, but only when generating HTML. + See also \l {alias-variable} {alias}. + \target naturallanguage-variable \section1 naturallanguage -- cgit v0.12 From 779a58513f0c2d4e55410aee4cae6a6510841d57 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 7 Apr 2011 13:51:45 +0200 Subject: qdoc: Added missing copyright notice --- tools/qdoc3/doc/corefeatures.qdoc | 41 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/tools/qdoc3/doc/corefeatures.qdoc b/tools/qdoc3/doc/corefeatures.qdoc index 50bd726..ff903f8 100644 --- a/tools/qdoc3/doc/corefeatures.qdoc +++ b/tools/qdoc3/doc/corefeatures.qdoc @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + /*! \page corefeatures.html \title Core Features -- cgit v0.12 From 384679ff46d2f970de3010fd6aac8a697dbfb907 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Thu, 7 Apr 2011 19:25:06 +0200 Subject: Ensured that incomplete downloads are removed. Task-number: QTBUG-18509 --- doc/src/examples/ftp.qdoc | 4 +++- examples/network/qftp/ftpwindow.cpp | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/doc/src/examples/ftp.qdoc b/doc/src/examples/ftp.qdoc index 4fa2cfd..841d298 100644 --- a/doc/src/examples/ftp.qdoc +++ b/doc/src/examples/ftp.qdoc @@ -131,7 +131,9 @@ \snippet examples/network/qftp/ftpwindow.cpp 5 - QFtp supports canceling the download of files. + QFtp supports canceling the download of files. We make sure that + any file that is currently being written to is closed and removed, + and tidy up by deleting the file object. \snippet examples/network/qftp/ftpwindow.cpp 6 diff --git a/examples/network/qftp/ftpwindow.cpp b/examples/network/qftp/ftpwindow.cpp index c3e629f..159cad6 100644 --- a/examples/network/qftp/ftpwindow.cpp +++ b/examples/network/qftp/ftpwindow.cpp @@ -243,6 +243,12 @@ void FtpWindow::downloadFile() void FtpWindow::cancelDownload() { ftp->abort(); + + if (file->exists()) { + file->close(); + file->remove(); + } + delete file; } //![5] -- cgit v0.12 From 932b28483f82f3fbc3a007ecdc5fbb152b504024 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Fri, 8 Apr 2011 08:05:55 +0200 Subject: qdoc: Fixed license comment. --- tools/qdoc3/doc/corefeatures.qdoc | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/tools/qdoc3/doc/corefeatures.qdoc b/tools/qdoc3/doc/corefeatures.qdoc index ff903f8..ee579cf 100644 --- a/tools/qdoc3/doc/corefeatures.qdoc +++ b/tools/qdoc3/doc/corefeatures.qdoc @@ -4,37 +4,23 @@ ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the tools applications of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:FDL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** -** 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 Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of this +** file. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** ** $QT_END_LICENSE$ ** ****************************************************************************/ -- cgit v0.12 From 78722d6b6e9ba0f6de1a4eba232aad2f96a339f2 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Mon, 11 Apr 2011 12:43:28 +1000 Subject: Remove autotest code related to old Qt versions Reviewed-by: Rohan McGovern --- tests/auto/qbuttongroup/tst_qbuttongroup.cpp | 10 +--------- tests/auto/qeasingcurve/tst_qeasingcurve.cpp | 6 ------ tests/auto/qsharedpointer/tst_qsharedpointer.cpp | 4 +--- tests/auto/selftests/tst_selftests.cpp | 14 -------------- tests/auto/symbols/tst_symbols.cpp | 4 ---- 5 files changed, 2 insertions(+), 36 deletions(-) diff --git a/tests/auto/qbuttongroup/tst_qbuttongroup.cpp b/tests/auto/qbuttongroup/tst_qbuttongroup.cpp index a809101..34be20c 100644 --- a/tests/auto/qbuttongroup/tst_qbuttongroup.cpp +++ b/tests/auto/qbuttongroup/tst_qbuttongroup.cpp @@ -98,10 +98,7 @@ private slots: void task106609(); - // fixed for Qt 4.6.0 -#if QT_VERSION >= 0x040600 void autoIncrementId(); -#endif void task209485_removeFromGroupInEventHandler_data(); void task209485_removeFromGroupInEventHandler(); @@ -338,10 +335,7 @@ void tst_QButtonGroup::testSignals() QCOMPARE(clickedSpy.count(), 1); QCOMPARE(clickedIdSpy.count(), 1); - int expectedId = -1; -#if QT_VERSION >= 0x040600 - expectedId = -2; -#endif + int expectedId = -2; QVERIFY(clickedIdSpy.takeFirst().at(0).toInt() == expectedId); QCOMPARE(pressedSpy.count(), 1); @@ -500,7 +494,6 @@ void tst_QButtonGroup::task209485_removeFromGroupInEventHandler() QCOMPARE(spy1.count() + spy2.count(), signalCount); } -#if QT_VERSION >= 0x040600 void tst_QButtonGroup::autoIncrementId() { QDialog dlg(0); @@ -529,7 +522,6 @@ void tst_QButtonGroup::autoIncrementId() dlg.show(); } -#endif QTEST_MAIN(tst_QButtonGroup) #include "tst_qbuttongroup.moc" diff --git a/tests/auto/qeasingcurve/tst_qeasingcurve.cpp b/tests/auto/qeasingcurve/tst_qeasingcurve.cpp index 327b6f3..f10d35b 100644 --- a/tests/auto/qeasingcurve/tst_qeasingcurve.cpp +++ b/tests/auto/qeasingcurve/tst_qeasingcurve.cpp @@ -42,10 +42,6 @@ #include -#if QT_VERSION < 0x040200 -QTEST_NOOP_MAIN -#else - #include //TESTED_CLASS= @@ -578,5 +574,3 @@ void tst_QEasingCurve::metaTypes() QTEST_MAIN(tst_QEasingCurve) #include "tst_qeasingcurve.moc" - -#endif //QT_VERSION diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index e7c8175..bb04621 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -698,7 +698,7 @@ void tst_QSharedPointer::noSharedPointerFromWeakQObject() QSharedPointer strong = weak.toStrongRef(); QVERIFY(strong.isNull()); - // is something went wrong, we'll probably crash here + // if something went wrong, we'll probably crash here } void tst_QSharedPointer::weakQObjectFromSharedPointer() @@ -1747,7 +1747,6 @@ void tst_QSharedPointer::invalidConstructs_data() "QSharedPointer b;\n" "if (a + b) return;"; -#if QT_VERSION >= 0x040600 // two objects with the same pointer QTest::newRow("same-pointer") << &QTest::QExternalTest::tryRunFail @@ -1761,7 +1760,6 @@ void tst_QSharedPointer::invalidConstructs_data() << "Data *aData = new Data;\n" "QSharedPointer ptr1 = QSharedPointer(aData);" "ptr1 = QSharedPointer(aData);"; -#endif // any type of cast for unrelated types: // (we have no reinterpret_cast) diff --git a/tests/auto/selftests/tst_selftests.cpp b/tests/auto/selftests/tst_selftests.cpp index 0d27d38..1c01c5f 100644 --- a/tests/auto/selftests/tst_selftests.cpp +++ b/tests/auto/selftests/tst_selftests.cpp @@ -515,8 +515,6 @@ BenchmarkResult BenchmarkResult::parse(QString const& line, QString* error) } bool ok; -#if QT_VERSION >= 0x040700 - // Qt 4.7 uses floating point double total = sTotal.toDouble(&ok); if (!ok) { if (error) *error = sTotal + " is not a valid number"; @@ -527,18 +525,6 @@ BenchmarkResult BenchmarkResult::parse(QString const& line, QString* error) if (error) *error = sIterations + " is not a valid number"; return out; } -#else - qlonglong total = sTotal.toLongLong(&ok); - if (!ok) { - if (error) *error = sTotal + " is not a valid integer"; - return out; - } - qlonglong iterations = sIterations.toLongLong(&ok); - if (!ok) { - if (error) *error = sIterations + " is not a valid integer"; - return out; - } -#endif out.unit = unit; out.total = total; diff --git a/tests/auto/symbols/tst_symbols.cpp b/tests/auto/symbols/tst_symbols.cpp index db1cbea..6f21c71 100644 --- a/tests/auto/symbols/tst_symbols.cpp +++ b/tests/auto/symbols/tst_symbols.cpp @@ -169,11 +169,7 @@ void tst_Symbols::globalObjects() } if (isFailed) { -#if QT_VERSION >= 0x040600 QVERIFY2(!isFailed, "Libraries contain static global objects. See Debug output above."); -#else - QSKIP("Libraries contains static global objects. See Debug output above. [These errors cannot be fixed in 4.5 in time]", SkipSingle); -#endif } } -- cgit v0.12 From a5d40fd3814ab7c8e865912c03a918bfd5994998 Mon Sep 17 00:00:00 2001 From: Fabien Freling Date: Mon, 11 Apr 2011 12:56:56 +0200 Subject: Switch the default graphics system to raster on Mac. Reviewed-by: Lars Knoll --- src/gui/painting/qgraphicssystemfactory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qgraphicssystemfactory.cpp b/src/gui/painting/qgraphicssystemfactory.cpp index 62a60d7..6212674 100644 --- a/src/gui/painting/qgraphicssystemfactory.cpp +++ b/src/gui/painting/qgraphicssystemfactory.cpp @@ -74,7 +74,7 @@ QGraphicsSystem *QGraphicsSystemFactory::create(const QString& key) if (system.isEmpty()) { system = QLatin1String("runtime"); } -#elif defined (QT_GRAPHICSSYSTEM_RASTER) && !defined(Q_WS_WIN) && !defined(Q_OS_SYMBIAN) || defined(Q_WS_X11) +#elif defined (QT_GRAPHICSSYSTEM_RASTER) && !defined(Q_WS_WIN) && !defined(Q_OS_SYMBIAN) || defined(Q_WS_X11) || (defined (Q_WS_MAC) && defined(QT_MAC_USE_COCOA)) if (system.isEmpty()) { system = QLatin1String("raster"); } -- cgit v0.12 From a769192ef0393afa07c08a1672b45604fdf64be1 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 11 Apr 2011 15:44:03 +0200 Subject: Doc: Fixed reference to a name in a table. Task-number: QTBUG-18679 --- src/gui/itemviews/qdatawidgetmapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/itemviews/qdatawidgetmapper.cpp b/src/gui/itemviews/qdatawidgetmapper.cpp index 745ef5a..dac4613 100644 --- a/src/gui/itemviews/qdatawidgetmapper.cpp +++ b/src/gui/itemviews/qdatawidgetmapper.cpp @@ -291,7 +291,7 @@ void QDataWidgetMapperPrivate::_q_modelDestroyed() \snippet doc/src/snippets/code/src_gui_itemviews_qdatawidgetmapper.cpp 0 After the call to toFirst(), \c mySpinBox displays the value \c{1}, \c myLineEdit - displays \c {Nokia Corporation and/or its subsidiary(-ies)} and \c myCountryChooser displays \c{Oslo}. The + displays \c{Qt Norway} and \c myCountryChooser displays \c{Oslo}. The navigational functions toFirst(), toNext(), toPrevious(), toLast() and setCurrentIndex() can be used to navigate in the model and update the widgets with contents from the model. -- cgit v0.12 From 5b3872b2d7523d44ba454a76613e7a3fa45387f7 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 11 Apr 2011 16:52:59 +0200 Subject: Fixed a crash in QListView The problem was that QAbstractScrollArea calls layoutChildren on resize but the QListView requires that updateGeometries is called before. Task: QTBUG-18558 Reviewed-By: Pierre --- src/gui/itemviews/qabstractitemview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index 081a6d9..5142107 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -1542,6 +1542,7 @@ bool QAbstractItemView::event(QEvent *event) break; case QEvent::LayoutDirectionChange: case QEvent::ApplicationLayoutDirectionChange: + case QEvent::Resize: updateGeometries(); break; case QEvent::StyleChange: @@ -2396,7 +2397,6 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event) void QAbstractItemView::resizeEvent(QResizeEvent *event) { QAbstractScrollArea::resizeEvent(event); - updateGeometries(); } /*! -- cgit v0.12 From 3475168550c1a804f04f2a4edfeb30c04cd36551 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Tue, 12 Apr 2011 14:53:36 +1000 Subject: Reduce usage of Q_ASSERT in autotests. Using Q_ASSERT does nothing in release-mode builds, and in debug builds it causes tests to terminate prematurely. It is much better to use QVERIFY or QCOMPARE. Task-number: QTBUG-17582 Reviewed-by: Rohan McGovern --- .../qdeclarativedebug/tst_qdeclarativedebug.cpp | 40 +++--- .../tst_qdeclarativedebugclient.cpp | 2 +- .../tst_qdeclarativedebugservice.cpp | 2 +- .../tst_qdeclarativefontloader.cpp | 10 +- tests/auto/modeltest/modeltest.cpp | 139 ++++++++++----------- tests/auto/q3listview/tst_q3listview.cpp | 2 +- tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp | 10 +- tests/auto/qbuffer/tst_qbuffer.cpp | 3 +- tests/auto/qchar/tst_qchar.cpp | 4 +- tests/auto/qcompleter/tst_qcompleter.cpp | 2 - tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp | 2 +- tests/auto/qdbusthreading/tst_qdbusthreading.cpp | 2 +- tests/auto/qdirmodel/tst_qdirmodel.cpp | 6 +- tests/auto/qfiledialog2/tst_qfiledialog2.cpp | 2 +- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 2 +- tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp | 2 +- tests/auto/qinputdialog/tst_qinputdialog.cpp | 18 +-- tests/auto/qlocale/tst_qlocale.cpp | 4 +- tests/auto/qmessagebox/tst_qmessagebox.cpp | 49 ++++---- tests/auto/qpixmap/tst_qpixmap.cpp | 4 +- tests/auto/qprocess/tst_qprocess.cpp | 2 +- .../tst_qscriptvalueiterator.cpp | 4 +- tests/auto/qsharedpointer/tst_qsharedpointer.cpp | 22 ++-- tests/auto/qsplitter/tst_qsplitter.cpp | 6 +- tests/auto/qsqldatabase/tst_qsqldatabase.cpp | 4 +- tests/auto/qstring/tst_qstring.cpp | 30 ++--- .../tst_qtextboundaryfinder.cpp | 18 +-- tests/auto/qtextcodec/tst_qtextcodec.cpp | 8 +- tests/auto/qwidget/tst_qwidget.cpp | 3 +- tests/auto/xmlpatternsxqts/tst_suitetest.cpp | 2 +- 30 files changed, 197 insertions(+), 207 deletions(-) diff --git a/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp b/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp index 6bcb4eb..7237553 100644 --- a/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp +++ b/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp @@ -81,7 +81,7 @@ private: void recursiveCompareObjects(const QDeclarativeDebugObjectReference &a, const QDeclarativeDebugObjectReference &b) const; void recursiveCompareContexts(const QDeclarativeDebugContextReference &a, const QDeclarativeDebugContextReference &b) const; void compareProperties(const QDeclarativeDebugPropertyReference &a, const QDeclarativeDebugPropertyReference &b) const; - + QDeclarativeDebugConnection *m_conn; QDeclarativeEngineDebug *m_dbg; QDeclarativeEngine *m_engine; @@ -123,7 +123,7 @@ QDeclarativeDebugObjectReference tst_QDeclarativeDebug::findRootObject(int conte { QDeclarativeDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); waitForQuery(q_engines); - + if (q_engines->engines().count() == 0) return QDeclarativeDebugObjectReference(); QDeclarativeDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); @@ -353,7 +353,7 @@ void tst_QDeclarativeDebug::initTestCase() for (int i=0; i(component.create()); } m_rootItem = qobject_cast(m_components.first()); @@ -367,7 +367,7 @@ void tst_QDeclarativeDebug::initTestCase() QTest::ignoreMessage(QtWarningMsg, "QDeclarativeDebugServer: Connection established"); bool ok = m_conn->waitForConnected(); - Q_ASSERT(ok); + QVERIFY(ok); QTRY_VERIFY(QDeclarativeDebugService::hasDebuggingClient()); m_dbg = new QDeclarativeEngineDebug(m_conn, this); QTRY_VERIFY(m_dbg->status() == QDeclarativeEngineDebug::Enabled); @@ -424,7 +424,7 @@ void tst_QDeclarativeDebug::watch_property() QDeclarativeDebugPropertyReference prop = findProperty(obj.properties(), "width"); QDeclarativeDebugPropertyWatch *watch; - + QDeclarativeEngineDebug *unconnected = new QDeclarativeEngineDebug(0); watch = unconnected->addWatch(prop, this); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Dead); @@ -435,7 +435,7 @@ void tst_QDeclarativeDebug::watch_property() QVERIFY(QDeclarativeDebugTest::waitForSignal(watch, SIGNAL(stateChanged(QDeclarativeDebugWatch::State)))); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Inactive); delete watch; - + watch = m_dbg->addWatch(prop, this); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Waiting); QCOMPARE(watch->objectDebugId(), obj.debugId()); @@ -467,12 +467,12 @@ void tst_QDeclarativeDebug::watch_object() { QDeclarativeDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); waitForQuery(q_engines); - - Q_ASSERT(q_engines->engines().count() > 0); + + QVERIFY(q_engines->engines().count() > 0); QDeclarativeDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); waitForQuery(q_context); - Q_ASSERT(q_context->rootContext().objects().count() > 0); + QVERIFY(q_context->rootContext().objects().count() > 0); QDeclarativeDebugObjectQuery *q_obj = m_dbg->queryObject(q_context->rootContext().objects()[0], this); waitForQuery(q_obj); @@ -489,7 +489,7 @@ void tst_QDeclarativeDebug::watch_object() QCOMPARE(watch->state(), QDeclarativeDebugWatch::Dead); delete watch; delete unconnected; - + watch = m_dbg->addWatch(QDeclarativeDebugObjectReference(), this); QVERIFY(QDeclarativeDebugTest::waitForSignal(watch, SIGNAL(stateChanged(QDeclarativeDebugWatch::State)))); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Inactive); @@ -543,7 +543,7 @@ void tst_QDeclarativeDebug::watch_expression() QFETCH(int, incrementCount); int origWidth = m_rootItem->property("width").toInt(); - + QDeclarativeDebugObjectReference obj = findRootObject(); QDeclarativeDebugObjectExpressionWatch *watch; @@ -553,12 +553,12 @@ void tst_QDeclarativeDebug::watch_expression() QCOMPARE(watch->state(), QDeclarativeDebugWatch::Dead); delete watch; delete unconnected; - + watch = m_dbg->addWatch(QDeclarativeDebugObjectReference(), expr, this); QVERIFY(QDeclarativeDebugTest::waitForSignal(watch, SIGNAL(stateChanged(QDeclarativeDebugWatch::State)))); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Inactive); delete watch; - + watch = m_dbg->addWatch(obj, expr, this); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Waiting); QCOMPARE(watch->objectDebugId(), obj.debugId()); @@ -588,7 +588,7 @@ void tst_QDeclarativeDebug::watch_expression() delete watch; // restore original value and verify spy doesn't get a signal since watch has been removed - m_rootItem->setProperty("width", origWidth); + m_rootItem->setProperty("width", origWidth); QTest::qWait(100); QCOMPARE(spy.count(), expectedSpyCount); @@ -659,7 +659,7 @@ void tst_QDeclarativeDebug::queryRootContexts() int engineId = q_engines->engines()[0].debugId(); QDeclarativeDebugRootContextQuery *q_context; - + QDeclarativeEngineDebug *unconnected = new QDeclarativeEngineDebug(0); q_context = unconnected->queryRootContexts(engineId, this); QCOMPARE(q_context->state(), QDeclarativeDebugQuery::Error); @@ -698,7 +698,7 @@ void tst_QDeclarativeDebug::queryObject() QDeclarativeDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); waitForQuery(q_engines); - + QDeclarativeDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); waitForQuery(q_context); QDeclarativeDebugObjectReference rootObject = q_context->rootContext().objects()[0]; @@ -772,7 +772,7 @@ void tst_QDeclarativeDebug::queryExpressionResult() QDeclarativeDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); waitForQuery(q_engines); // check immediate deletion is ok - + QDeclarativeDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); waitForQuery(q_context); int objectId = q_context->rootContext().objects()[0].debugId(); @@ -784,7 +784,7 @@ void tst_QDeclarativeDebug::queryExpressionResult() QCOMPARE(q_expr->state(), QDeclarativeDebugQuery::Error); delete q_expr; delete unconnected; - + q_expr = m_dbg->queryExpressionResult(objectId, expr, this); delete q_expr; @@ -923,7 +923,7 @@ void tst_QDeclarativeDebug::tst_QDeclarativeDebugPropertyReference() QDeclarativeDebugObjectQuery *query = m_dbg->queryObject(rootObject, this); waitForQuery(query); QDeclarativeDebugObjectReference obj = query->object(); - delete query; + delete query; QDeclarativeDebugPropertyReference ref = findProperty(obj.properties(), "scale"); QVERIFY(ref.objectDebugId() > 0); @@ -932,7 +932,7 @@ void tst_QDeclarativeDebug::tst_QDeclarativeDebugPropertyReference() QVERIFY(!ref.valueTypeName().isEmpty()); QVERIFY(!ref.binding().isEmpty()); QVERIFY(ref.hasNotifySignal()); - + QDeclarativeDebugPropertyReference copy(ref); QDeclarativeDebugPropertyReference copyAssign; copyAssign = ref; diff --git a/tests/auto/declarative/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp b/tests/auto/declarative/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp index c182893..59214d1 100644 --- a/tests/auto/declarative/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp +++ b/tests/auto/declarative/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp @@ -88,7 +88,7 @@ void tst_QDeclarativeDebugClient::initTestCase() QTest::ignoreMessage(QtWarningMsg, "QDeclarativeDebugServer: Connection established"); bool ok = m_conn->waitForConnected(); - Q_ASSERT(ok); + QVERIFY(ok); QTRY_VERIFY(QDeclarativeDebugService::hasDebuggingClient()); QTRY_COMPARE(client.status(), QDeclarativeDebugClient::Enabled); diff --git a/tests/auto/declarative/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp b/tests/auto/declarative/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp index 0911a83..a61f4a8 100644 --- a/tests/auto/declarative/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp +++ b/tests/auto/declarative/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp @@ -87,7 +87,7 @@ void tst_QDeclarativeDebugService::initTestCase() QTest::ignoreMessage(QtWarningMsg, "QDeclarativeDebugServer: Connection established"); bool ok = m_conn->waitForConnected(); - Q_ASSERT(ok); + QVERIFY(ok); QTRY_VERIFY(QDeclarativeDebugService::hasDebuggingClient()); } diff --git a/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp b/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp index e684bbe..2f0992c 100644 --- a/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp +++ b/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp @@ -55,13 +55,13 @@ #endif class tst_qdeclarativefontloader : public QObject - { Q_OBJECT public: tst_qdeclarativefontloader(); private slots: + void init(); void noFont(); void namedFont(); void localFont(); @@ -71,8 +71,6 @@ private slots: void failWebFont(); void changeFont(); -private slots: - private: QDeclarativeEngine engine; TestHTTPServer server; @@ -82,7 +80,11 @@ tst_qdeclarativefontloader::tst_qdeclarativefontloader() : server(SERVER_PORT) { server.serveDirectory(SRCDIR "/data"); - Q_ASSERT(server.isValid()); +} + +void tst_qdeclarativefontloader::init() +{ + QVERIFY(server.isValid()); } void tst_qdeclarativefontloader::noFont() diff --git a/tests/auto/modeltest/modeltest.cpp b/tests/auto/modeltest/modeltest.cpp index 98d707c..5ef27f9 100644 --- a/tests/auto/modeltest/modeltest.cpp +++ b/tests/auto/modeltest/modeltest.cpp @@ -45,8 +45,6 @@ #include "modeltest.h" #include -#undef Q_ASSERT -#define Q_ASSERT QVERIFY Q_DECLARE_METATYPE ( QModelIndex ) @@ -118,15 +116,15 @@ void ModelTest::runAllTests() */ void ModelTest::nonDestructiveBasicTest() { - Q_ASSERT ( model->buddy ( QModelIndex() ) == QModelIndex() ); + QVERIFY( model->buddy ( QModelIndex() ) == QModelIndex() ); model->canFetchMore ( QModelIndex() ); - Q_ASSERT ( model->columnCount ( QModelIndex() ) >= 0 ); - Q_ASSERT ( model->data ( QModelIndex() ) == QVariant() ); + QVERIFY( model->columnCount ( QModelIndex() ) >= 0 ); + QVERIFY( model->data ( QModelIndex() ) == QVariant() ); fetchingMore = true; model->fetchMore ( QModelIndex() ); fetchingMore = false; Qt::ItemFlags flags = model->flags ( QModelIndex() ); - Q_ASSERT ( flags == Qt::ItemIsDropEnabled || flags == 0 ); + QVERIFY( flags == Qt::ItemIsDropEnabled || flags == 0 ); model->hasChildren ( QModelIndex() ); model->hasIndex ( 0, 0 ); model->headerData ( 0, Qt::Horizontal ); @@ -135,8 +133,8 @@ void ModelTest::nonDestructiveBasicTest() QVariant cache; model->match ( QModelIndex(), -1, cache ); model->mimeTypes(); - Q_ASSERT ( model->parent ( QModelIndex() ) == QModelIndex() ); - Q_ASSERT ( model->rowCount() >= 0 ); + QVERIFY( model->parent ( QModelIndex() ) == QModelIndex() ); + QVERIFY( model->rowCount() >= 0 ); QVariant variant; model->setData ( QModelIndex(), variant, -1 ); model->setHeaderData ( -1, Qt::Horizontal, QVariant() ); @@ -158,17 +156,17 @@ void ModelTest::rowCount() // check top row QModelIndex topIndex = model->index ( 0, 0, QModelIndex() ); int rows = model->rowCount ( topIndex ); - Q_ASSERT ( rows >= 0 ); + QVERIFY( rows >= 0 ); if ( rows > 0 ) - Q_ASSERT ( model->hasChildren ( topIndex ) == true ); + QVERIFY( model->hasChildren ( topIndex ) ); QModelIndex secondLevelIndex = model->index ( 0, 0, topIndex ); if ( secondLevelIndex.isValid() ) { // not the top level // check a row count where parent is valid rows = model->rowCount ( secondLevelIndex ); - Q_ASSERT ( rows >= 0 ); + QVERIFY( rows >= 0 ); if ( rows > 0 ) - Q_ASSERT ( model->hasChildren ( secondLevelIndex ) == true ); + QVERIFY( model->hasChildren ( secondLevelIndex ) ); } // The models rowCount() is tested more extensively in checkChildren(), @@ -182,12 +180,12 @@ void ModelTest::columnCount() { // check top row QModelIndex topIndex = model->index ( 0, 0, QModelIndex() ); - Q_ASSERT ( model->columnCount ( topIndex ) >= 0 ); + QVERIFY( model->columnCount ( topIndex ) >= 0 ); // check a column count where parent is valid QModelIndex childIndex = model->index ( 0, 0, topIndex ); if ( childIndex.isValid() ) - Q_ASSERT ( model->columnCount ( childIndex ) >= 0 ); + QVERIFY( model->columnCount ( childIndex ) >= 0 ); // columnCount() is tested more extensively in checkChildren(), // but this catches the big mistakes @@ -200,19 +198,19 @@ void ModelTest::hasIndex() { // qDebug() << "hi"; // Make sure that invalid values returns an invalid index - Q_ASSERT ( model->hasIndex ( -2, -2 ) == false ); - Q_ASSERT ( model->hasIndex ( -2, 0 ) == false ); - Q_ASSERT ( model->hasIndex ( 0, -2 ) == false ); + QVERIFY( !model->hasIndex ( -2, -2 ) ); + QVERIFY( !model->hasIndex ( -2, 0 ) ); + QVERIFY( !model->hasIndex ( 0, -2 ) ); int rows = model->rowCount(); int columns = model->columnCount(); // check out of bounds - Q_ASSERT ( model->hasIndex ( rows, columns ) == false ); - Q_ASSERT ( model->hasIndex ( rows + 1, columns + 1 ) == false ); + QVERIFY( !model->hasIndex ( rows, columns ) ); + QVERIFY( !model->hasIndex ( rows + 1, columns + 1 ) ); if ( rows > 0 ) - Q_ASSERT ( model->hasIndex ( 0, 0 ) == true ); + QVERIFY( model->hasIndex ( 0, 0 ) ); // hasIndex() is tested more extensively in checkChildren(), // but this catches the big mistakes @@ -225,9 +223,9 @@ void ModelTest::index() { // qDebug() << "i"; // Make sure that invalid values returns an invalid index - Q_ASSERT ( model->index ( -2, -2 ) == QModelIndex() ); - Q_ASSERT ( model->index ( -2, 0 ) == QModelIndex() ); - Q_ASSERT ( model->index ( 0, -2 ) == QModelIndex() ); + QVERIFY( model->index ( -2, -2 ) == QModelIndex() ); + QVERIFY( model->index ( -2, 0 ) == QModelIndex() ); + QVERIFY( model->index ( 0, -2 ) == QModelIndex() ); int rows = model->rowCount(); int columns = model->columnCount(); @@ -236,13 +234,13 @@ void ModelTest::index() return; // Catch off by one errors - Q_ASSERT ( model->index ( rows, columns ) == QModelIndex() ); - Q_ASSERT ( model->index ( 0, 0 ).isValid() == true ); + QVERIFY( model->index ( rows, columns ) == QModelIndex() ); + QVERIFY( model->index ( 0, 0 ).isValid() ); // Make sure that the same index is *always* returned QModelIndex a = model->index ( 0, 0 ); QModelIndex b = model->index ( 0, 0 ); - Q_ASSERT ( a == b ); + QVERIFY( a == b ); // index() is tested more extensively in checkChildren(), // but this catches the big mistakes @@ -256,7 +254,7 @@ void ModelTest::parent() // qDebug() << "p"; // Make sure the model wont crash and will return an invalid QModelIndex // when asked for the parent of an invalid index. - Q_ASSERT ( model->parent ( QModelIndex() ) == QModelIndex() ); + QVERIFY( model->parent ( QModelIndex() ) == QModelIndex() ); if ( model->rowCount() == 0 ) return; @@ -269,13 +267,13 @@ void ModelTest::parent() // Common error test #1, make sure that a top level index has a parent // that is a invalid QModelIndex. QModelIndex topIndex = model->index ( 0, 0, QModelIndex() ); - Q_ASSERT ( model->parent ( topIndex ) == QModelIndex() ); + QVERIFY( model->parent ( topIndex ) == QModelIndex() ); // Common error test #2, make sure that a second level index has a parent // that is the first level index. if ( model->rowCount ( topIndex ) > 0 ) { QModelIndex childIndex = model->index ( 0, 0, topIndex ); - Q_ASSERT ( model->parent ( childIndex ) == topIndex ); + QVERIFY( model->parent ( childIndex ) == topIndex ); } // Common error test #3, the second column should NOT have the same children @@ -285,7 +283,7 @@ void ModelTest::parent() if ( model->rowCount ( topIndex1 ) > 0 ) { QModelIndex childIndex = model->index ( 0, 0, topIndex ); QModelIndex childIndex1 = model->index ( 0, 0, topIndex1 ); - Q_ASSERT ( childIndex != childIndex1 ); + QVERIFY( childIndex != childIndex1 ); } // Full test, walk n levels deep through the model making sure that all @@ -325,47 +323,47 @@ void ModelTest::checkChildren ( const QModelIndex &parent, int currentDepth ) int columns = model->columnCount ( parent ); if ( rows > 0 ) - Q_ASSERT ( model->hasChildren ( parent ) ); + QVERIFY( model->hasChildren ( parent ) ); // Some further testing against rows(), columns(), and hasChildren() - Q_ASSERT ( rows >= 0 ); - Q_ASSERT ( columns >= 0 ); + QVERIFY( rows >= 0 ); + QVERIFY( columns >= 0 ); if ( rows > 0 ) - Q_ASSERT ( model->hasChildren ( parent ) == true ); + QVERIFY( model->hasChildren ( parent ) ); //qDebug() << "parent:" << model->data(parent).toString() << "rows:" << rows // << "columns:" << columns << "parent column:" << parent.column(); - Q_ASSERT ( model->hasIndex ( rows + 1, 0, parent ) == false ); + QVERIFY( !model->hasIndex ( rows + 1, 0, parent ) ); for ( int r = 0; r < rows; ++r ) { if ( model->canFetchMore ( parent ) ) { fetchingMore = true; model->fetchMore ( parent ); fetchingMore = false; } - Q_ASSERT ( model->hasIndex ( r, columns + 1, parent ) == false ); + QVERIFY( !model->hasIndex ( r, columns + 1, parent ) ); for ( int c = 0; c < columns; ++c ) { - Q_ASSERT ( model->hasIndex ( r, c, parent ) == true ); + QVERIFY( model->hasIndex ( r, c, parent ) ); QModelIndex index = model->index ( r, c, parent ); // rowCount() and columnCount() said that it existed... - Q_ASSERT ( index.isValid() == true ); + QVERIFY( index.isValid() ); // index() should always return the same index when called twice in a row QModelIndex modifiedIndex = model->index ( r, c, parent ); - Q_ASSERT ( index == modifiedIndex ); + QVERIFY( index == modifiedIndex ); // Make sure we get the same index if we request it twice in a row QModelIndex a = model->index ( r, c, parent ); QModelIndex b = model->index ( r, c, parent ); - Q_ASSERT ( a == b ); + QVERIFY( a == b ); // Some basic checking on the index that is returned - Q_ASSERT ( index.model() == model ); - Q_ASSERT ( index.row() == r ); - Q_ASSERT ( index.column() == c ); + QVERIFY( index.model() == model ); + QCOMPARE( index.row(), r ); + QCOMPARE( index.column(), c ); // While you can technically return a QVariant usually this is a sign - // of an bug in data() Disable if this really is ok in your model. -// Q_ASSERT ( model->data ( index, Qt::DisplayRole ).isValid() == true ); + // of a bug in data(). Disable if this really is ok in your model. +// QVERIFY( model->data ( index, Qt::DisplayRole ).isValid() ); // If the next test fails here is some somewhat useful debug you play with. @@ -380,8 +378,7 @@ void ModelTest::checkChildren ( const QModelIndex &parent, int currentDepth ) } // Check that we can get back our real parent. -// qDebug() << model->parent ( index ) << parent ; - Q_ASSERT ( model->parent ( index ) == parent ); + QCOMPARE( model->parent ( index ), parent ); // recursively go down the children if ( model->hasChildren ( index ) && currentDepth < 10 ) { @@ -391,7 +388,7 @@ void ModelTest::checkChildren ( const QModelIndex &parent, int currentDepth ) // make sure that after testing the children that the index doesn't change. QModelIndex newerIndex = model->index ( r, c, parent ); - Q_ASSERT ( index == newerIndex ); + QVERIFY( index == newerIndex ); } } } @@ -402,68 +399,68 @@ void ModelTest::checkChildren ( const QModelIndex &parent, int currentDepth ) void ModelTest::data() { // Invalid index should return an invalid qvariant - Q_ASSERT ( !model->data ( QModelIndex() ).isValid() ); + QVERIFY( !model->data ( QModelIndex() ).isValid() ); if ( model->rowCount() == 0 ) return; // A valid index should have a valid QVariant data - Q_ASSERT ( model->index ( 0, 0 ).isValid() ); + QVERIFY( model->index ( 0, 0 ).isValid() ); // shouldn't be able to set data on an invalid index - Q_ASSERT ( model->setData ( QModelIndex(), QLatin1String ( "foo" ), Qt::DisplayRole ) == false ); + QVERIFY( !model->setData ( QModelIndex(), QLatin1String ( "foo" ), Qt::DisplayRole ) ); // General Purpose roles that should return a QString QVariant variant = model->data ( model->index ( 0, 0 ), Qt::ToolTipRole ); if ( variant.isValid() ) { - Q_ASSERT ( qVariantCanConvert ( variant ) ); + QVERIFY( qVariantCanConvert ( variant ) ); } variant = model->data ( model->index ( 0, 0 ), Qt::StatusTipRole ); if ( variant.isValid() ) { - Q_ASSERT ( qVariantCanConvert ( variant ) ); + QVERIFY( qVariantCanConvert ( variant ) ); } variant = model->data ( model->index ( 0, 0 ), Qt::WhatsThisRole ); if ( variant.isValid() ) { - Q_ASSERT ( qVariantCanConvert ( variant ) ); + QVERIFY( qVariantCanConvert ( variant ) ); } // General Purpose roles that should return a QSize variant = model->data ( model->index ( 0, 0 ), Qt::SizeHintRole ); if ( variant.isValid() ) { - Q_ASSERT ( qVariantCanConvert ( variant ) ); + QVERIFY( qVariantCanConvert ( variant ) ); } // General Purpose roles that should return a QFont QVariant fontVariant = model->data ( model->index ( 0, 0 ), Qt::FontRole ); if ( fontVariant.isValid() ) { - Q_ASSERT ( qVariantCanConvert ( fontVariant ) ); + QVERIFY( qVariantCanConvert ( fontVariant ) ); } // Check that the alignment is one we know about QVariant textAlignmentVariant = model->data ( model->index ( 0, 0 ), Qt::TextAlignmentRole ); if ( textAlignmentVariant.isValid() ) { int alignment = textAlignmentVariant.toInt(); - Q_ASSERT ( alignment == ( alignment & ( Qt::AlignHorizontal_Mask | Qt::AlignVertical_Mask ) ) ); + QCOMPARE( alignment, ( alignment & ( Qt::AlignHorizontal_Mask | Qt::AlignVertical_Mask ) ) ); } // General Purpose roles that should return a QColor QVariant colorVariant = model->data ( model->index ( 0, 0 ), Qt::BackgroundColorRole ); if ( colorVariant.isValid() ) { - Q_ASSERT ( qVariantCanConvert ( colorVariant ) ); + QVERIFY( qVariantCanConvert ( colorVariant ) ); } colorVariant = model->data ( model->index ( 0, 0 ), Qt::TextColorRole ); if ( colorVariant.isValid() ) { - Q_ASSERT ( qVariantCanConvert ( colorVariant ) ); + QVERIFY( qVariantCanConvert ( colorVariant ) ); } // Check that the "check state" is one we know about. QVariant checkStateVariant = model->data ( model->index ( 0, 0 ), Qt::CheckStateRole ); if ( checkStateVariant.isValid() ) { int state = checkStateVariant.toInt(); - Q_ASSERT ( state == Qt::Unchecked || - state == Qt::PartiallyChecked || - state == Qt::Checked ); + QVERIFY( state == Qt::Unchecked || + state == Qt::PartiallyChecked || + state == Qt::Checked ); } } @@ -494,7 +491,7 @@ void ModelTest::rowsAboutToBeInserted ( const QModelIndex &parent, int start, in void ModelTest::rowsInserted ( const QModelIndex & parent, int start, int end ) { Changing c = insert.pop(); - Q_ASSERT ( c.parent == parent ); + QVERIFY( c.parent == parent ); // qDebug() << "rowsInserted" << "start=" << start << "end=" << end << "oldsize=" << c.oldSize // << "parent=" << model->data ( parent ).toString() << "current rowcount of parent=" << model->rowCount ( parent ); @@ -504,8 +501,8 @@ void ModelTest::rowsInserted ( const QModelIndex & parent, int start, int end ) // } // qDebug(); - Q_ASSERT ( c.oldSize + ( end - start + 1 ) == model->rowCount ( parent ) ); - Q_ASSERT ( c.last == model->data ( model->index ( start - 1, 0, c.parent ) ) ); + QVERIFY( c.oldSize + ( end - start + 1 ) == model->rowCount ( parent ) ); + QVERIFY( c.last == model->data ( model->index ( start - 1, 0, c.parent ) ) ); if (c.next != model->data(model->index(end + 1, 0, c.parent))) { qDebug() << start << end; @@ -514,7 +511,7 @@ void ModelTest::rowsInserted ( const QModelIndex & parent, int start, int end ) qDebug() << c.next << model->data(model->index(end + 1, 0, c.parent)); } - Q_ASSERT ( c.next == model->data ( model->index ( end + 1, 0, c.parent ) ) ); + QVERIFY( c.next == model->data ( model->index ( end + 1, 0, c.parent ) ) ); } void ModelTest::layoutAboutToBeChanged() @@ -527,7 +524,7 @@ void ModelTest::layoutChanged() { for ( int i = 0; i < changing.count(); ++i ) { QPersistentModelIndex p = changing[i]; - Q_ASSERT ( p == model->index ( p.row(), p.column(), p.parent() ) ); + QVERIFY( p == model->index ( p.row(), p.column(), p.parent() ) ); } changing.clear(); } @@ -557,10 +554,10 @@ void ModelTest::rowsRemoved ( const QModelIndex & parent, int start, int end ) { qDebug() << "rr" << parent << start << end; Changing c = remove.pop(); - Q_ASSERT ( c.parent == parent ); - Q_ASSERT ( c.oldSize - ( end - start + 1 ) == model->rowCount ( parent ) ); - Q_ASSERT ( c.last == model->data ( model->index ( start - 1, 0, c.parent ) ) ); - Q_ASSERT ( c.next == model->data ( model->index ( start, 0, c.parent ) ) ); + QVERIFY( c.parent == parent ); + QVERIFY( c.oldSize - ( end - start + 1 ) == model->rowCount ( parent ) ); + QVERIFY( c.last == model->data ( model->index ( start - 1, 0, c.parent ) ) ); + QVERIFY( c.next == model->data ( model->index ( start, 0, c.parent ) ) ); } diff --git a/tests/auto/q3listview/tst_q3listview.cpp b/tests/auto/q3listview/tst_q3listview.cpp index 601d74f..c1b3950 100644 --- a/tests/auto/q3listview/tst_q3listview.cpp +++ b/tests/auto/q3listview/tst_q3listview.cpp @@ -678,7 +678,7 @@ void tst_Q3ListView::selections_mouseClick() for (i = 0; i < items.count(); ++i) { Q3ListViewItem *item = items.at(i); - Q_ASSERT(item); + QVERIFY(item); if ( item->isSelected() ) { QVERIFY( selectedItems.contains( i ) ); } else { diff --git a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp index 6f3722d..838fd22 100644 --- a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp +++ b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp @@ -251,7 +251,7 @@ void tst_Q3SqlCursor::copyConstructor() } QSqlRecord* rec = cur2.primeUpdate(); - Q_ASSERT( rec ); + QVERIFY( rec ); QCOMPARE( (int)rec->count(), 4 ); int i = 0; @@ -398,7 +398,7 @@ void tst_Q3SqlCursor::batchInsert() int i = 0; for ( ; i < 100; ++i ) { QSqlRecord* irec = cur.primeInsert(); - Q_ASSERT( irec ); + QVERIFY( irec ); irec->setValue( "id", i ); irec->setValue( "t_varchar", "blah" ); irec->setValue( "t_char", "blah" ); @@ -412,7 +412,7 @@ void tst_Q3SqlCursor::batchInsert() for ( ; i < 200; ++i ) { QSqlRecord* irec = cur.primeInsert(); - Q_ASSERT( irec ); + QVERIFY( irec ); irec->setValue( "id", i ); irec->setValue( "t_varchar", "blah" ); irec->setValue( "t_char", "blah" ); @@ -699,7 +699,7 @@ void tst_Q3SqlCursor::updateNoPK() Q3SqlCursor cur(qTableName("qtestPK", __FILE__), true, db); QSqlRecord* rec = cur.primeInsert(); - Q_ASSERT(rec); + QVERIFY(rec); rec->setNull(0); rec->setNull(1); rec->setNull(2); @@ -724,7 +724,7 @@ void tst_Q3SqlCursor::updateNoPK() } rec = cur.primeUpdate(); - Q_ASSERT(rec); + QVERIFY(rec); rec->setValue(0, 1); rec->setNull(1); rec->setNull(2); diff --git a/tests/auto/qbuffer/tst_qbuffer.cpp b/tests/auto/qbuffer/tst_qbuffer.cpp index 3e3cc73..5d6b84f 100644 --- a/tests/auto/qbuffer/tst_qbuffer.cpp +++ b/tests/auto/qbuffer/tst_qbuffer.cpp @@ -309,8 +309,7 @@ void tst_QBuffer::seekTest() // (see Task 184730) { char c; - const int offset = 1; - Q_ASSERT(offset > 0); // any positive integer will do + const int offset = 1; // any positive integer will do const qint64 pos = buf.size() + offset; QVERIFY(buf.seek(pos)); QCOMPARE(buf.pos(), pos); diff --git a/tests/auto/qchar/tst_qchar.cpp b/tests/auto/qchar/tst_qchar.cpp index 45dd7eb..911a30c 100644 --- a/tests/auto/qchar/tst_qchar.cpp +++ b/tests/auto/qchar/tst_qchar.cpp @@ -548,14 +548,14 @@ void tst_QChar::normalization_data() QList l = line.split(';'); - Q_ASSERT(l.size() == 5); + QCOMPARE(l.size(), 5); QStringList columns; for (int i = 0; i < 5; ++i) { columns.append(QString()); QList c = l.at(i).split(' '); - Q_ASSERT(!c.isEmpty()); + QVERIFY(!c.isEmpty()); for (int j = 0; j < c.size(); ++j) { bool ok; diff --git a/tests/auto/qcompleter/tst_qcompleter.cpp b/tests/auto/qcompleter/tst_qcompleter.cpp index 932c19e..afcc433 100644 --- a/tests/auto/qcompleter/tst_qcompleter.cpp +++ b/tests/auto/qcompleter/tst_qcompleter.cpp @@ -1248,9 +1248,7 @@ public: void tst_QCompleter::task189564_omitNonSelectableItems() { const QString prefix("a"); - Q_ASSERT(!prefix.isEmpty()); const int n = 5; - Q_ASSERT(n > 0); QStringList strings; for (int i = 0; i < n; ++i) diff --git a/tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp b/tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp index c8c3b90..98632ae 100644 --- a/tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp +++ b/tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp @@ -2751,7 +2751,7 @@ void tst_QDateTimeEdit::setCurrentSection() QFETCH(QList, setCurrentSections); QFETCH(QList, expectedCursorPositions); - Q_ASSERT(setCurrentSections.size() == expectedCursorPositions.size()); + QCOMPARE(setCurrentSections.size(), expectedCursorPositions.size()); testWidget->setDisplayFormat(format); testWidget->setDateTime(dateTime); #ifdef Q_WS_MAC diff --git a/tests/auto/qdbusthreading/tst_qdbusthreading.cpp b/tests/auto/qdbusthreading/tst_qdbusthreading.cpp index bfb806b..142b6c2 100644 --- a/tests/auto/qdbusthreading/tst_qdbusthreading.cpp +++ b/tests/auto/qdbusthreading/tst_qdbusthreading.cpp @@ -592,7 +592,7 @@ void tst_QDBusThreading::callbackInAnotherAuxThread() // wait for the event loop sem1.release(); sem2.acquire(); - Q_ASSERT(loop); + QVERIFY(loop); // create the second thread new Thread; diff --git a/tests/auto/qdirmodel/tst_qdirmodel.cpp b/tests/auto/qdirmodel/tst_qdirmodel.cpp index 38a6b8a..a6985a4 100644 --- a/tests/auto/qdirmodel/tst_qdirmodel.cpp +++ b/tests/auto/qdirmodel/tst_qdirmodel.cpp @@ -641,10 +641,10 @@ void tst_QDirModel::filter() QDirModel model; model.setNameFilters(QStringList() << "*.nada"); QModelIndex index = model.index(SRCDIR "test"); - Q_ASSERT(model.rowCount(index) == 0); + QCOMPARE(model.rowCount(index), 0); QModelIndex index2 = model.index(SRCDIR "test/file01.tst"); - Q_ASSERT(!index2.isValid()); - Q_ASSERT(model.rowCount(index) == 0); + QVERIFY(!index2.isValid()); + QCOMPARE(model.rowCount(index), 0); } void tst_QDirModel::task244669_remove() diff --git a/tests/auto/qfiledialog2/tst_qfiledialog2.cpp b/tests/auto/qfiledialog2/tst_qfiledialog2.cpp index 5e9f130..dc3ca52 100644 --- a/tests/auto/qfiledialog2/tst_qfiledialog2.cpp +++ b/tests/auto/qfiledialog2/tst_qfiledialog2.cpp @@ -812,7 +812,7 @@ void tst_QFileDialog2::task239706_editableFilterCombo() break; } } - Q_ASSERT(filterCombo); + QVERIFY(filterCombo); filterCombo->setEditable(true); QTest::mouseClick(filterCombo, Qt::LeftButton); QTest::keyPress(filterCombo, Qt::Key_X); diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 168f75e..269b576 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -10655,7 +10655,7 @@ void tst_QGraphicsItem::deviceCoordinateCache_simpleRotations() QTRY_VERIFY(view.repaints > 0); QGraphicsItemCache *itemCache = QGraphicsItemPrivate::get(item)->extraItemCache(); - Q_ASSERT(itemCache); + QVERIFY(itemCache); QPixmapCache::Key currentKey = itemCache->deviceData.value(view.viewport()).key; // Trigger an update and verify that the cache is unchanged. diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index 9ff086c..0927577 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -3594,7 +3594,7 @@ void tst_QGraphicsScene::task160653_selectionChanged() item->flags() | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable); item->setSelected(true); } - Q_ASSERT(scene.items().size() > 1); + QVERIFY(scene.items().size() > 1); QCOMPARE(scene.items().size(), scene.selectedItems().size()); QSignalSpy spy(&scene, SIGNAL(selectionChanged())); diff --git a/tests/auto/qinputdialog/tst_qinputdialog.cpp b/tests/auto/qinputdialog/tst_qinputdialog.cpp index 1d13eb6..e0317df 100644 --- a/tests/auto/qinputdialog/tst_qinputdialog.cpp +++ b/tests/auto/qinputdialog/tst_qinputdialog.cpp @@ -193,12 +193,12 @@ void testGetNumeric(QInputDialog *dialog, SpinBoxType * = 0, ValueType * = 0) void testGetText(QInputDialog *dialog) { QLineEdit *ledit = qFindChild(dialog); - Q_ASSERT(ledit); + QVERIFY(ledit); QDialogButtonBox *bbox = qFindChild(dialog); - Q_ASSERT(bbox); + QVERIFY(bbox); QPushButton *okButton = bbox->button(QDialogButtonBox::Ok); - Q_ASSERT(okButton); + QVERIFY(okButton); QVERIFY(ledit->hasAcceptableInput()); QCOMPARE(ledit->selectedText(), ledit->text()); @@ -211,12 +211,12 @@ void testGetText(QInputDialog *dialog) void testGetItem(QInputDialog *dialog) { QComboBox *cbox = qFindChild(dialog); - Q_ASSERT(cbox); + QVERIFY(cbox); QDialogButtonBox *bbox = qFindChild(dialog); - Q_ASSERT(bbox); + QVERIFY(bbox); QPushButton *okButton = bbox->button(QDialogButtonBox::Ok); - Q_ASSERT(okButton); + QVERIFY(okButton); QVERIFY(okButton->isEnabled()); const int origIndex = cbox->currentIndex(); @@ -249,7 +249,7 @@ void tst_QInputDialog::timerEvent(QTimerEvent *event) { killTimer(event->timerId()); QInputDialog *dialog = qFindChild(parent); - Q_ASSERT(dialog); + QVERIFY(dialog); if (testFunc) testFunc(dialog); dialog->done(doneCode); // cause static function call to return @@ -270,7 +270,7 @@ void tst_QInputDialog::getInteger() { QFETCH(int, min); QFETCH(int, max); - Q_ASSERT(min < max); + QVERIFY(min < max); parent = new QWidget; doneCode = QDialog::Accepted; testFunc = &tst_QInputDialog::testFuncGetInteger; @@ -310,7 +310,7 @@ void tst_QInputDialog::getDouble() QFETCH(double, min); QFETCH(double, max); QFETCH(int, decimals); - Q_ASSERT(min < max && decimals >= 0 && decimals <= 13); + QVERIFY(min < max && decimals >= 0 && decimals <= 13); parent = new QWidget; doneCode = QDialog::Accepted; testFunc = &tst_QInputDialog::testFuncGetDouble; diff --git a/tests/auto/qlocale/tst_qlocale.cpp b/tests/auto/qlocale/tst_qlocale.cpp index 16846de..4f0de4c 100644 --- a/tests/auto/qlocale/tst_qlocale.cpp +++ b/tests/auto/qlocale/tst_qlocale.cpp @@ -317,7 +317,7 @@ void tst_QLocale::ctor() TEST_CTOR("en_GB@.bla", English, UnitedKingdom) TEST_CTOR("en_GB@bla", English, UnitedKingdom) - Q_ASSERT(QLocale::Norwegian == QLocale::NorwegianBokmal); + QVERIFY(QLocale::Norwegian == QLocale::NorwegianBokmal); TEST_CTOR("no", Norwegian, Norway) TEST_CTOR("nb", Norwegian, Norway) TEST_CTOR("nn", NorwegianNynorsk, Norway) @@ -397,7 +397,7 @@ void tst_QLocale::emptyCtor() TEST_CTOR("en_GB@bla", "en_GB") TEST_CTOR("de", "de_DE") - Q_ASSERT(QLocale::Norwegian == QLocale::NorwegianBokmal); + QVERIFY(QLocale::Norwegian == QLocale::NorwegianBokmal); TEST_CTOR("no", "nb_NO") TEST_CTOR("nb", "nb_NO") TEST_CTOR("nn", "nn_NO") diff --git a/tests/auto/qmessagebox/tst_qmessagebox.cpp b/tests/auto/qmessagebox/tst_qmessagebox.cpp index c11e76c..ed121ce 100644 --- a/tests/auto/qmessagebox/tst_qmessagebox.cpp +++ b/tests/auto/qmessagebox/tst_qmessagebox.cpp @@ -609,48 +609,43 @@ void tst_QMessageBox::testSymbols() button = QMessageBox::FlagMask; mb1.setText("Foo"); - QString text = mb1.text(); - Q_ASSERT(text == "Foo"); + QCOMPARE(mb1.text(), "Foo"); icon = mb1.icon(); - Q_ASSERT(icon == QMessageBox::NoIcon); + QVERIFY(icon == QMessageBox::NoIcon); mb1.setIcon(QMessageBox::Question); - Q_ASSERT(mb1.icon() == QMessageBox::Question); + QVERIFY(mb1.icon() == QMessageBox::Question); QPixmap iconPixmap = mb1.iconPixmap(); mb1.setIconPixmap(iconPixmap); - Q_ASSERT(mb1.icon() == QMessageBox::NoIcon); + QVERIFY(mb1.icon() == QMessageBox::NoIcon); - QString bt0 = mb1.buttonText(QMessageBox::Ok); - QString bt1 = mb1.buttonText(QMessageBox::Cancel); - QString bt2 = mb1.buttonText(QMessageBox::Ok | QMessageBox::Default); - - Q_ASSERT(bt0 == "OK"); - Q_ASSERT(bt1.isEmpty()); - Q_ASSERT(bt2.isEmpty()); + QCOMPARE(mb1.buttonText(QMessageBox::Ok), "OK"); + QCOMPARE(mb1.buttonText(QMessageBox::Cancel), QString()); + QCOMPARE(mb1.buttonText(QMessageBox::Ok | QMessageBox::Default), QString()); mb2.setButtonText(QMessageBox::Cancel, "Foo"); mb2.setButtonText(QMessageBox::Ok, "Bar"); mb2.setButtonText(QMessageBox::Ok | QMessageBox::Default, "Baz"); - Q_ASSERT(mb2.buttonText(QMessageBox::Cancel).isEmpty()); - Q_ASSERT(mb2.buttonText(QMessageBox::Ok) == "Bar"); + QCOMPARE(mb2.buttonText(QMessageBox::Cancel), QString()); + QCOMPARE(mb2.buttonText(QMessageBox::Ok), "Bar"); - Q_ASSERT(mb3b.buttonText(QMessageBox::Yes).endsWith("Yes")); - Q_ASSERT(mb3b.buttonText(QMessageBox::YesAll).isEmpty()); - Q_ASSERT(mb3b.buttonText(QMessageBox::Ok).isEmpty()); + QVERIFY(mb3b.buttonText(QMessageBox::Yes).endsWith("Yes")); + QCOMPARE(mb3b.buttonText(QMessageBox::YesAll), QString()); + QCOMPARE(mb3b.buttonText(QMessageBox::Ok), QString()); mb3b.setButtonText(QMessageBox::Yes, "Blah"); mb3b.setButtonText(QMessageBox::YesAll, "Zoo"); mb3b.setButtonText(QMessageBox::Ok, "Zoo"); - Q_ASSERT(mb3b.buttonText(QMessageBox::Yes) == "Blah"); - Q_ASSERT(mb3b.buttonText(QMessageBox::YesAll).isEmpty()); - Q_ASSERT(mb3b.buttonText(QMessageBox::Ok).isEmpty()); + QCOMPARE(mb3b.buttonText(QMessageBox::Yes), "Blah"); + QCOMPARE(mb3b.buttonText(QMessageBox::YesAll), QString()); + QCOMPARE(mb3b.buttonText(QMessageBox::Ok), QString()); - Q_ASSERT(mb1.textFormat() == Qt::AutoText); + QCOMPARE(mb1.textFormat(), Qt::AutoText); mb1.setTextFormat(Qt::PlainText); - Q_ASSERT(mb1.textFormat() == Qt::PlainText); + QCOMPARE(mb1.textFormat(), Qt::PlainText); CONVENIENCE_FUNC_SYMS(information); CONVENIENCE_FUNC_SYMS_EXTRA(information); @@ -660,7 +655,7 @@ void tst_QMessageBox::testSymbols() CONVENIENCE_FUNC_SYMS(critical); QSize sizeHint = mb1.sizeHint(); - Q_ASSERT(sizeHint.width() > 20 && sizeHint.height() > 20); + QVERIFY(sizeHint.width() > 20 && sizeHint.height() > 20); #ifdef QT3_SUPPORT //test QT3_SUPPORT stuff @@ -672,8 +667,8 @@ void tst_QMessageBox::testSymbols() QPixmap pm = QMessageBox::standardIcon(QMessageBox::Question, Qt::GUIStyle(1)); QPixmap pm2 = QMessageBox::standardIcon(QMessageBox::Question); - Q_ASSERT(pm.toImage() == iconPixmap.toImage()); - Q_ASSERT(pm2.toImage() == iconPixmap.toImage()); + QVERIFY(pm.toImage() == iconPixmap.toImage()); + QVERIFY(pm2.toImage() == iconPixmap.toImage()); int ret1 = QMessageBox::message("title", "text"); int ret2 = QMessageBox::message("title", "text", "OK"); @@ -692,10 +687,10 @@ void tst_QMessageBox::testSymbols() Q_UNUSED(ret5); QPixmap pm3 = QMessageBox::standardIcon(QMessageBox::NoIcon); - Q_ASSERT(pm3.isNull()); + QVERIFY(pm3.isNull()); pm3 = QMessageBox::standardIcon(QMessageBox::Information); - Q_ASSERT(!pm3.isNull()); + QVERIFY(!pm3.isNull()); #endif //QT3_SUPPORT QMessageBox::about(&mb1, "title", "text"); diff --git a/tests/auto/qpixmap/tst_qpixmap.cpp b/tests/auto/qpixmap/tst_qpixmap.cpp index 4d032e8..198a275 100644 --- a/tests/auto/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/qpixmap/tst_qpixmap.cpp @@ -1696,8 +1696,8 @@ void tst_QPixmap::fromImageReaderAnimatedGif() QImageReader referenceReader(path); QImageReader pixmapReader(path); - Q_ASSERT(referenceReader.canRead()); - Q_ASSERT(referenceReader.imageCount() > 1); + QVERIFY(referenceReader.canRead()); + QVERIFY(referenceReader.imageCount() > 1); for (int i = 0; i < referenceReader.imageCount(); ++i) { QImage refImage = referenceReader.read(); diff --git a/tests/auto/qprocess/tst_qprocess.cpp b/tests/auto/qprocess/tst_qprocess.cpp index 2a8874e..3e0c3ff 100644 --- a/tests/auto/qprocess/tst_qprocess.cpp +++ b/tests/auto/qprocess/tst_qprocess.cpp @@ -668,7 +668,7 @@ void tst_QProcess::exitStatus() QSKIP("This test opens a crash dialog on Windows", SkipSingle); #endif - Q_ASSERT(processList.count() == exitStatus.count()); + QCOMPARE(exitStatus.count(), processList.count()); for (int i = 0; i < processList.count(); ++i) { process->start(processList.at(i)); QVERIFY(process->waitForStarted(5000)); diff --git a/tests/auto/qscriptvalueiterator/tst_qscriptvalueiterator.cpp b/tests/auto/qscriptvalueiterator/tst_qscriptvalueiterator.cpp index 03e5c0f..1d4745e 100644 --- a/tests/auto/qscriptvalueiterator/tst_qscriptvalueiterator.cpp +++ b/tests/auto/qscriptvalueiterator/tst_qscriptvalueiterator.cpp @@ -106,7 +106,7 @@ void tst_QScriptValueIterator::iterateForward() QFETCH(QStringList, propertyNames); QFETCH(QStringList, propertyValues); QMap pmap; - Q_ASSERT(propertyNames.size() == propertyValues.size()); + QVERIFY(propertyNames.size() == propertyValues.size()); QScriptEngine engine; QScriptValue object = engine.newObject(); @@ -165,7 +165,7 @@ void tst_QScriptValueIterator::iterateBackward() QFETCH(QStringList, propertyNames); QFETCH(QStringList, propertyValues); QMap pmap; - Q_ASSERT(propertyNames.size() == propertyValues.size()); + QVERIFY(propertyNames.size() == propertyValues.size()); QScriptEngine engine; QScriptValue object = engine.newObject(); diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index bb04621..f25f8e8 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -283,8 +283,8 @@ void tst_QSharedPointer::operators() QSharedPointer p1; QSharedPointer p2(new char); qptrdiff diff = p2.data() - p1.data(); - Q_ASSERT(p1.data() != p2.data()); - Q_ASSERT(diff != 0); + QVERIFY(p1.data() != p2.data()); + QVERIFY(diff != 0); // operator- QCOMPARE(p2 - p1.data(), diff); @@ -867,8 +867,8 @@ void tst_QSharedPointer::differentPointers() { DiffPtrDerivedData *aData = new DiffPtrDerivedData; Data *aBase = aData; - Q_ASSERT(aData == aBase); - Q_ASSERT(*reinterpret_cast(&aData) != *reinterpret_cast(&aBase)); + QVERIFY(aData == aBase); + QVERIFY(*reinterpret_cast(&aData) != *reinterpret_cast(&aBase)); QSharedPointer baseptr = QSharedPointer(aData); QSharedPointer ptr = qSharedPointerCast(baseptr); @@ -885,8 +885,8 @@ void tst_QSharedPointer::differentPointers() { DiffPtrDerivedData *aData = new DiffPtrDerivedData; Data *aBase = aData; - Q_ASSERT(aData == aBase); - Q_ASSERT(*reinterpret_cast(&aData) != *reinterpret_cast(&aBase)); + QVERIFY(aData == aBase); + QVERIFY(*reinterpret_cast(&aData) != *reinterpret_cast(&aBase)); QSharedPointer ptr = QSharedPointer(aData); QSharedPointer baseptr = ptr; @@ -908,8 +908,8 @@ void tst_QSharedPointer::virtualBaseDifferentPointers() { VirtualDerived *aData = new VirtualDerived; Data *aBase = aData; - Q_ASSERT(aData == aBase); - Q_ASSERT(*reinterpret_cast(&aData) != *reinterpret_cast(&aBase)); + QVERIFY(aData == aBase); + QVERIFY(*reinterpret_cast(&aData) != *reinterpret_cast(&aBase)); QSharedPointer ptr = QSharedPointer(aData); QSharedPointer baseptr = qSharedPointerCast(ptr); @@ -928,8 +928,8 @@ void tst_QSharedPointer::virtualBaseDifferentPointers() { VirtualDerived *aData = new VirtualDerived; Data *aBase = aData; - Q_ASSERT(aData == aBase); - Q_ASSERT(*reinterpret_cast(&aData) != *reinterpret_cast(&aBase)); + QVERIFY(aData == aBase); + QVERIFY(*reinterpret_cast(&aData) != *reinterpret_cast(&aBase)); QSharedPointer ptr = QSharedPointer(aData); QSharedPointer baseptr = ptr; @@ -1605,7 +1605,7 @@ void hashAndMapTest() QVERIFY(it != c.find(Key())); if (Ordered) { - Q_ASSERT(k0 < k1); + QVERIFY(k0 < k1); it = c.begin(); QCOMPARE(it.key(), k0); diff --git a/tests/auto/qsplitter/tst_qsplitter.cpp b/tests/auto/qsplitter/tst_qsplitter.cpp index 0482661..60be944 100644 --- a/tests/auto/qsplitter/tst_qsplitter.cpp +++ b/tests/auto/qsplitter/tst_qsplitter.cpp @@ -1340,14 +1340,14 @@ void tst_QSplitter::task187373_addAbstractScrollAreas() QFETCH(QString, className); QFETCH(bool, addInConstructor); QFETCH(bool, addOutsideConstructor); - Q_ASSERT(addInConstructor || addOutsideConstructor); + QVERIFY(addInConstructor || addOutsideConstructor); QSplitter *splitter = new QSplitter; splitter->show(); - Q_ASSERT(splitter->isVisible()); + QVERIFY(splitter->isVisible()); QAbstractScrollArea *w = task187373_createScrollArea(splitter, className, addInConstructor); - Q_ASSERT(w); + QVERIFY(w); if (addOutsideConstructor) splitter->addWidget(w); diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index 4462659..185e046 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -767,7 +767,7 @@ void tst_QSqlDatabase::checkValues(const FieldDef fieldDefs[], QSqlDatabase db) Q3SqlCursor cur(qTableName("qtestfields", __FILE__), true, db); QVERIFY_SQL(cur, select()); QSqlRecord* rec = cur.primeInsert(); - Q_ASSERT(rec); + QVERIFY(rec); rec->setValue("id", pkey++); int i = 0; for (i = 0; !fieldDefs[ i ].typeName.isNull(); ++i) { @@ -828,7 +828,7 @@ void tst_QSqlDatabase::checkNullValues(const FieldDef fieldDefs[], QSqlDatabase Q3SqlCursor cur(qTableName("qtestfields", __FILE__), true, db); QVERIFY_SQL(cur, select()); QSqlRecord* rec = cur.primeInsert(); - Q_ASSERT(rec); + QVERIFY(rec); rec->setValue("id", pkey++); int i = 0; for (i = 0; !fieldDefs[ i ].typeName.isNull(); ++i) { diff --git a/tests/auto/qstring/tst_qstring.cpp b/tests/auto/qstring/tst_qstring.cpp index abc8d9a..ad7515b 100644 --- a/tests/auto/qstring/tst_qstring.cpp +++ b/tests/auto/qstring/tst_qstring.cpp @@ -3415,9 +3415,9 @@ void tst_QString::fromLatin1Roundtrip() QFETCH(QString, unicode); // QtTest safety check: - Q_ASSERT(latin1.isNull() == unicode.isNull()); - Q_ASSERT(latin1.isEmpty() == unicode.isEmpty()); - Q_ASSERT(latin1.length() == unicode.length()); + QCOMPARE(latin1.isNull(), unicode.isNull()); + QCOMPARE(latin1.isEmpty(), unicode.isEmpty()); + QCOMPARE(latin1.length(), unicode.length()); if (!latin1.isEmpty()) while (latin1.length() < 128) { @@ -3470,12 +3470,12 @@ void tst_QString::toLatin1Roundtrip() QFETCH(QString, unicodedst); // QtTest safety check: - Q_ASSERT(latin1.isNull() == unicodesrc.isNull()); - Q_ASSERT(latin1.isEmpty() == unicodesrc.isEmpty()); - Q_ASSERT(latin1.length() == unicodesrc.length()); - Q_ASSERT(latin1.isNull() == unicodedst.isNull()); - Q_ASSERT(latin1.isEmpty() == unicodedst.isEmpty()); - Q_ASSERT(latin1.length() == unicodedst.length()); + QCOMPARE(latin1.isNull(), unicodesrc.isNull()); + QCOMPARE(latin1.isEmpty(), unicodesrc.isEmpty()); + QCOMPARE(latin1.length(), unicodesrc.length()); + QCOMPARE(latin1.isNull(), unicodedst.isNull()); + QCOMPARE(latin1.isEmpty(), unicodedst.isEmpty()); + QCOMPARE(latin1.length(), unicodedst.length()); if (!latin1.isEmpty()) while (latin1.length() < 128) { @@ -3505,12 +3505,12 @@ void tst_QString::stringRef_toLatin1Roundtrip() QFETCH(QString, unicodedst); // QtTest safety check: - Q_ASSERT(latin1.isNull() == unicodesrc.isNull()); - Q_ASSERT(latin1.isEmpty() == unicodesrc.isEmpty()); - Q_ASSERT(latin1.length() == unicodesrc.length()); - Q_ASSERT(latin1.isNull() == unicodedst.isNull()); - Q_ASSERT(latin1.isEmpty() == unicodedst.isEmpty()); - Q_ASSERT(latin1.length() == unicodedst.length()); + QCOMPARE(latin1.isNull(), unicodesrc.isNull()); + QCOMPARE(latin1.isEmpty(), unicodesrc.isEmpty()); + QCOMPARE(latin1.length(), unicodesrc.length()); + QCOMPARE(latin1.isNull(), unicodedst.isNull()); + QCOMPARE(latin1.isEmpty(), unicodedst.isEmpty()); + QCOMPARE(latin1.length(), unicodedst.length()); if (!latin1.isEmpty()) while (latin1.length() < 128) { diff --git a/tests/auto/qtextboundaryfinder/tst_qtextboundaryfinder.cpp b/tests/auto/qtextboundaryfinder/tst_qtextboundaryfinder.cpp index 6157004..1da0bde 100644 --- a/tests/auto/qtextboundaryfinder/tst_qtextboundaryfinder.cpp +++ b/tests/auto/qtextboundaryfinder/tst_qtextboundaryfinder.cpp @@ -123,14 +123,14 @@ void tst_QTextBoundaryFinder::graphemeBoundaries() if (test.at(pos).unicode() == 0xf7) breakPositions.append(strPos); else - Q_ASSERT(test.at(pos).unicode() == 0xd7); + QVERIFY(test.at(pos).unicode() == 0xd7); ++pos; if (pos < test.length()) { - Q_ASSERT(pos < test.length() - 4); + QVERIFY(pos < test.length() - 4); QString hex = test.mid(pos, 4); bool ok = true; testString.append(QChar(hex.toInt(&ok, 16))); - Q_ASSERT(ok); + QVERIFY(ok); pos += 4; } ++strPos; @@ -176,14 +176,14 @@ void tst_QTextBoundaryFinder::wordBoundaries() if (test.at(pos).unicode() == 0xf7) breakPositions.append(strPos); else - Q_ASSERT(test.at(pos).unicode() == 0xd7); + QVERIFY(test.at(pos).unicode() == 0xd7); ++pos; if (pos < test.length()) { - Q_ASSERT(pos < test.length() - 4); + QVERIFY(pos < test.length() - 4); QString hex = test.mid(pos, 4); bool ok = true; testString.append(QChar(hex.toInt(&ok, 16))); - Q_ASSERT(ok); + QVERIFY(ok); pos += 4; } ++strPos; @@ -228,14 +228,14 @@ void tst_QTextBoundaryFinder::sentenceBoundaries() if (test.at(pos).unicode() == 0xf7) breakPositions.append(strPos); else - Q_ASSERT(test.at(pos).unicode() == 0xd7); + QVERIFY(test.at(pos).unicode() == 0xd7); ++pos; if (pos < test.length()) { - Q_ASSERT(pos < test.length() - 4); + QVERIFY(pos < test.length() - 4); QString hex = test.mid(pos, 4); bool ok = true; testString.append(QChar(hex.toInt(&ok, 16))); - Q_ASSERT(ok); + QVERIFY(ok); pos += 4; } ++strPos; diff --git a/tests/auto/qtextcodec/tst_qtextcodec.cpp b/tests/auto/qtextcodec/tst_qtextcodec.cpp index 43656c8..d122b0b 100644 --- a/tests/auto/qtextcodec/tst_qtextcodec.cpp +++ b/tests/auto/qtextcodec/tst_qtextcodec.cpp @@ -428,7 +428,7 @@ void tst_QTextCodec::flagCodepointFFFF() const QString input(ch); QTextCodec *const codec = QTextCodec::codecForMib(106); // UTF-8 - Q_ASSERT(codec); + QVERIFY(codec); const QByteArray asDecoded(codec->fromUnicode(input)); QCOMPARE(asDecoded, QByteArray("?")); @@ -465,7 +465,7 @@ void tst_QTextCodec::flagF7808080() const QTextCodec *const codec = QTextCodec::codecForMib(106); // UTF-8 - Q_ASSERT(codec); + QVERIFY(codec); //QVERIFY(!codec->canEncode(QChar(0x1C0000))); @@ -482,7 +482,7 @@ void tst_QTextCodec::flagEFBFBF() const invalidInput[2] = char(0xBF); const QTextCodec *const codec = QTextCodec::codecForMib(106); // UTF-8 - Q_ASSERT(codec); + QVERIFY(codec); { //QVERIFY(!codec->canEncode(QChar(0xFFFF))); @@ -1627,7 +1627,7 @@ void tst_QTextCodec::utf8bom() QFETCH(QString, result); QTextCodec *const codec = QTextCodec::codecForMib(106); // UTF-8 - Q_ASSERT(codec); + QVERIFY(codec); QCOMPARE(codec->toUnicode(data.constData(), data.length(), 0), result); diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index 35014c9..64d543f 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -7220,8 +7220,7 @@ void tst_QWidget::render_systemClip2() QFETCH(bool, usePaintEvent); QFETCH(QColor, expectedColor); - Q_ASSERT_X(expectedColor != QColor(Qt::red), Q_FUNC_INFO, - "Qt::red is the reference color for the image, pick another color"); + QVERIFY2(expectedColor != QColor(Qt::red), "Qt::red is the reference color for the image, pick another color"); class MyWidget : public QWidget { diff --git a/tests/auto/xmlpatternsxqts/tst_suitetest.cpp b/tests/auto/xmlpatternsxqts/tst_suitetest.cpp index 62cc4bb..ff6121f 100644 --- a/tests/auto/xmlpatternsxqts/tst_suitetest.cpp +++ b/tests/auto/xmlpatternsxqts/tst_suitetest.cpp @@ -108,7 +108,7 @@ void tst_SuiteTest::runTestSuite() const /* Run the tests, and serialize the result(as according to XQTSResult.xsd) to standard out. */ TestSuiteResult *const result = ts->runSuite(); - Q_ASSERT(result); + QVERIFY(result); QFile out(m_candidateBaseline); QVERIFY(out.open(QIODevice::WriteOnly)); -- cgit v0.12 From f3092b91a7a2e9e34dfe7eefb3c6b0ed8c3c3786 Mon Sep 17 00:00:00 2001 From: Guoqing Zhang Date: Tue, 12 Apr 2011 10:45:43 +0300 Subject: Fix OpenGL build break on Symbian Task-number: QT-4871 Reviewed-by: Dmitry Trofimov --- src/s60installs/eabi/QtOpenGLu.def | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/s60installs/eabi/QtOpenGLu.def b/src/s60installs/eabi/QtOpenGLu.def index 44f7306..34b5266 100644 --- a/src/s60installs/eabi/QtOpenGLu.def +++ b/src/s60installs/eabi/QtOpenGLu.def @@ -759,7 +759,7 @@ EXPORTS _ZNK14QGLPaintDevice9isFlippedEv @ 758 NONAME _ZNK16QGLWindowSurface8featuresEv @ 759 NONAME _ZNK26QGLFramebufferObjectFormat6mipmapEv @ 760 NONAME - _ZTI22QGLContextResourceBase @ 761 NONAME + _ZTI22QGLContextResourceBase @ 761 NONAME ABSENT _ZTI27QGLContextGroupResourceBase @ 762 NONAME _ZTV22QGLContextResourceBase @ 763 NONAME _ZTV27QGLContextGroupResourceBase @ 764 NONAME -- cgit v0.12 From efc004a7ad9f1e40fdba6afc06e161052d9fae2f Mon Sep 17 00:00:00 2001 From: Guoqing Zhang Date: Tue, 12 Apr 2011 10:49:08 +0300 Subject: Add focus frame support in style sheet Task-number: QTBUG-16027 Reviewed-by: Olivier Goffart --- src/gui/styles/qstylesheetstyle.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp index ecf924c..faa929e 100644 --- a/src/gui/styles/qstylesheetstyle.cpp +++ b/src/gui/styles/qstylesheetstyle.cpp @@ -3323,6 +3323,13 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q } break; + case CE_FocusFrame: + if (!rule.hasNativeBorder()) { + rule.drawBorder(p, opt->rect); + return; + } + break; + case CE_PushButton: if (const QStyleOptionButton *btn = qstyleoption_cast(opt)) { if (rule.hasDrawable() || rule.hasBox() || rule.hasPosition() || rule.hasPalette() || -- cgit v0.12 From 930db5826ff2c02d54f2851494000c5fab97da54 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Tue, 12 Apr 2011 15:23:33 +0300 Subject: Fix "make sis" for projects that have empty OBJECTS_DIR Temp directory for packagaging got created to system root if OBJECTS_DIR was empty. Fixed it to use '.' instead in those cases. Reviewed-by: Janne Koskinen --- mkspecs/features/symbian/sis_targets.prf | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mkspecs/features/symbian/sis_targets.prf b/mkspecs/features/symbian/sis_targets.prf index d0fe881..f3452b7 100644 --- a/mkspecs/features/symbian/sis_targets.prf +++ b/mkspecs/features/symbian/sis_targets.prf @@ -26,7 +26,11 @@ equals(GENERATE_SIS_TARGETS, true) { qtPrepareTool(QMAKE_CREATEPACKAGE, createpackage) - CREATEPACKAGE_DIR = $$OBJECTS_DIR/createpackage_tmp + sis_objects_dir = $$OBJECTS_DIR + isEmpty(sis_objects_dir):sis_objects_dir = . + + CREATEPACKAGE_DIR = $$sis_objects_dir/createpackage_tmp + QMAKE_CLEAN += $$CREATEPACKAGE_DIR/* symbian-abld|symbian-sbsv2 { -- cgit v0.12 From abc5a632942c23496d75c49b3b0b4a674cdafdf8 Mon Sep 17 00:00:00 2001 From: Fabien Freling Date: Tue, 12 Apr 2011 16:23:57 +0200 Subject: Fix a race condition when the main window is being destructed. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During the destructor of QWidget, we delete the layout. If the layout is not set to 0 afterwards, a check on the layout might turn true, but any access will end with a segfault. Reviewed-by: João Abecasis --- src/gui/kernel/qwidget.cpp | 1 + src/gui/painting/qunifiedtoolbarsurface_mac.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 5705214..758ccce 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -1588,6 +1588,7 @@ QWidget::~QWidget() // delete layout while we still are a valid widget delete d->layout; + d->layout = 0; // Remove myself from focus list Q_ASSERT(d->focus_next->d_func()->focus_prev == this); diff --git a/src/gui/painting/qunifiedtoolbarsurface_mac.cpp b/src/gui/painting/qunifiedtoolbarsurface_mac.cpp index 3876c3d..2fda6b9 100644 --- a/src/gui/painting/qunifiedtoolbarsurface_mac.cpp +++ b/src/gui/painting/qunifiedtoolbarsurface_mac.cpp @@ -152,7 +152,8 @@ void QUnifiedToolbarSurface::beginPaint(const QRegion &rgn) void QUnifiedToolbarSurface::updateToolbarOffset(QWidget *widget) { QMainWindowLayout *mlayout = qobject_cast (widget->window()->layout()); - mlayout->updateUnifiedToolbarOffset(); + if (mlayout) + mlayout->updateUnifiedToolbarOffset(); } void QUnifiedToolbarSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &offset) -- cgit v0.12 From 9632fdefa9012ca11cd1345d66bafd6f417de88e Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 12 Apr 2011 17:58:12 +0100 Subject: 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 --- 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 146d2f3..4317aad 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -4101,6 +4101,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())); @@ -4351,6 +4352,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 9cddc00..2cd870f 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 f4207d6..7bf5ba0 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 623e02b..f83c4cf 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); -- cgit v0.12 From 0aa780235c24ed724fcf6a9095a6467e34b9346e Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 12 Apr 2011 18:01:49 +0100 Subject: 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 --- 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 f1b2982..b2b655e 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 -- cgit v0.12 From 9af8b63fd730bf29179a08ee53dc99b7e7646bda Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 12 Apr 2011 18:06:17 +0100 Subject: Fix error handling in write for socks socket engine When socks socket engine calls the write function of the native socket engine, it now propagates errors to the abstract socket. Task-number: QTBUG-18713 Reviewed-by: Markus Goetz --- src/network/socket/qsocks5socketengine.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/network/socket/qsocks5socketengine.cpp b/src/network/socket/qsocks5socketengine.cpp index c365635..88b5aca 100644 --- a/src/network/socket/qsocks5socketengine.cpp +++ b/src/network/socket/qsocks5socketengine.cpp @@ -1540,8 +1540,13 @@ qint64 QSocks5SocketEngine::write(const char *data, qint64 len) // ### Handle this error. } - d->data->controlSocket->write(sealedBuf); + qint64 written = d->data->controlSocket->write(sealedBuf); + if (written <= 0) { + QSOCKS5_Q_DEBUG << "native write returned" << written; + return written; + } d->data->controlSocket->waitForBytesWritten(0); + //NB: returning len rather than written for the OK case, because the "sealing" may increase the length return len; #ifndef QT_NO_UDPSOCKET } else if (d->mode == QSocks5SocketEnginePrivate::UdpAssociateMode) { -- cgit v0.12 From 16fe5d5b87ed1d819bf0791fabbd121481d62d22 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Wed, 13 Apr 2011 09:31:21 +0200 Subject: qdoc: Last commit before merge into master. Added a function to class Config to unload the qdocconf file. This is for the qdoc wizard. --- tools/qdoc3/config.cpp | 27 ++++++++++++++++++++++++++- tools/qdoc3/config.h | 1 + 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/tools/qdoc3/config.cpp b/tools/qdoc3/config.cpp index 838f6ac..eaec327 100644 --- a/tools/qdoc3/config.cpp +++ b/tools/qdoc3/config.cpp @@ -48,7 +48,7 @@ #include #include #include - +#include #include "config.h" #include @@ -175,6 +175,7 @@ Config::Config(const QString& programName) } /*! + The destructor has nothing special to do. */ Config::~Config() { @@ -202,6 +203,30 @@ void Config::load(const QString& fileName) } /*! + Writes the qdoc configuration data to the named file. + The previous contents of the file are overwritten. + */ +void Config::unload(const QString& fileName) +{ + + QStringMultiMap::ConstIterator v = stringValueMap.begin(); + while (v != stringValueMap.end()) { + qDebug() << v.key() << " = " << v.value(); +#if 0 + if (v.key().startsWith(varDot)) { + QString subVar = v.key().mid(varDot.length()); + int dot = subVar.indexOf(QLatin1Char('.')); + if (dot != -1) + subVar.truncate(dot); + t.insert(subVar,v.value()); + } +#endif + ++v; + } + qDebug() << "fileName:" << fileName; +} + +/*! Joins all the strings in \a values into a single string with the individual \a values separated by ' '. Then it inserts the result into the string list map with \a var as the key. diff --git a/tools/qdoc3/config.h b/tools/qdoc3/config.h index 8e19ed2..94f0060 100644 --- a/tools/qdoc3/config.h +++ b/tools/qdoc3/config.h @@ -63,6 +63,7 @@ class Config ~Config(); void load(const QString& fileName); + void unload(const QString& fileName); void setStringList(const QString& var, const QStringList& values); const QString& programName() const { return prog; } -- cgit v0.12 From f16c261348193b4c03f796db4e1e3a5db09267a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 13 Apr 2011 09:47:56 +0200 Subject: Prepared for SIMD implementation of radial gradients. Made the radial gradient fetch func into a template to be able to optimize the inner loop using SIMD instructions. Reviewed-by: Benjamin Poulain --- src/gui/painting/qdrawhelper.cpp | 200 +++++---------------------------------- src/gui/painting/qdrawhelper_p.h | 151 +++++++++++++++++++++++++++++ 2 files changed, 174 insertions(+), 177 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 5e75e4a..535313e 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -75,43 +75,9 @@ enum { fixed_scale = 1 << 16, half_point = 1 << 15 }; -static const int buffer_size = 2048; - -struct LinearGradientValues -{ - qreal dx; - qreal dy; - qreal l; - qreal off; -}; -struct RadialGradientValues -{ - qreal dx; - qreal dy; - qreal a; -}; - -struct Operator; -typedef uint* (QT_FASTCALL *DestFetchProc)(uint *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length); -typedef void (QT_FASTCALL *DestStoreProc)(QRasterBuffer *rasterBuffer, int x, int y, const uint *buffer, int length); -typedef const uint* (QT_FASTCALL *SourceFetchProc)(uint *buffer, const Operator *o, const QSpanData *data, int y, int x, int length); - - -struct Operator -{ - QPainter::CompositionMode mode; - DestFetchProc dest_fetch; - DestStoreProc dest_store; - SourceFetchProc src_fetch; - CompositionFunctionSolid funcSolid; - CompositionFunction func; - union { - LinearGradientValues linear; - RadialGradientValues radial; -// TextureValues texture; - }; -}; +// must be multiple of 4 for easier SIMD implementations +static const int buffer_size = 2048; /* Destination fetch. This is simple as we don't have to do bounds checks or @@ -1346,64 +1312,13 @@ static const SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = { }, }; - -static inline uint qt_gradient_pixel(const QGradientData *data, qreal pos) -{ - int ipos = int(pos * (GRADIENT_STOPTABLE_SIZE - 1) + qreal(0.5)); - - // calculate the actual offset. - if (ipos < 0 || ipos >= GRADIENT_STOPTABLE_SIZE) { - if (data->spread == QGradient::RepeatSpread) { - ipos = ipos % GRADIENT_STOPTABLE_SIZE; - ipos = ipos < 0 ? GRADIENT_STOPTABLE_SIZE + ipos : ipos; - - } else if (data->spread == QGradient::ReflectSpread) { - const int limit = GRADIENT_STOPTABLE_SIZE * 2 - 1; - ipos = ipos % limit; - ipos = ipos < 0 ? limit + ipos : ipos; - ipos = ipos >= GRADIENT_STOPTABLE_SIZE ? limit - ipos : ipos; - - } else { - if (ipos < 0) ipos = 0; - else if (ipos >= GRADIENT_STOPTABLE_SIZE) ipos = GRADIENT_STOPTABLE_SIZE-1; - } - } - - Q_ASSERT(ipos >= 0); - Q_ASSERT(ipos < GRADIENT_STOPTABLE_SIZE); - - return data->colorTable[ipos]; -} - #define FIXPT_BITS 8 #define FIXPT_SIZE (1<> FIXPT_BITS; - - // calculate the actual offset. - if (ipos < 0 || ipos >= GRADIENT_STOPTABLE_SIZE) { - if (data->spread == QGradient::RepeatSpread) { - ipos = ipos % GRADIENT_STOPTABLE_SIZE; - ipos = ipos < 0 ? GRADIENT_STOPTABLE_SIZE + ipos : ipos; - - } else if (data->spread == QGradient::ReflectSpread) { - const int limit = GRADIENT_STOPTABLE_SIZE * 2 - 1; - ipos = ipos % limit; - ipos = ipos < 0 ? limit + ipos : ipos; - ipos = ipos >= GRADIENT_STOPTABLE_SIZE ? limit - ipos : ipos; - - } else { - if (ipos < 0) ipos = 0; - else if (ipos >= GRADIENT_STOPTABLE_SIZE) ipos = GRADIENT_STOPTABLE_SIZE-1; - } - } - - Q_ASSERT(ipos >= 0); - Q_ASSERT(ipos < GRADIENT_STOPTABLE_SIZE); - - return data->colorTable[ipos]; + return data->colorTable[qt_gradient_clamp(data, ipos)]; } static void QT_FASTCALL getLinearGradientValues(LinearGradientValues *v, const QSpanData *data) @@ -1419,8 +1334,8 @@ static void QT_FASTCALL getLinearGradientValues(LinearGradientValues *v, const Q } } -static const uint * QT_FASTCALL fetchLinearGradient(uint *buffer, const Operator *op, const QSpanData *data, - int y, int x, int length) +static const uint * QT_FASTCALL qt_fetch_linear_gradient(uint *buffer, const Operator *op, const QSpanData *data, + int y, int x, int length) { const uint *b = buffer; qreal t, inc; @@ -1487,22 +1402,6 @@ static const uint * QT_FASTCALL fetchLinearGradient(uint *buffer, const Operator return b; } -static inline qreal determinant(qreal a, qreal b, qreal c) -{ - return (b * b) - (4 * a * c); -} - -// function to evaluate real roots -static inline qreal realRoots(qreal a, qreal b, qreal detSqrt) -{ - return (-b + detSqrt)/(2 * a); -} - -static inline qreal qSafeSqrt(qreal x) -{ - return x > 0 ? qSqrt(x) : 0; -} - static void QT_FASTCALL getRadialGradientValues(RadialGradientValues *v, const QSpanData *data) { v->dx = data->gradient.radial.center.x - data->gradient.radial.focal.x; @@ -1510,51 +1409,14 @@ static void QT_FASTCALL getRadialGradientValues(RadialGradientValues *v, const Q v->a = data->gradient.radial.radius*data->gradient.radial.radius - v->dx*v->dx - v->dy*v->dy; } -static const uint * QT_FASTCALL fetchRadialGradient(uint *buffer, const Operator *op, const QSpanData *data, - int y, int x, int length) +class RadialFetchPlain { - const uint *b = buffer; - qreal rx = data->m21 * (y + qreal(0.5)) - + data->dx + data->m11 * (x + qreal(0.5)); - qreal ry = data->m22 * (y + qreal(0.5)) - + data->dy + data->m12 * (x + qreal(0.5)); - bool affine = !data->m13 && !data->m23; - //qreal r = data->gradient.radial.radius; - - const uint *end = buffer + length; - if (affine) { - rx -= data->gradient.radial.focal.x; - ry -= data->gradient.radial.focal.y; - - qreal inv_a = 1 / qreal(2 * op->radial.a); - - const qreal delta_rx = data->m11; - const qreal delta_ry = data->m12; - - qreal b = 2*(rx * op->radial.dx + ry * op->radial.dy); - qreal delta_b = 2*(delta_rx * op->radial.dx + delta_ry * op->radial.dy); - const qreal b_delta_b = 2 * b * delta_b; - const qreal delta_b_delta_b = 2 * delta_b * delta_b; - - const qreal bb = b * b; - const qreal delta_bb = delta_b * delta_b; - - b *= inv_a; - delta_b *= inv_a; - - const qreal rxrxryry = rx * rx + ry * ry; - const qreal delta_rxrxryry = delta_rx * delta_rx + delta_ry * delta_ry; - const qreal rx_plus_ry = 2*(rx * delta_rx + ry * delta_ry); - const qreal delta_rx_plus_ry = 2 * delta_rxrxryry; - - inv_a *= inv_a; - - qreal det = (bb + 4 * op->radial.a * rxrxryry) * inv_a; - qreal delta_det = (b_delta_b + delta_bb + 4 * op->radial.a * (rx_plus_ry + delta_rxrxryry)) * inv_a; - const qreal delta_delta_det = (delta_b_delta_b + 4 * op->radial.a * delta_rx_plus_ry) * inv_a; - +public: + static inline void fetch(uint *buffer, uint *end, const QSpanData *data, qreal det, qreal delta_det, + qreal delta_delta_det, qreal b, qreal delta_b) + { while (buffer < end) { - *buffer = qt_gradient_pixel(&data->gradient, qSafeSqrt(det) - b); + *buffer = qt_gradient_pixel(&data->gradient, (det > 0 ? qSqrt(det) : 0) - b); det += delta_det; delta_det += delta_delta_det; @@ -1562,35 +1424,19 @@ static const uint * QT_FASTCALL fetchRadialGradient(uint *buffer, const Operator ++buffer; } - } else { - qreal rw = data->m23 * (y + qreal(0.5)) - + data->m33 + data->m13 * (x + qreal(0.5)); - if (!rw) - rw = 1; - while (buffer < end) { - qreal gx = rx/rw - data->gradient.radial.focal.x; - qreal gy = ry/rw - data->gradient.radial.focal.y; - qreal b = 2*(gx*op->radial.dx + gy*op->radial.dy); - qreal det = determinant(op->radial.a, b , -(gx*gx + gy*gy)); - qreal s = realRoots(op->radial.a, b, qSafeSqrt(det)); - - *buffer = qt_gradient_pixel(&data->gradient, s); - - rx += data->m11; - ry += data->m12; - rw += data->m13; - if (!rw) { - rw += data->m13; - } - ++buffer; - } } +}; - return b; +const uint * QT_FASTCALL qt_fetch_radial_gradient_plain(uint *buffer, const Operator *op, const QSpanData *data, + int y, int x, int length) +{ + return qt_fetch_radial_gradient_template(buffer, op, data, y, x, length); } -static const uint * QT_FASTCALL fetchConicalGradient(uint *buffer, const Operator *, const QSpanData *data, - int y, int x, int length) +static SourceFetchProc qt_fetch_radial_gradient = qt_fetch_radial_gradient_plain; + +static const uint * QT_FASTCALL qt_fetch_conical_gradient(uint *buffer, const Operator *, const QSpanData *data, + int y, int x, int length) { const uint *b = buffer; qreal rx = data->m21 * (y + qreal(0.5)) @@ -3347,16 +3193,16 @@ static inline Operator getOperator(const QSpanData *data, const QSpan *spans, in case QSpanData::LinearGradient: solidSource = !data->gradient.alphaColor; getLinearGradientValues(&op.linear, data); - op.src_fetch = fetchLinearGradient; + op.src_fetch = qt_fetch_linear_gradient; break; case QSpanData::RadialGradient: solidSource = !data->gradient.alphaColor; getRadialGradientValues(&op.radial, data); - op.src_fetch = fetchRadialGradient; + op.src_fetch = qt_fetch_radial_gradient; break; case QSpanData::ConicalGradient: solidSource = !data->gradient.alphaColor; - op.src_fetch = fetchConicalGradient; + op.src_fetch = qt_fetch_conical_gradient; break; case QSpanData::Texture: op.src_fetch = sourceFetch[getBlendType(data)][data->texture.format]; diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index d4e731b..2cfcffb 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -63,6 +63,7 @@ #endif #include "private/qrasterdefs_p.h" #include +#include #ifdef Q_WS_QWS #include "QtGui/qscreen_qws.h" @@ -178,6 +179,40 @@ void qBlendTextureCallback(int count, const QSpan *spans, void *userData); typedef void (QT_FASTCALL *CompositionFunction)(uint *dest, const uint *src, int length, uint const_alpha); typedef void (QT_FASTCALL *CompositionFunctionSolid)(uint *dest, int length, uint color, uint const_alpha); +struct LinearGradientValues +{ + qreal dx; + qreal dy; + qreal l; + qreal off; +}; + +struct RadialGradientValues +{ + qreal dx; + qreal dy; + qreal a; +}; + +struct Operator; +typedef uint* (QT_FASTCALL *DestFetchProc)(uint *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length); +typedef void (QT_FASTCALL *DestStoreProc)(QRasterBuffer *rasterBuffer, int x, int y, const uint *buffer, int length); +typedef const uint* (QT_FASTCALL *SourceFetchProc)(uint *buffer, const Operator *o, const QSpanData *data, int y, int x, int length); + +struct Operator +{ + QPainter::CompositionMode mode; + DestFetchProc dest_fetch; + DestStoreProc dest_store; + SourceFetchProc src_fetch; + CompositionFunctionSolid funcSolid; + CompositionFunction func; + union { + LinearGradientValues linear; + RadialGradientValues radial; + }; +}; + void qInitDrawhelperAsm(); class QRasterPaintEngine; @@ -308,6 +343,122 @@ struct QSpanData void adjustSpanMethods(); }; +static inline uint qt_gradient_clamp(const QGradientData *data, int ipos) +{ + if (ipos < 0 || ipos >= GRADIENT_STOPTABLE_SIZE) { + if (data->spread == QGradient::RepeatSpread) { + ipos = ipos % GRADIENT_STOPTABLE_SIZE; + ipos = ipos < 0 ? GRADIENT_STOPTABLE_SIZE + ipos : ipos; + + } else if (data->spread == QGradient::ReflectSpread) { + const int limit = GRADIENT_STOPTABLE_SIZE * 2 - 1; + ipos = ipos % limit; + ipos = ipos < 0 ? limit + ipos : ipos; + ipos = ipos >= GRADIENT_STOPTABLE_SIZE ? limit - ipos : ipos; + + } else { + if (ipos < 0) + ipos = 0; + else if (ipos >= GRADIENT_STOPTABLE_SIZE) + ipos = GRADIENT_STOPTABLE_SIZE-1; + } + } + + + Q_ASSERT(ipos >= 0); + Q_ASSERT(ipos < GRADIENT_STOPTABLE_SIZE); + + return ipos; +} + +static inline uint qt_gradient_pixel(const QGradientData *data, qreal pos) +{ + int ipos = int(pos * (GRADIENT_STOPTABLE_SIZE - 1) + qreal(0.5)); + return data->colorTable[qt_gradient_clamp(data, ipos)]; +} + +static inline qreal qRadialDeterminant(qreal a, qreal b, qreal c) +{ + return (b * b) - (4 * a * c); +} + +// function to evaluate real roots +static inline qreal qRadialRealRoots(qreal a, qreal b, qreal detSqrt) +{ + return (-b + detSqrt)/(2 * a); +} + +template +const uint * QT_FASTCALL qt_fetch_radial_gradient_template(uint *buffer, const Operator *op, const QSpanData *data, + int y, int x, int length) +{ + const uint *b = buffer; + qreal rx = data->m21 * (y + qreal(0.5)) + + data->dx + data->m11 * (x + qreal(0.5)); + qreal ry = data->m22 * (y + qreal(0.5)) + + data->dy + data->m12 * (x + qreal(0.5)); + bool affine = !data->m13 && !data->m23; + + uint *end = buffer + length; + if (affine) { + rx -= data->gradient.radial.focal.x; + ry -= data->gradient.radial.focal.y; + + qreal inv_a = 1 / qreal(2 * op->radial.a); + + const qreal delta_rx = data->m11; + const qreal delta_ry = data->m12; + + qreal b = 2*(rx * op->radial.dx + ry * op->radial.dy); + qreal delta_b = 2*(delta_rx * op->radial.dx + delta_ry * op->radial.dy); + const qreal b_delta_b = 2 * b * delta_b; + const qreal delta_b_delta_b = 2 * delta_b * delta_b; + + const qreal bb = b * b; + const qreal delta_bb = delta_b * delta_b; + + b *= inv_a; + delta_b *= inv_a; + + const qreal rxrxryry = rx * rx + ry * ry; + const qreal delta_rxrxryry = delta_rx * delta_rx + delta_ry * delta_ry; + const qreal rx_plus_ry = 2*(rx * delta_rx + ry * delta_ry); + const qreal delta_rx_plus_ry = 2 * delta_rxrxryry; + + inv_a *= inv_a; + + qreal det = (bb + 4 * op->radial.a * rxrxryry) * inv_a; + qreal delta_det = (b_delta_b + delta_bb + 4 * op->radial.a * (rx_plus_ry + delta_rxrxryry)) * inv_a; + const qreal delta_delta_det = (delta_b_delta_b + 4 * op->radial.a * delta_rx_plus_ry) * inv_a; + + RadialFetchFunc::fetch(buffer, end, data, det, delta_det, delta_delta_det, b, delta_b); + } else { + qreal rw = data->m23 * (y + qreal(0.5)) + + data->m33 + data->m13 * (x + qreal(0.5)); + if (!rw) + rw = 1; + while (buffer < end) { + qreal gx = rx/rw - data->gradient.radial.focal.x; + qreal gy = ry/rw - data->gradient.radial.focal.y; + qreal b = 2*(gx*op->radial.dx + gy*op->radial.dy); + qreal det = qRadialDeterminant(op->radial.a, b , -(gx*gx + gy*gy)); + qreal s = qRadialRealRoots(op->radial.a, b, (det > 0 ? qSqrt(det) : 0)); + + *buffer = qt_gradient_pixel(&data->gradient, s); + + rx += data->m11; + ry += data->m12; + rw += data->m13; + if (!rw) { + rw += data->m13; + } + ++buffer; + } + } + + return b; +} + #if defined(Q_CC_RVCT) # pragma push # pragma arm -- cgit v0.12 From 44dd7ef86a3970694a4f8fd9516575c0533a336e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Sat, 18 Sep 2010 11:04:29 +0200 Subject: Improved qt_gradient_clamp for reflect spreads. Using GRADIENT_STOPTABLE_SIZE * 2 as the modulo gives more correct behaviour, and also improves performance slightly. Reviewed-by: Benjamin Poulain --- src/gui/painting/qdrawhelper_p.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 2cfcffb..6377fe1 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -349,13 +349,11 @@ static inline uint qt_gradient_clamp(const QGradientData *data, int ipos) if (data->spread == QGradient::RepeatSpread) { ipos = ipos % GRADIENT_STOPTABLE_SIZE; ipos = ipos < 0 ? GRADIENT_STOPTABLE_SIZE + ipos : ipos; - } else if (data->spread == QGradient::ReflectSpread) { - const int limit = GRADIENT_STOPTABLE_SIZE * 2 - 1; + const int limit = GRADIENT_STOPTABLE_SIZE * 2; ipos = ipos % limit; ipos = ipos < 0 ? limit + ipos : ipos; - ipos = ipos >= GRADIENT_STOPTABLE_SIZE ? limit - ipos : ipos; - + ipos = ipos >= GRADIENT_STOPTABLE_SIZE ? limit - 1 - ipos : ipos; } else { if (ipos < 0) ipos = 0; @@ -364,7 +362,6 @@ static inline uint qt_gradient_clamp(const QGradientData *data, int ipos) } } - Q_ASSERT(ipos >= 0); Q_ASSERT(ipos < GRADIENT_STOPTABLE_SIZE); -- cgit v0.12 From 26bd3dccdee8c6a8f1cf9d254a2a6be7d403aa8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 17 Sep 2010 21:53:43 +0200 Subject: Optimized radial gradient fetch using SSE 2. On an i7 this improves performance by 22 % in parcycle, 107 % in default svgviewer example, and 283 % in a synthetic radial gradient benchmark. Reviewed-by: Andreas Kling --- src/gui/painting/qdrawhelper.cpp | 5 +++ src/gui/painting/qdrawhelper_p.h | 9 ++++ src/gui/painting/qdrawhelper_sse2.cpp | 84 +++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 535313e..a676fe9 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -7734,6 +7734,11 @@ void qInitDrawhelperAsm() qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2; qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2; qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2; + + extern const uint * QT_FASTCALL qt_fetch_radial_gradient_sse2(uint *buffer, const Operator *op, const QSpanData *data, + int y, int x, int length); + + qt_fetch_radial_gradient = qt_fetch_radial_gradient_sse2; } #ifdef QT_HAVE_SSSE3 diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 6377fe1..db5ec70 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -268,8 +268,10 @@ struct QGradientData #ifdef Q_WS_QWS #define GRADIENT_STOPTABLE_SIZE 256 +#define GRADIENT_STOPTABLE_SIZE_SHIFT 8 #else #define GRADIENT_STOPTABLE_SIZE 1024 +#define GRADIENT_STOPTABLE_SIZE_SHIFT 10 #endif uint* colorTable; //[GRADIENT_STOPTABLE_SIZE]; @@ -389,6 +391,13 @@ template const uint * QT_FASTCALL qt_fetch_radial_gradient_template(uint *buffer, const Operator *op, const QSpanData *data, int y, int x, int length) { + // avoid division by zero + if (qFuzzyIsNull(op->radial.a)) { + extern void (*qt_memfill32)(quint32 *dest, quint32 value, int count); + qt_memfill32(buffer, data->gradient.colorTable[0], length); + return buffer; + } + const uint *b = buffer; qreal rx = data->m21 * (y + qreal(0.5)) + data->dx + data->m11 * (x + qreal(0.5)); diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp index aad6bc9..eef4cda 100644 --- a/src/gui/painting/qdrawhelper_sse2.cpp +++ b/src/gui/painting/qdrawhelper_sse2.cpp @@ -491,6 +491,90 @@ void qt_bitmapblit16_sse2(QRasterBuffer *rasterBuffer, int x, int y, } } +extern const uint * QT_FASTCALL qt_fetch_radial_gradient_plain(uint *buffer, const Operator *op, const QSpanData *data, + int y, int x, int length); +class RadialFetchSse2 +{ +public: + static inline void fetch(uint *buffer, uint *end, const QSpanData *data, qreal det, qreal delta_det, + qreal delta_delta_det, qreal b, qreal delta_b) + { + union Vect_buffer_f { __m128 v; float f[4]; }; + union Vect_buffer_i { __m128i v; int i[4]; }; + + Vect_buffer_f det_vec; + Vect_buffer_f delta_det4_vec; + Vect_buffer_f b_vec; + + for (int i = 0; i < 4; ++i) { + det_vec.f[i] = det; + delta_det4_vec.f[i] = 4 * delta_det; + b_vec.f[i] = b; + + det += delta_det; + delta_det += delta_delta_det; + b += delta_b; + } + + const __m128 v_delta_delta_det16 = _mm_set1_ps(16 * delta_delta_det); + const __m128 v_delta_delta_det6 = _mm_set1_ps(6 * delta_delta_det); + const __m128 v_delta_b4 = _mm_set1_ps(4 * delta_b); + + const __m128 v_min = _mm_set1_ps(0.0f); + const __m128 v_max = _mm_set1_ps(GRADIENT_STOPTABLE_SIZE-1.5f); + const __m128 v_half = _mm_set1_ps(0.5f); + + const __m128 v_table_size_minus_one = _mm_set1_ps(float(GRADIENT_STOPTABLE_SIZE-1)); + + const __m128i v_repeat_mask = _mm_set1_epi32(uint(0xffffff) << GRADIENT_STOPTABLE_SIZE_SHIFT); + const __m128i v_reflect_mask = _mm_set1_epi32(uint(0xffffff) << (GRADIENT_STOPTABLE_SIZE_SHIFT+1)); + + const __m128i v_reflect_limit = _mm_set1_epi32(2 * GRADIENT_STOPTABLE_SIZE - 1); + +#define FETCH_RADIAL_LOOP_PROLOGUE \ + while (buffer < end) { \ + const __m128 v_index_local = _mm_sub_ps(_mm_sqrt_ps(_mm_max_ps(v_min, det_vec.v)), b_vec.v); \ + const __m128 v_index = _mm_add_ps(_mm_mul_ps(v_index_local, v_table_size_minus_one), v_half); \ + Vect_buffer_i index_vec; +#define FETCH_RADIAL_LOOP_CLAMP_REPEAT \ + index_vec.v = _mm_andnot_si128(v_repeat_mask, _mm_cvttps_epi32(v_index)); +#define FETCH_RADIAL_LOOP_CLAMP_REFLECT \ + const __m128i v_index_i = _mm_andnot_si128(v_reflect_mask, _mm_cvttps_epi32(v_index)); \ + const __m128i v_index_i_inv = _mm_sub_epi32(v_reflect_limit, v_index_i); \ + index_vec.v = _mm_min_epi16(v_index_i, v_index_i_inv); +#define FETCH_RADIAL_LOOP_CLAMP_PAD \ + index_vec.v = _mm_cvttps_epi32(_mm_min_ps(v_max, _mm_max_ps(v_min, v_index))); +#define FETCH_RADIAL_LOOP_EPILOGUE \ + det_vec.v = _mm_add_ps(_mm_add_ps(det_vec.v, delta_det4_vec.v), v_delta_delta_det6); \ + delta_det4_vec.v = _mm_add_ps(delta_det4_vec.v, v_delta_delta_det16); \ + b_vec.v = _mm_add_ps(b_vec.v, v_delta_b4); \ + for (int i = 0; i < 4; ++i) \ + *buffer++ = data->gradient.colorTable[index_vec.i[i]]; \ + } + + if (data->gradient.spread == QGradient::RepeatSpread) { + FETCH_RADIAL_LOOP_PROLOGUE + FETCH_RADIAL_LOOP_CLAMP_REPEAT + FETCH_RADIAL_LOOP_EPILOGUE + } else if (data->gradient.spread == QGradient::ReflectSpread) { + FETCH_RADIAL_LOOP_PROLOGUE + FETCH_RADIAL_LOOP_CLAMP_REFLECT + FETCH_RADIAL_LOOP_EPILOGUE + } else { + FETCH_RADIAL_LOOP_PROLOGUE + FETCH_RADIAL_LOOP_CLAMP_PAD + FETCH_RADIAL_LOOP_EPILOGUE + } + } +}; + +const uint * QT_FASTCALL qt_fetch_radial_gradient_sse2(uint *buffer, const Operator *op, const QSpanData *data, + int y, int x, int length) +{ + return qt_fetch_radial_gradient_template(buffer, op, data, y, x, length); +} + + QT_END_NAMESPACE #endif // QT_HAVE_SSE2 -- cgit v0.12 From 5b74a70ac630073582be56f8a0539624a1080185 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 13 Apr 2011 10:15:06 +0200 Subject: Improved gradient table generation performance for two-stop gradients. Two stops is a fairly common case so we gain quite a bit by special casing it. Improves performance by 10 % in parcycle benchmark, and by 90 % in a synthetic benchmark. Reviewed-by: Andreas Kling --- src/gui/painting/qdrawhelper.cpp | 5 ++ src/gui/painting/qdrawhelper_neon.cpp | 38 ++++++++++++ src/gui/painting/qdrawhelper_p.h | 73 ++++++++++++++++++++++ src/gui/painting/qdrawhelper_sse2.cpp | 100 +++++++++---------------------- src/gui/painting/qpaintengine_raster.cpp | 78 ++++++++++++++++++++++++ tests/auto/qpainter/tst_qpainter.cpp | 39 ++++++++++-- 6 files changed, 256 insertions(+), 77 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index a676fe9..fd26676 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -7834,6 +7834,11 @@ void qInitDrawhelperAsm() qMemRotateFunctions[QImage::Format_RGB16][0] = qt_memrotate90_16_neon; qMemRotateFunctions[QImage::Format_RGB16][2] = qt_memrotate270_16_neon; qt_memfill32 = qt_memfill32_neon; + + extern const uint * QT_FASTCALL qt_fetch_radial_gradient_neon(uint *buffer, const Operator *op, const QSpanData *data, + int y, int x, int length); + + qt_fetch_radial_gradient = qt_fetch_radial_gradient_neon; } #endif diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp index debca37..7eb2f09 100644 --- a/src/gui/painting/qdrawhelper_neon.cpp +++ b/src/gui/painting/qdrawhelper_neon.cpp @@ -955,6 +955,44 @@ void qt_memrotate270_16_neon(const uchar *srcPixels, int w, int h, } } +class QSimdNeon +{ +public: + typedef int32x4_t Int32x4; + typedef float32x4_t Float32x4; + + union Vect_buffer_i { Int32x4 v; int i[4]; }; + union Vect_buffer_f { Float32x4 v; float f[4]; }; + + static inline Float32x4 v_dup(float x) { return vdupq_n_f32(x); } + static inline Int32x4 v_dup(int x) { return vdupq_n_s32(x); } + static inline Int32x4 v_dup(uint x) { return vdupq_n_s32(x); } + + static inline Float32x4 v_add(Float32x4 a, Float32x4 b) { return vaddq_f32(a, b); } + static inline Int32x4 v_add(Int32x4 a, Int32x4 b) { return vaddq_s32(a, b); } + + static inline Float32x4 v_max(Float32x4 a, Float32x4 b) { return vmaxq_f32(a, b); } + static inline Float32x4 v_min(Float32x4 a, Float32x4 b) { return vminq_f32(a, b); } + static inline Int32x4 v_min_16(Int32x4 a, Int32x4 b) { return vminq_s32(a, b); } + + static inline Int32x4 v_and(Int32x4 a, Int32x4 b) { return vandq_s32(a, b); } + + static inline Float32x4 v_sub(Float32x4 a, Float32x4 b) { return vsubq_f32(a, b); } + static inline Int32x4 v_sub(Int32x4 a, Int32x4 b) { return vsubq_s32(a, b); } + + static inline Float32x4 v_mul(Float32x4 a, Float32x4 b) { return vmulq_f32(a, b); } + + static inline Float32x4 v_sqrt(Float32x4 x) { Float32x4 y = vrsqrteq_f32(x); y = vmulq_f32(y, vrsqrtsq_f32(x, vmulq_f32(y, y))); return vmulq_f32(x, y); } + + static inline Int32x4 v_toInt(Float32x4 x) { return vcvtq_s32_f32(x); } +}; + +const uint * QT_FASTCALL qt_fetch_radial_gradient_neon(uint *buffer, const Operator *op, const QSpanData *data, + int y, int x, int length) +{ + return qt_fetch_radial_gradient_template >(buffer, op, data, y, x, length); +} + QT_END_NAMESPACE #endif // QT_HAVE_NEON diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index db5ec70..a92f686 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -465,6 +465,79 @@ const uint * QT_FASTCALL qt_fetch_radial_gradient_template(uint *buffer, const O return b; } +template +class QRadialFetchSimd +{ +public: + static inline void fetch(uint *buffer, uint *end, const QSpanData *data, qreal det, qreal delta_det, + qreal delta_delta_det, qreal b, qreal delta_b) + { + typename Simd::Vect_buffer_f det_vec; + typename Simd::Vect_buffer_f delta_det4_vec; + typename Simd::Vect_buffer_f b_vec; + + for (int i = 0; i < 4; ++i) { + det_vec.f[i] = det; + delta_det4_vec.f[i] = 4 * delta_det; + b_vec.f[i] = b; + + det += delta_det; + delta_det += delta_delta_det; + b += delta_b; + } + + const typename Simd::Float32x4 v_delta_delta_det16 = Simd::v_dup(16 * delta_delta_det); + const typename Simd::Float32x4 v_delta_delta_det6 = Simd::v_dup(6 * delta_delta_det); + const typename Simd::Float32x4 v_delta_b4 = Simd::v_dup(4 * delta_b); + + const typename Simd::Float32x4 v_min = Simd::v_dup(0.0f); + const typename Simd::Float32x4 v_max = Simd::v_dup(GRADIENT_STOPTABLE_SIZE-1.5f); + const typename Simd::Float32x4 v_half = Simd::v_dup(0.5f); + + const typename Simd::Float32x4 v_table_size_minus_one = Simd::v_dup(float(GRADIENT_STOPTABLE_SIZE-1)); + + const typename Simd::Int32x4 v_repeat_mask = Simd::v_dup(~(uint(0xffffff) << GRADIENT_STOPTABLE_SIZE_SHIFT)); + const typename Simd::Int32x4 v_reflect_mask = Simd::v_dup(~(uint(0xffffff) << (GRADIENT_STOPTABLE_SIZE_SHIFT+1))); + + const typename Simd::Int32x4 v_reflect_limit = Simd::v_dup(2 * GRADIENT_STOPTABLE_SIZE - 1); + +#define FETCH_RADIAL_LOOP_PROLOGUE \ + while (buffer < end) { \ + const typename Simd::Float32x4 v_index_local = Simd::v_sub(Simd::v_sqrt(Simd::v_max(v_min, det_vec.v)), b_vec.v); \ + const typename Simd::Float32x4 v_index = Simd::v_add(Simd::v_mul(v_index_local, v_table_size_minus_one), v_half); \ + typename Simd::Vect_buffer_i index_vec; +#define FETCH_RADIAL_LOOP_CLAMP_REPEAT \ + index_vec.v = Simd::v_and(v_repeat_mask, Simd::v_toInt(v_index)); +#define FETCH_RADIAL_LOOP_CLAMP_REFLECT \ + const typename Simd::Int32x4 v_index_i = Simd::v_and(v_reflect_mask, Simd::v_toInt(v_index)); \ + const typename Simd::Int32x4 v_index_i_inv = Simd::v_sub(v_reflect_limit, v_index_i); \ + index_vec.v = Simd::v_min_16(v_index_i, v_index_i_inv); +#define FETCH_RADIAL_LOOP_CLAMP_PAD \ + index_vec.v = Simd::v_toInt(Simd::v_min(v_max, Simd::v_max(v_min, v_index))); +#define FETCH_RADIAL_LOOP_EPILOGUE \ + det_vec.v = Simd::v_add(Simd::v_add(det_vec.v, delta_det4_vec.v), v_delta_delta_det6); \ + delta_det4_vec.v = Simd::v_add(delta_det4_vec.v, v_delta_delta_det16); \ + b_vec.v = Simd::v_add(b_vec.v, v_delta_b4); \ + for (int i = 0; i < 4; ++i) \ + *buffer++ = data->gradient.colorTable[index_vec.i[i]]; \ + } + + if (data->gradient.spread == QGradient::RepeatSpread) { + FETCH_RADIAL_LOOP_PROLOGUE + FETCH_RADIAL_LOOP_CLAMP_REPEAT + FETCH_RADIAL_LOOP_EPILOGUE + } else if (data->gradient.spread == QGradient::ReflectSpread) { + FETCH_RADIAL_LOOP_PROLOGUE + FETCH_RADIAL_LOOP_CLAMP_REFLECT + FETCH_RADIAL_LOOP_EPILOGUE + } else { + FETCH_RADIAL_LOOP_PROLOGUE + FETCH_RADIAL_LOOP_CLAMP_PAD + FETCH_RADIAL_LOOP_EPILOGUE + } + } +}; + #if defined(Q_CC_RVCT) # pragma push # pragma arm diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp index eef4cda..542d845 100644 --- a/src/gui/painting/qdrawhelper_sse2.cpp +++ b/src/gui/painting/qdrawhelper_sse2.cpp @@ -491,87 +491,43 @@ void qt_bitmapblit16_sse2(QRasterBuffer *rasterBuffer, int x, int y, } } -extern const uint * QT_FASTCALL qt_fetch_radial_gradient_plain(uint *buffer, const Operator *op, const QSpanData *data, - int y, int x, int length); -class RadialFetchSse2 +class QSimdSse2 { public: - static inline void fetch(uint *buffer, uint *end, const QSpanData *data, qreal det, qreal delta_det, - qreal delta_delta_det, qreal b, qreal delta_b) - { - union Vect_buffer_f { __m128 v; float f[4]; }; - union Vect_buffer_i { __m128i v; int i[4]; }; - - Vect_buffer_f det_vec; - Vect_buffer_f delta_det4_vec; - Vect_buffer_f b_vec; - - for (int i = 0; i < 4; ++i) { - det_vec.f[i] = det; - delta_det4_vec.f[i] = 4 * delta_det; - b_vec.f[i] = b; - - det += delta_det; - delta_det += delta_delta_det; - b += delta_b; - } + typedef __m128i Int32x4; + typedef __m128 Float32x4; - const __m128 v_delta_delta_det16 = _mm_set1_ps(16 * delta_delta_det); - const __m128 v_delta_delta_det6 = _mm_set1_ps(6 * delta_delta_det); - const __m128 v_delta_b4 = _mm_set1_ps(4 * delta_b); - - const __m128 v_min = _mm_set1_ps(0.0f); - const __m128 v_max = _mm_set1_ps(GRADIENT_STOPTABLE_SIZE-1.5f); - const __m128 v_half = _mm_set1_ps(0.5f); - - const __m128 v_table_size_minus_one = _mm_set1_ps(float(GRADIENT_STOPTABLE_SIZE-1)); - - const __m128i v_repeat_mask = _mm_set1_epi32(uint(0xffffff) << GRADIENT_STOPTABLE_SIZE_SHIFT); - const __m128i v_reflect_mask = _mm_set1_epi32(uint(0xffffff) << (GRADIENT_STOPTABLE_SIZE_SHIFT+1)); - - const __m128i v_reflect_limit = _mm_set1_epi32(2 * GRADIENT_STOPTABLE_SIZE - 1); - -#define FETCH_RADIAL_LOOP_PROLOGUE \ - while (buffer < end) { \ - const __m128 v_index_local = _mm_sub_ps(_mm_sqrt_ps(_mm_max_ps(v_min, det_vec.v)), b_vec.v); \ - const __m128 v_index = _mm_add_ps(_mm_mul_ps(v_index_local, v_table_size_minus_one), v_half); \ - Vect_buffer_i index_vec; -#define FETCH_RADIAL_LOOP_CLAMP_REPEAT \ - index_vec.v = _mm_andnot_si128(v_repeat_mask, _mm_cvttps_epi32(v_index)); -#define FETCH_RADIAL_LOOP_CLAMP_REFLECT \ - const __m128i v_index_i = _mm_andnot_si128(v_reflect_mask, _mm_cvttps_epi32(v_index)); \ - const __m128i v_index_i_inv = _mm_sub_epi32(v_reflect_limit, v_index_i); \ - index_vec.v = _mm_min_epi16(v_index_i, v_index_i_inv); -#define FETCH_RADIAL_LOOP_CLAMP_PAD \ - index_vec.v = _mm_cvttps_epi32(_mm_min_ps(v_max, _mm_max_ps(v_min, v_index))); -#define FETCH_RADIAL_LOOP_EPILOGUE \ - det_vec.v = _mm_add_ps(_mm_add_ps(det_vec.v, delta_det4_vec.v), v_delta_delta_det6); \ - delta_det4_vec.v = _mm_add_ps(delta_det4_vec.v, v_delta_delta_det16); \ - b_vec.v = _mm_add_ps(b_vec.v, v_delta_b4); \ - for (int i = 0; i < 4; ++i) \ - *buffer++ = data->gradient.colorTable[index_vec.i[i]]; \ - } + union Vect_buffer_i { Int32x4 v; int i[4]; }; + union Vect_buffer_f { Float32x4 v; float f[4]; }; - if (data->gradient.spread == QGradient::RepeatSpread) { - FETCH_RADIAL_LOOP_PROLOGUE - FETCH_RADIAL_LOOP_CLAMP_REPEAT - FETCH_RADIAL_LOOP_EPILOGUE - } else if (data->gradient.spread == QGradient::ReflectSpread) { - FETCH_RADIAL_LOOP_PROLOGUE - FETCH_RADIAL_LOOP_CLAMP_REFLECT - FETCH_RADIAL_LOOP_EPILOGUE - } else { - FETCH_RADIAL_LOOP_PROLOGUE - FETCH_RADIAL_LOOP_CLAMP_PAD - FETCH_RADIAL_LOOP_EPILOGUE - } - } + static inline Float32x4 v_dup(float x) { return _mm_set1_ps(x); } + static inline Float32x4 v_dup(double x) { return _mm_set1_ps(x); } + static inline Int32x4 v_dup(int x) { return _mm_set1_epi32(x); } + static inline Int32x4 v_dup(uint x) { return _mm_set1_epi32(x); } + + static inline Float32x4 v_add(Float32x4 a, Float32x4 b) { return _mm_add_ps(a, b); } + static inline Int32x4 v_add(Int32x4 a, Int32x4 b) { return _mm_add_epi32(a, b); } + + static inline Float32x4 v_max(Float32x4 a, Float32x4 b) { return _mm_max_ps(a, b); } + static inline Float32x4 v_min(Float32x4 a, Float32x4 b) { return _mm_min_ps(a, b); } + static inline Int32x4 v_min_16(Int32x4 a, Int32x4 b) { return _mm_min_epi16(a, b); } + + static inline Int32x4 v_and(Int32x4 a, Int32x4 b) { return _mm_and_si128(a, b); } + + static inline Float32x4 v_sub(Float32x4 a, Float32x4 b) { return _mm_sub_ps(a, b); } + static inline Int32x4 v_sub(Int32x4 a, Int32x4 b) { return _mm_sub_epi32(a, b); } + + static inline Float32x4 v_mul(Float32x4 a, Float32x4 b) { return _mm_mul_ps(a, b); } + + static inline Float32x4 v_sqrt(Float32x4 x) { return _mm_sqrt_ps(x); } + + static inline Int32x4 v_toInt(Float32x4 x) { return _mm_cvttps_epi32(x); } }; const uint * QT_FASTCALL qt_fetch_radial_gradient_sse2(uint *buffer, const Operator *op, const QSpanData *data, int y, int x, int length) { - return qt_fetch_radial_gradient_template(buffer, op, data, y, x, length); + return qt_fetch_radial_gradient_template >(buffer, op, data, y, x, length); } diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 6902543..8486adb 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -5033,6 +5033,84 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint bool colorInterpolation = (gradient.interpolationMode() == QGradient::ColorInterpolation); + if (stopCount == 2) { + uint first_color = ARGB_COMBINE_ALPHA(stops[0].second.rgba(), opacity); + uint second_color = ARGB_COMBINE_ALPHA(stops[1].second.rgba(), opacity); + + qreal first_stop = stops[0].first; + qreal second_stop = stops[1].first; + + if (second_stop < first_stop) { + qSwap(first_color, second_color); + qSwap(first_stop, second_stop); + } + + if (colorInterpolation) { + first_color = PREMUL(first_color); + second_color = PREMUL(second_color); + } + + int first_index = qRound(first_stop * (GRADIENT_STOPTABLE_SIZE-1)); + int second_index = qRound(second_stop * (GRADIENT_STOPTABLE_SIZE-1)); + + uint red_first = qRed(first_color) << 16; + uint green_first = qGreen(first_color) << 16; + uint blue_first = qBlue(first_color) << 16; + uint alpha_first = qAlpha(first_color) << 16; + + uint red_second = qRed(second_color) << 16; + uint green_second = qGreen(second_color) << 16; + uint blue_second = qBlue(second_color) << 16; + uint alpha_second = qAlpha(second_color) << 16; + + int i = 0; + for (; i <= qMin(GRADIENT_STOPTABLE_SIZE, first_index); ++i) { + if (colorInterpolation) + colorTable[i] = first_color; + else + colorTable[i] = PREMUL(first_color); + } + + if (i < second_index) { + qreal reciprocal = qreal(1) / (second_index - first_index); + + int red_delta = qRound(int(red_second - red_first) * reciprocal); + int green_delta = qRound(int(green_second - green_first) * reciprocal); + int blue_delta = qRound(int(blue_second - blue_first) * reciprocal); + int alpha_delta = qRound(int(alpha_second - alpha_first) * reciprocal); + + // rounding + red_first += 1 << 15; + green_first += 1 << 15; + blue_first += 1 << 15; + alpha_first += 1 << 15; + + for (; i < qMin(GRADIENT_STOPTABLE_SIZE, second_index); ++i) { + red_first += red_delta; + green_first += green_delta; + blue_first += blue_delta; + alpha_first += alpha_delta; + + const uint color = ((alpha_first << 8) & 0xff000000) | (red_first & 0xff0000) + | ((green_first >> 8) & 0xff00) | (blue_first >> 16); + + if (colorInterpolation) + colorTable[i] = color; + else + colorTable[i] = PREMUL(color); + } + } + + for (; i < GRADIENT_STOPTABLE_SIZE; ++i) { + if (colorInterpolation) + colorTable[i] = second_color; + else + colorTable[i] = PREMUL(second_color); + } + + return; + } + uint current_color = ARGB_COMBINE_ALPHA(stops[0].second.rgba(), opacity); if (stopCount == 1) { current_color = PREMUL(current_color); diff --git a/tests/auto/qpainter/tst_qpainter.cpp b/tests/auto/qpainter/tst_qpainter.cpp index c21514b..fa80635 100644 --- a/tests/auto/qpainter/tst_qpainter.cpp +++ b/tests/auto/qpainter/tst_qpainter.cpp @@ -77,6 +77,7 @@ # define SRCDIR "." #endif +Q_DECLARE_METATYPE(QGradientStops) Q_DECLARE_METATYPE(QLine) Q_DECLARE_METATYPE(QRect) Q_DECLARE_METATYPE(QSize) @@ -189,6 +190,7 @@ private slots: void fillRect_stretchToDeviceMode(); void monoImages(); + void linearGradientSymmetry_data(); void linearGradientSymmetry(); void gradientInterpolation(); @@ -3983,8 +3985,39 @@ static QLinearGradient inverseGradient(QLinearGradient g) return g2; } +void tst_QPainter::linearGradientSymmetry_data() +{ + QTest::addColumn("stops"); + + { + QGradientStops stops; + stops << qMakePair(qreal(0.0), QColor(Qt::blue)); + stops << qMakePair(qreal(0.2), QColor(220, 220, 220, 0)); + stops << qMakePair(qreal(0.6), QColor(Qt::red)); + stops << qMakePair(qreal(0.9), QColor(220, 220, 220, 255)); + stops << qMakePair(qreal(1.0), QColor(Qt::black)); + QTest::newRow("multiple stops") << stops; + } + + { + QGradientStops stops; + stops << qMakePair(qreal(0.0), QColor(Qt::blue)); + stops << qMakePair(qreal(1.0), QColor(Qt::black)); + QTest::newRow("two stops") << stops; + } + + { + QGradientStops stops; + stops << qMakePair(qreal(0.3), QColor(Qt::blue)); + stops << qMakePair(qreal(0.6), QColor(Qt::black)); + QTest::newRow("two stops 2") << stops; + } +} + void tst_QPainter::linearGradientSymmetry() { + QFETCH(QGradientStops, stops); + QImage a(64, 8, QImage::Format_ARGB32_Premultiplied); QImage b(64, 8, QImage::Format_ARGB32_Premultiplied); @@ -3992,11 +4025,7 @@ void tst_QPainter::linearGradientSymmetry() b.fill(0); QLinearGradient gradient(QRectF(b.rect()).topLeft(), QRectF(b.rect()).topRight()); - gradient.setColorAt(0.0, Qt::blue); - gradient.setColorAt(0.2, QColor(220, 220, 220, 0)); - gradient.setColorAt(0.6, Qt::red); - gradient.setColorAt(0.9, QColor(220, 220, 220, 255)); - gradient.setColorAt(1.0, Qt::black); + gradient.setStops(stops); QPainter pa(&a); pa.fillRect(a.rect(), gradient); -- cgit v0.12 From 01477af79d8114b3f8993c3967892538a599dfa6 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Wed, 13 Apr 2011 11:58:40 +0300 Subject: Improve logic to find default certificates in createpackage script Original implementation assumed createpackage script was always run from under Qt source tree bin directory, which is not always the case as on some platforms the Qt tools can be found from under EPOCROOT. Fixed it so that if the default directory for default certificates can't be found in the expected location, createpackage will attempt to query qmake in the same directory as the createpackage script for the location of the Qt source tree (QT_INSTALL_PREFIX) and look for default certificates directory from under there. Task-number: QTBUG-18684 Reviewed-by: Janne Koskinen --- bin/createpackage.pl | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/bin/createpackage.pl b/bin/createpackage.pl index b7457e1..aae20ae 100755 --- a/bin/createpackage.pl +++ b/bin/createpackage.pl @@ -238,11 +238,7 @@ if ($templatepkg =~ m/_installer\.pkg$/i && $onlyUnsigned) { my $unsigned_sis_name = $sisoutputbasename."_unsigned.sis"; my $stub_sis_name = $sisoutputbasename.".sis"; -# Store some utility variables -my $scriptpath = dirname(__FILE__); my $certtext = $certificate; -# certificates are one step up in hierarchy -my $certpath = File::Spec->catdir($scriptpath, File::Spec->updir(), "src/s60installs/"); # Check some pre-conditions and print error messages if needed. unless (length($templatepkg)) { @@ -265,6 +261,16 @@ if (length($certificate)) { } } else { #If no certificate is given, check default options + my $scriptpath = dirname(__FILE__); + my $certpath = File::Spec->catdir($scriptpath, File::Spec->updir(), "src/s60installs"); + + unless (-e $certpath) { + my $qmakeCmd = File::Spec->catfile($scriptpath, "qmake"); + $certpath = `$qmakeCmd -query QT_INSTALL_PREFIX`; + $certpath =~ s/\s+$//; + $certpath = File::Spec->catdir($certpath, "src/s60installs"); + } + $certtext = "RnD"; $certificate = File::Spec->catfile($certpath, "rd.cer"); $key = File::Spec->catfile($certpath, "rd-key.pem"); -- cgit v0.12 From da55c1ea92474e989e5582b02815936bbf584405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 13 Apr 2011 10:16:43 +0200 Subject: Added support for six-parameter radial gradients. The extended radial gradients conform to the radial gradient specification in HTML 5 canvas. Task-number: QTBUG-14075 Reviewed-by: Andreas Kling --- src/gui/painting/qbrush.cpp | 191 ++++++++++++++++++--- src/gui/painting/qbrush.h | 12 +- src/gui/painting/qdrawhelper.cpp | 42 ++++- src/gui/painting/qdrawhelper_neon.cpp | 2 + src/gui/painting/qdrawhelper_p.h | 100 +++++++---- src/gui/painting/qdrawhelper_sse2.cpp | 2 + src/gui/painting/qpaintengine_mac.cpp | 3 +- src/gui/painting/qpaintengine_raster.cpp | 3 +- src/gui/painting/qpaintengineex.cpp | 46 +++++ src/gui/painting/qpainter.cpp | 14 +- src/gui/painting/qpainter.h | 1 + .../gl2paintengineex/qglengineshadermanager.cpp | 2 + .../gl2paintengineex/qglengineshadermanager_p.h | 2 + .../gl2paintengineex/qglengineshadersource_p.h | 18 +- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 8 +- src/opengl/qpaintengine_opengl.cpp | 60 ++----- src/openvg/qpaintengine_vg.cpp | 111 ++++++++++++ tests/arthur/common/paintcommands.cpp | 34 +++- tests/arthur/common/paintcommands.h | 1 + .../arthur/data/qps/radial_gradients_extended.qps | 95 ++++++++++ .../data/qps/radial_gradients_extended_qps.png | Bin 0 -> 107978 bytes 21 files changed, 617 insertions(+), 130 deletions(-) create mode 100644 tests/arthur/data/qps/radial_gradients_extended.qps create mode 100644 tests/arthur/data/qps/radial_gradients_extended_qps.png diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp index bf5764a..3ff7eb8 100644 --- a/src/gui/painting/qbrush.cpp +++ b/src/gui/painting/qbrush.cpp @@ -840,6 +840,22 @@ const QGradient *QBrush::gradient() const return 0; } +Q_GUI_EXPORT bool qt_isExtendedRadialGradient(const QBrush &brush) +{ + if (brush.style() == Qt::RadialGradientPattern) { + const QGradient *g = brush.gradient(); + const QRadialGradient *rg = static_cast(g); + + if (!qFuzzyIsNull(rg->focalRadius())) + return true; + + QPointF delta = rg->focalPoint() - rg->center(); + if (delta.x() * delta.x() + delta.y() * delta.y() > rg->radius() * rg->radius()) + return true; + } + + return false; +} /*! Returns true if the brush is fully opaque otherwise false. A brush @@ -849,6 +865,7 @@ const QGradient *QBrush::gradient() const \i The alpha component of the color() is 255. \i Its texture() does not have an alpha channel and is not a QBitmap. \i The colors in the gradient() all have an alpha component that is 255. + \i It is an extended radial gradient. \endlist */ @@ -860,6 +877,9 @@ bool QBrush::isOpaque() const if (d->style == Qt::SolidPattern) return opaqueColor; + if (qt_isExtendedRadialGradient(*this)) + return false; + if (d->style == Qt::LinearGradientPattern || d->style == Qt::RadialGradientPattern || d->style == Qt::ConicalGradientPattern) { @@ -1209,8 +1229,10 @@ QDataStream &operator>>(QDataStream &s, QBrush &b) \list \o \e Linear gradients interpolate colors between start and end points. - \o \e Radial gradients interpolate colors between a focal point and end - points on a circle surrounding it. + \o \e Simple radial gradients interpolate colors between a focal point + and end points on a circle surrounding it. + \o \e Extended radial gradients interpolate colors between a center and + a focal circle. \o \e Conical gradients interpolate colors around a center point. \endlist @@ -1506,8 +1528,6 @@ void QGradient::setInterpolationMode(InterpolationMode mode) dummy = p; } -#undef Q_DUMMY_ACCESSOR - /*! \fn bool QGradient::operator!=(const QGradient &gradient) const \since 4.2 @@ -1541,7 +1561,7 @@ bool QGradient::operator==(const QGradient &gradient) const || m_data.radial.cy != gradient.m_data.radial.cy || m_data.radial.fx != gradient.m_data.radial.fx || m_data.radial.fy != gradient.m_data.radial.fy - || m_data.radial.radius != gradient.m_data.radial.radius) + || m_data.radial.cradius != gradient.m_data.radial.cradius) return false; } else { // m_type == ConicalGradient if (m_data.conical.cx != gradient.m_data.conical.cx @@ -1747,10 +1767,17 @@ void QLinearGradient::setFinalStop(const QPointF &stop) \brief The QRadialGradient class is used in combination with QBrush to specify a radial gradient brush. - Radial gradients interpolate colors between a focal point and end - points on a circle surrounding it. Outside the end points the - gradient is either padded, reflected or repeated depending on the - currently set \l {QGradient::Spread}{spread} method: + Qt supports both simple and extended radial gradients. + + Simple radial gradients interpolate colors between a focal point and end + points on a circle surrounding it. Extended radial gradients interpolate + colors between a focal circle and a center circle. Points outside the cone + defined by the two circles will be transparent. For simple radial gradients + the focal point is adjusted to lie inside the center circle, whereas the + focal point can have any position in an extended radial gradient. + + Outside the end points the gradient is either padded, reflected or repeated + depending on the currently set \l {QGradient::Spread}{spread} method: \table \row @@ -1795,9 +1822,14 @@ static QPointF qt_radial_gradient_adapt_focal_point(const QPointF ¢er, } /*! - Constructs a radial gradient with the given \a center, \a + Constructs a simple radial gradient with the given \a center, \a radius and \a focalPoint. + \note If the given focal point is outside the circle defined by the + center (\a cx, \a cy) and the \a radius it will be re-adjusted to + the intersection between the line from the center to the focal point + and the circle. + \sa QGradient::setColorAt(), QGradient::setStops() */ @@ -1807,7 +1839,7 @@ QRadialGradient::QRadialGradient(const QPointF ¢er, qreal radius, const QPoi m_spread = PadSpread; m_data.radial.cx = center.x(); m_data.radial.cy = center.y(); - m_data.radial.radius = radius; + m_data.radial.cradius = radius; QPointF adapted_focal = qt_radial_gradient_adapt_focal_point(center, radius, focalPoint); m_data.radial.fx = adapted_focal.x(); @@ -1815,7 +1847,7 @@ QRadialGradient::QRadialGradient(const QPointF ¢er, qreal radius, const QPoi } /*! - Constructs a radial gradient with the given \a center, \a + Constructs a simple radial gradient with the given \a center, \a radius and the focal point in the circle center. \sa QGradient::setColorAt(), QGradient::setStops() @@ -1826,16 +1858,21 @@ QRadialGradient::QRadialGradient(const QPointF ¢er, qreal radius) m_spread = PadSpread; m_data.radial.cx = center.x(); m_data.radial.cy = center.y(); - m_data.radial.radius = radius; + m_data.radial.cradius = radius; m_data.radial.fx = center.x(); m_data.radial.fy = center.y(); } /*! - Constructs a radial gradient with the given center (\a cx, \a cy), + Constructs a simple radial gradient with the given center (\a cx, \a cy), \a radius and focal point (\a fx, \a fy). + \note If the given focal point is outside the circle defined by the + center (\a cx, \a cy) and the \a radius it will be re-adjusted to + the intersection between the line from the center to the focal point + and the circle. + \sa QGradient::setColorAt(), QGradient::setStops() */ @@ -1845,7 +1882,7 @@ QRadialGradient::QRadialGradient(qreal cx, qreal cy, qreal radius, qreal fx, qre m_spread = PadSpread; m_data.radial.cx = cx; m_data.radial.cy = cy; - m_data.radial.radius = radius; + m_data.radial.cradius = radius; QPointF adapted_focal = qt_radial_gradient_adapt_focal_point(QPointF(cx, cy), radius, @@ -1856,7 +1893,7 @@ QRadialGradient::QRadialGradient(qreal cx, qreal cy, qreal radius, qreal fx, qre } /*! - Constructs a radial gradient with the center at (\a cx, \a cy) and the + Constructs a simple radial gradient with the center at (\a cx, \a cy) and the specified \a radius. The focal point lies at the center of the circle. \sa QGradient::setColorAt(), QGradient::setStops() @@ -1867,14 +1904,14 @@ QRadialGradient::QRadialGradient(qreal cx, qreal cy, qreal radius) m_spread = PadSpread; m_data.radial.cx = cx; m_data.radial.cy = cy; - m_data.radial.radius = radius; + m_data.radial.cradius = radius; m_data.radial.fx = cx; m_data.radial.fy = cy; } /*! - Constructs a radial gradient with the center and focal point at + Constructs a simple radial gradient with the center and focal point at (0, 0) with a radius of 1. */ QRadialGradient::QRadialGradient() @@ -1883,11 +1920,51 @@ QRadialGradient::QRadialGradient() m_spread = PadSpread; m_data.radial.cx = 0; m_data.radial.cy = 0; - m_data.radial.radius = 1; + m_data.radial.cradius = 1; m_data.radial.fx = 0; m_data.radial.fy = 0; } +/*! + \since 4.8 + + Constructs an extended radial gradient with the given \a center, \a + centerRadius, \a focalPoint, and \a focalRadius. +*/ +QRadialGradient::QRadialGradient(const QPointF ¢er, qreal centerRadius, const QPointF &focalPoint, qreal focalRadius) +{ + m_type = RadialGradient; + m_spread = PadSpread; + m_data.radial.cx = center.x(); + m_data.radial.cy = center.y(); + m_data.radial.cradius = centerRadius; + + m_data.radial.fx = focalPoint.x(); + m_data.radial.fy = focalPoint.y(); + setFocalRadius(focalRadius); +} + +/*! + \since 4.8 + + Constructs an extended radial gradient with the given \a center, \a + centerRadius, \a focalPoint, and \a focalRadius. + Constructs a radial gradient with the given center (\a cx, \a cy), + center radius \a centerRadius, focal point (\a fx, \a fy), and + focal radius \a focalRadius. +*/ +QRadialGradient::QRadialGradient(qreal cx, qreal cy, qreal centerRadius, qreal fx, qreal fy, qreal focalRadius) +{ + m_type = RadialGradient; + m_spread = PadSpread; + m_data.radial.cx = cx; + m_data.radial.cy = cy; + m_data.radial.cradius = centerRadius; + + m_data.radial.fx = fx; + m_data.radial.fy = fy; + setFocalRadius(focalRadius); +} /*! Returns the center of this radial gradient in logical coordinates. @@ -1932,13 +2009,15 @@ void QRadialGradient::setCenter(const QPointF ¢er) /*! Returns the radius of this radial gradient in logical coordinates. + Equivalent to centerRadius() + \sa QGradient::stops() */ qreal QRadialGradient::radius() const { Q_ASSERT(m_type == RadialGradient); - return m_data.radial.radius; + return m_data.radial.cradius; } @@ -1947,13 +2026,81 @@ qreal QRadialGradient::radius() const Sets the radius of this radial gradient in logical coordinates to \a radius + + Equivalent to setCenterRadius() */ void QRadialGradient::setRadius(qreal radius) { Q_ASSERT(m_type == RadialGradient); - m_data.radial.radius = radius; + m_data.radial.cradius = radius; +} + +/*! + \since 4.8 + + Returns the center radius of this radial gradient in logical + coordinates. + + \sa QGradient::stops() +*/ +qreal QRadialGradient::centerRadius() const +{ + Q_ASSERT(m_type == RadialGradient); + return m_data.radial.cradius; +} + +/* + \since 4.8 + + Sets the center radius of this radial gradient in logical coordinates + to \a radius +*/ +void QRadialGradient::setCenterRadius(qreal radius) +{ + Q_ASSERT(m_type == RadialGradient); + m_data.radial.cradius = radius; +} + +/*! + \since 4.8 + + Returns the focal radius of this radial gradient in logical + coordinates. + + \sa QGradient::stops() +*/ +qreal QRadialGradient::focalRadius() const +{ + Q_ASSERT(m_type == RadialGradient); + Q_DUMMY_ACCESSOR + + // mask away low three bits + union { float f; quint32 i; } u; + u.i = i & ~0x07; + return u.f; } +/* + \since 4.8 + + Sets the focal radius of this radial gradient in logical coordinates + to \a radius +*/ +void QRadialGradient::setFocalRadius(qreal radius) +{ + Q_ASSERT(m_type == RadialGradient); + Q_DUMMY_ACCESSOR + + // Since there's no QGradientData, we only have the dummy void * to + // store additional data in. The three lowest bits are already + // taken, thus we cut the three lowest bits from the significand + // and store the radius as a float. + union { float f; quint32 i; } u; + u.f = float(radius); + // add 0x04 to round up when we drop the three lowest bits + i |= (u.i + 0x04) & ~0x07; + dummy = p; +} /*! Returns the focal point of this radial gradient in logical @@ -2193,4 +2340,6 @@ void QConicalGradient::setAngle(qreal angle) \sa setTransform() */ +#undef Q_DUMMY_ACCESSOR + QT_END_NAMESPACE diff --git a/src/gui/painting/qbrush.h b/src/gui/painting/qbrush.h index 8b31319..d914c8c 100644 --- a/src/gui/painting/qbrush.h +++ b/src/gui/painting/qbrush.h @@ -255,6 +255,7 @@ private: friend class QLinearGradient; friend class QRadialGradient; friend class QConicalGradient; + friend class QBrush; Type m_type; Spread m_spread; @@ -264,7 +265,7 @@ private: qreal x1, y1, x2, y2; } linear; struct { - qreal cx, cy, fx, fy, radius; + qreal cx, cy, fx, fy, cradius; } radial; struct { qreal cx, cy, angle; @@ -303,6 +304,9 @@ public: QRadialGradient(const QPointF ¢er, qreal radius); QRadialGradient(qreal cx, qreal cy, qreal radius); + QRadialGradient(const QPointF ¢er, qreal centerRadius, const QPointF &focalPoint, qreal focalRadius); + QRadialGradient(qreal cx, qreal cy, qreal centerRadius, qreal fx, qreal fy, qreal focalRadius); + QPointF center() const; void setCenter(const QPointF ¢er); inline void setCenter(qreal x, qreal y) { setCenter(QPointF(x, y)); } @@ -313,6 +317,12 @@ public: qreal radius() const; void setRadius(qreal radius); + + qreal centerRadius() const; + void setCenterRadius(qreal radius); + + qreal focalRadius() const; + void setFocalRadius(qreal radius); }; diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index fd26676..ae9993e 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -1406,23 +1406,47 @@ static void QT_FASTCALL getRadialGradientValues(RadialGradientValues *v, const Q { v->dx = data->gradient.radial.center.x - data->gradient.radial.focal.x; v->dy = data->gradient.radial.center.y - data->gradient.radial.focal.y; - v->a = data->gradient.radial.radius*data->gradient.radial.radius - v->dx*v->dx - v->dy*v->dy; + + v->dr = data->gradient.radial.center.radius - data->gradient.radial.focal.radius; + v->sqrfr = data->gradient.radial.focal.radius * data->gradient.radial.focal.radius; + + v->a = v->dr * v->dr - v->dx*v->dx - v->dy*v->dy; + v->inv2a = 1 / (2 * v->a); + + v->extended = !qFuzzyIsNull(data->gradient.radial.focal.radius) || v->a <= 0; } class RadialFetchPlain { public: - static inline void fetch(uint *buffer, uint *end, const QSpanData *data, qreal det, qreal delta_det, - qreal delta_delta_det, qreal b, qreal delta_b) + static inline void fetch(uint *buffer, uint *end, const Operator *op, const QSpanData *data, qreal det, + qreal delta_det, qreal delta_delta_det, qreal b, qreal delta_b) { - while (buffer < end) { - *buffer = qt_gradient_pixel(&data->gradient, (det > 0 ? qSqrt(det) : 0) - b); + if (op->radial.extended) { + while (buffer < end) { + quint32 result = 0; + if (det >= 0) { + qreal w = qSqrt(det) - b; + if (data->gradient.radial.focal.radius + op->radial.dr * w >= 0) + result = qt_gradient_pixel(&data->gradient, w); + } - det += delta_det; - delta_det += delta_delta_det; - b += delta_b; + *buffer = result; - ++buffer; + det += delta_det; + delta_det += delta_delta_det; + b += delta_b; + + ++buffer; + } + } else { + while (buffer < end) { + *buffer++ = qt_gradient_pixel(&data->gradient, qSqrt(det) - b); + + det += delta_det; + delta_det += delta_delta_det; + b += delta_b; + } } } }; diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp index 7eb2f09..e673dd9 100644 --- a/src/gui/painting/qdrawhelper_neon.cpp +++ b/src/gui/painting/qdrawhelper_neon.cpp @@ -985,6 +985,8 @@ public: static inline Float32x4 v_sqrt(Float32x4 x) { Float32x4 y = vrsqrteq_f32(x); y = vmulq_f32(y, vrsqrtsq_f32(x, vmulq_f32(y, y))); return vmulq_f32(x, y); } static inline Int32x4 v_toInt(Float32x4 x) { return vcvtq_s32_f32(x); } + + static inline Int32x4 v_greaterOrEqual(Float32x4 a, Float32x4 b) { return vcge_f32(a, b); } }; const uint * QT_FASTCALL qt_fetch_radial_gradient_neon(uint *buffer, const Operator *op, const QSpanData *data, diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index a92f686..e93d736 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -191,7 +191,11 @@ struct RadialGradientValues { qreal dx; qreal dy; + qreal dr; + qreal sqrfr; qreal a; + qreal inv2a; + bool extended; }; struct Operator; @@ -239,12 +243,13 @@ struct QRadialGradientData struct { qreal x; qreal y; + qreal radius; } center; struct { qreal x; qreal y; + qreal radius; } focal; - qreal radius; }; struct QConicalGradientData @@ -381,12 +386,6 @@ static inline qreal qRadialDeterminant(qreal a, qreal b, qreal c) return (b * b) - (4 * a * c); } -// function to evaluate real roots -static inline qreal qRadialRealRoots(qreal a, qreal b, qreal detSqrt) -{ - return (-b + detSqrt)/(2 * a); -} - template const uint * QT_FASTCALL qt_fetch_radial_gradient_template(uint *buffer, const Operator *op, const QSpanData *data, int y, int x, int length) @@ -394,7 +393,7 @@ const uint * QT_FASTCALL qt_fetch_radial_gradient_template(uint *buffer, const O // avoid division by zero if (qFuzzyIsNull(op->radial.a)) { extern void (*qt_memfill32)(quint32 *dest, quint32 value, int count); - qt_memfill32(buffer, data->gradient.colorTable[0], length); + qt_memfill32(buffer, 0, length); return buffer; } @@ -415,7 +414,7 @@ const uint * QT_FASTCALL qt_fetch_radial_gradient_template(uint *buffer, const O const qreal delta_rx = data->m11; const qreal delta_ry = data->m12; - qreal b = 2*(rx * op->radial.dx + ry * op->radial.dy); + qreal b = 2*(op->radial.dr*data->gradient.radial.focal.radius + rx * op->radial.dx + ry * op->radial.dy); qreal delta_b = 2*(delta_rx * op->radial.dx + delta_ry * op->radial.dy); const qreal b_delta_b = 2 * b * delta_b; const qreal delta_b_delta_b = 2 * delta_b * delta_b; @@ -433,31 +432,45 @@ const uint * QT_FASTCALL qt_fetch_radial_gradient_template(uint *buffer, const O inv_a *= inv_a; - qreal det = (bb + 4 * op->radial.a * rxrxryry) * inv_a; + qreal det = (bb - 4 * op->radial.a * (op->radial.sqrfr - rxrxryry)) * inv_a; qreal delta_det = (b_delta_b + delta_bb + 4 * op->radial.a * (rx_plus_ry + delta_rxrxryry)) * inv_a; const qreal delta_delta_det = (delta_b_delta_b + 4 * op->radial.a * delta_rx_plus_ry) * inv_a; - RadialFetchFunc::fetch(buffer, end, data, det, delta_det, delta_delta_det, b, delta_b); + RadialFetchFunc::fetch(buffer, end, op, data, det, delta_det, delta_delta_det, b, delta_b); } else { qreal rw = data->m23 * (y + qreal(0.5)) + data->m33 + data->m13 * (x + qreal(0.5)); - if (!rw) - rw = 1; + while (buffer < end) { - qreal gx = rx/rw - data->gradient.radial.focal.x; - qreal gy = ry/rw - data->gradient.radial.focal.y; - qreal b = 2*(gx*op->radial.dx + gy*op->radial.dy); - qreal det = qRadialDeterminant(op->radial.a, b , -(gx*gx + gy*gy)); - qreal s = qRadialRealRoots(op->radial.a, b, (det > 0 ? qSqrt(det) : 0)); + if (rw == 0) { + *buffer = 0; + } else { + qreal invRw = 1 / rw; + qreal gx = rx * invRw - data->gradient.radial.focal.x; + qreal gy = ry * invRw - data->gradient.radial.focal.y; + qreal b = 2*(op->radial.dr*data->gradient.radial.focal.radius + gx*op->radial.dx + gy*op->radial.dy); + qreal det = qRadialDeterminant(op->radial.a, b, op->radial.sqrfr - (gx*gx + gy*gy)); + + quint32 result = 0; + if (det >= 0) { + qreal detSqrt = qSqrt(det); + + qreal s0 = (-b - detSqrt) * op->radial.inv2a; + qreal s1 = (-b + detSqrt) * op->radial.inv2a; + + qreal s = qMax(s0, s1); - *buffer = qt_gradient_pixel(&data->gradient, s); + if (data->gradient.radial.focal.radius + op->radial.dr * s >= 0) + result = qt_gradient_pixel(&data->gradient, s); + } + + *buffer = result; + } rx += data->m11; ry += data->m12; rw += data->m13; - if (!rw) { - rw += data->m13; - } + ++buffer; } } @@ -469,8 +482,8 @@ template class QRadialFetchSimd { public: - static inline void fetch(uint *buffer, uint *end, const QSpanData *data, qreal det, qreal delta_det, - qreal delta_delta_det, qreal b, qreal delta_b) + static void fetch(uint *buffer, uint *end, const Operator *op, const QSpanData *data, qreal det, + qreal delta_det, qreal delta_delta_det, qreal b, qreal delta_b) { typename Simd::Vect_buffer_f det_vec; typename Simd::Vect_buffer_f delta_det4_vec; @@ -490,6 +503,9 @@ public: const typename Simd::Float32x4 v_delta_delta_det6 = Simd::v_dup(6 * delta_delta_det); const typename Simd::Float32x4 v_delta_b4 = Simd::v_dup(4 * delta_b); + const typename Simd::Float32x4 v_r0 = Simd::v_dup(data->gradient.radial.focal.radius); + const typename Simd::Float32x4 v_dr = Simd::v_dup(op->radial.dr); + const typename Simd::Float32x4 v_min = Simd::v_dup(0.0f); const typename Simd::Float32x4 v_max = Simd::v_dup(GRADIENT_STOPTABLE_SIZE-1.5f); const typename Simd::Float32x4 v_half = Simd::v_dup(0.5f); @@ -501,10 +517,15 @@ public: const typename Simd::Int32x4 v_reflect_limit = Simd::v_dup(2 * GRADIENT_STOPTABLE_SIZE - 1); + const int extended_mask = op->radial.extended ? 0x0 : ~0x0; + #define FETCH_RADIAL_LOOP_PROLOGUE \ while (buffer < end) { \ + typename Simd::Vect_buffer_i v_buffer_mask; \ + v_buffer_mask.v = Simd::v_greaterOrEqual(det_vec.v, v_min); \ const typename Simd::Float32x4 v_index_local = Simd::v_sub(Simd::v_sqrt(Simd::v_max(v_min, det_vec.v)), b_vec.v); \ const typename Simd::Float32x4 v_index = Simd::v_add(Simd::v_mul(v_index_local, v_table_size_minus_one), v_half); \ + v_buffer_mask.v = Simd::v_and(v_buffer_mask.v, Simd::v_greaterOrEqual(Simd::v_add(v_r0, Simd::v_mul(v_dr, v_index_local)), v_min)); \ typename Simd::Vect_buffer_i index_vec; #define FETCH_RADIAL_LOOP_CLAMP_REPEAT \ index_vec.v = Simd::v_and(v_repeat_mask, Simd::v_toInt(v_index)); @@ -519,21 +540,26 @@ public: delta_det4_vec.v = Simd::v_add(delta_det4_vec.v, v_delta_delta_det16); \ b_vec.v = Simd::v_add(b_vec.v, v_delta_b4); \ for (int i = 0; i < 4; ++i) \ - *buffer++ = data->gradient.colorTable[index_vec.i[i]]; \ + *buffer++ = (extended_mask | v_buffer_mask.i[i]) & data->gradient.colorTable[index_vec.i[i]]; \ } - if (data->gradient.spread == QGradient::RepeatSpread) { - FETCH_RADIAL_LOOP_PROLOGUE - FETCH_RADIAL_LOOP_CLAMP_REPEAT - FETCH_RADIAL_LOOP_EPILOGUE - } else if (data->gradient.spread == QGradient::ReflectSpread) { - FETCH_RADIAL_LOOP_PROLOGUE - FETCH_RADIAL_LOOP_CLAMP_REFLECT - FETCH_RADIAL_LOOP_EPILOGUE - } else { - FETCH_RADIAL_LOOP_PROLOGUE - FETCH_RADIAL_LOOP_CLAMP_PAD - FETCH_RADIAL_LOOP_EPILOGUE +#define FETCH_RADIAL_LOOP(FETCH_RADIAL_LOOP_CLAMP) \ + FETCH_RADIAL_LOOP_PROLOGUE \ + FETCH_RADIAL_LOOP_CLAMP \ + FETCH_RADIAL_LOOP_EPILOGUE + + switch (data->gradient.spread) { + case QGradient::RepeatSpread: + FETCH_RADIAL_LOOP(FETCH_RADIAL_LOOP_CLAMP_REPEAT) + break; + case QGradient::ReflectSpread: + FETCH_RADIAL_LOOP(FETCH_RADIAL_LOOP_CLAMP_REFLECT) + break; + case QGradient::PadSpread: + FETCH_RADIAL_LOOP(FETCH_RADIAL_LOOP_CLAMP_PAD) + break; + default: + Q_ASSERT(false); } } }; diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp index 542d845..fdab95f 100644 --- a/src/gui/painting/qdrawhelper_sse2.cpp +++ b/src/gui/painting/qdrawhelper_sse2.cpp @@ -522,6 +522,8 @@ public: static inline Float32x4 v_sqrt(Float32x4 x) { return _mm_sqrt_ps(x); } static inline Int32x4 v_toInt(Float32x4 x) { return _mm_cvttps_epi32(x); } + + static inline Int32x4 v_greaterOrEqual(Float32x4 a, Float32x4 b) { return (__m128i)_mm_cmpgt_ps(a, b); } }; const uint * QT_FASTCALL qt_fetch_radial_gradient_sse2(uint *buffer, const Operator *op, const QSpanData *data, diff --git a/src/gui/painting/qpaintengine_mac.cpp b/src/gui/painting/qpaintengine_mac.cpp index 8aab7c7..cc75b86 100644 --- a/src/gui/painting/qpaintengine_mac.cpp +++ b/src/gui/painting/qpaintengine_mac.cpp @@ -1544,8 +1544,9 @@ void QCoreGraphicsPaintEnginePrivate::setFillBrush(const QPointF &offset) QPointF center(radialGrad->center()); QPointF focal(radialGrad->focalPoint()); qreal radius = radialGrad->radius(); + qreal focalRadius = radialGrad->focalRadius(); shading = CGShadingCreateRadial(colorspace, CGPointMake(focal.x(), focal.y()), - 0.0, CGPointMake(center.x(), center.y()), radius, fill_func, false, true); + focalRadius, CGPointMake(center.x(), center.y()), radius, fill_func, false, true); } CGFunctionRelease(fill_func); diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 8486adb..2119e30 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -5282,10 +5282,11 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode QPointF center = g->center(); radialData.center.x = center.x(); radialData.center.y = center.y(); + radialData.center.radius = g->centerRadius(); QPointF focal = g->focalPoint(); radialData.focal.x = focal.x(); radialData.focal.y = focal.y(); - radialData.radius = g->radius(); + radialData.focal.radius = g->focalRadius(); } break; diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 509fb77..7f601eb 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -1012,4 +1012,50 @@ void QPaintEngineEx::updateState(const QPaintEngineState &) // do nothing... } +Q_GUI_EXPORT QPainterPath qt_painterPathFromVectorPath(const QVectorPath &path) +{ + const qreal *points = path.points(); + const QPainterPath::ElementType *types = path.elements(); + + QPainterPath p; + if (types) { + int id = 0; + for (int i=0; isave(); state->matrix = QTransform(); - state->dirtyFlags |= QPaintEngine::DirtyTransform; - updateState(state); + if (extended) { + extended->transformChanged(); + } else { + state->dirtyFlags |= QPaintEngine::DirtyTransform; + updateState(state); + } engine->drawImage(absPathRect, image, QRectF(0, 0, absPathRect.width(), absPathRect.height()), @@ -686,11 +690,14 @@ void QPainterPrivate::updateInvMatrix() invMatrix = state->matrix.inverted(); } +extern bool qt_isExtendedRadialGradient(const QBrush &brush); + void QPainterPrivate::updateEmulationSpecifier(QPainterState *s) { bool alpha = false; bool linearGradient = false; bool radialGradient = false; + bool extendedRadialGradient = false; bool conicalGradient = false; bool patternBrush = false; bool xform = false; @@ -722,6 +729,7 @@ void QPainterPrivate::updateEmulationSpecifier(QPainterState *s) (brushStyle == Qt::LinearGradientPattern)); radialGradient = ((penBrushStyle == Qt::RadialGradientPattern) || (brushStyle == Qt::RadialGradientPattern)); + extendedRadialGradient = radialGradient && (qt_isExtendedRadialGradient(penBrush) || qt_isExtendedRadialGradient(s->brush)); conicalGradient = ((penBrushStyle == Qt::ConicalGradientPattern) || (brushStyle == Qt::ConicalGradientPattern)); patternBrush = (((penBrushStyle > Qt::SolidPattern @@ -805,7 +813,7 @@ void QPainterPrivate::updateEmulationSpecifier(QPainterState *s) s->emulationSpecifier &= ~QPaintEngine::LinearGradientFill; // Radial gradient emulation - if (radialGradient && !engine->hasFeature(QPaintEngine::RadialGradientFill)) + if (extendedRadialGradient || (radialGradient && !engine->hasFeature(QPaintEngine::RadialGradientFill))) s->emulationSpecifier |= QPaintEngine::RadialGradientFill; else s->emulationSpecifier &= ~QPaintEngine::RadialGradientFill; diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h index ae2fdf2..604225e 100644 --- a/src/gui/painting/qpainter.h +++ b/src/gui/painting/qpainter.h @@ -551,6 +551,7 @@ private: friend class QPaintEngine; friend class QPaintEngineExPrivate; friend class QOpenGLPaintEngine; + friend class QVGPaintEngine; friend class QX11PaintEngine; friend class QX11PaintEnginePrivate; friend class QWin32PaintEngine; diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index 8068aa8..207ab3d 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -495,6 +495,8 @@ GLuint QGLEngineShaderManager::getUniformLocation(Uniform id) "fmp", "fmp2_m_radius2", "inverse_2_fmp2_m_radius2", + "sqrfr", + "bradius", "invertedTextureSize", "brushTransform", "brushTexture", diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h index 7cc9dc3..bf2fe42 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h @@ -442,6 +442,8 @@ public: Fmp, Fmp2MRadius2, Inverse2Fmp2MRadius2, + SqrFr, + BRadius, InvertedTextureSize, BrushTransform, BrushTexture, diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h index fc8b9ef..9362c58 100644 --- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h @@ -241,6 +241,7 @@ static const char* const qglslPositionWithRadialGradientBrushVertexShader = "\n\ uniform mediump vec2 halfViewportSize; \n\ uniform highp mat3 brushTransform; \n\ uniform highp vec2 fmp; \n\ + uniform highp vec3 bradius; \n\ varying highp float b; \n\ varying highp vec2 A; \n\ void setPosition(void) \n\ @@ -253,7 +254,7 @@ static const char* const qglslPositionWithRadialGradientBrushVertexShader = "\n\ mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\ gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\ A = hTexCoords.xy * invertedHTexCoordsZ; \n\ - b = 2.0 * dot(A, fmp); \n\ + b = bradius.x + 2.0 * dot(A, fmp); \n\ }\n"; static const char* const qglslAffinePositionWithRadialGradientBrushVertexShader @@ -263,13 +264,22 @@ static const char* const qglslRadialGradientBrushSrcFragmentShader = "\n\ uniform sampler2D brushTexture; \n\ uniform highp float fmp2_m_radius2; \n\ uniform highp float inverse_2_fmp2_m_radius2; \n\ + uniform highp float sqrfr; \n\ varying highp float b; \n\ varying highp vec2 A; \n\ + uniform highp vec3 bradius; \n\ lowp vec4 srcPixel() \n\ { \n\ - highp float c = -dot(A, A); \n\ - highp vec2 val = vec2((-b + sqrt(b*b - 4.0*fmp2_m_radius2*c)) * inverse_2_fmp2_m_radius2, 0.5); \n\ - return texture2D(brushTexture, val); \n\ + highp float c = sqrfr-dot(A, A); \n\ + highp float det = b*b - 4.0*fmp2_m_radius2*c; \n\ + lowp vec4 result = vec4(0.0); \n\ + if (det >= 0.0) { \n\ + highp float detSqrt = sqrt(det); \n\ + highp float w = max((-b - detSqrt) * inverse_2_fmp2_m_radius2, (-b + detSqrt) * inverse_2_fmp2_m_radius2); \n\ + if (bradius.y + w * bradius.z >= 0.0) \n\ + result = texture2D(brushTexture, vec2(w, 0.5)); \n\ + } \n\ + return result; \n\ }\n"; diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 18c684f..a2707e0 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -301,7 +301,7 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() const QRadialGradient *g = static_cast(currentBrush.gradient()); QPointF realCenter = g->center(); QPointF realFocal = g->focalPoint(); - qreal realRadius = g->radius(); + qreal realRadius = g->centerRadius() - g->focalRadius(); translationPoint = realFocal; QPointF fmp = realCenter - realFocal; @@ -311,6 +311,12 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::Fmp2MRadius2), fmp2_m_radius2); shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::Inverse2Fmp2MRadius2), GLfloat(1.0 / (2.0*fmp2_m_radius2))); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::SqrFr), + GLfloat(g->focalRadius() * g->focalRadius())); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::BRadius), + GLfloat(2 * (g->centerRadius() - g->focalRadius()) * g->focalRadius()), + g->focalRadius(), + g->centerRadius() - g->focalRadius()); QVector2D halfViewportSize(width*0.5, height*0.5); shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::HalfViewportSize), halfViewportSize); diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp index 2c01ac4..efa050d 100644 --- a/src/opengl/qpaintengine_opengl.cpp +++ b/src/opengl/qpaintengine_opengl.cpp @@ -2119,6 +2119,7 @@ void QOpenGLPaintEnginePrivate::fillPath(const QPainterPath &path) updateGLMatrix(); } +extern bool qt_isExtendedRadialGradient(const QBrush &brush); static inline bool needsEmulation(Qt::BrushStyle style) { @@ -2129,9 +2130,11 @@ static inline bool needsEmulation(Qt::BrushStyle style) void QOpenGLPaintEnginePrivate::updateUseEmulation() { - use_emulation = !use_fragment_programs - && ((has_pen && needsEmulation(pen_brush_style)) - || (has_brush && needsEmulation(brush_style))); + use_emulation = (!use_fragment_programs + && ((has_pen && needsEmulation(pen_brush_style)) + || (has_brush && needsEmulation(brush_style)))) + || (has_pen && qt_isExtendedRadialGradient(cpen.brush())) + || (has_brush && qt_isExtendedRadialGradient(cbrush)); } void QOpenGLPaintEngine::updatePen(const QPen &pen) @@ -5442,50 +5445,7 @@ void QOpenGLPaintEngine::transformChanged() updateMatrix(state()->matrix); } -static QPainterPath painterPathFromVectorPath(const QVectorPath &path) -{ - const qreal *points = path.points(); - const QPainterPath::ElementType *types = path.elements(); - - QPainterPath p; - if (types) { - int id = 0; - for (int i=0; iuse_fragment_programs && needsEmulation(brush.style())) { + if ((!d->use_fragment_programs && needsEmulation(brush.style())) || qt_isExtendedRadialGradient(brush)) { QPainter *p = painter(); QBrush oldBrush = p->brush(); p->setBrush(brush); - qt_draw_helper(p->d_ptr.data(), painterPathFromVectorPath(path), QPainterPrivate::FillDraw); + qt_draw_helper(p->d_ptr.data(), qt_painterPathFromVectorPath(path), QPainterPrivate::FillDraw); p->setBrush(oldBrush); return; } @@ -5515,7 +5475,7 @@ void QOpenGLPaintEngine::fill(const QVectorPath &path, const QBrush &brush) drawRects(&r, 1); updatePen(old_pen); } else { - d->fillPath(painterPathFromVectorPath(path)); + d->fillPath(qt_painterPathFromVectorPath(path)); } updateBrush(old_brush, state()->brushOrigin); diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index 3c2b5fd..7c9d102 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -173,6 +173,9 @@ public: bool forcePenChange; // Force a pen change, even if the same. bool forceBrushChange; // Force a brush change, even if the same. + bool hasExtendedRadialGradientPen; // Current pen's brush is extended radial gradient. + bool hasExtendedRadialGradientBrush; // Current brush is extended radial gradient. + VGPaintType penType; // Type of the last pen that was set. VGPaintType brushType; // Type of the last brush that was set. @@ -275,6 +278,27 @@ public: } } + inline bool needsEmulation(const QBrush &brush) const + { + extern bool qt_isExtendedRadialGradient(const QBrush &brush); + return qt_isExtendedRadialGradient(brush); + } + + inline bool needsEmulation() const + { + return hasExtendedRadialGradientPen || hasExtendedRadialGradientBrush; + } + + inline bool needsPenEmulation() const + { + return hasExtendedRadialGradientPen; + } + + inline bool needsBrushEmulation() const + { + return hasExtendedRadialGradientBrush; + } + // Set various modes, but only if different. inline void setImageMode(VGImageMode mode); inline void setRenderingQuality(VGRenderingQuality mode); @@ -355,6 +379,10 @@ void QVGPaintEnginePrivate::init() forcePenChange = true; forceBrushChange = true; + + hasExtendedRadialGradientPen = false; + hasExtendedRadialGradientBrush = false; + penType = (VGPaintType)0; brushType = (VGPaintType)0; @@ -1534,6 +1562,10 @@ bool QVGPaintEngine::end() void QVGPaintEngine::draw(const QVectorPath &path) { Q_D(QVGPaintEngine); + if (d->needsEmulation()) { + QPaintEngineEx::draw(path); + return; + } QVGPainterState *s = state(); VGPath vgpath = d->vectorPathToVGPath(path); if (!path.hasWindingFill()) @@ -1543,9 +1575,19 @@ void QVGPaintEngine::draw(const QVectorPath &path) vgDestroyPath(vgpath); } +extern QPainterPath qt_painterPathFromVectorPath(const QVectorPath &path); + void QVGPaintEngine::fill(const QVectorPath &path, const QBrush &brush) { Q_D(QVGPaintEngine); + if (d->needsEmulation(brush)) { + QPainter *p = painter(); + QBrush oldBrush = p->brush(); + p->setBrush(brush); + qt_draw_helper(p->d_ptr.data(), qt_painterPathFromVectorPath(path), QPainterPrivate::FillDraw); + p->setBrush(oldBrush); + return; + } VGPath vgpath = d->vectorPathToVGPath(path); if (!path.hasWindingFill()) d->fill(vgpath, brush, VG_EVEN_ODD); @@ -1557,6 +1599,10 @@ void QVGPaintEngine::fill(const QVectorPath &path, const QBrush &brush) void QVGPaintEngine::stroke(const QVectorPath &path, const QPen &pen) { Q_D(QVGPaintEngine); + if (d->needsEmulation(pen.brush())) { + QPaintEngineEx::stroke(path, pen); + return; + } VGPath vgpath = d->vectorPathToVGPath(path); d->stroke(vgpath, pen); vgDestroyPath(vgpath); @@ -2360,12 +2406,17 @@ void QVGPaintEngine::penChanged() { Q_D(QVGPaintEngine); d->dirty |= QPaintEngine::DirtyPen; + + d->hasExtendedRadialGradientPen = + state()->pen.style() != Qt::NoPen && d->needsEmulation(state()->pen.brush()); } void QVGPaintEngine::brushChanged() { Q_D(QVGPaintEngine); d->dirty |= QPaintEngine::DirtyBrush; + + d->hasExtendedRadialGradientPen = d->needsEmulation(state()->brush); } void QVGPaintEngine::brushOriginChanged() @@ -2544,6 +2595,11 @@ void QVGPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) return; } + if (d->needsEmulation(brush)) { + QPaintEngineEx::fillRect(rect, brush); + return; + } + #if !defined(QVG_NO_MODIFY_PATH) VGfloat coords[8]; if (d->simpleTransform) { @@ -2621,6 +2677,10 @@ void QVGPaintEngine::fillRect(const QRectF &rect, const QColor &color) void QVGPaintEngine::drawRoundedRect(const QRectF &rect, qreal xrad, qreal yrad, Qt::SizeMode mode) { Q_D(QVGPaintEngine); + if (d->needsEmulation()) { + QPaintEngineEx::drawRoundedRect(rect, xrad, yrad, mode); + return; + } if (d->simpleTransform) { QVGPainterState *s = state(); VGPath vgpath = d->roundedRectPath(rect, xrad, yrad, mode); @@ -2637,6 +2697,10 @@ void QVGPaintEngine::drawRects(const QRect *rects, int rectCount) { #if !defined(QVG_NO_MODIFY_PATH) Q_D(QVGPaintEngine); + if (d->needsEmulation()) { + QPaintEngineEx::drawRects(rects, rectCount); + return; + } QVGPainterState *s = state(); for (int i = 0; i < rectCount; ++i, ++rects) { VGfloat coords[8]; @@ -2678,6 +2742,10 @@ void QVGPaintEngine::drawRects(const QRectF *rects, int rectCount) { #if !defined(QVG_NO_MODIFY_PATH) Q_D(QVGPaintEngine); + if (d->needsEmulation()) { + QPaintEngineEx::drawRects(rects, rectCount); + return; + } QVGPainterState *s = state(); for (int i = 0; i < rectCount; ++i, ++rects) { VGfloat coords[8]; @@ -2716,6 +2784,10 @@ void QVGPaintEngine::drawLines(const QLine *lines, int lineCount) { #if !defined(QVG_NO_MODIFY_PATH) Q_D(QVGPaintEngine); + if (d->needsEmulation()) { + QPaintEngineEx::drawLines(lines, lineCount); + return; + } QVGPainterState *s = state(); for (int i = 0; i < lineCount; ++i, ++lines) { VGfloat coords[4]; @@ -2744,6 +2816,10 @@ void QVGPaintEngine::drawLines(const QLineF *lines, int lineCount) { #if !defined(QVG_NO_MODIFY_PATH) Q_D(QVGPaintEngine); + if (d->needsEmulation()) { + QPaintEngineEx::drawLines(lines, lineCount); + return; + } QVGPainterState *s = state(); for (int i = 0; i < lineCount; ++i, ++lines) { VGfloat coords[4]; @@ -2773,6 +2849,10 @@ void QVGPaintEngine::drawEllipse(const QRectF &r) // Based on the description of vguEllipse() in the OpenVG specification. // We don't use vguEllipse(), to avoid unnecessary library dependencies. Q_D(QVGPaintEngine); + if (d->needsEmulation()) { + QPaintEngineEx::drawEllipse(r); + return; + } if (d->simpleTransform) { QVGPainterState *s = state(); VGPath path = vgCreatePath(VG_PATH_FORMAT_STANDARD, @@ -2823,6 +2903,10 @@ void QVGPaintEngine::drawPath(const QPainterPath &path) // Shortcut past the QPainterPath -> QVectorPath conversion, // converting the QPainterPath directly into a VGPath. Q_D(QVGPaintEngine); + if (d->needsEmulation()) { + QPaintEngineEx::drawPath(path); + return; + } QVGPainterState *s = state(); VGPath vgpath = d->painterPathToVGPath(path); if (path.fillRule() == Qt::OddEvenFill) @@ -2837,6 +2921,11 @@ void QVGPaintEngine::drawPoints(const QPointF *points, int pointCount) #if !defined(QVG_NO_MODIFY_PATH) Q_D(QVGPaintEngine); + if (d->needsPenEmulation()) { + QPaintEngineEx::drawPoints(points, pointCount); + return; + } + // Set up a new pen if necessary. QPen pen = state()->pen; if (pen.style() == Qt::NoPen) @@ -2871,6 +2960,11 @@ void QVGPaintEngine::drawPoints(const QPoint *points, int pointCount) #if !defined(QVG_NO_MODIFY_PATH) Q_D(QVGPaintEngine); + if (d->needsEmulation()) { + QPaintEngineEx::drawPoints(points, pointCount); + return; + } + // Set up a new pen if necessary. QPen pen = state()->pen; if (pen.style() == Qt::NoPen) @@ -2903,6 +2997,12 @@ void QVGPaintEngine::drawPoints(const QPoint *points, int pointCount) void QVGPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) { Q_D(QVGPaintEngine); + + if (d->needsEmulation()) { + QPaintEngineEx::drawPolygon(points, pointCount, mode); + return; + } + QVGPainterState *s = state(); VGPath path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, @@ -2950,6 +3050,12 @@ void QVGPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonD void QVGPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode) { Q_D(QVGPaintEngine); + + if (d->needsEmulation()) { + QPaintEngineEx::drawPolygon(points, pointCount, mode); + return; + } + QVGPainterState *s = state(); VGPath path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, @@ -3596,6 +3702,11 @@ void QVGPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem) return; } + if (d->needsPenEmulation()) { + QPaintEngineEx::drawTextItem(p, textItem); + return; + } + // Get the glyphs and positions associated with the text item. QVarLengthArray positions; QVarLengthArray glyphs; diff --git a/tests/arthur/common/paintcommands.cpp b/tests/arthur/common/paintcommands.cpp index 7a018e3..9273142 100644 --- a/tests/arthur/common/paintcommands.cpp +++ b/tests/arthur/common/paintcommands.cpp @@ -346,8 +346,12 @@ void PaintCommands::staticInit() "gradient_setLinear 1.0 1.0 2.0 2.0"); DECL_PAINTCOMMAND("gradient_setRadial", command_gradient_setRadial, "^gradient_setRadial\\s+([\\w.]*)\\s+([\\w.]*)\\s+([\\w.]*)\\s?([\\w.]*)\\s?([\\w.]*)$", - "gradient_setRadial \n - C is the center\n - rad is the angle in degrees\n - F is the focal point", + "gradient_setRadial \n - C is the center\n - rad is the radius\n - F is the focal point", "gradient_setRadial 1.0 1.0 45.0 2.0 2.0"); + DECL_PAINTCOMMAND("gradient_setRadialExtended", command_gradient_setRadialExtended, + "^gradient_setRadialExtended\\s+([\\w.]*)\\s+([\\w.]*)\\s+([\\w.]*)\\s?([\\w.]*)\\s?([\\w.]*)\\s?([\\w.]*)$", + "gradient_setRadialExtended \n - C is the center\n - rad is the center radius\n - F is the focal point\n - frad is the focal radius", + "gradient_setRadialExtended 1.0 1.0 45.0 2.0 2.0 45.0"); DECL_PAINTCOMMAND("gradient_setLinearPen", command_gradient_setLinearPen, "^gradient_setLinearPen\\s+([\\w.]*)\\s+([\\w.]*)\\s+([\\w.]*)\\s+([\\w.]*)$", "gradient_setLinearPen ", @@ -2400,7 +2404,7 @@ void PaintCommands::command_gradient_setRadial(QRegExp re) double fy = convertToDouble(caps.at(5)); if (m_verboseMode) - printf(" -(lance) gradient_setRadial center=(%.2f, %.2f), radius=%.2f focal=(%.2f, %.2f), " + printf(" -(lance) gradient_setRadial center=(%.2f, %.2f), radius=%.2f, focal=(%.2f, %.2f), " "spread=%d\n", cx, cy, rad, fx, fy, m_gradientSpread); @@ -2415,6 +2419,32 @@ void PaintCommands::command_gradient_setRadial(QRegExp re) } /***************************************************************************************************/ +void PaintCommands::command_gradient_setRadialExtended(QRegExp re) +{ + QStringList caps = re.capturedTexts(); + double cx = convertToDouble(caps.at(1)); + double cy = convertToDouble(caps.at(2)); + double rad = convertToDouble(caps.at(3)); + double fx = convertToDouble(caps.at(4)); + double fy = convertToDouble(caps.at(5)); + double frad = convertToDouble(caps.at(6)); + + if (m_verboseMode) + printf(" -(lance) gradient_setRadialExtended center=(%.2f, %.2f), radius=%.2f, focal=(%.2f, %.2f), " + "focal radius=%.2f, spread=%d\n", + cx, cy, rad, fx, fy, frad, m_gradientSpread); + + QRadialGradient rg(QPointF(cx, cy), rad, QPointF(fx, fy), frad); + rg.setStops(m_gradientStops); + rg.setSpread(m_gradientSpread); + rg.setCoordinateMode(m_gradientCoordinate); + QBrush brush(rg); + QTransform brush_matrix = m_painter->brush().transform(); + brush.setTransform(brush_matrix); + m_painter->setBrush(brush); +} + +/***************************************************************************************************/ void PaintCommands::command_gradient_setConical(QRegExp re) { QStringList caps = re.capturedTexts(); diff --git a/tests/arthur/common/paintcommands.h b/tests/arthur/common/paintcommands.h index 2740412..08c0e25 100644 --- a/tests/arthur/common/paintcommands.h +++ b/tests/arthur/common/paintcommands.h @@ -179,6 +179,7 @@ private: void command_gradient_setConical(QRegExp re); void command_gradient_setLinear(QRegExp re); void command_gradient_setRadial(QRegExp re); + void command_gradient_setRadialExtended(QRegExp re); void command_gradient_setLinearPen(QRegExp re); void command_gradient_setSpread(QRegExp re); void command_gradient_setCoordinateMode(QRegExp re); diff --git a/tests/arthur/data/qps/radial_gradients_extended.qps b/tests/arthur/data/qps/radial_gradients_extended.qps new file mode 100644 index 0000000..d80a149 --- /dev/null +++ b/tests/arthur/data/qps/radial_gradients_extended.qps @@ -0,0 +1,95 @@ +path_addRect path 400 0 80 80 +path_addEllipse path 440 40 60 60 + +setRenderHint Antialiasing + +setPen black + +begin_block gradients +gradient_clearStops +gradient_appendStop 0 red +gradient_appendStop 0.25 orange +gradient_appendStop 0.5 yellow +gradient_appendStop 0.8 green +gradient_appendStop 1 cyan + +gradient_setSpread PadSpread +gradient_setRadialExtended 0 0 20 40 40 10 +drawRect 0 0 100 100 + +gradient_setSpread ReflectSpread +gradient_setRadialExtended 120 20 20 140 40 10 +drawEllipse 100 0 100 100 + +gradient_setSpread RepeatSpread +gradient_setRadialExtended 240 20 20 260 40 10 +drawRoundRect 200 0 100 100 + +gradient_clearStops +gradient_appendStop 0 3f7f7fff +gradient_appendStop 0.5 dfdfffff +gradient_appendStop 1 7f00007f + +gradient_setSpread PadSpread +gradient_setRadialExtended 320 20 20 340 40 10 +drawPolygon [300 0 390 0 350 99] + +gradient_setSpread ReflectSpread +gradient_setRadialExtended 420 20 20 440 40 10 +drawPath path + +gradient_setSpread RepeatSpread +gradient_setRadialExtended 520 20 20 540 40 10 +drawPie 500 0 100 100 720 4320 +end_block + +translate 0 100 +scale 1 2 +repeat_block gradients + +resetMatrix +translate 0 300 +brushTranslate 30 0 +brushScale 0.9 0.9 +repeat_block gradients + +# Some helpful info perhaps? +resetMatrix +setPen black + +drawText 610 50 "No XForm" +drawText 610 200 "scale 1x2" +drawText 610 300 "brush transform" +drawText 10 450 "Pad" +drawText 110 450 "Reflect" +drawText 210 450 "Repeat" +drawText 310 450 "Pad w/alpha" +drawText 410 450 "Reflect w/alpha" +drawText 510 450 "Repeat w/alpha" + +# Radius and focal indicators +setPen 3f000000 +setBrush nobrush + +begin_block ellipse_draw +setClipRect 0 0 100 100 +drawEllipse -30 -30 100 100 +drawEllipse 35 35 11 11 +translate 100 0 +end_block + +repeat_block ellipse_draw +repeat_block ellipse_draw +repeat_block ellipse_draw +repeat_block ellipse_draw +repeat_block ellipse_draw + +resetMatrix +translate 0 100 +scale 1 2 +repeat_block ellipse_draw +repeat_block ellipse_draw +repeat_block ellipse_draw +repeat_block ellipse_draw +repeat_block ellipse_draw +repeat_block ellipse_draw diff --git a/tests/arthur/data/qps/radial_gradients_extended_qps.png b/tests/arthur/data/qps/radial_gradients_extended_qps.png new file mode 100644 index 0000000..45a3e60 Binary files /dev/null and b/tests/arthur/data/qps/radial_gradients_extended_qps.png differ -- cgit v0.12 From dd8de4c2437397748daba49569cbc7f89a8bfbee Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 13 Apr 2011 18:04:00 +0100 Subject: 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 --- 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 b2b655e..b6d12fe 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 85ab54a..2e7c155 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, -- cgit v0.12 From 00b18457d5efb9224f3b066bab9e9f601fbcf543 Mon Sep 17 00:00:00 2001 From: Tomi Vihria Date: Thu, 14 Apr 2011 11:19:24 +0300 Subject: Enablers for the Qt eclipsing in Symbian Remove file listing from the stub package file to ease maintenance, generate stub sis from it and export it to the correct location to be included into ROM. Task-number: QT-4817 Reviewed-by: Guoqing Zhang --- config.profiles/symbian/bld.inf | 6 ++-- config.profiles/symbian/qt_stub.pkg | 53 ------------------------------------ config.profiles/symbian/qt_stub.sis | Bin 0 -> 324 bytes 3 files changed, 4 insertions(+), 55 deletions(-) create mode 100644 config.profiles/symbian/qt_stub.sis diff --git a/config.profiles/symbian/bld.inf b/config.profiles/symbian/bld.inf index ddb5157..16a9e15 100644 --- a/config.profiles/symbian/bld.inf +++ b/config.profiles/symbian/bld.inf @@ -38,10 +38,12 @@ loc.prf /epoc32/tools/qt/mkspecs/features/loc.prf //For UDA image confml/qt.confml CONFML_EXPORT_PATH(qt.confml,uda_content) implml/qt_copy.implml CRML_EXPORT_PATH(qt_copy.implml,uda_content) -content/apps/qt.sisx CRML_EXPORT_PATH(../content/sis/,uda_content) -content/apps/qt_stub.sis /epoc32/data/z/system/install/qt_stub.sis +content/apps/qt.sisx CRML_EXPORT_PATH(../content/sis/,uda_content) #endif +/* export stub sis to enable eclipsing */ +qt_stub.sis /epoc32/data/z/system/install/qt_stub.sis + //tools ../../bin/createpackage.bat /epoc32/tools/createpackage.bat ../../bin/createpackage.pl /epoc32/tools/createpackage.pl diff --git a/config.profiles/symbian/qt_stub.pkg b/config.profiles/symbian/qt_stub.pkg index dadf696..0ac4439 100644 --- a/config.profiles/symbian/qt_stub.pkg +++ b/config.profiles/symbian/qt_stub.pkg @@ -15,56 +15,3 @@ ; Unique Vendor name :"Nokia, Qt" -; Dependencies of Qt libraries - -"" - "z:\sys\bin\QtCore.dll" -"" - "z:\sys\bin\QtXml.dll" -"" - "z:\sys\bin\QtGui.dll" -"" - "z:\sys\bin\QtNetwork.dll" -"" - "z:\sys\bin\QtTest.dll" -"" - "z:\sys\bin\QtSql.dll" -"" - "z:\sys\bin\QtSvg.dll" -"" - "z:\sys\bin\phonon.dll" -"" - "z:\sys\bin\QtScript.dll" -"" - "z:\sys\bin\QtXmlPatterns.dll" -"" - "z:\sys\bin\QtDeclarative.dll" -"" - "z:\sys\bin\QtOpenVG.dll" -"" - "z:\sys\bin\QtOpenGL.dll" -"" - "z:\sys\bin\QtMultimedia.dll" -"" - "z:\private\10202D56\import\packages\2001E61C\backup_registration.xml" -"" - "z:\sys\bin\qjpeg.dll" -"" - "z:\resource\qt\plugins\imageformats\qjpeg.qtplugin" -"" - "z:\sys\bin\qgif.dll" -"" - "z:\resource\qt\plugins\imageformats\qgif.qtplugin" -"" - "z:\sys\bin\qmng.dll" -"" - "z:\resource\qt\plugins\imageformats\qmng.qtplugin" -"" - "z:\sys\bin\qtiff.dll" -"" - "z:\resource\qt\plugins\imageformats\qtiff.qtplugin" -"" - "z:\sys\bin\qico.dll" -"" - "z:\resource\qt\plugins\imageformats\qico.qtplugin" -"" - "z:\sys\bin\qsvg.dll" -"" - "z:\resource\qt\plugins\imageformats\qsvg.qtplugin" -"" - "z:\sys\bin\qcncodecs.dll" -"" - "z:\resource\qt\plugins\codecs\qcncodecs.qtplugin" -"" - "z:\sys\bin\qjpcodecs.dll" -"" - "z:\resource\qt\plugins\codecs\qjpcodecs.qtplugin" -"" - "z:\sys\bin\qtwcodecs.dll" -"" - "z:\resource\qt\plugins\codecs\qtwcodecs.qtplugin" -"" - "z:\sys\bin\qkrcodecs.dll" -"" - "z:\resource\qt\plugins\codecs\qkrcodecs.qtplugin" -"" - "z:\sys\bin\qvggraphicssystem.dll" -"" - "z:\resource\qt\plugins\graphicssystems\qvggraphicssystem.qtplugin" -"" - "z:\sys\bin\qglgraphicssystem.dll" -"" - "z:\resource\qt\plugins\graphicssystems\qglgraphicssystem.qtplugin" -"" - "z:\sys\bin\qsvgicon.dll" -"" - "z:\resource\qt\plugins\iconengines\qsvgicon.qtplugin" -"" - "z:\sys\bin\qmlfolderlistmodelplugin.dll" -"" - "z:\resource\qt\imports\Qt\labs\folderlistmodel\qmlfolderlistmodelplugin.qtplugin" -"" - "z:\resource\qt\imports\Qt\labs\folderlistmodel\qmldir" -"" - "z:\sys\bin\qmlgesturesplugin.dll" -"" - "z:\resource\qt\imports\Qt\labs\gestures\qmlgesturesplugin.qtplugin" -"" - "z:\resource\qt\imports\Qt\labs\gestures\qmldir" -"" - "z:\sys\bin\qmlparticlesplugin.dll" -"" - "z:\resource\qt\imports\Qt\labs\particles\qmlparticlesplugin.qtplugin" -"" - "z:\resource\qt\imports\Qt\labs\particles\qmldir" - diff --git a/config.profiles/symbian/qt_stub.sis b/config.profiles/symbian/qt_stub.sis new file mode 100644 index 0000000..30d91a9 Binary files /dev/null and b/config.profiles/symbian/qt_stub.sis differ -- cgit v0.12 From febdcef08f22310cbd70ec13b315f70ff8e41e83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Tue, 15 Feb 2011 13:40:32 +0100 Subject: Do not call setSizePolicy from ctor, it might call a virtual function More specifically, it might very well call updateGeometry() Reviewed-by: Frederik Gladhorn --- src/gui/graphicsview/qgraphicslayout.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/graphicsview/qgraphicslayout.cpp b/src/gui/graphicsview/qgraphicslayout.cpp index ed213f1..0ee1f06 100644 --- a/src/gui/graphicsview/qgraphicslayout.cpp +++ b/src/gui/graphicsview/qgraphicslayout.cpp @@ -167,7 +167,7 @@ QGraphicsLayout::QGraphicsLayout(QGraphicsLayoutItem *parent) " neither a QGraphicsWidget nor QGraphicsLayout"); } } - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, QSizePolicy::DefaultType); + d_func()->sizePolicy = QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, QSizePolicy::DefaultType); setOwnedByLayout(true); } @@ -188,7 +188,7 @@ QGraphicsLayout::QGraphicsLayout(QGraphicsLayoutPrivate &dd, QGraphicsLayoutItem " neither a QGraphicsWidget nor QGraphicsLayout"); } } - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, QSizePolicy::DefaultType); + d_func()->sizePolicy = QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, QSizePolicy::DefaultType); setOwnedByLayout(true); } -- cgit v0.12 From 42bbdbef501caec06981981585a0302339818ac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Wed, 9 Feb 2011 15:07:24 +0100 Subject: Avoid flicker when invalidate is propagated in a widget/layout hierarchy * Do not call invalidate from activateRecursive(). This resulted in that a layout was invalidated as many times as there were items in the layout. * Several improvements. Do not call resize(size()) too often. Calling resize() from the widgetEvent() is not very nice though... * Remove commented out code * make sure layout is activated even if the widget does not change size * activate the layout if the resize is same as size() * In order to not break existing apps, make this an opt-in feature with QGraphicsLayout::setInstantInvalidatePropagation(true); Reviewed-by: Frederik Gladhorn Reviewed-by: John Tapsell --- src/gui/graphicsview/qgraphicslayout.cpp | 141 ++++++++++++++++----- src/gui/graphicsview/qgraphicslayout.h | 2 + src/gui/graphicsview/qgraphicslayout_p.cpp | 9 +- src/gui/graphicsview/qgraphicslinearlayout.cpp | 9 +- src/gui/graphicsview/qgraphicswidget.cpp | 105 ++++++++++----- .../tst_qgraphicsanchorlayout.cpp | 3 + tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp | 88 +++++++++++++ .../tst_qgraphicslinearlayout.cpp | 40 ++++++ 8 files changed, 321 insertions(+), 76 deletions(-) diff --git a/src/gui/graphicsview/qgraphicslayout.cpp b/src/gui/graphicsview/qgraphicslayout.cpp index 0ee1f06..e50989c 100644 --- a/src/gui/graphicsview/qgraphicslayout.cpp +++ b/src/gui/graphicsview/qgraphicslayout.cpp @@ -269,12 +269,20 @@ void QGraphicsLayout::activate() return; Q_ASSERT(!parentItem->isLayout()); - setGeometry(parentItem->contentsRect()); // relayout children - - // ### bug, should be parentItem ? - parentLayoutItem()->updateGeometry(); // bubble up; will set activated to false - // ### too many resizes? maybe we should walk up the chain to the - // ### top-level layouted layoutItem and call activate there. + if (QGraphicsLayout::instantInvalidatePropagation()) { + QGraphicsWidget *parentWidget = static_cast(parentItem); + if (!parentWidget->parentLayoutItem()) { + // we've reached the topmost widget, resize it + bool wasResized = parentWidget->testAttribute(Qt::WA_Resized); + parentWidget->resize(parentWidget->size()); + parentWidget->setAttribute(Qt::WA_Resized, wasResized); + } + + setGeometry(parentItem->contentsRect()); // relayout children + } else { + setGeometry(parentItem->contentsRect()); // relayout children + parentLayoutItem()->updateGeometry(); + } } /*! @@ -300,32 +308,36 @@ bool QGraphicsLayout::isActivated() const */ void QGraphicsLayout::invalidate() { - // only mark layouts as invalid (activated = false) if we can post a LayoutRequest event. - QGraphicsLayoutItem *layoutItem = this; - while (layoutItem && layoutItem->isLayout()) { - // we could call updateGeometry(), but what if that method - // does not call the base implementation? In addition, updateGeometry() - // does more than we need. - layoutItem->d_func()->sizeHintCacheDirty = true; - layoutItem->d_func()->sizeHintWithConstraintCacheDirty = true; - layoutItem = layoutItem->parentLayoutItem(); - } - if (layoutItem) { - layoutItem->d_func()->sizeHintCacheDirty = true; - layoutItem->d_func()->sizeHintWithConstraintCacheDirty = true; - } - - bool postIt = layoutItem ? !layoutItem->isLayout() : false; - if (postIt) { - layoutItem = this; - while (layoutItem && layoutItem->isLayout() - && static_cast(layoutItem)->d_func()->activated) { - static_cast(layoutItem)->d_func()->activated = false; + if (QGraphicsLayout::instantInvalidatePropagation()) { + updateGeometry(); + } else { + // only mark layouts as invalid (activated = false) if we can post a LayoutRequest event. + QGraphicsLayoutItem *layoutItem = this; + while (layoutItem && layoutItem->isLayout()) { + // we could call updateGeometry(), but what if that method + // does not call the base implementation? In addition, updateGeometry() + // does more than we need. + layoutItem->d_func()->sizeHintCacheDirty = true; + layoutItem->d_func()->sizeHintWithConstraintCacheDirty = true; layoutItem = layoutItem->parentLayoutItem(); } - if (layoutItem && !layoutItem->isLayout()) { - // If a layout has a parent that is not a layout it must be a QGraphicsWidget. - QApplication::postEvent(static_cast(layoutItem), new QEvent(QEvent::LayoutRequest)); + if (layoutItem) { + layoutItem->d_func()->sizeHintCacheDirty = true; + layoutItem->d_func()->sizeHintWithConstraintCacheDirty = true; + } + + bool postIt = layoutItem ? !layoutItem->isLayout() : false; + if (postIt) { + layoutItem = this; + while (layoutItem && layoutItem->isLayout() + && static_cast(layoutItem)->d_func()->activated) { + static_cast(layoutItem)->d_func()->activated = false; + layoutItem = layoutItem->parentLayoutItem(); + } + if (layoutItem && !layoutItem->isLayout()) { + // If a layout has a parent that is not a layout it must be a QGraphicsWidget. + QApplication::postEvent(static_cast(layoutItem), new QEvent(QEvent::LayoutRequest)); + } } } } @@ -335,12 +347,27 @@ void QGraphicsLayout::invalidate() */ void QGraphicsLayout::updateGeometry() { - QGraphicsLayoutItem::updateGeometry(); - if (QGraphicsLayoutItem *parentItem = parentLayoutItem()) { - if (parentItem->isLayout()) { + Q_D(QGraphicsLayout); + if (QGraphicsLayout::instantInvalidatePropagation()) { + d->activated = false; + QGraphicsLayoutItem::updateGeometry(); + + QGraphicsLayoutItem *parentItem = parentLayoutItem(); + if (!parentItem) + return; + + if (parentItem->isLayout()) + static_cast(parentItem)->invalidate(); + else parentItem->updateGeometry(); - } else { - invalidate(); + } else { + QGraphicsLayoutItem::updateGeometry(); + if (QGraphicsLayoutItem *parentItem = parentLayoutItem()) { + if (parentItem->isLayout()) { + parentItem->updateGeometry(); + } else { + invalidate(); + } } } } @@ -446,6 +473,50 @@ void QGraphicsLayout::addChildLayoutItem(QGraphicsLayoutItem *layoutItem) d->addChildLayoutItem(layoutItem); } +static bool g_instantInvalidatePropagation = false; + +/*! + \internal + \since 4.8 + \see instantInvalidatePropagation + + Calling this function with \a enable set to true will enable a feature that + makes propagation of invalidation up to ancestor layout items to be done in + one go. It will propagate up the parentLayoutItem() hierarchy until it has + reached the root. If the root item is a QGraphicsWidget, it will *post* a + layout request to it. When the layout request is consumed it will traverse + down the hierarchy of layouts and widgets and activate all layouts that is + invalid (not activated). This is the recommended behaviour. + + If not set it will also propagate up the parentLayoutItem() hierarchy, but + it will stop at the \i first \i widget it encounters, and post a layout + request to the widget. When the layout request is consumed, this might + cause it to continue propagation up to the parentLayoutItem() of the + widget. It will continue in this fashion until it has reached a widget with + no parentLayoutItem(). This strategy might cause drawing artifacts, since + it is not done in one go, and the consumption of layout requests might be + interleaved by consumption of paint events, which might cause significant + flicker. + Note, this is not the recommended behavior, but for compatibility reasons + this is the default behaviour. +*/ +void QGraphicsLayout::setInstantInvalidatePropagation(bool enable) +{ + g_instantInvalidatePropagation = enable; +} + +/*! + \internal + \since 4.8 + \see setInstantInvalidatePropagation + + returns true if the complete widget/layout hierarchy is rearranged in one go. +*/ +bool QGraphicsLayout::instantInvalidatePropagation() +{ + return g_instantInvalidatePropagation; +} + QT_END_NAMESPACE #endif //QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicslayout.h b/src/gui/graphicsview/qgraphicslayout.h index c622fb8..6031174 100644 --- a/src/gui/graphicsview/qgraphicslayout.h +++ b/src/gui/graphicsview/qgraphicslayout.h @@ -76,6 +76,8 @@ public: virtual QGraphicsLayoutItem *itemAt(int i) const = 0; virtual void removeAt(int index) = 0; + static void setInstantInvalidatePropagation(bool enable); + static bool instantInvalidatePropagation(); protected: QGraphicsLayout(QGraphicsLayoutPrivate &, QGraphicsLayoutItem *); void addChildLayoutItem(QGraphicsLayoutItem *layoutItem); diff --git a/src/gui/graphicsview/qgraphicslayout_p.cpp b/src/gui/graphicsview/qgraphicslayout_p.cpp index c2d4a08..6afdc19 100644 --- a/src/gui/graphicsview/qgraphicslayout_p.cpp +++ b/src/gui/graphicsview/qgraphicslayout_p.cpp @@ -180,8 +180,13 @@ void QGraphicsLayoutPrivate::activateRecursive(QGraphicsLayoutItem *item) { if (item->isLayout()) { QGraphicsLayout *layout = static_cast(item); - if (layout->d_func()->activated) - layout->invalidate(); + if (layout->d_func()->activated) { + if (QGraphicsLayout::instantInvalidatePropagation()) { + return; + } else { + layout->invalidate(); // ### LOOKS SUSPICIOUSLY WRONG!!??? + } + } for (int i = layout->count() - 1; i >= 0; --i) { QGraphicsLayoutItem *childItem = layout->itemAt(i); diff --git a/src/gui/graphicsview/qgraphicslinearlayout.cpp b/src/gui/graphicsview/qgraphicslinearlayout.cpp index 5591638..1229379 100644 --- a/src/gui/graphicsview/qgraphicslinearlayout.cpp +++ b/src/gui/graphicsview/qgraphicslinearlayout.cpp @@ -275,17 +275,16 @@ void QGraphicsLinearLayout::insertItem(int index, QGraphicsLayoutItem *item) qWarning("QGraphicsLinearLayout::insertItem: cannot insert itself"); return; } - Q_ASSERT(item); - //the order of the following instructions is very important because - //invalidating the layout before adding the child item will make the layout happen - //before we try to paint the item - invalidate(); d->addChildLayoutItem(item); d->fixIndex(&index); d->engine.insertRow(index, d->orientation); new QGridLayoutItem(&d->engine, item, d->gridRow(index), d->gridColumn(index), 1, 1, 0, index); + //the order of the following instructions is very important because + //invalidating the layout before adding the child item will make the layout happen + //before we try to paint the item + invalidate(); } /*! diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index 675a5c5..141e305 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -354,8 +354,10 @@ void QGraphicsWidget::setGeometry(const QRectF &rect) newGeom = rect; newGeom.setSize(rect.size().expandedTo(effectiveSizeHint(Qt::MinimumSize)) .boundedTo(effectiveSizeHint(Qt::MaximumSize))); - if (newGeom == d->geom) - return; + + if (newGeom == d->geom) { + goto relayoutChildrenAndReturn; + } // setPos triggers ItemPositionChange, which can adjust position wd->inSetGeometry = 1; @@ -363,8 +365,9 @@ void QGraphicsWidget::setGeometry(const QRectF &rect) wd->inSetGeometry = 0; newGeom.moveTopLeft(pos()); - if (newGeom == d->geom) - return; + if (newGeom == d->geom) { + goto relayoutChildrenAndReturn; + } // Update and prepare to change the geometry (remove from index) if the size has changed. if (wd->scene) { @@ -375,35 +378,54 @@ void QGraphicsWidget::setGeometry(const QRectF &rect) } // Update the layout item geometry - bool moved = oldPos != pos(); - if (moved) { - // Send move event. - QGraphicsSceneMoveEvent event; - event.setOldPos(oldPos); - event.setNewPos(pos()); - QApplication::sendEvent(this, &event); - if (wd->inSetPos) { - //set the new pos - d->geom.moveTopLeft(pos()); - emit geometryChanged(); - return; + { + bool moved = oldPos != pos(); + if (moved) { + // Send move event. + QGraphicsSceneMoveEvent event; + event.setOldPos(oldPos); + event.setNewPos(pos()); + QApplication::sendEvent(this, &event); + if (wd->inSetPos) { + //set the new pos + d->geom.moveTopLeft(pos()); + emit geometryChanged(); + goto relayoutChildrenAndReturn; + } + } + QSizeF oldSize = size(); + QGraphicsLayoutItem::setGeometry(newGeom); + // Send resize event + bool resized = newGeom.size() != oldSize; + if (resized) { + QGraphicsSceneResizeEvent re; + re.setOldSize(oldSize); + re.setNewSize(newGeom.size()); + if (oldSize.width() != newGeom.size().width()) + emit widthChanged(); + if (oldSize.height() != newGeom.size().height()) + emit heightChanged(); + QGraphicsLayout *lay = wd->layout; + if (QGraphicsLayout::instantInvalidatePropagation()) { + if (!lay || lay->isActivated()) { + QApplication::sendEvent(this, &re); + } + } else { + QApplication::sendEvent(this, &re); + } } } - QSizeF oldSize = size(); - QGraphicsLayoutItem::setGeometry(newGeom); - // Send resize event - bool resized = newGeom.size() != oldSize; - if (resized) { - QGraphicsSceneResizeEvent re; - re.setOldSize(oldSize); - re.setNewSize(newGeom.size()); - if (oldSize.width() != newGeom.size().width()) - emit widthChanged(); - if (oldSize.height() != newGeom.size().height()) - emit heightChanged(); - QApplication::sendEvent(this, &re); - } + emit geometryChanged(); +relayoutChildrenAndReturn: + if (QGraphicsLayout::instantInvalidatePropagation()) { + if (QGraphicsLayout *lay = wd->layout) { + if (!lay->isActivated()) { + QEvent layoutRequest(QEvent::LayoutRequest); + QApplication::sendEvent(this, &layoutRequest); + } + } + } } /*! @@ -1052,16 +1074,31 @@ void QGraphicsWidget::updateGeometry() QGraphicsLayoutItem *parentItem = parentLayoutItem(); if (parentItem && parentItem->isLayout()) { - parentItem->updateGeometry(); + if (QGraphicsLayout::instantInvalidatePropagation()) { + static_cast(parentItem)->invalidate(); + } else { + parentItem->updateGeometry(); + } } else { if (parentItem) { + // This is for custom layouting QGraphicsWidget *parentWid = parentWidget(); //### if (parentWid->isVisible()) QApplication::postEvent(parentWid, new QEvent(QEvent::LayoutRequest)); + } else { + /** + * If this is the topmost widget, post a LayoutRequest event to the widget. + * When the event is received, it will start flowing all the way down to the leaf + * widgets in one go. This will make a relayout flicker-free. + */ + if (QGraphicsLayout::instantInvalidatePropagation()) + QApplication::postEvent(static_cast(this), new QEvent(QEvent::LayoutRequest)); + } + if (!QGraphicsLayout::instantInvalidatePropagation()) { + bool wasResized = testAttribute(Qt::WA_Resized); + resize(size()); // this will restrict the size + setAttribute(Qt::WA_Resized, wasResized); } - bool wasResized = testAttribute(Qt::WA_Resized); - resize(size()); // this will restrict the size - setAttribute(Qt::WA_Resized, wasResized); } } diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index e7c63d5..447385a 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -1091,6 +1091,9 @@ void tst_QGraphicsAnchorLayout::setSpacing() #ifdef Q_WS_MAC QTest::qWait(200); #endif + + // 21x21 + QCOMPARE(p->size(), QSizeF(41, 41)); QCOMPARE(a->geometry(), QRectF(0, 0, 20, 20)); QCOMPARE(b->geometry(), QRectF(21, 0, 20, 20)); QCOMPARE(c->geometry(), QRectF(0, 21, 41, 20)); diff --git a/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp b/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp index 979f03d..c57392640 100644 --- a/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp +++ b/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp @@ -62,6 +62,7 @@ private slots: void compressLayoutRequest(); void automaticReparenting(); void verifyActivate(); + void invalidate(); void constructors(); void alternativeLayoutItems(); void ownership(); @@ -218,6 +219,7 @@ class TestLayout : public QGraphicsLinearLayout : QGraphicsLinearLayout(parent) { m_count = 0; + m_invalidateCount = 0; } void setGeometry(const QRectF &rect) { @@ -226,7 +228,12 @@ class TestLayout : public QGraphicsLinearLayout QGraphicsLinearLayout::setGeometry(rect); } + void invalidate() { + ++m_invalidateCount; + QGraphicsLinearLayout::invalidate(); + } + int m_invalidateCount; int m_count; }; @@ -251,6 +258,87 @@ void tst_QGraphicsLayout::verifyActivate() } +void tst_QGraphicsLayout::invalidate() +{ + QGraphicsLayout::setInstantInvalidatePropagation(true); + QGraphicsScene scene; + QGraphicsView view(&scene); + + TestGraphicsWidget *a = new TestGraphicsWidget; + scene.addItem(a); + TestLayout *alay = new TestLayout(a); + TestGraphicsWidget *b = new TestGraphicsWidget; + alay->addItem(b); + TestLayout *blay = new TestLayout(b); + TestGraphicsWidget *e = new TestGraphicsWidget; + blay->addItem(e); + + + TestGraphicsWidget *c = new TestGraphicsWidget; + alay->addItem(c); + TestLayout *clay = new TestLayout(c); + TestGraphicsWidget *f = new TestGraphicsWidget; + clay->addItem(f); + + TestGraphicsWidget *d = new TestGraphicsWidget; + alay->addItem(d); + TestLayout *dlay = new TestLayout(d); + TestGraphicsWidget *g = new TestGraphicsWidget; + dlay->addItem(g); + + view.show(); + + alay->m_invalidateCount = 0; + blay->m_invalidateCount = 0; + clay->m_invalidateCount = 0; + dlay->m_invalidateCount = 0; + + QCoreApplication::sendPostedEvents(); + QCoreApplication::processEvents(); + + alay->activate(); + QCOMPARE(alay->isActivated(), true); + QCOMPARE(blay->isActivated(), true); + QCOMPARE(clay->isActivated(), true); + qDebug() << "alay->m_invalidateCount:" << alay->m_invalidateCount; + qDebug() << "blay->m_invalidateCount:" << blay->m_invalidateCount; + qDebug() << "clay->m_invalidateCount:" << clay->m_invalidateCount; + qDebug() << "dlay->m_invalidateCount:" << dlay->m_invalidateCount; + + a->clearEventCount(); + b->clearEventCount(); + c->clearEventCount(); + + blay->invalidate(); + QCOMPARE(alay->isActivated(), false); + QCOMPARE(blay->isActivated(), false); + QCOMPARE(clay->isActivated(), true); + QCOMPARE(a->eventCount(QEvent::LayoutRequest), 0); + QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0); + QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0); + + + alay->m_invalidateCount = 0; + blay->m_invalidateCount = 0; + clay->m_invalidateCount = 0; + dlay->m_invalidateCount = 0; + clay->invalidate(); + QCOMPARE(alay->isActivated(), false); + QCOMPARE(blay->isActivated(), false); + QCOMPARE(clay->isActivated(), false); + + QCoreApplication::sendPostedEvents(); + QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0); + QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0); + qDebug() << "alay->m_invalidateCount:" << alay->m_invalidateCount; + qDebug() << "blay->m_invalidateCount:" << blay->m_invalidateCount; + qDebug() << "clay->m_invalidateCount:" << clay->m_invalidateCount; + qDebug() << "dlay->m_invalidateCount:" << dlay->m_invalidateCount; + + QGraphicsLayout::setInstantInvalidatePropagation(false); +} + class Layout : public QGraphicsLayout { public: diff --git a/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp b/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp index 62ba1b4..8f8ac67 100644 --- a/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp +++ b/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp @@ -94,6 +94,7 @@ private slots: void itemSpacing(); void setStretchFactor_data(); void setStretchFactor(); + void testStretch(); void defaultStretchFactors_data(); void defaultStretchFactors(); void sizeHint_data(); @@ -667,6 +668,10 @@ void tst_QGraphicsLinearLayout::invalidate() layout.setContentsMargins(0, 0, 0, 0); view.show(); widget->show(); + //QTest::qWait(1000); + QTest::qWaitForWindowShown(&view); + qApp->processEvents(); + layout.layoutRequest = 0; layout.setContentsMargins(1, 2, 3, 4); QApplication::sendPostedEvents(0, 0); @@ -1130,6 +1135,41 @@ void tst_QGraphicsLinearLayout::setStretchFactor() delete widget; } +void tst_QGraphicsLinearLayout::testStretch() +{ + QGraphicsScene scene; + QGraphicsView *view = new QGraphicsView(&scene); + QGraphicsWidget *form = new QGraphicsWidget(0, Qt::Window); + + scene.addItem(form); + form->setMinimumSize(600, 600); + form->setMaximumSize(600, 600); + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Horizontal, form); + QGraphicsWidget *w1 = new RectWidget; + w1->setPreferredSize(100,100); + w1->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + QGraphicsWidget *w2 = new RectWidget; + w2->setPreferredSize(200,200); + w2->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + layout->setSpacing(0); + layout->setContentsMargins(0, 0, 0, 0); + layout->addItem(w1); + layout->addStretch(2); + layout->addItem(w2); + QCOMPARE(layout->count(), 2); + QVERIFY(layout->itemAt(0) == w1); + QVERIFY(layout->itemAt(1) == w2); + layout->activate(); + + //view->setSceneRect(-50, -50, 800, 800); + //view->show(); + //QTest::qWaitForWindowShown(view); + //QTest::qWait(5000); + QCOMPARE(form->geometry().size(), QSizeF(600,600)); + QCOMPARE(w1->geometry(), QRectF(0, 0, 100, 100)); + QCOMPARE(w2->geometry(), QRectF(400, 0, 200, 200)); +} + void tst_QGraphicsLinearLayout::defaultStretchFactors_data() { QTest::addColumn("orientation"); -- cgit v0.12 From b8b4e6fe141d99c4639d492a546226cdc3fc06c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Fri, 18 Mar 2011 10:52:03 +0100 Subject: Improve invalidate() testcase. Test number of: * events * setGeometry() calls * invalidate() calls --- tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp | 335 +++++++++++++++++---- 1 file changed, 276 insertions(+), 59 deletions(-) diff --git a/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp b/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp index c57392640..29ea074 100644 --- a/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp +++ b/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp @@ -96,6 +96,14 @@ void tst_QGraphicsLayout::sizeHints() } +enum FunctionType { + SetGeometry = 0, + Invalidate, + NumFunctionTypes +}; + + + class TestGraphicsWidget : public QGraphicsWidget { public: TestGraphicsWidget(QGraphicsWidget *parent = 0) : QGraphicsWidget(parent) @@ -109,9 +117,28 @@ public: int eventCount(QEvent::Type type) { return m_eventCount.value(int(type)); } + void clearEventCount() { m_eventCount.clear(); } + + void clearCounters() { + m_eventCount.clear(); + functionCount.clear(); + } + + void setGeometry(const QRectF &rect) + { + QGraphicsWidget::setGeometry(rect); + ++(functionCount[SetGeometry]); + } + + void callUpdateGeometry() + { + // updateGeometry() is protected + QGraphicsWidget::updateGeometry(); + } + QMap functionCount; private: QMap m_eventCount; }; @@ -123,6 +150,8 @@ void tst_QGraphicsLayout::compressLayoutRequest() TestGraphicsWidget *tw = new TestGraphicsWidget(); scene.addItem(tw); view.show(); + + QTest::qWaitForWindowShown(&view); QGraphicsLinearLayout *lout = new QGraphicsLinearLayout(tw); for (int i = 0; i < 4; ++i) { QGraphicsWidget *gw = new QGraphicsWidget(tw); @@ -218,23 +247,27 @@ class TestLayout : public QGraphicsLinearLayout TestLayout(QGraphicsLayoutItem *parent = 0) : QGraphicsLinearLayout(parent) { - m_count = 0; - m_invalidateCount = 0; + setContentsMargins(0,0,0,0); + setSpacing(0); } - void setGeometry(const QRectF &rect) { - - ++m_count; + void setGeometry(const QRectF &rect) + { + ++(functionCount[SetGeometry]); QGraphicsLinearLayout::setGeometry(rect); } - void invalidate() { - ++m_invalidateCount; + void invalidate() + { + ++(functionCount[Invalidate]); QGraphicsLinearLayout::invalidate(); } - int m_invalidateCount; - int m_count; + void clearCounters() { + functionCount.clear(); + } + + QMap functionCount; }; void tst_QGraphicsLayout::verifyActivate() @@ -249,15 +282,47 @@ void tst_QGraphicsLayout::verifyActivate() lout->addItem(w); window->setLayout(lout); - QCOMPARE(lout->m_count, 0); + QCOMPARE(lout->functionCount[SetGeometry], 0); window->setVisible(false); - QCOMPARE(lout->m_count, 0); + QCOMPARE(lout->functionCount[SetGeometry], 0); window->setVisible(true); // on polish or the first time a widget is shown, the widget is resized. - QCOMPARE(lout->m_count, 1); + QCOMPARE(lout->functionCount[SetGeometry], 1); + +} + +static void clearAllCounters(TestGraphicsWidget *widget) +{ + if (!widget) + return; + widget->clearCounters(); + TestLayout *layout = static_cast(widget->layout()); + if (layout) { + layout->clearCounters(); + for (int i = layout->count() - 1; i >=0; --i) { + QGraphicsLayoutItem *item = layout->itemAt(i); + if (item->isLayout()) { + // ### Not used ATM + //TestLayout *lay = static_cast(static_cast(item)); + //clearAllCounters(lay); + } else { + TestGraphicsWidget *wid = static_cast(item); + clearAllCounters(wid); + } + } + } +} +static void activateAndReset(TestGraphicsWidget *widget) +{ + QApplication::sendPostedEvents(); + QApplication::processEvents(); + if (widget->layout()) + widget->layout()->activate(); + clearAllCounters(widget); } + void tst_QGraphicsLayout::invalidate() { QGraphicsLayout::setInstantInvalidatePropagation(true); @@ -265,76 +330,228 @@ void tst_QGraphicsLayout::invalidate() QGraphicsView view(&scene); TestGraphicsWidget *a = new TestGraphicsWidget; + a->setData(0, QString("a")); scene.addItem(a); TestLayout *alay = new TestLayout(a); TestGraphicsWidget *b = new TestGraphicsWidget; + b->setData(0, QString("b")); alay->addItem(b); TestLayout *blay = new TestLayout(b); TestGraphicsWidget *e = new TestGraphicsWidget; + e->setData(0, QString("e")); blay->addItem(e); TestGraphicsWidget *c = new TestGraphicsWidget; + c->setData(0, QString("c")); alay->addItem(c); TestLayout *clay = new TestLayout(c); TestGraphicsWidget *f = new TestGraphicsWidget; + f->setData(0, QString("f")); clay->addItem(f); TestGraphicsWidget *d = new TestGraphicsWidget; + d->setData(0, QString("d")); alay->addItem(d); TestLayout *dlay = new TestLayout(d); TestGraphicsWidget *g = new TestGraphicsWidget; + g->setData(0, QString("g")); dlay->addItem(g); view.show(); - alay->m_invalidateCount = 0; - blay->m_invalidateCount = 0; - clay->m_invalidateCount = 0; - dlay->m_invalidateCount = 0; - - QCoreApplication::sendPostedEvents(); - QCoreApplication::processEvents(); - - alay->activate(); - QCOMPARE(alay->isActivated(), true); - QCOMPARE(blay->isActivated(), true); - QCOMPARE(clay->isActivated(), true); - qDebug() << "alay->m_invalidateCount:" << alay->m_invalidateCount; - qDebug() << "blay->m_invalidateCount:" << blay->m_invalidateCount; - qDebug() << "clay->m_invalidateCount:" << clay->m_invalidateCount; - qDebug() << "dlay->m_invalidateCount:" << dlay->m_invalidateCount; - - a->clearEventCount(); - b->clearEventCount(); - c->clearEventCount(); - - blay->invalidate(); - QCOMPARE(alay->isActivated(), false); - QCOMPARE(blay->isActivated(), false); - QCOMPARE(clay->isActivated(), true); - QCOMPARE(a->eventCount(QEvent::LayoutRequest), 0); - QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0); - QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0); - - - alay->m_invalidateCount = 0; - blay->m_invalidateCount = 0; - clay->m_invalidateCount = 0; - dlay->m_invalidateCount = 0; - clay->invalidate(); - QCOMPARE(alay->isActivated(), false); - QCOMPARE(blay->isActivated(), false); - QCOMPARE(clay->isActivated(), false); - - QCoreApplication::sendPostedEvents(); - QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1); - QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0); - QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0); - qDebug() << "alay->m_invalidateCount:" << alay->m_invalidateCount; - qDebug() << "blay->m_invalidateCount:" << blay->m_invalidateCount; - qDebug() << "clay->m_invalidateCount:" << clay->m_invalidateCount; - qDebug() << "dlay->m_invalidateCount:" << dlay->m_invalidateCount; + { + clearAllCounters(a); + + QCoreApplication::sendPostedEvents(); + QCoreApplication::processEvents(); + + alay->activate(); + QCOMPARE(alay->isActivated(), true); + QCOMPARE(blay->isActivated(), true); + QCOMPARE(clay->isActivated(), true); + QCOMPARE(dlay->isActivated(), true); + } + + { + clearAllCounters(a); + e->callUpdateGeometry(); + QCOMPARE(alay->isActivated(), false); + QCOMPARE(blay->isActivated(), false); + QCOMPARE(clay->isActivated(), true); + QCOMPARE(dlay->isActivated(), true); + QCOMPARE(a->eventCount(QEvent::LayoutRequest), 0); + QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0); + QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0); + QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0); + + // should only invalidate ascendants of e + QCOMPARE(blay->functionCount[Invalidate], 1); + QCOMPARE(alay->functionCount[Invalidate], 1); + // not siblings + QCOMPARE(clay->functionCount[Invalidate], 0); + QCOMPARE(dlay->functionCount[Invalidate], 0); + + QApplication::sendPostedEvents(); + QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(b->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0); + QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0); + } + + + { + activateAndReset(a); + f->callUpdateGeometry(); + QCOMPARE(alay->isActivated(), false); + QCOMPARE(blay->isActivated(), true); + QCOMPARE(clay->isActivated(), false); + QCOMPARE(dlay->isActivated(), true); + + QCoreApplication::sendPostedEvents(); + QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0); + QCOMPARE(c->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0); + + QCOMPARE(a->functionCount[SetGeometry], 1); + QCOMPARE(alay->functionCount[SetGeometry], 1); + + QCOMPARE(b->functionCount[SetGeometry], 1); + QCOMPARE(c->functionCount[SetGeometry], 1); + QCOMPARE(d->functionCount[SetGeometry], 1); + // Since nothing really changed, blay and dlay don't need + // to be resized. + QCOMPARE(blay->functionCount[SetGeometry], 0); + QCOMPARE(clay->functionCount[SetGeometry], 1); + QCOMPARE(dlay->functionCount[SetGeometry], 0); + + QCOMPARE(f->functionCount[SetGeometry], 1); + + QCOMPARE(a->size(), QSizeF(150, 50)); + } + + { + activateAndReset(a); + f->setPreferredSize(QSizeF(60,50)); + QCOMPARE(alay->isActivated(), false); + QCOMPARE(blay->isActivated(), true); + QCOMPARE(clay->isActivated(), false); + QCOMPARE(dlay->isActivated(), true); + + QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0); + QCoreApplication::sendPostedEvents(); + QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0); + QCOMPARE(c->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0); + + QCOMPARE(a->functionCount[SetGeometry], 1); + QCOMPARE(alay->functionCount[SetGeometry], 1); + + QCOMPARE(b->functionCount[SetGeometry], 1); + QCOMPARE(c->functionCount[SetGeometry], 1); + QCOMPARE(d->functionCount[SetGeometry], 1); + // f actually got wider, need to rearrange its siblings + QCOMPARE(blay->functionCount[SetGeometry], 1); + QCOMPARE(clay->functionCount[SetGeometry], 1); + QCOMPARE(dlay->functionCount[SetGeometry], 1); + + QCOMPARE(e->functionCount[SetGeometry], 1); + QCOMPARE(f->functionCount[SetGeometry], 1); + QCOMPARE(g->functionCount[SetGeometry], 1); + + QVERIFY(e->size().width() < f->size().width()); + QVERIFY(g->size().width() < f->size().width()); + } + + { + // resize f so much that it'll force a resize of the top widget + // this will currently generate two setGeometry() calls on the child layout + // of the top widget. + activateAndReset(a); + f->setPreferredSize(QSizeF()); + f->setMinimumSize(QSizeF(200,50)); + QCOMPARE(alay->isActivated(), false); + QCOMPARE(blay->isActivated(), true); + QCOMPARE(clay->isActivated(), false); + QCOMPARE(dlay->isActivated(), true); + + QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0); + QCoreApplication::sendPostedEvents(); + QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0); + QCOMPARE(c->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0); + + QCOMPARE(a->functionCount[SetGeometry], 1); + + /* well, ideally one call to setGeometry(), but it will currently + * get two calls to setGeometry(): + * 1. The first LayoutRequest will call activate() - that will call + * setGeometry() on the layout. This geometry will be based on + * the widget geometry which is not correct at this moment. + * (it is still 150 wide) + * 2. Next, we check if the widget is top level, and then we call + * parentWidget->resize(parentWidget->size()); + * This will be adjusted to be minimum 200 pixels wide. + * The new size will then be propagated down to the layout + * + */ + QCOMPARE(alay->functionCount[SetGeometry], 2); + + QCOMPARE(b->functionCount[SetGeometry], 2); + QCOMPARE(c->functionCount[SetGeometry], 2); + QCOMPARE(d->functionCount[SetGeometry], 2); + // f actually got wider, need to rearrange its siblings + QCOMPARE(blay->functionCount[SetGeometry], 1); + QCOMPARE(clay->functionCount[SetGeometry], 1); + QCOMPARE(dlay->functionCount[SetGeometry], 1); + + QCOMPARE(e->functionCount[SetGeometry], 1); + QCOMPARE(f->functionCount[SetGeometry], 1); + QCOMPARE(g->functionCount[SetGeometry], 1); + + QVERIFY(e->size().width() < f->size().width()); + QVERIFY(g->size().width() < f->size().width()); + } + + { + f->setPreferredSize(QSizeF()); + f->setMinimumSize(QSizeF()); + a->adjustSize(); + activateAndReset(a); + // update two different leaf widgets, + // eventCount and functionCount should never be >= 2 + e->callUpdateGeometry(); + g->callUpdateGeometry(); + QCOMPARE(alay->isActivated(), false); + QCOMPARE(blay->isActivated(), false); + QCOMPARE(clay->isActivated(), true); + QCOMPARE(dlay->isActivated(), false); + + QCoreApplication::sendPostedEvents(); + QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(b->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0); + QCOMPARE(d->eventCount(QEvent::LayoutRequest), 1); + + QCOMPARE(a->functionCount[SetGeometry], 1); + QCOMPARE(alay->functionCount[SetGeometry], 1); + + QCOMPARE(b->functionCount[SetGeometry], 1); + QCOMPARE(c->functionCount[SetGeometry], 1); + QCOMPARE(d->functionCount[SetGeometry], 1); + // f actually got wider, need to rearrange its siblings + QCOMPARE(blay->functionCount[SetGeometry], 1); + QCOMPARE(clay->functionCount[SetGeometry], 0); + QCOMPARE(dlay->functionCount[SetGeometry], 1); + + QCOMPARE(e->functionCount[SetGeometry], 1); + QCOMPARE(f->functionCount[SetGeometry], 0); + QCOMPARE(g->functionCount[SetGeometry], 1); + + } QGraphicsLayout::setInstantInvalidatePropagation(false); } -- cgit v0.12 From fae8bb9f583b416bf47208561c38e0b102f8578c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Fri, 18 Mar 2011 16:33:31 +0100 Subject: Manual test for layout flickering --- tests/manual/qgraphicslayout/flicker/flicker.pro | 8 + tests/manual/qgraphicslayout/flicker/main.cpp | 15 ++ tests/manual/qgraphicslayout/flicker/window.cpp | 32 +++ tests/manual/qgraphicslayout/flicker/window.h | 243 +++++++++++++++++++++++ 4 files changed, 298 insertions(+) create mode 100644 tests/manual/qgraphicslayout/flicker/flicker.pro create mode 100644 tests/manual/qgraphicslayout/flicker/main.cpp create mode 100644 tests/manual/qgraphicslayout/flicker/window.cpp create mode 100644 tests/manual/qgraphicslayout/flicker/window.h diff --git a/tests/manual/qgraphicslayout/flicker/flicker.pro b/tests/manual/qgraphicslayout/flicker/flicker.pro new file mode 100644 index 0000000..323a30f --- /dev/null +++ b/tests/manual/qgraphicslayout/flicker/flicker.pro @@ -0,0 +1,8 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +# Input +HEADERS += window.h +SOURCES += main.cpp window.cpp diff --git a/tests/manual/qgraphicslayout/flicker/main.cpp b/tests/manual/qgraphicslayout/flicker/main.cpp new file mode 100644 index 0000000..838d45f --- /dev/null +++ b/tests/manual/qgraphicslayout/flicker/main.cpp @@ -0,0 +1,15 @@ +#include +#include +#include "window.h" + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + Window *window = new Window(); + window->resize(800, 600); + + window->show(); + + return app.exec(); + +} diff --git a/tests/manual/qgraphicslayout/flicker/window.cpp b/tests/manual/qgraphicslayout/flicker/window.cpp new file mode 100644 index 0000000..d193ad1 --- /dev/null +++ b/tests/manual/qgraphicslayout/flicker/window.cpp @@ -0,0 +1,32 @@ +#include "window.h" + +void SlowWidget::setGeometry(const QRectF &rect) +{ + bool reiterate = false; + Statistics &stats = *m_stats; + if (stats.relayoutClicked) { + ++(stats.setGeometryTracker[this]); + ++stats.setGeometryCount; + qDebug() << "setGeometryCount:" << stats.setGeometryCount; + if (stats.setGeometryTracker.count() == m_window->m_depthSpinBox->value()) { + ++stats.currentBenchmarkIteration; + qDebug() << "currentBenchmarkIteration:" << stats.currentBenchmarkIteration; + if (stats.currentBenchmarkIteration == m_window->m_benchmarkIterationsSpinBox->value()) { + if (stats.output) + stats.output->setText(tr("DONE. Elapsed: %1, setGeometryCount: %2").arg(stats.time.elapsed()).arg(stats.setGeometryCount)); + } else { + reiterate = true; + } + stats.setGeometryTracker.clear(); + + } + } + + QGraphicsWidget::setGeometry(rect); + + if (reiterate) { + m_window->doAgain(); + //QTimer::singleShot(0, m_window, SLOT(doAgain())); + } +} + diff --git a/tests/manual/qgraphicslayout/flicker/window.h b/tests/manual/qgraphicslayout/flicker/window.h new file mode 100644 index 0000000..df1fc82 --- /dev/null +++ b/tests/manual/qgraphicslayout/flicker/window.h @@ -0,0 +1,243 @@ +#ifndef WINDOW_H +#define WINDOW_H + + +#include + +static void qSleep(int msec) +{ + + struct Thread : public QThread + { + static void wait(int msec) + { + QThread::msleep(msec); + } + }; + Thread::wait(msec); +} + +struct Statistics { + Statistics() : output(0), + setGeometryCount(0), currentBenchmarkIteration(0), relayoutClicked(false), sleepMsecs(0) + { + } + QMap setGeometryTracker; + QTime time; + int setGeometryCount; + int sleepMsecs; + QLabel *output; + void sleep() + { + qSleep(sleepMsecs); + } + int currentBenchmarkIteration; + bool relayoutClicked; + +}; + + +class Window; + +class SlowWidget : public QGraphicsWidget { +public: + SlowWidget(QGraphicsWidget *w = 0, Qt::WindowFlags wFlags = 0) : QGraphicsWidget(w, wFlags) + { + m_window = 0; + } + + void setStats(Statistics *stats) + { + m_stats = stats; + } + + void setWindow(Window *window) + { + m_window = window; + } + + void setGeometry(const QRectF &rect); + + bool event(QEvent *e) + { + if (e->type() == QEvent::LayoutRequest) { + if (m_stats->sleepMsecs > 0) { + m_stats->sleep(); + qDebug("sleep %d ms\n", m_stats->sleepMsecs); + } + } + return QGraphicsWidget::event(e); + } + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) + { + Q_UNUSED(option); + Q_UNUSED(widget); + painter->setBrush(m_brush); + painter->drawRoundRect(rect()); + painter->drawLine(rect().topLeft(), rect().bottomRight()); + painter->drawLine(rect().bottomLeft(), rect().topRight()); + } + + void setBrush(const QBrush &brush) + { + m_brush = brush; + } +private: + QBrush m_brush; + Statistics *m_stats; + Window *m_window; +}; + +class Window : public QWidget { + Q_OBJECT +public: + Window() : QWidget() + { + QGraphicsView *m_view = new QGraphicsView(&scene); + + m_window = 0; + m_leaf = 0; + + m_button = new QPushButton(tr("Relayout")); + m_button->setObjectName("button"); + + m_sleepLabel = new QLabel(tr("Sleep:")); + m_sleepSpinBox = new QSpinBox; + m_sleepSpinBox->setRange(0, 1000); + m_sleepSpinBox->setSingleStep(10); + + m_depthLabel = new QLabel(tr("Depth:")); + m_depthSpinBox = new QSpinBox; + m_depthSpinBox->setObjectName("depthSpinBox"); + m_depthSpinBox->setRange(1, 200); + m_depthSpinBox->setSingleStep(5); + + m_benchmarkIterationsLabel = new QLabel(tr("Benchmark iterations")); + m_benchmarkIterationsSpinBox = new QSpinBox; + m_benchmarkIterationsSpinBox->setObjectName("benchmarkIterationsSpinBox"); + m_benchmarkIterationsSpinBox->setRange(1, 1000); + m_benchmarkIterationsSpinBox->setValue(41); + m_benchmarkIterationsSpinBox->setSingleStep(10); + + m_instantCheckBox = new QCheckBox(tr("Instant propagation")); + m_instantCheckBox->setObjectName("instantPropagationCheckbox"); + QGraphicsLayout::setInstantInvalidatePropagation(true); + m_instantCheckBox->setChecked(QGraphicsLayout::instantInvalidatePropagation()); + + m_resultLabel = new QLabel(tr("Press relayout to start test")); + + QHBoxLayout *hbox = new QHBoxLayout; + hbox->addWidget(m_sleepLabel); + hbox->addWidget(m_sleepSpinBox); + hbox->addWidget(m_depthLabel); + hbox->addWidget(m_depthSpinBox); + hbox->addWidget(m_benchmarkIterationsLabel); + hbox->addWidget(m_benchmarkIterationsSpinBox); + hbox->addWidget(m_instantCheckBox); + hbox->addWidget(m_resultLabel); + hbox->addStretch(); + hbox->addWidget(m_button); + + QVBoxLayout *vbox = new QVBoxLayout; + vbox->addWidget(m_view); + vbox->addLayout(hbox); + setLayout(vbox); + + metaObject()->connectSlotsByName(this); + + m_depthSpinBox->setValue(20); // triggers purposedly on_depthSpinBox_valueChanged + } + +private slots: + void on_depthSpinBox_valueChanged(int value) + { + m_stats.relayoutClicked = false; + if (m_window) { + QApplication::processEvents(); + delete m_window; + } + m_window = new SlowWidget(0, Qt::Window); + m_window->setStats(&m_stats); + m_window->setWindow(this); + QColor col(Qt::black); + m_window->setBrush(col); + scene.addItem(m_window); + m_leaf = 0; + const int depth = value; + SlowWidget *parent = m_window; + for (int i = 1; i < depth; ++i) { + QGraphicsLinearLayout *l = new QGraphicsLinearLayout(parent); + l->setContentsMargins(2,2,2,2); + SlowWidget *child = new SlowWidget; + QColor col; + col.setHsl(0, 0, 255*i/(depth - 1)); + child->setBrush(col); + child->setStats(&m_stats); + child->setWindow(this); + l->addItem(child); + parent = child; + } + m_leaf = parent; + } + + void on_button_clicked(bool /*check = false*/) + { + m_stats.relayoutClicked = true; + if (m_leaf) { + QSizeF sz = m_leaf->size(); + int w = int(sz.width()); + w^=16; + sz = QSizeF(w,w); + m_stats.output = m_resultLabel; + m_stats.output->setText(QString("wait...")); + m_stats.setGeometryCount = 0; + m_stats.setGeometryTracker.clear(); + m_stats.sleepMsecs = m_sleepSpinBox->value(); + m_stats.time.start(); + m_stats.currentBenchmarkIteration = 0; + m_leaf->setMinimumSize(sz); + m_leaf->setMaximumSize(sz); + } + } + + void on_instantPropagationCheckbox_toggled(bool checked) + { + QGraphicsLayout::setInstantInvalidatePropagation(checked); + } + +public slots: + void doAgain() + { + if (m_leaf) { + QSizeF sz = m_leaf->size(); + int w = int(sz.width()); + w^=16; + sz = QSizeF(w,w); + m_leaf->setMinimumSize(sz); + m_leaf->setMaximumSize(sz); + } + } + +private: +public: + QGraphicsScene scene; + QGraphicsView *m_view; + QPushButton *m_button; + QLabel *m_sleepLabel; + QSpinBox *m_sleepSpinBox; + QLabel *m_depthLabel; + QSpinBox *m_depthSpinBox; + QLabel *m_benchmarkIterationsLabel; + QSpinBox *m_benchmarkIterationsSpinBox; + QCheckBox *m_instantCheckBox; + QLabel *m_resultLabel; + QGraphicsWidget *m_leaf; + SlowWidget *m_window; + Statistics m_stats; + + +}; + + +#endif //WINDOW_H -- cgit v0.12 From cb503a3f4901c0b017374f099b0de8c0c4c50648 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Fri, 1 Apr 2011 14:50:18 +0200 Subject: Benchmark for layout hierarchies --- tests/benchmarks/gui/graphicsview/graphicsview.pro | 1 + .../qgraphicslayout/qgraphicslayout.pro | 6 + .../qgraphicslayout/tst_qgraphicslayout.cpp | 153 +++++++++++++++++++++ 3 files changed, 160 insertions(+) create mode 100644 tests/benchmarks/gui/graphicsview/qgraphicslayout/qgraphicslayout.pro create mode 100644 tests/benchmarks/gui/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp diff --git a/tests/benchmarks/gui/graphicsview/graphicsview.pro b/tests/benchmarks/gui/graphicsview/graphicsview.pro index e4fed19..1509466 100644 --- a/tests/benchmarks/gui/graphicsview/graphicsview.pro +++ b/tests/benchmarks/gui/graphicsview/graphicsview.pro @@ -3,6 +3,7 @@ SUBDIRS = \ functional \ qgraphicsanchorlayout \ qgraphicsitem \ + qgraphicslayout \ qgraphicsscene \ qgraphicsview \ qgraphicswidget diff --git a/tests/benchmarks/gui/graphicsview/qgraphicslayout/qgraphicslayout.pro b/tests/benchmarks/gui/graphicsview/qgraphicslayout/qgraphicslayout.pro new file mode 100644 index 0000000..19e2979 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/qgraphicslayout/qgraphicslayout.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_bench_qgraphicslayout + +SOURCES += tst_qgraphicslayout.cpp + diff --git a/tests/benchmarks/gui/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp b/tests/benchmarks/gui/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp new file mode 100644 index 0000000..4bdcfb3 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp @@ -0,0 +1,153 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include + +class tst_QGraphicsLayout : public QObject +{ + Q_OBJECT +public: + tst_QGraphicsLayout() {} + ~tst_QGraphicsLayout() {} + +private slots: + void invalidate(); +}; + + +class RectWidget : public QGraphicsWidget +{ +public: + RectWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0) : QGraphicsWidget(parent, wFlags), setGeometryCalls(0) {} + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) + { + Q_UNUSED(option); + Q_UNUSED(widget); + painter->drawRoundRect(rect()); + painter->drawLine(rect().topLeft(), rect().bottomRight()); + painter->drawLine(rect().bottomLeft(), rect().topRight()); + } + + void setGeometry(const QRectF &rect) + { + //qDebug() << "setGeometry():" << this->data(0).toString(); + setGeometryCalls->insert(this, rect); + QGraphicsWidget::setGeometry(rect); + } + + void callUpdateGeometry() { + QGraphicsWidget::updateGeometry(); + } + + QMap *setGeometryCalls; +}; + +/** + * Test to see how much time is needed to resize all widgets in a + * layout-widget-layout-widget-.... hierarchy from the point where a + * leaf widget changes its size hint. (updateGeometry() is called). + * + * If you run the test for 4.7 you'll get some really high numbers, but + * that's because they also include painting (and possible processing of + * some other events). + */ +void tst_QGraphicsLayout::invalidate() +{ + QGraphicsLayout::setInstantInvalidatePropagation(true); + QGraphicsScene scene; + QGraphicsView *view = new QGraphicsView(&scene); + QMap setGeometryCalls; + + RectWidget *window = new RectWidget(0, Qt::Window); + window->setGeometryCalls = &setGeometryCalls; + window->setData(0, QString(QChar('a'))); + + scene.addItem(window); + RectWidget *leaf = 0; + const int depth = 100; + RectWidget *parent = window; + for (int i = 1; i < depth; ++i) { + QGraphicsLinearLayout *l = new QGraphicsLinearLayout(parent); + l->setContentsMargins(0,0,0,0); + RectWidget *child = new RectWidget; + child->setData(0, QString(QChar('a' + i))); + child->setGeometryCalls = &setGeometryCalls; + l->addItem(child); + parent = child; + } + leaf = parent; + leaf->setMinimumSize(QSizeF(1,1)); + + view->show(); + + QTest::qWaitForWindowShown(view); + + // ...then measure... + + int pass = 1; + + // should be as small as possible, to reduce overhead of painting + QSizeF size(1, 1); + setGeometryCalls.clear(); + QBENCHMARK { + leaf->setMinimumSize(size); + leaf->setMaximumSize(size); + while (setGeometryCalls.count() < depth) { + QApplication::sendPostedEvents(); + } + // force a resize on each widget, this will ensure + // that each iteration will resize all 50 widgets + int w = int(size.width()); + w^=2; + size.setWidth(w); + } + delete view; + QGraphicsLayout::setInstantInvalidatePropagation(false); +} + +QTEST_MAIN(tst_QGraphicsLayout) + +#include "tst_qgraphicslayout.moc" -- cgit v0.12 From 6414bda3218790fb8a20a8ff5b3acf6fc6e206da Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 14 Apr 2011 13:40:36 +0200 Subject: qdoc: Completed task QTBUG-18733 --- tools/qdoc3/codemarker.h | 3 +- tools/qdoc3/ditaxmlgenerator.cpp | 76 +++++++++++++++++++++++------ tools/qdoc3/ditaxmlgenerator.h | 13 +++-- tools/qdoc3/htmlgenerator.cpp | 101 +-------------------------------------- tools/qdoc3/pagegenerator.cpp | 6 --- 5 files changed, 74 insertions(+), 125 deletions(-) diff --git a/tools/qdoc3/codemarker.h b/tools/qdoc3/codemarker.h index 21bc31f..00660e7 100644 --- a/tools/qdoc3/codemarker.h +++ b/tools/qdoc3/codemarker.h @@ -165,10 +165,11 @@ class CodeMarker static const Node *nodeForString(const QString& string); static QString stringForNode(const Node *node); + QString typified(const QString &string); + protected: virtual QString sortName(const Node *node); QString protect(const QString &string); - QString typified(const QString &string); QString taggedNode(const Node* node); #ifdef QDOC_QML QString taggedQmlNode(const Node* node); diff --git a/tools/qdoc3/ditaxmlgenerator.cpp b/tools/qdoc3/ditaxmlgenerator.cpp index 69afde9..e394249 100644 --- a/tools/qdoc3/ditaxmlgenerator.cpp +++ b/tools/qdoc3/ditaxmlgenerator.cpp @@ -92,6 +92,7 @@ QString DitaXmlGenerator::ditaTags[] = "apiDesc", "APIMap", "apiName", + "apiRelation", "audience", "author", "b", @@ -284,14 +285,15 @@ void DitaXmlGenerator::writeCharacters(const QString& text) with the \a href attribute and the \a text. */ void DitaXmlGenerator::addLink(const QString& href, - const QStringRef& text) + const QStringRef& text, + DitaTag t) { if (!href.isEmpty()) { - writeStartTag(DT_xref); + writeStartTag(t); // formathtml xmlWriter().writeAttribute("href", href); writeCharacters(text.toString()); - writeEndTag(); // + writeEndTag(); //
} else { writeCharacters(text.toString()); @@ -1718,7 +1720,7 @@ DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* mark */ generateHeader(inner, fullTitle); generateBrief(inner, marker); // - writeProlog(inner,marker); + writeProlog(inner); writeStartTag(DT_cxxClassDetail); writeStartTag(DT_cxxClassDefinition); @@ -1838,7 +1840,7 @@ DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* mark generateHeader(inner, fullTitle); generateBrief(inner, marker); // - writeProlog(inner,marker); + writeProlog(inner); writeStartTag(DT_cxxClassDetail); writeStartTag(DT_cxxClassDefinition); @@ -1974,7 +1976,7 @@ DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* mark */ generateHeader(inner, fullTitle); generateBrief(inner, marker); // - writeProlog(inner,marker); + writeProlog(inner); writeStartTag(DT_cxxClassDetail); enterApiDesc(QString(),title); @@ -2093,7 +2095,7 @@ DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* mark generateHeader(inner, fullTitle); generateBrief(inner, marker); // - writeProlog(inner,marker); + writeProlog(inner); writeStartTag(DT_cxxClassDetail); enterApiDesc(QString(),title); @@ -2195,7 +2197,7 @@ void DitaXmlGenerator::generateFakeNode(const FakeNode* fake, CodeMarker* marker generateHeader(fake, fullTitle); generateBrief(fake, marker); // - writeProlog(fake, marker); + writeProlog(fake); writeStartTag(DT_body); enterSection(QString(),QString()); @@ -4712,7 +4714,7 @@ void DitaXmlGenerator::writeLocation(const Node* n) Write the elements. */ void DitaXmlGenerator::writeFunctions(const Section& s, - const Node* n, + const InnerNode* parent, CodeMarker* marker, const QString& attribute) { @@ -4775,7 +4777,7 @@ void DitaXmlGenerator::writeFunctions(const Section& s, } } - if (fn->name() == n->name()) { + if (fn->name() == parent->name()) { writeStartTag(DT_cxxFunctionConstructor); xmlWriter().writeAttribute("name","constructor"); xmlWriter().writeAttribute("value","constructor"); @@ -4789,7 +4791,8 @@ void DitaXmlGenerator::writeFunctions(const Section& s, } else { writeStartTag(DT_cxxFunctionDeclaredType); - writeCharacters(fn->returnType()); + QString src = marker->typified(fn->returnType()); + replaceTypesWithLinks(fn,parent,marker,src); writeEndTag(); // } @@ -4825,7 +4828,7 @@ void DitaXmlGenerator::writeFunctions(const Section& s, writeEndTag(); // } } - writeParameters(fn); + writeParameters(fn,parent,marker); writeLocation(fn); writeEndTag(); // @@ -4846,10 +4849,51 @@ void DitaXmlGenerator::writeFunctions(const Section& s, } } +static const QString typeTag("type"); +static const QChar charLangle = '<'; +static const QChar charAt = '@'; + +/*! + This function replaces class and enum names with + elements, i.e. links. + */ +void DitaXmlGenerator::replaceTypesWithLinks(const Node* n, + const InnerNode* parent, + CodeMarker* marker, + QString& src) +{ + QStringRef arg; + QStringRef par1; + int srcSize = src.size(); + QString text; + for (int i=0; iresolveTarget(arg.toString(), myTree, parent, n); + addLink(linkForNode(tn,parent),arg,DT_apiRelation); + } + } + else { + text += src.at(i++); + } + } + if (!text.isEmpty()) { + writeCharacters(text); + text.clear(); + } +} + /*! This function writes the element. */ -void DitaXmlGenerator::writeParameters(const FunctionNode* fn) +void DitaXmlGenerator::writeParameters(const FunctionNode* fn, + const InnerNode* parent, + CodeMarker* marker) { const QList& parameters = fn->parameters(); if (!parameters.isEmpty()) { @@ -4858,7 +4902,9 @@ void DitaXmlGenerator::writeParameters(const FunctionNode* fn) while (p != parameters.end()) { writeStartTag(DT_cxxFunctionParameter); writeStartTag(DT_cxxFunctionParameterDeclaredType); - writeCharacters((*p).leftType()); + QString src = marker->typified((*p).leftType()); + replaceTypesWithLinks(fn,parent,marker,src); + //writeCharacters((*p).leftType()); if (!(*p).rightType().isEmpty()) writeCharacters((*p).rightType()); writeEndTag(); // @@ -5695,7 +5741,7 @@ QString DitaXmlGenerator::metadataDefault(DitaTag t) const */ void -DitaXmlGenerator::writeProlog(const InnerNode* inner, CodeMarker* marker) +DitaXmlGenerator::writeProlog(const InnerNode* inner) { if (!inner) return; diff --git a/tools/qdoc3/ditaxmlgenerator.h b/tools/qdoc3/ditaxmlgenerator.h index ffca234..0044eff 100644 --- a/tools/qdoc3/ditaxmlgenerator.h +++ b/tools/qdoc3/ditaxmlgenerator.h @@ -87,6 +87,7 @@ class DitaXmlGenerator : public PageGenerator DT_apiDesc, DT_APIMap, DT_apiName, + DT_apiRelation, DT_audience, DT_author, DT_b, @@ -292,11 +293,15 @@ class DitaXmlGenerator : public PageGenerator void writeDerivations(const ClassNode* cn, CodeMarker* marker); void writeLocation(const Node* n); void writeFunctions(const Section& s, - const Node* n, + const InnerNode* parent, CodeMarker* marker, const QString& attribute = QString()); void writeNestedClasses(const Section& s, const Node* n); - void writeParameters(const FunctionNode* fn); + void replaceTypesWithLinks(const Node* n, + const InnerNode* parent, + CodeMarker* marker, + QString& src); + void writeParameters(const FunctionNode* fn, const InnerNode* parent, CodeMarker* marker); void writeEnumerations(const Section& s, CodeMarker* marker, const QString& attribute = QString()); @@ -315,7 +320,7 @@ class DitaXmlGenerator : public PageGenerator void writePropertyParameter(const QString& tag, const NodeList& nlist); void writeRelatedLinks(const FakeNode* fake, CodeMarker* marker); void writeLink(const Node* node, const QString& tex, const QString& role); - void writeProlog(const InnerNode* inner, CodeMarker* marker); + void writeProlog(const InnerNode* inner); bool writeMetadataElement(const InnerNode* inner, DitaXmlGenerator::DitaTag t, bool force=true); @@ -438,7 +443,7 @@ class DitaXmlGenerator : public PageGenerator virtual void generateInnerNode(const InnerNode* node); QXmlStreamWriter& xmlWriter(); void writeApiDesc(const Node* node, CodeMarker* marker, const QString& title); - void addLink(const QString& href, const QStringRef& text); + void addLink(const QString& href, const QStringRef& text, DitaTag t = DT_xref); void writeDitaMap(); void writeStartTag(DitaTag t); void writeEndTag(DitaTag t=DT_NONE); diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index 88bc3e2..a6cf646 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -93,104 +93,6 @@ static QRegExp typeTag("(<@(type|headerfile|func)(?: +[^>]*)?>)(.*)()"); static QRegExp spanTag(""); static QRegExp unknownTag("]*>"); -bool parseArg(const QString &src, - const QString &tag, - int *pos, - int n, - QStringRef *contents, - QStringRef *par1 = 0, - bool debug = false) -{ -#define SKIP_CHAR(c) \ - if (debug) \ - qDebug() << "looking for " << c << " at " << QString(src.data() + i, n - i); \ - if (i >= n || src[i] != c) { \ - if (debug) \ - qDebug() << " char '" << c << "' not found"; \ - return false; \ - } \ - ++i; - - -#define SKIP_SPACE \ - while (i < n && src[i] == ' ') \ - ++i; - - int i = *pos; - int j = i; - - // assume "<@" has been parsed outside - //SKIP_CHAR('<'); - //SKIP_CHAR('@'); - - if (tag != QStringRef(&src, i, tag.length())) { - if (0 && debug) - qDebug() << "tag " << tag << " not found at " << i; - return false; - } - - if (debug) - qDebug() << "haystack:" << src << "needle:" << tag << "i:" <).*()"); - if (par1) { - SKIP_SPACE; - // read parameter name - j = i; - while (i < n && src[i].isLetter()) - ++i; - if (src[i] == '=') { - if (debug) - qDebug() << "read parameter" << QString(src.data() + j, i - j); - SKIP_CHAR('='); - SKIP_CHAR('"'); - // skip parameter name - j = i; - while (i < n && src[i] != '"') - ++i; - *par1 = QStringRef(&src, j, i - j); - SKIP_CHAR('"'); - SKIP_SPACE; - } else { - if (debug) - qDebug() << "no optional parameter found"; - } - } - SKIP_SPACE; - SKIP_CHAR('>'); - - // find contents up to closing " - j = i; - for (; true; ++i) { - if (i + 4 + tag.length() > n) - return false; - if (src[i] != '<') - continue; - if (src[i + 1] != '/') - continue; - if (src[i + 2] != '@') - continue; - if (tag != QStringRef(&src, i + 3, tag.length())) - continue; - if (src[i + 3 + tag.length()] != '>') - continue; - break; - } - - *contents = QStringRef(&src, j, i - j); - - i += tag.length() + 4; - - *pos = i; - if (debug) - qDebug() << " tag " << tag << " found: pos now: " << i; - return true; -#undef SKIP_CHAR -} - static void addLink(const QString &linkTarget, const QStringRef &nestedStuff, QString *res) @@ -2849,7 +2751,7 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, static const QString headerTag("headerfile"); static const QString funcTag("func"); static const QString linkTag("link"); - + // replace all <@link> tags: "(<@link node=\"([^\"]+)\">).*()" bool done = false; for (int i = 0, srcSize = src.size(); i < srcSize;) { @@ -2884,6 +2786,7 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, if (src.at(i) == charLangle && src.at(i + 1) == charAt) { i += 2; if (parseArg(src, funcTag, &i, srcSize, &arg, &par1)) { + const Node* n = marker->resolveTarget(par1.toString(), myTree, relative); diff --git a/tools/qdoc3/pagegenerator.cpp b/tools/qdoc3/pagegenerator.cpp index d5564f7..d331d41 100644 --- a/tools/qdoc3/pagegenerator.cpp +++ b/tools/qdoc3/pagegenerator.cpp @@ -70,12 +70,6 @@ PageGenerator::~PageGenerator() endSubPage(); } -static QRegExp linkTag("(<@link node=\"([^\"]+)\">).*()"); -static QRegExp funcTag("(<@func target=\"([^\"]*)\">)(.*)()"); -static QRegExp typeTag("(<@(type|headerfile|func)(?: +[^>]*)?>)(.*)()"); -static QRegExp spanTag(""); -static QRegExp unknownTag("]*>"); - bool PageGenerator::parseArg(const QString& src, const QString& tag, int* pos, -- cgit v0.12 From 7cc4ffce36c24596630ca83cd6418869d6383670 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Thu, 14 Apr 2011 14:33:02 +0200 Subject: Compile fix in qdrawhelper_sse2.cpp. --- src/gui/painting/qdrawhelper_sse2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp index fdab95f..c6bd339 100644 --- a/src/gui/painting/qdrawhelper_sse2.cpp +++ b/src/gui/painting/qdrawhelper_sse2.cpp @@ -523,7 +523,7 @@ public: static inline Int32x4 v_toInt(Float32x4 x) { return _mm_cvttps_epi32(x); } - static inline Int32x4 v_greaterOrEqual(Float32x4 a, Float32x4 b) { return (__m128i)_mm_cmpgt_ps(a, b); } + static inline Int32x4 v_greaterOrEqual(Float32x4 a, Float32x4 b) { return _mm_castps_si128(_mm_cmpgt_ps(a, b)); } }; const uint * QT_FASTCALL qt_fetch_radial_gradient_sse2(uint *buffer, const Operator *op, const QSpanData *data, -- cgit v0.12 From 6dcb0028e44cba2a00c2fb867fb1757ad5b1a254 Mon Sep 17 00:00:00 2001 From: Tomi Vihria Date: Thu, 14 Apr 2011 15:39:08 +0300 Subject: Fixed Qt UDA creation for Symbian Added a dummy Qt sis file and fixed paths in bld.inf. Otherwise build would fail when FF_QT_IN_UDA is defined. Dummy Qt sis file needs to replaced with a real one when actual UDA image is created. Task-number: QT-4888 Reviewed-by: Guoqing Zhang --- config.profiles/symbian/bld.inf | 2 +- config.profiles/symbian/qt.sisx | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 config.profiles/symbian/qt.sisx diff --git a/config.profiles/symbian/bld.inf b/config.profiles/symbian/bld.inf index 16a9e15..6ccb11c 100644 --- a/config.profiles/symbian/bld.inf +++ b/config.profiles/symbian/bld.inf @@ -38,7 +38,7 @@ loc.prf /epoc32/tools/qt/mkspecs/features/loc.prf //For UDA image confml/qt.confml CONFML_EXPORT_PATH(qt.confml,uda_content) implml/qt_copy.implml CRML_EXPORT_PATH(qt_copy.implml,uda_content) -content/apps/qt.sisx CRML_EXPORT_PATH(../content/sis/,uda_content) +qt.sisx CRML_EXPORT_PATH(../content/sis/,uda_content) #endif /* export stub sis to enable eclipsing */ diff --git a/config.profiles/symbian/qt.sisx b/config.profiles/symbian/qt.sisx new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/config.profiles/symbian/qt.sisx @@ -0,0 +1 @@ +1 \ No newline at end of file -- cgit v0.12 From 7f921ea08c296e7451a44a1dae15350ae183ea20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Thu, 14 Apr 2011 18:00:42 +0200 Subject: Compile fix in qdrawhelper_sse2.cpp for MSVC 2005. --- src/gui/painting/qdrawhelper_sse2.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp index c6bd339..affc6cc 100644 --- a/src/gui/painting/qdrawhelper_sse2.cpp +++ b/src/gui/painting/qdrawhelper_sse2.cpp @@ -523,7 +523,12 @@ public: static inline Int32x4 v_toInt(Float32x4 x) { return _mm_cvttps_epi32(x); } + // pre-VS 2008 doesn't have cast intrinsics, whereas 2008 and later requires it +#if defined(Q_CC_MSVC) && _MSC_VER < 1500 + static inline Int32x4 v_greaterOrEqual(Float32x4 a, Float32x4 b) { return (__m128i)_mm_cmpgt_ps(a, b); } +#else static inline Int32x4 v_greaterOrEqual(Float32x4 a, Float32x4 b) { return _mm_castps_si128(_mm_cmpgt_ps(a, b)); } +#endif }; const uint * QT_FASTCALL qt_fetch_radial_gradient_sse2(uint *buffer, const Operator *op, const QSpanData *data, -- cgit v0.12 From 1750a4351a8125756bf38a53d6d8312993c7d85e Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Fri, 15 Apr 2011 14:15:49 +1000 Subject: Remove Q_ASSERT calls that wrap side-effecting code. In release mode builds, code inside Q_ASSERT macros is not executed, so putting code with side-effects inside Q_ASSERT is not a good idea. Task-number: QTBUG-17582 Change-Id: I1a5d8ccce666ee7b7f120bf9cbb49e30dac9add4 Reviewed-by: Rohan McGovern --- tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp b/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp index 2dbed3b..50c634f 100644 --- a/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp +++ b/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp @@ -185,16 +185,22 @@ QString tst_qmlvisual::toTestScript(const QString &file, Mode mode) if (platformsuffix && (mode == UpdatePlatformVisuals || QFile::exists(testdata+QLatin1String(platformsuffix)+QDir::separator()+testname+".qml"))) { QString platformdir = testdata + QLatin1String(platformsuffix); if (mode == UpdatePlatformVisuals) { - Q_ASSERT(QDir().mkpath(platformdir)); + if (!QDir().mkpath(platformdir)) { + qFatal("Cannot make path %s", qPrintable(platformdir)); + } // Copy from base QDir dir(testdata,testname+".*"); dir.setFilter(QDir::Files); QFileInfoList list = dir.entryInfoList(); for (int i = 0; i < list.size(); ++i) { QFile in(list.at(i).filePath()); - Q_ASSERT(in.open(QIODevice::ReadOnly)); + if (!in.open(QIODevice::ReadOnly)) { + qFatal("Cannot open file %s: %s", qPrintable(in.fileName()), qPrintable(in.errorString())); + } QFile out(platformdir + QDir::separator() + list.at(i).fileName()); - Q_ASSERT(out.open(QIODevice::WriteOnly)); + if (!out.open(QIODevice::WriteOnly)) { + qFatal("Cannot open file %s: %s", qPrintable(out.fileName()), qPrintable(out.errorString())); + } out.write(in.readAll()); } } -- cgit v0.12 From d6bd4db2db6dbefec327e226bf54a69a20690a45 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Fri, 15 Apr 2011 15:25:45 +1000 Subject: Remove redundant Q_ASSERT from qmlvisual autotest. Change-Id: I5c413793ee6322b5be1ae52658362803dc4c2010 Task-number: QTBUG-17582 Reviewed-by: Alan Alpert --- tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp b/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp index 50c634f..61e1883 100644 --- a/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp +++ b/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp @@ -240,8 +240,6 @@ QStringList tst_qmlvisual::findQmlFiles(const QDir &d) void action(Mode mode, const QString &file) { - Q_ASSERT(mode != Test); - QString testdata = tst_qmlvisual::toTestScript(file,mode); QStringList arguments; -- cgit v0.12 From 59a6e6200984ccbb862b8758436a5e88b8c40bbc Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Fri, 15 Apr 2011 16:15:39 +1000 Subject: Remove Q_ASSERT from QDeclarativeListModel autotest. Change-Id: Ic15b747fa50bcec54df748b173b299058f69c681 Task-number: QTBUG-17582 Reviewed-by: Rohan McGovern --- .../declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp index 45072f3..14af19c 100644 --- a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp +++ b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp @@ -114,7 +114,6 @@ int tst_qdeclarativelistmodel::roleFromName(const QDeclarativeListModel *model, if (model->toString(roles[i]) == roleName) return roles[i]; } - Q_ASSERT(false); return -1; } @@ -740,6 +739,7 @@ void tst_qdeclarativelistmodel::get() "}", QUrl()); QDeclarativeListModel *model = qobject_cast(component.create()); int role = roleFromName(model, roleName); + QVERIFY(role >= 0); QSignalSpy spy(model, SIGNAL(itemsChanged(int, int, QList))); QDeclarativeExpression expr(eng.rootContext(), model, expression); @@ -801,6 +801,7 @@ void tst_qdeclarativelistmodel::get_worker() model.append(sv); model.append(sv); int role = roleFromName(&model, roleName); + QVERIFY(role >= 0); const char *warning = ": QML ListModel: Cannot add list-type data when modifying or after modification from a worker script"; if (roleValue.type() == QVariant::List || roleValue.type() == QVariant::Map) @@ -892,6 +893,7 @@ void tst_qdeclarativelistmodel::get_nested() int outerListIndex = testData[i].first; QString outerListRoleName = testData[i].second; int outerListRole = roleFromName(model, outerListRoleName); + QVERIFY(outerListRole >= 0); childModel = qobject_cast(model->data(outerListIndex, outerListRole).value()); QVERIFY(childModel); @@ -904,6 +906,7 @@ void tst_qdeclarativelistmodel::get_nested() QVERIFY(!expr.hasError()); int role = roleFromName(childModel, roleName); + QVERIFY(role >= 0); QCOMPARE(childModel->data(index, role), roleValue); QCOMPARE(spy.count(), 1); -- cgit v0.12 From 45c60ceac3d5a401543d7d56a44d1f9227464431 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 15 Apr 2011 09:12:07 +0200 Subject: Another attempt at fixing the MSVC2005 build. Apparently direct casting is illegal there too, even though they don't have the cast operators. Reviewed-by: Kim --- src/gui/painting/qdrawhelper_sse2.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp index affc6cc..be6dc91 100644 --- a/src/gui/painting/qdrawhelper_sse2.cpp +++ b/src/gui/painting/qdrawhelper_sse2.cpp @@ -525,7 +525,12 @@ public: // pre-VS 2008 doesn't have cast intrinsics, whereas 2008 and later requires it #if defined(Q_CC_MSVC) && _MSC_VER < 1500 - static inline Int32x4 v_greaterOrEqual(Float32x4 a, Float32x4 b) { return (__m128i)_mm_cmpgt_ps(a, b); } + static inline Int32x4 v_greaterOrEqual(Float32x4 a, Float32x4 b) + { + union Convert { Int32x4 vi; Float32x4 vf; } convert; + convert.vf = _mm_cmpgt_ps(a, b); + return convert.vi; + } #else static inline Int32x4 v_greaterOrEqual(Float32x4 a, Float32x4 b) { return _mm_castps_si128(_mm_cmpgt_ps(a, b)); } #endif -- cgit v0.12 From ee55dec1efe9c67518bf3e27f81b0696075f7153 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Fri, 15 Apr 2011 17:35:13 +1000 Subject: Make tst_exceptionsafety_objects part of the test set. Re-enable this test, with the two test functions that fail on Linux disabled until the failures can be diagnosed. Change-Id: I915e1a0d675cb71a80086e89f9799a4f9f6b600c Reviewed-by: Rohan McGovern --- tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp | 2 ++ tests/auto/other.pro | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp b/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp index e7e516e..3e4ccf5 100644 --- a/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp +++ b/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp @@ -352,6 +352,7 @@ void tst_ExceptionSafetyObjects::cleanupTestCase() void tst_ExceptionSafetyObjects::objects() { + QSKIP("This test currently crashes", SkipAll); QFETCH(AbstractTester *, objectCreator); doOOMTest(*objectCreator, 0); @@ -457,6 +458,7 @@ void tst_ExceptionSafetyObjects::widgets_data() void tst_ExceptionSafetyObjects::widgets() { + QSKIP("This test currently crashes", SkipAll); QFETCH(AbstractTester *, widgetCreator); doOOMTest(*widgetCreator, 0, 00000); diff --git a/tests/auto/other.pro b/tests/auto/other.pro index 8819879..4d8ff4e 100644 --- a/tests/auto/other.pro +++ b/tests/auto/other.pro @@ -3,7 +3,7 @@ TEMPLATE=subdirs SUBDIRS=\ -# exceptionsafety_objects \ shouldn't enable it + exceptionsafety_objects \ # baselineexample \ Just an example demonstrating qbaselinetest usage lancelot \ qaccessibility \ -- cgit v0.12 From 3bff1637cd49617d334c1be63c20e008fac93be1 Mon Sep 17 00:00:00 2001 From: Fabien Freling Date: Thu, 14 Apr 2011 19:12:59 +0200 Subject: Fix an race condition in the auto test. Deleting the page in the wizard without removing it first leads to a crash when the wizard tries to access a deleted page. Reviewed-by: jasplin --- tests/auto/qwizard/tst_qwizard.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/auto/qwizard/tst_qwizard.cpp b/tests/auto/qwizard/tst_qwizard.cpp index a813727..bbac8a3 100644 --- a/tests/auto/qwizard/tst_qwizard.cpp +++ b/tests/auto/qwizard/tst_qwizard.cpp @@ -1770,8 +1770,11 @@ public: ~TestWizard() { - foreach (int id, pageIds) - delete page(id); + foreach (int id, pageIds) { + QWizardPage *page_to_delete = page(id); + removePage(id); + delete page_to_delete; + } } void applyOperations(const QList &operations) -- cgit v0.12 From 75aea79ce599d5f62a1642a875774544f548c904 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Fri, 15 Apr 2011 12:22:02 +0200 Subject: qdoc: Completed task QTBUG-18790 --- tools/qdoc3/ditaxmlgenerator.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/qdoc3/ditaxmlgenerator.cpp b/tools/qdoc3/ditaxmlgenerator.cpp index e394249..5f44cd8 100644 --- a/tools/qdoc3/ditaxmlgenerator.cpp +++ b/tools/qdoc3/ditaxmlgenerator.cpp @@ -769,6 +769,7 @@ int DitaXmlGenerator::generateAtom(const Atom *atom, case Atom::Code: { writeStartTag(DT_codeblock); + xmlWriter().writeAttribute("outputclass","cpp"); QString chars = trimmedTrailing(atom->string()); writeText(chars, marker, relative); writeEndTag(); // @@ -776,6 +777,7 @@ int DitaXmlGenerator::generateAtom(const Atom *atom, break; case Atom::Qml: writeStartTag(DT_codeblock); + xmlWriter().writeAttribute("outputclass","qml"); writeText(trimmedTrailing(atom->string()), marker, relative); writeEndTag(); // break; -- cgit v0.12 From 1348f4f0853155182d2ea5836902794d1e43980c Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 22 Mar 2011 10:57:59 +0100 Subject: Long live QRawFont! The QGlyphs API was initially attempted with a bastardization of QFont which was meant to encapsulate a single, physical font instance (a QFontEngine) where a set of glyph indexes would make sense. This is not how QFont was intended to be used, and it caused several issues. At the same time, the requirement for loading a font from ttf/otf data and be able to access it and use it without polluting the rest of the process with the font arose. To support these two APIs we introduce QRawFont, which is an abstraction on top of a single physical font. Done-with: Jiang Jiang --- src/corelib/global/qglobal.h | 6 + src/gui/painting/qpaintbuffer.cpp | 23 +- src/gui/painting/qpainter.cpp | 54 +- src/gui/painting/qpainter.h | 2 + src/gui/painting/qpainter_p.h | 10 +- src/gui/text/qfont.cpp | 26 +- src/gui/text/qfont_win.cpp | 17 +- src/gui/text/qfontdatabase.cpp | 27 +- src/gui/text/qfontdatabase_mac.cpp | 7 +- src/gui/text/qfontdatabase_s60.cpp | 2 +- src/gui/text/qfontdatabase_win.cpp | 90 +-- src/gui/text/qfontengine.cpp | 18 - src/gui/text/qfontengine_coretext.mm | 316 +++++++---- src/gui/text/qfontengine_coretext_p.h | 27 +- src/gui/text/qfontengine_ft.cpp | 162 +++++- src/gui/text/qfontengine_ft_p.h | 15 +- src/gui/text/qfontengine_mac.mm | 21 - src/gui/text/qfontengine_mac_p.h | 2 - src/gui/text/qfontengine_p.h | 5 +- src/gui/text/qfontengine_x11_p.h | 1 + src/gui/text/qfontenginedirectwrite.cpp | 54 +- src/gui/text/qfontenginedirectwrite_p.h | 11 +- src/gui/text/qglyphs.cpp | 97 +++- src/gui/text/qglyphs.h | 19 +- src/gui/text/qglyphs_p.h | 25 +- src/gui/text/qrawfont.cpp | 612 ++++++++++++++++++++ src/gui/text/qrawfont.h | 140 +++++ src/gui/text/qrawfont_ft.cpp | 189 +++++++ src/gui/text/qrawfont_mac.cpp | 105 ++++ src/gui/text/qrawfont_p.h | 132 +++++ src/gui/text/qrawfont_win.cpp | 750 +++++++++++++++++++++++++ src/gui/text/qtextlayout.cpp | 58 +- src/gui/text/qtextlayout.h | 5 + src/gui/text/qtextobject.cpp | 2 + src/gui/text/qtextobject.h | 2 + src/gui/text/text.pri | 22 +- tests/auto/gui.pro | 1 + tests/auto/qglyphs/tst_qglyphs.cpp | 17 +- tests/auto/qrawfont/qrawfont.pro | 13 + tests/auto/qrawfont/testfont.ttf | Bin 0 -> 63212 bytes tests/auto/qrawfont/testfont_bold_italic.ttf | Bin 0 -> 49760 bytes tests/auto/qrawfont/tst_qrawfont.cpp | 812 +++++++++++++++++++++++++++ 42 files changed, 3509 insertions(+), 388 deletions(-) create mode 100644 src/gui/text/qrawfont.cpp create mode 100644 src/gui/text/qrawfont.h create mode 100644 src/gui/text/qrawfont_ft.cpp create mode 100644 src/gui/text/qrawfont_mac.cpp create mode 100644 src/gui/text/qrawfont_p.h create mode 100644 src/gui/text/qrawfont_win.cpp create mode 100644 tests/auto/qrawfont/qrawfont.pro create mode 100644 tests/auto/qrawfont/testfont.ttf create mode 100644 tests/auto/qrawfont/testfont_bold_italic.ttf create mode 100644 tests/auto/qrawfont/tst_qrawfont.cpp diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 7c5c354..d8ffd6d 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -2743,6 +2743,12 @@ QT_LICENSED_MODULE(DBus) # endif #endif +#if !(defined(Q_WS_WIN) && !defined(Q_WS_WINCE)) \ + && !(defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)) \ + && !(defined(Q_WS_X11) && !defined(QT_NO_FREETYPE)) +# define QT_NO_RAWFONT +#endif + QT_END_NAMESPACE QT_END_HEADER diff --git a/src/gui/painting/qpaintbuffer.cpp b/src/gui/painting/qpaintbuffer.cpp index dd4b3db..7870def 100644 --- a/src/gui/painting/qpaintbuffer.cpp +++ b/src/gui/painting/qpaintbuffer.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include @@ -1754,26 +1755,38 @@ void QPainterReplayer::process(const QPaintBufferCommand &cmd) painter->setClipRegion(region, Qt::ClipOperation(cmd.extra)); break; } +#if !defined(QT_NO_RAWFONT) case QPaintBufferPrivate::Cmd_DrawStaticText: { QVariantList variants(d->variants.at(cmd.offset).value()); QFont font = variants.at(0).value(); - QVector glyphs; + QVector glyphIndexes; QVector positions; for (int i=0; i<(variants.size() - 1) / 2; ++i) { - glyphs.append(variants.at(i*2 + 1).toUInt()); + glyphIndexes.append(variants.at(i*2 + 1).toUInt()); positions.append(variants.at(i*2 + 2).toPointF()); } painter->setFont(font); - qt_draw_glyphs(painter, glyphs.constData(), positions.constData(), glyphs.size()); - - break; + QRawFont rawFont; + QRawFontPrivate *rawFontD = QRawFontPrivate::get(rawFont); + QFontPrivate *fontD = QFontPrivate::get(font); + rawFontD->fontEngine = fontD->engineForScript(QUnicodeTables::Common); + rawFontD->fontEngine->ref.ref(); + + QGlyphs glyphs; + glyphs.setFont(rawFont); + glyphs.setGlyphIndexes(glyphIndexes); + glyphs.setPositions(positions); + + painter->drawGlyphs(QPointF(), glyphs); + break; } +#endif case QPaintBufferPrivate::Cmd_DrawText: { QPointF pos(d->floats.at(cmd.extra), d->floats.at(cmd.extra+1)); diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index eddb9eb..cbd16ae 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -75,6 +75,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -5798,12 +5799,14 @@ void QPainter::drawImage(const QRectF &targetRect, const QImage &image, const QR \sa QGlyphs::setFont(), QGlyphs::setPositions(), QGlyphs::setGlyphIndexes() */ +#if !defined(QT_NO_RAWFONT) void QPainter::drawGlyphs(const QPointF &position, const QGlyphs &glyphs) { Q_D(QPainter); - QFont oldFont = d->state->font; - d->state->font = glyphs.font(); + QRawFont font = glyphs.font(); + if (!font.isValid()) + return; QVector glyphIndexes = glyphs.glyphIndexes(); QVector glyphPositions = glyphs.positions(); @@ -5822,39 +5825,20 @@ void QPainter::drawGlyphs(const QPointF &position, const QGlyphs &glyphs) fixedPointPositions[i] = QFixedPoint::fromPointF(processedPosition); } - d->drawGlyphs(glyphIndexes.data(), fixedPointPositions.data(), count); - - d->state->font = oldFont; + d->drawGlyphs(glyphIndexes.data(), fixedPointPositions.data(), count, font, glyphs.overline(), + glyphs.underline(), glyphs.strikeOut()); } -void qt_draw_glyphs(QPainter *painter, const quint32 *glyphArray, const QPointF *positionArray, - int glyphCount) -{ - QVarLengthArray positions(glyphCount); - for (int i=0; idrawGlyphs(const_cast(glyphArray), positions.data(), glyphCount); -} - -void QPainterPrivate::drawGlyphs(quint32 *glyphArray, QFixedPoint *positions, int glyphCount) +void QPainterPrivate::drawGlyphs(quint32 *glyphArray, QFixedPoint *positions, int glyphCount, + const QRawFont &font, bool overline, bool underline, + bool strikeOut) { Q_Q(QPainter); updateState(state); - QFontEngine *fontEngine = state->font.d->engineForScript(QUnicodeTables::Common); - - while (fontEngine->type() == QFontEngine::Multi) { - // Pick engine based on first glyph in array if we are using a multi engine. - // (all glyphs must be for same font) - int engineIdx = 0; - if (glyphCount > 0) - engineIdx = glyphArray[0] >> 24; - - fontEngine = static_cast(fontEngine)->engine(engineIdx); - } + QRawFontPrivate *fontD = QRawFontPrivate::get(font); + QFontEngine *fontEngine = fontD->fontEngine; QFixed leftMost; QFixed rightMost; @@ -5889,7 +5873,6 @@ void QPainterPrivate::drawGlyphs(quint32 *glyphArray, QFixedPoint *positions, in extended->drawStaticTextItem(&staticTextItem); } else { QTextItemInt textItem; - textItem.f = &state->font; textItem.fontEngine = fontEngine; QVarLengthArray advances(glyphCount); @@ -5911,20 +5894,21 @@ void QPainterPrivate::drawGlyphs(quint32 *glyphArray, QFixedPoint *positions, in } QTextItemInt::RenderFlags flags; - if (state->font.underline()) + if (underline) flags |= QTextItemInt::Underline; - if (state->font.overline()) + if (overline) flags |= QTextItemInt::Overline; - if (state->font.strikeOut()) + if (strikeOut) flags |= QTextItemInt::StrikeOut; drawTextItemDecoration(q, QPointF(leftMost.toReal(), baseLine.toReal()), fontEngine, - (state->font.underline() - ? QTextCharFormat::SingleUnderline - : QTextCharFormat::NoUnderline), + (underline + ? QTextCharFormat::SingleUnderline + : QTextCharFormat::NoUnderline), flags, width.toReal(), QTextCharFormat()); } +#endif // QT_NO_RAWFONT /*! diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h index 604225e..1a432e6 100644 --- a/src/gui/painting/qpainter.h +++ b/src/gui/painting/qpainter.h @@ -399,7 +399,9 @@ public: void setLayoutDirection(Qt::LayoutDirection direction); Qt::LayoutDirection layoutDirection() const; +#if !defined(QT_NO_RAWFONT) void drawGlyphs(const QPointF &position, const QGlyphs &glyphs); +#endif void drawStaticText(const QPointF &topLeftPosition, const QStaticText &staticText); inline void drawStaticText(const QPoint &topLeftPosition, const QStaticText &staticText); diff --git a/src/gui/painting/qpainter_p.h b/src/gui/painting/qpainter_p.h index 26d8fc3..205c10a 100644 --- a/src/gui/painting/qpainter_p.h +++ b/src/gui/painting/qpainter_p.h @@ -184,6 +184,7 @@ struct QPainterDummyState QTransform transform; }; +class QRawFont; class QPainterPrivate { Q_DECLARE_PUBLIC(QPainter) @@ -229,7 +230,12 @@ public: void draw_helper(const QPainterPath &path, DrawOperation operation = StrokeAndFillDraw); void drawStretchedGradient(const QPainterPath &path, DrawOperation operation); void drawOpaqueBackground(const QPainterPath &path, DrawOperation operation); - void drawGlyphs(quint32 *glyphArray, QFixedPoint *positionArray, int glyphCount); + +#if !defined(QT_NO_RAWFONT) + void drawGlyphs(quint32 *glyphArray, QFixedPoint *positionArray, int glyphCount, + const QRawFont &font, bool overline = false, bool underline = false, + bool strikeOut = false); +#endif void updateMatrix(); void updateInvMatrix(); @@ -259,8 +265,6 @@ public: }; Q_GUI_EXPORT void qt_draw_helper(QPainterPrivate *p, const QPainterPath &path, QPainterPrivate::DrawOperation operation); -Q_GUI_EXPORT void qt_draw_glyphs(QPainter *painter, const quint32 *glyphArray, - const QPointF *positionArray, int glyphCount); QString qt_generate_brush_key(const QBrush &brush); diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index f77e237..b8cfb1f 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -282,27 +282,16 @@ QFontPrivate::~QFontPrivate() scFont = 0; } -#if !defined(Q_WS_MAC) extern QMutex *qt_fontdatabase_mutex(); -QFontEngine *QFontPrivate::engineForScript(int script) const -{ - QMutexLocker locker(qt_fontdatabase_mutex()); - if (script >= QUnicodeTables::Inherited) - script = QUnicodeTables::Common; - if (engineData && engineData->fontCache != QFontCache::instance()) { - // throw out engineData that came from a different thread - engineData->ref.deref(); - engineData = 0; - } - if (!engineData || !engineData->engines[script]) - QFontDatabase::load(this, script); - return engineData->engines[script]; -} +#if !defined(Q_WS_MAC) +#define QT_FONT_ENGINE_FROM_DATA(data, script) data->engines[script] #else +#define QT_FONT_ENGINE_FROM_DATA(data, script) data->engine +#endif + QFontEngine *QFontPrivate::engineForScript(int script) const { - extern QMutex *qt_fontdatabase_mutex(); QMutexLocker locker(qt_fontdatabase_mutex()); if (script >= QUnicodeTables::Inherited) script = QUnicodeTables::Common; @@ -311,11 +300,10 @@ QFontEngine *QFontPrivate::engineForScript(int script) const engineData->ref.deref(); engineData = 0; } - if (!engineData || !engineData->engine) + if (!engineData || !QT_FONT_ENGINE_FROM_DATA(engineData, script)) QFontDatabase::load(this, script); - return engineData->engine; + return QT_FONT_ENGINE_FROM_DATA(engineData, script); } -#endif void QFontPrivate::alterCharForCapitalization(QChar &c) const { switch (capital) { diff --git a/src/gui/text/qfont_win.cpp b/src/gui/text/qfont_win.cpp index 7d710ea..3ef761b 100644 --- a/src/gui/text/qfont_win.cpp +++ b/src/gui/text/qfont_win.cpp @@ -58,6 +58,7 @@ QT_BEGIN_NAMESPACE extern HDC shared_dc(); // common dc for all fonts +extern QFont::Weight weightFromInteger(int weight); // qfontdatabase.cpp // ### maybe move to qapplication_win QFont qt_LOGFONTtoQFont(LOGFONT& lf, bool /*scale*/) @@ -65,20 +66,8 @@ QFont qt_LOGFONTtoQFont(LOGFONT& lf, bool /*scale*/) QString family = QString::fromWCharArray(lf.lfFaceName); QFont qf(family); qf.setItalic(lf.lfItalic); - if (lf.lfWeight != FW_DONTCARE) { - int weight; - if (lf.lfWeight < 400) - weight = QFont::Light; - else if (lf.lfWeight < 600) - weight = QFont::Normal; - else if (lf.lfWeight < 700) - weight = QFont::DemiBold; - else if (lf.lfWeight < 800) - weight = QFont::Bold; - else - weight = QFont::Black; - qf.setWeight(weight); - } + if (lf.lfWeight != FW_DONTCARE) + qf.setWeight(weightFromInteger(lf.lfWeight)); int lfh = qAbs(lf.lfHeight); qf.setPointSizeF(lfh * 72.0 / GetDeviceCaps(shared_dc(),LOGPIXELSY)); qf.setUnderline(false); diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 94f21b8..36b0ea9 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -136,6 +136,21 @@ static int getFontWeight(const QString &weightString) return (int) QFont::Normal; } +// convert 0 ~ 1000 integer to QFont::Weight +QFont::Weight weightFromInteger(int weight) +{ + if (weight < 400) + return QFont::Light; + else if (weight < 600) + return QFont::Normal; + else if (weight < 700) + return QFont::DemiBold; + else if (weight < 800) + return QFont::Bold; + else + return QFont::Black; +} + struct QtFontEncoding { signed int encoding : 16; @@ -497,8 +512,6 @@ QtFontFoundry *QtFontFamily::foundry(const QString &f, bool create) // ### copied to tools/makeqpf/qpf2.cpp -#if (defined(Q_WS_QWS) && !defined(QT_NO_FREETYPE)) || defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN) || (defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)) - // see the Unicode subset bitfields in the MSDN docs static int requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = { // Any, @@ -576,7 +589,7 @@ static int requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = { #define JapaneseCsbBit 17 #define KoreanCsbBit 21 -static QList determineWritingSystemsFromTrueTypeBits(quint32 unicodeRange[4], quint32 codePageRange[2]) +QList qt_determine_writing_systems_from_truetype_bits(quint32 unicodeRange[4], quint32 codePageRange[2]) { QList writingSystems; bool hasScript = false; @@ -623,7 +636,6 @@ static QList determineWritingSystemsFromTrueTypeBi return writingSystems; } -#endif #if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE) // class with virtual destructor, derived in qfontdatabase_s60.cpp @@ -873,7 +885,7 @@ QStringList QFontDatabasePrivate::addTTFile(const QByteArray &file, const QByteA os2->ulCodePageRange1, os2->ulCodePageRange2 }; - writingSystems = determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange); + writingSystems = qt_determine_writing_systems_from_truetype_bits(unicodeRange, codePageRange); //for (int i = 0; i < writingSystems.count(); ++i) // qDebug() << QFontDatabase::writingSystemName(writingSystems.at(i)); } @@ -936,6 +948,11 @@ static const int scriptForWritingSystem[] = { QUnicodeTables::Nko // Nko }; +int qt_script_for_writing_system(QFontDatabase::WritingSystem writingSystem) +{ + return scriptForWritingSystem[writingSystem]; +} + #if defined Q_WS_QWS || (defined(Q_WS_X11) && !defined(QT_NO_FONTCONFIG)) || defined(Q_WS_WIN) static inline bool requiresOpenType(int writingSystem) diff --git a/src/gui/text/qfontdatabase_mac.cpp b/src/gui/text/qfontdatabase_mac.cpp index ad2c1b2..5ba236b 100644 --- a/src/gui/text/qfontdatabase_mac.cpp +++ b/src/gui/text/qfontdatabase_mac.cpp @@ -72,7 +72,7 @@ static void initWritingSystems(QtFontFamily *family, ATSFontRef atsFont) qFromBigEndian(os2Table.data() + 54) }; quint32 codePageRange[2] = { qFromBigEndian(os2Table.data() + 78), qFromBigEndian(os2Table.data() + 82) }; - QList systems = determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange); + QList systems = qt_determine_writing_systems_from_truetype_bits(unicodeRange, codePageRange); #if 0 QCFString name; ATSFontGetName(atsFont, kATSOptionFlagsDefault, &name); @@ -244,6 +244,11 @@ static const char *styleHint(const QFontDef &request) return stylehint; } +static inline float weightToFloat(unsigned int weight) +{ + return (weight - 50) / 100.0; +} + void QFontDatabase::load(const QFontPrivate *d, int script) { // sanity checks diff --git a/src/gui/text/qfontdatabase_s60.cpp b/src/gui/text/qfontdatabase_s60.cpp index 6d3970e..1db4a7d 100644 --- a/src/gui/text/qfontdatabase_s60.cpp +++ b/src/gui/text/qfontdatabase_s60.cpp @@ -521,7 +521,7 @@ static bool registerScreenDeviceFont(int screenDeviceFontIndex, qFromBigEndian(ulCodePageRange + 4) }; const QList writingSystems = - determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange); + qt_determine_writing_systems_from_truetype_bits(unicodeRange, codePageRange); foreach (const QFontDatabase::WritingSystem system, writingSystems) family->writingSystems[system] = QtFontFamily::Supported; return true; diff --git a/src/gui/text/qfontdatabase_win.cpp b/src/gui/text/qfontdatabase_win.cpp index 8279195..05b7509 100644 --- a/src/gui/text/qfontdatabase_win.cpp +++ b/src/gui/text/qfontdatabase_win.cpp @@ -242,6 +242,8 @@ error: return i18n_name; } +extern QFont::Weight weightFromInteger(int weight); // qfontdatabase.cpp + static void addFontToDatabase(QString familyName, const QString &scriptName, TEXTMETRIC *textmetric, @@ -274,16 +276,7 @@ void addFontToDatabase(QString familyName, const QString &scriptName, if (familyName[0] != QLatin1Char('@') && !familyName.startsWith(QLatin1String("WST_"))) { QtFontStyle::Key styleKey; styleKey.style = italic ? QFont::StyleItalic : QFont::StyleNormal; - if (weight < 400) - styleKey.weight = QFont::Light; - else if (weight < 600) - styleKey.weight = QFont::Normal; - else if (weight < 700) - styleKey.weight = QFont::DemiBold; - else if (weight < 800) - styleKey.weight = QFont::Bold; - else - styleKey.weight = QFont::Black; + styleKey.weight = weightFromInteger(weight); QtFontFamily *family = privateDb()->family(familyName, true); @@ -340,7 +333,7 @@ void addFontToDatabase(QString familyName, const QString &scriptName, quint32 codePageRange[2] = { signature->fsCsb[0], signature->fsCsb[1] }; - QList systems = determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange); + QList systems = qt_determine_writing_systems_from_truetype_bits(unicodeRange, codePageRange); for (int i = 0; i < systems.count(); ++i) { QFontDatabase::WritingSystem writingSystem = systems.at(i); @@ -530,26 +523,26 @@ static inline void load(const QString &family = QString(), int = -1) -static void initFontInfo(QFontEngineWin *fe, const QFontDef &request, const QFontPrivate *fp) +static void initFontInfo(QFontEngineWin *fe, const QFontDef &request, HDC fontHdc, int dpi) { fe->fontDef = request; // most settings are equal - HDC dc = ((request.styleStrategy & QFont::PreferDevice) && fp->hdc) ? fp->hdc : shared_dc(); + HDC dc = ((request.styleStrategy & QFont::PreferDevice) && fontHdc) ? fontHdc : shared_dc(); SelectObject(dc, fe->hfont); wchar_t n[64]; GetTextFace(dc, 64, n); fe->fontDef.family = QString::fromWCharArray(n); fe->fontDef.fixedPitch = !(fe->tm.tmPitchAndFamily & TMPF_FIXED_PITCH); if (fe->fontDef.pointSize < 0) { - fe->fontDef.pointSize = fe->fontDef.pixelSize * 72. / fp->dpi; + fe->fontDef.pointSize = fe->fontDef.pixelSize * 72. / dpi; } else if (fe->fontDef.pixelSize == -1) { - fe->fontDef.pixelSize = qRound(fe->fontDef.pointSize * fp->dpi / 72.); + fe->fontDef.pixelSize = qRound(fe->fontDef.pointSize * dpi / 72.); } } #if !defined(QT_NO_DIRECTWRITE) static void initFontInfo(QFontEngineDirectWrite *fe, const QFontDef &request, - const QFontPrivate *fp, IDWriteFont *font) + int dpi, IDWriteFont *font) { fe->fontDef = request; @@ -601,9 +594,9 @@ static void initFontInfo(QFontEngineDirectWrite *fe, const QFontDef &request, qErrnoWarning(hr, "initFontInfo: Failed to get family name"); if (fe->fontDef.pointSize < 0) - fe->fontDef.pointSize = fe->fontDef.pixelSize * 72. / fp->dpi; + fe->fontDef.pointSize = fe->fontDef.pixelSize * 72. / dpi; else if (fe->fontDef.pixelSize == -1) - fe->fontDef.pixelSize = qRound(fe->fontDef.pointSize * fp->dpi / 72.); + fe->fontDef.pixelSize = qRound(fe->fontDef.pointSize * dpi / 72.); } #endif @@ -679,20 +672,21 @@ static inline HFONT systemFont() #define DEFAULT_GUI_FONT 17 #endif -static -QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &request, const QtFontDesc *desc, - const QStringList &family_list) +static QFontEngine *loadEngine(int script, const QFontDef &request, + HDC fontHdc, int dpi, bool rawMode, + const QtFontDesc *desc, + const QStringList &family_list) { LOGFONT lf; memset(&lf, 0, sizeof(LOGFONT)); - bool useDevice = (request.styleStrategy & QFont::PreferDevice) && fp->hdc; + bool useDevice = (request.styleStrategy & QFont::PreferDevice) && fontHdc; HDC hdc = shared_dc(); - QString font_name = desc->family->name; + QString font_name = desc != 0 ? desc->family->name : request.family; if (useDevice) { - hdc = fp->hdc; + hdc = fontHdc; font_name = request.family; } @@ -710,9 +704,9 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ bool useDirectWrite = false; #endif - if (fp->rawMode) { // will choose a stock font + if (rawMode) { // will choose a stock font int f, deffnt = SYSTEM_FONT; - QString fam = desc->family->name.toLower(); + QString fam = desc != 0 ? desc->family->name.toLower() : request.family.toLower(); if (fam == QLatin1String("default")) f = deffnt; else if (fam == QLatin1String("system")) @@ -766,11 +760,11 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ lf.lfWidth = 0; lf.lfEscapement = 0; lf.lfOrientation = 0; - if (desc->style->key.weight == 50) + if (desc == 0 || desc->style->key.weight == 50) lf.lfWeight = FW_DONTCARE; else lf.lfWeight = (desc->style->key.weight*900)/99; - lf.lfItalic = (desc->style->key.style != QFont::StyleNormal); + lf.lfItalic = (desc != 0 && desc->style->key.style != QFont::StyleNormal); lf.lfCharSet = DEFAULT_CHARSET; int strat = OUT_DEFAULT_PRECIS; @@ -901,9 +895,11 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ &lf, &directWriteFont); if (FAILED(hr)) { +#ifndef QT_NO_DEBUG qErrnoWarning("QFontEngine::loadEngine: CreateFontFromLOGFONT failed " "for %ls (0x%lx)", lf.lfFaceName, hr); +#endif } else { DeleteObject(hfont); useDirectWrite = true; @@ -933,22 +929,27 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ } } - initFontInfo(few, request, fp); + initFontInfo(few, request, fontHdc, dpi); fe = few; } #if !defined(QT_NO_DIRECTWRITE) else { QFontDatabasePrivate *db = privateDb(); - QFontEngineDirectWrite *fedw = new QFontEngineDirectWrite(font_name, - db->directWriteFactory, - db->directWriteGdiInterop, - directWriteFont, - request.pixelSize); - initFontInfo(fedw, request, fp, directWriteFont); + IDWriteFontFace *directWriteFontFace = NULL; + HRESULT hr = directWriteFont->CreateFontFace(&directWriteFontFace); + if (SUCCEEDED(hr)) { + QFontEngineDirectWrite *fedw = new QFontEngineDirectWrite(db->directWriteFactory, + directWriteFontFace, + request.pixelSize); + + initFontInfo(fedw, request, dpi, directWriteFont); - fe = fedw; + fe = fedw; + } else { + qErrnoWarning(hr, "QFontEngine::loadEngine: CreateFontFace failed"); + } } if (directWriteFont != 0) @@ -957,6 +958,7 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ if(script == QUnicodeTables::Common && !(request.styleStrategy & QFont::NoFontMerging) + && desc != 0 && !(desc->family->writingSystems[QFontDatabase::Symbol] & QtFontFamily::Supported)) { if(!tryFonts) { LANGID lid = GetUserDefaultLangID(); @@ -993,6 +995,20 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ return fe; } +QFontEngine *qt_load_font_engine_win(const QFontDef &request) +{ + // From qfont.cpp + extern int qt_defaultDpi(); + + QFontCache::Key key(request, QUnicodeTables::Common); + QFontEngine *fe = QFontCache::instance()->findEngine(key); + if (fe != 0) + return fe; + else + return loadEngine(QUnicodeTables::Common, request, 0, qt_defaultDpi(), false, 0, + QStringList()); +} + const char *styleHint(const QFontDef &request) { const char *stylehint = 0; @@ -1053,7 +1069,7 @@ static QFontEngine *loadWin(const QFontPrivate *d, int script, const QFontDef &r } if (!desc.family) break; - fe = loadEngine(script, d, req, &desc, family_list); + fe = loadEngine(script, req, d->hdc, d->dpi, d->rawMode, &desc, family_list); if (!fe) blacklistedFamilies.append(desc.familyIndex); } diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 3adf4eb..2f76cc6 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -237,24 +237,6 @@ glyph_metrics_t QFontEngine::boundingBox(glyph_t glyph, const QTransform &matrix return metrics; } -QFont QFontEngine::createExplicitFont() const -{ - return createExplicitFontWithName(fontDef.family); -} - -QFont QFontEngine::createExplicitFontWithName(const QString &familyName) const -{ - QFont font(familyName); - font.setStyleStrategy(QFont::NoFontMerging); - font.setWeight(fontDef.weight); - font.setItalic(fontDef.style == QFont::StyleItalic); - if (fontDef.pointSize < 0) - font.setPixelSize(fontDef.pixelSize); - else - font.setPointSizeF(fontDef.pointSize); - return font; -} - QFixed QFontEngine::xHeight() const { QGlyphLayoutArray<8> glyphs; diff --git a/src/gui/text/qfontengine_coretext.mm b/src/gui/text/qfontengine_coretext.mm index 4d9192e..20b3730 100644 --- a/src/gui/text/qfontengine_coretext.mm +++ b/src/gui/text/qfontengine_coretext.mm @@ -52,6 +52,31 @@ QT_BEGIN_NAMESPACE static float SYNTHETIC_ITALIC_SKEW = tanf(14 * acosf(0) / 90); +static void loadAdvancesForGlyphs(CTFontRef ctfont, + QVarLengthArray &cgGlyphs, + QGlyphLayout *glyphs, int len, + QTextEngine::ShaperFlags flags, + const QFontDef &fontDef) +{ + Q_UNUSED(flags); + QVarLengthArray advances(len); + CTFontGetAdvancesForGlyphs(ctfont, kCTFontHorizontalOrientation, cgGlyphs.data(), advances.data(), len); + + for (int i = 0; i < len; ++i) { + if (glyphs->glyphs[i] & 0xff000000) + continue; + glyphs->advances_x[i] = QFixed::fromReal(advances[i].width); + glyphs->advances_y[i] = QFixed::fromReal(advances[i].height); + } + + if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { + for (int i = 0; i < len; ++i) { + glyphs->advances_x[i] = glyphs->advances_x[i].round(); + glyphs->advances_y[i] = glyphs->advances_y[i].round(); + } + } +} + QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const QCFString &name, const QFontDef &fontDef, bool kerning) : QFontEngineMulti(0) { @@ -83,7 +108,31 @@ QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const QCFString &name, const ctfont = baseFont; CFRetain(ctfont); } + init(kerning); +} + +QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(CGFontRef cgFontRef, const QFontDef &fontDef, bool kerning) + : QFontEngineMulti(0) +{ + this->fontDef = fontDef; + + transform = CGAffineTransformIdentity; + if (fontDef.stretch != 100) { + transform = CGAffineTransformMakeScale(float(fontDef.stretch) / float(100), 1); + } + + ctfont = CTFontCreateWithGraphicsFont(cgFontRef, fontDef.pixelSize, &transform, NULL); + init(kerning); +} + +QCoreTextFontEngineMulti::~QCoreTextFontEngineMulti() +{ + CFRelease(ctfont); +} +void QCoreTextFontEngineMulti::init(bool kerning) +{ + Q_ASSERT(ctfont != NULL); attributeDict = CFDictionaryCreateMutable(0, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); @@ -94,26 +143,20 @@ QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const QCFString &name, const CFDictionaryAddValue(attributeDict, kCTKernAttributeName, noKern); } - QCoreTextFontEngine *fe = new QCoreTextFontEngine(ctfont, fontDef, this); + QCoreTextFontEngine *fe = new QCoreTextFontEngine(ctfont, fontDef); fe->ref.ref(); engines.append(fe); - -} - -QCoreTextFontEngineMulti::~QCoreTextFontEngineMulti() -{ - CFRelease(ctfont); } -uint QCoreTextFontEngineMulti::fontIndexForFont(CTFontRef id) const +uint QCoreTextFontEngineMulti::fontIndexForFont(CTFontRef font) const { for (int i = 0; i < engines.count(); ++i) { - if (CFEqual(engineAt(i)->ctfont, id)) + if (CFEqual(engineAt(i)->ctfont, font)) return i; } QCoreTextFontEngineMulti *that = const_cast(this); - QCoreTextFontEngine *fe = new QCoreTextFontEngine(id, fontDef, that); + QCoreTextFontEngine *fe = new QCoreTextFontEngine(font, fontDef); fe->ref.ref(); that->engines.append(fe); return engines.count() - 1; @@ -317,72 +360,45 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay if (flags & QTextEngine::GlyphIndicesOnly) return true; - QVarLengthArray advances(len); - CTFontGetAdvancesForGlyphs(ctfont, kCTFontHorizontalOrientation, cgGlyphs.data(), advances.data(), len); - - for (int i = 0; i < len; ++i) { - if (glyphs->glyphs[i] & 0xff000000) - continue; - glyphs->advances_x[i] = QFixed::fromReal(advances[i].width); - glyphs->advances_y[i] = QFixed::fromReal(advances[i].height); - } - - if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { - for (int i = 0; i < len; ++i) { - glyphs->advances_x[i] = glyphs->advances_x[i].round(); - glyphs->advances_y[i] = glyphs->advances_y[i].round(); - } - } - + loadAdvancesForGlyphs(ctfont, cgGlyphs, glyphs, len, flags, fontDef); return true; } -void QCoreTextFontEngineMulti::recalcAdvances(int , QGlyphLayout *, QTextEngine::ShaperFlags) const -{ -} -void QCoreTextFontEngineMulti::doKerning(int , QGlyphLayout *, QTextEngine::ShaperFlags) const -{ -} - void QCoreTextFontEngineMulti::loadEngine(int) { // Do nothing Q_ASSERT(false); } +extern int qt_antialiasing_threshold; // from qapplication.cpp +static inline CGAffineTransform transformFromFontDef(const QFontDef &fontDef) +{ + CGAffineTransform transform = CGAffineTransformIdentity; + if (fontDef.stretch != 100) + transform = CGAffineTransformMakeScale(float(fontDef.stretch) / float(100), 1); + return transform; +} -QCoreTextFontEngine::QCoreTextFontEngine(CTFontRef font, const QFontDef &def, - QCoreTextFontEngineMulti *multiEngine) +QCoreTextFontEngine::QCoreTextFontEngine(CTFontRef font, const QFontDef &def) { fontDef = def; - parentEngine = multiEngine; - synthesisFlags = 0; + transform = transformFromFontDef(fontDef); ctfont = font; CFRetain(ctfont); - cgFont = CTFontCopyGraphicsFont(ctfont, NULL); - CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(ctfont); - if (fontDef.weight >= QFont::Bold && !(traits & kCTFontBoldTrait)) { - synthesisFlags |= SynthesizedBold; - } - - if (fontDef.style != QFont::StyleNormal && !(traits & kCTFontItalicTrait)) { - synthesisFlags |= SynthesizedItalic; - } - transform = CGAffineTransformIdentity; - if (fontDef.stretch != 100) { - transform = CGAffineTransformMakeScale(float(fontDef.stretch) / float(100), 1); - } - QByteArray os2Table = getSfntTable(MAKE_TAG('O', 'S', '/', '2')); - if (os2Table.size() >= 10) - fsType = qFromBigEndian(reinterpret_cast(os2Table.constData() + 8)); + cgFont = CTFontCopyGraphicsFont(font, NULL); + init(); +} - QSettings appleSettings(QLatin1String("apple.com")); - QVariant appleValue = appleSettings.value(QLatin1String("AppleAntiAliasingThreshold")); - if (appleValue.isValid()) - antialiasing_threshold = appleValue.toInt(); - else - antialiasing_threshold = -1; +QCoreTextFontEngine::QCoreTextFontEngine(CGFontRef font, const QFontDef &def) +{ + fontDef = def; + transform = transformFromFontDef(fontDef); + cgFont = font; + // Keep reference count balanced + CFRetain(cgFont); + ctfont = CTFontCreateWithGraphicsFont(font, fontDef.pixelSize, &transform, NULL); + init(); } QCoreTextFontEngine::~QCoreTextFontEngine() @@ -391,9 +407,89 @@ QCoreTextFontEngine::~QCoreTextFontEngine() CFRelease(ctfont); } -bool QCoreTextFontEngine::stringToCMap(const QChar *, int, QGlyphLayout *, int *, QTextEngine::ShaperFlags) const +extern QFont::Weight weightFromInteger(int weight); // qfontdatabase.cpp + +int getTraitValue(CFDictionaryRef allTraits, CFStringRef trait) { - return false; + if (CFDictionaryContainsKey(allTraits, trait)) { + CFNumberRef traitNum = (CFNumberRef) CFDictionaryGetValue(allTraits, trait); + float v = 0; + CFNumberGetValue(traitNum, kCFNumberFloatType, &v); + // the value we get from CFNumberRef is from -1.0 to 1.0 + int value = v * 500 + 500; + return value; + } + + return 0; +} + +void QCoreTextFontEngine::init() +{ + Q_ASSERT(ctfont != NULL); + Q_ASSERT(cgFont != NULL); + + QCFString family = CTFontCopyFamilyName(ctfont); + fontDef.family = family; + + synthesisFlags = 0; + CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(ctfont); + if (traits & kCTFontItalicTrait) + fontDef.style = QFont::StyleItalic; + + CFDictionaryRef allTraits = CTFontCopyTraits(ctfont); + fontDef.weight = weightFromInteger(getTraitValue(allTraits, kCTFontWeightTrait)); + int slant = getTraitValue(allTraits, kCTFontSlantTrait); + if (slant > 500 && !(traits & kCTFontItalicTrait)) + fontDef.style = QFont::StyleOblique; + CFRelease(allTraits); + + if (fontDef.weight >= QFont::Bold && !(traits & kCTFontBoldTrait)) + synthesisFlags |= SynthesizedBold; + // XXX: we probably don't need to synthesis italic for oblique font + if (fontDef.style != QFont::StyleNormal && !(traits & kCTFontItalicTrait)) + synthesisFlags |= SynthesizedItalic; + + avgCharWidth = 0; + QByteArray os2Table = getSfntTable(MAKE_TAG('O', 'S', '/', '2')); + unsigned emSize = CTFontGetUnitsPerEm(ctfont); + if (os2Table.size() >= 10) { + fsType = qFromBigEndian(reinterpret_cast(os2Table.constData() + 8)); + // qAbs is a workaround for weird fonts like Lucida Grande + qint16 width = qAbs(qFromBigEndian(reinterpret_cast(os2Table.constData() + 2))); + avgCharWidth = QFixed::fromReal(width * fontDef.pixelSize / emSize); + } else + avgCharWidth = QFontEngine::averageCharWidth(); + + ctMaxCharWidth = ctMinLeftBearing = ctMinRightBearing = 0; + QByteArray hheaTable = getSfntTable(MAKE_TAG('h', 'h', 'e', 'a')); + if (hheaTable.size() >= 16) { + quint16 width = qFromBigEndian(reinterpret_cast(hheaTable.constData() + 10)); + ctMaxCharWidth = width * fontDef.pixelSize / emSize; + qint16 bearing = qFromBigEndian(reinterpret_cast(hheaTable.constData() + 12)); + ctMinLeftBearing = bearing * fontDef.pixelSize / emSize; + bearing = qFromBigEndian(reinterpret_cast(hheaTable.constData() + 14)); + ctMinRightBearing = bearing * fontDef.pixelSize / emSize; + } +} + +bool QCoreTextFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, + int *nglyphs, QTextEngine::ShaperFlags flags) const +{ + *nglyphs = len; + QCFType cfstring; + + QVarLengthArray cgGlyphs(len); + CTFontGetGlyphsForCharacters(ctfont, (const UniChar*)str, cgGlyphs.data(), len); + + for (int i = 0; i < len; ++i) + if (cgGlyphs[i]) + glyphs->glyphs[i] = cgGlyphs[i]; + + if (flags & QTextEngine::GlyphIndicesOnly) + return true; + + loadAdvancesForGlyphs(ctfont, cgGlyphs, glyphs, len, flags, fontDef); + return true; } glyph_metrics_t QCoreTextFontEngine::boundingBox(const QGlyphLayout &glyphs) @@ -407,6 +503,7 @@ glyph_metrics_t QCoreTextFontEngine::boundingBox(const QGlyphLayout &glyphs) } return glyph_metrics_t(0, -(ascent()), w - lastRightBearing(glyphs, round), ascent()+descent(), w, 0); } + glyph_metrics_t QCoreTextFontEngine::boundingBox(glyph_t glyph) { glyph_metrics_t ret; @@ -460,31 +557,29 @@ QFixed QCoreTextFontEngine::xHeight() const ? QFixed::fromReal(CTFontGetXHeight(ctfont)).round() : QFixed::fromReal(CTFontGetXHeight(ctfont)); } + QFixed QCoreTextFontEngine::averageCharWidth() const { - // ### Need to implement properly and get the information from the OS/2 Table. return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - ? QFontEngine::averageCharWidth().round() - : QFontEngine::averageCharWidth(); + ? avgCharWidth.round() : avgCharWidth; } qreal QCoreTextFontEngine::maxCharWidth() const { - // ### Max Help! - return 0; - + return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? qRound(ctMaxCharWidth) : ctMaxCharWidth; } + qreal QCoreTextFontEngine::minLeftBearing() const { - // ### Min Help! - return 0; - + return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? qRound(ctMinLeftBearing) : ctMinLeftBearing; } + qreal QCoreTextFontEngine::minRightBearing() const { - // ### Max Help! (even thought it's right) - return 0; - + return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? qRound(ctMinRightBearing) : ctMinLeftBearing; } void QCoreTextFontEngine::draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt &ti, int paintDeviceHeight) @@ -602,12 +697,6 @@ void QCoreTextFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *position } } -QFont QCoreTextFontEngine::createExplicitFont() const -{ - QString familyName = QCFString::toQString(CTFontCopyFamilyName(ctfont)); - return createExplicitFontWithName(familyName); -} - QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, int /*margin*/, bool aa) { const glyph_metrics_t br = boundingBox(glyph); @@ -624,7 +713,7 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition cgflags); CGContextSetFontSize(ctx, fontDef.pixelSize); CGContextSetShouldAntialias(ctx, aa || - (fontDef.pointSize > antialiasing_threshold + (fontDef.pointSize > qt_antialiasing_threshold && !(fontDef.styleStrategy & QFont::NoAntialias))); CGContextSetShouldSmoothFonts(ctx, aa); CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx); @@ -696,12 +785,19 @@ QImage QCoreTextFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed subPixelPo return im; } -void QCoreTextFontEngine::recalcAdvances(int numGlyphs, QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const +void QCoreTextFontEngine::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const { - Q_ASSERT(false); - Q_UNUSED(numGlyphs); - Q_UNUSED(glyphs); - Q_UNUSED(flags); + int i, numGlyphs = glyphs->numGlyphs; + QVarLengthArray cgGlyphs(numGlyphs); + + for (i = 0; i < numGlyphs; ++i) { + if (glyphs->glyphs[i] & 0xff000000) + cgGlyphs[i] = 0; + else + cgGlyphs[i] = glyphs->glyphs[i]; + } + + loadAdvancesForGlyphs(ctfont, cgGlyphs, glyphs, numGlyphs, flags, fontDef); } QFontEngine::FaceId QCoreTextFontEngine::faceId() const @@ -711,36 +807,36 @@ QFontEngine::FaceId QCoreTextFontEngine::faceId() const bool QCoreTextFontEngine::canRender(const QChar *string, int len) { - QCFType retFont = CTFontCreateForString(ctfont, - QCFType(CFStringCreateWithCharactersNoCopy(0, - reinterpret_cast(string), - len, kCFAllocatorNull)), - CFRangeMake(0, len)); - return retFont != 0; - return false; -} - - bool QCoreTextFontEngine::getSfntTableData(uint tag, uchar *buffer, uint *length) const - { - QCFType table = CTFontCopyTable(ctfont, tag, 0); - if (!table || !length) - return false; - CFIndex tableLength = CFDataGetLength(table); - int availableLength = *length; - *length = tableLength; - if (buffer) { - if (tableLength > availableLength) - return false; - CFDataGetBytes(table, CFRangeMake(0, tableLength), buffer); - } - return true; - } + QVarLengthArray cgGlyphs(len); + return CTFontGetGlyphsForCharacters(ctfont, (const UniChar *) string, cgGlyphs.data(), len); +} + +bool QCoreTextFontEngine::getSfntTableData(uint tag, uchar *buffer, uint *length) const +{ + QCFType table = CTFontCopyTable(ctfont, tag, 0); + if (!table || !length) + return false; + CFIndex tableLength = CFDataGetLength(table); + int availableLength = *length; + *length = tableLength; + if (buffer) { + if (tableLength > availableLength) + return false; + CFDataGetBytes(table, CFRangeMake(0, tableLength), buffer); + } + return true; +} void QCoreTextFontEngine::getUnscaledGlyph(glyph_t, QPainterPath *, glyph_metrics_t *) { // ### } +QFixed QCoreTextFontEngine::emSquareSize() const +{ + return QFixed::QFixed(int(CTFontGetUnitsPerEm(ctfont))); +} + QT_END_NAMESPACE #endif// !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) diff --git a/src/gui/text/qfontengine_coretext_p.h b/src/gui/text/qfontengine_coretext_p.h index 7d17aef..1503c3f 100644 --- a/src/gui/text/qfontengine_coretext_p.h +++ b/src/gui/text/qfontengine_coretext_p.h @@ -46,15 +46,17 @@ #if !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) +class QRawFontPrivate; class QCoreTextFontEngineMulti; class QCoreTextFontEngine : public QFontEngine { public: - QCoreTextFontEngine(CTFontRef font, const QFontDef &def, - QCoreTextFontEngineMulti *multiEngine = 0); + QCoreTextFontEngine(CTFontRef font, const QFontDef &def); + QCoreTextFontEngine(CGFontRef font, const QFontDef &def); ~QCoreTextFontEngine(); + virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const; - virtual void recalcAdvances(int , QGlyphLayout *, QTextEngine::ShaperFlags) const; + virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const; virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs); virtual glyph_metrics_t boundingBox(glyph_t glyph); @@ -87,23 +89,29 @@ public: virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t); virtual qreal minRightBearing() const; virtual qreal minLeftBearing() const; - virtual QFont createExplicitFont() const; + virtual QFixed emSquareSize() const; private: + friend class QRawFontPrivate; + + void init(); QImage imageForGlyph(glyph_t glyph, QFixed subPixelPosition, int margin, bool colorful); CTFontRef ctfont; CGFontRef cgFont; - QCoreTextFontEngineMulti *parentEngine; int synthesisFlags; CGAffineTransform transform; + QFixed avgCharWidth; + qreal ctMaxCharWidth; + qreal ctMinLeftBearing; + qreal ctMinRightBearing; friend class QCoreTextFontEngineMulti; - int antialiasing_threshold; }; class QCoreTextFontEngineMulti : public QFontEngineMulti { public: QCoreTextFontEngineMulti(const QCFString &name, const QFontDef &fontDef, bool kerning); + QCoreTextFontEngineMulti(CGFontRef cgFontRef, const QFontDef &fontDef, bool kerning); ~QCoreTextFontEngineMulti(); virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, @@ -112,19 +120,16 @@ public: QTextEngine::ShaperFlags flags, unsigned short *logClusters, const HB_CharAttributes *charAttributes) const; - - virtual void recalcAdvances(int , QGlyphLayout *, QTextEngine::ShaperFlags) const; - virtual void doKerning(int , QGlyphLayout *, QTextEngine::ShaperFlags) const; - virtual const char *name() const { return "CoreText"; } protected: virtual void loadEngine(int at); private: + void init(bool kerning); inline const QCoreTextFontEngine *engineAt(int i) const { return static_cast(engines.at(i)); } - uint fontIndexForFont(CTFontRef id) const; + uint fontIndexForFont(CTFontRef font) const; CTFontRef ctfont; mutable QCFType attributeDict; CGAffineTransform transform; diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index ffdaaa7..8f2da9b 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -200,9 +200,10 @@ HB_Error QFreetypeFace::getPointInOutline(HB_Glyph glyph, int flags, hb_uint32 p * Returns the freetype face or 0 in case of an empty file or any other problems * (like not being able to open the file) */ -QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id) +QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id, + const QByteArray &fontData) { - if (face_id.filename.isEmpty()) + if (face_id.filename.isEmpty() && fontData.isEmpty()) return 0; QtFreetypeData *freetypeData = qt_getFreetypeData(); @@ -215,21 +216,25 @@ QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id) } else { QScopedPointer newFreetype(new QFreetypeFace); FT_Face face; - QFile file(QString::fromUtf8(face_id.filename)); - if (face_id.filename.startsWith(":qmemoryfonts/")) { - // from qfontdatabase.cpp - extern QByteArray qt_fontdata_from_index(int); - QByteArray idx = face_id.filename; - idx.remove(0, 14); // remove ':qmemoryfonts/' - bool ok = false; - newFreetype->fontData = qt_fontdata_from_index(idx.toInt(&ok)); - if (!ok) - newFreetype->fontData = QByteArray(); - } else if (!(file.fileEngine()->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::LocalDiskFlag)) { - if (!file.open(QIODevice::ReadOnly)) { - return 0; + if (!face_id.filename.isEmpty()) { + QFile file(QString::fromUtf8(face_id.filename)); + if (face_id.filename.startsWith(":qmemoryfonts/")) { + // from qfontdatabase.cpp + extern QByteArray qt_fontdata_from_index(int); + QByteArray idx = face_id.filename; + idx.remove(0, 14); // remove ':qmemoryfonts/' + bool ok = false; + newFreetype->fontData = qt_fontdata_from_index(idx.toInt(&ok)); + if (!ok) + newFreetype->fontData = QByteArray(); + } else if (!(file.fileEngine()->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::LocalDiskFlag)) { + if (!file.open(QIODevice::ReadOnly)) { + return 0; + } + newFreetype->fontData = file.readAll(); } - newFreetype->fontData = file.readAll(); + } else { + newFreetype->fontData = fontData; } if (!newFreetype->fontData.isEmpty()) { if (FT_New_Memory_Face(freetypeData->library, (const FT_Byte *)newFreetype->fontData.constData(), newFreetype->fontData.size(), face_id.index, &face)) { @@ -651,8 +656,21 @@ void QFontEngineFT::freeGlyphSets() freeServerGlyphSet(transformedGlyphSets.at(i).id); } -bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format) +bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format, + const QByteArray &fontData) { + return init(faceId, antialias, format, QFreetypeFace::getFace(faceId, fontData)); +} + +bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format, + QFreetypeFace *freetypeFace) +{ + freetype = freetypeFace; + if (!freetype) { + xsize = 0; + ysize = 0; + return false; + } defaultFormat = format; this->antialias = antialias; @@ -664,12 +682,6 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format) glyphFormat = QFontEngineGlyphCache::Raster_RGBMask; face_id = faceId; - freetype = QFreetypeFace::getFace(face_id); - if (!freetype) { - xsize = 0; - ysize = 0; - return false; - } symbol = freetype->symbol_map != 0; PS_FontInfoRec psrec; @@ -791,6 +803,106 @@ int QFontEngineFT::loadFlags(QGlyphSet *set, GlyphFormat format, int flags, return load_flags; } +QFontEngineFT::Glyph *QFontEngineFT::loadGlyphMetrics(QGlyphSet *set, uint glyph, GlyphFormat format) const +{ + Glyph *g = set->getGlyph(glyph); + if (g && g->format == format) + return g; + + bool hsubpixel = false; + int vfactor = 1; + int load_flags = loadFlags(set, format, 0, hsubpixel, vfactor); + + // apply our matrix to this, but note that the metrics will not be affected by this. + FT_Face face = lockFace(); + FT_Matrix matrix = this->matrix; + FT_Matrix_Multiply(&set->transformationMatrix, &matrix); + FT_Set_Transform(face, &matrix, 0); + freetype->matrix = matrix; + + bool transform = matrix.xx != 0x10000 || matrix.yy != 0x10000 || matrix.xy != 0 || matrix.yx != 0; + if (transform) + load_flags |= FT_LOAD_NO_BITMAP; + + FT_Error err = FT_Load_Glyph(face, glyph, load_flags); + if (err && (load_flags & FT_LOAD_NO_BITMAP)) { + load_flags &= ~FT_LOAD_NO_BITMAP; + err = FT_Load_Glyph(face, glyph, load_flags); + } + if (err == FT_Err_Too_Few_Arguments) { + // this is an error in the bytecode interpreter, just try to run without it + load_flags |= FT_LOAD_FORCE_AUTOHINT; + err = FT_Load_Glyph(face, glyph, load_flags); + } + if (err != FT_Err_Ok) + qWarning("load glyph failed err=%x face=%p, glyph=%d", err, face, glyph); + + unlockFace(); + if (set->outline_drawing) + return 0; + + if (!g) { + g = new Glyph; + g->uploadedToServer = false; + g->data = 0; + } + + FT_GlyphSlot slot = face->glyph; + if (embolden) Q_FT_GLYPHSLOT_EMBOLDEN(slot); + int left = slot->metrics.horiBearingX; + int right = slot->metrics.horiBearingX + slot->metrics.width; + int top = slot->metrics.horiBearingY; + int bottom = slot->metrics.horiBearingY - slot->metrics.height; + if (transform && slot->format != FT_GLYPH_FORMAT_BITMAP) { // freetype doesn't apply the transformation on the metrics + int l, r, t, b; + FT_Vector vector; + vector.x = left; + vector.y = top; + FT_Vector_Transform(&vector, &matrix); + l = r = vector.x; + t = b = vector.y; + vector.x = right; + vector.y = top; + FT_Vector_Transform(&vector, &matrix); + if (l > vector.x) l = vector.x; + if (r < vector.x) r = vector.x; + if (t < vector.y) t = vector.y; + if (b > vector.y) b = vector.y; + vector.x = right; + vector.y = bottom; + FT_Vector_Transform(&vector, &matrix); + if (l > vector.x) l = vector.x; + if (r < vector.x) r = vector.x; + if (t < vector.y) t = vector.y; + if (b > vector.y) b = vector.y; + vector.x = left; + vector.y = bottom; + FT_Vector_Transform(&vector, &matrix); + if (l > vector.x) l = vector.x; + if (r < vector.x) r = vector.x; + if (t < vector.y) t = vector.y; + if (b > vector.y) b = vector.y; + left = l; + right = r; + top = t; + bottom = b; + } + left = FLOOR(left); + right = CEIL(right); + bottom = FLOOR(bottom); + top = CEIL(top); + + g->linearAdvance = face->glyph->linearHoriAdvance >> 10; + g->width = TRUNC(right-left); + g->height = TRUNC(top-bottom); + g->x = TRUNC(left); + g->y = TRUNC(top); + g->advance = TRUNC(ROUND(face->glyph->advance.x)); + g->format = Format_None; + + return g; +} + QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, QFixed subPixelPosition, GlyphFormat format, @@ -1511,7 +1623,7 @@ bool QFontEngineFT::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs mtx->lock(); } - if (FcCharSetHasChar(freetype->charset, uc)) { + if (freetype->charset != 0 && FcCharSetHasChar(freetype->charset, uc)) { #else if (false) { #endif @@ -1546,7 +1658,7 @@ bool QFontEngineFT::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs mtx->lock(); } - if (FcCharSetHasChar(freetype->charset, uc)) + if (freetype->charset == 0 || FcCharSetHasChar(freetype->charset, uc)) #endif { redo: diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h index 451d26e..887efed 100644 --- a/src/gui/text/qfontengine_ft_p.h +++ b/src/gui/text/qfontengine_ft_p.h @@ -74,6 +74,8 @@ QT_BEGIN_NAMESPACE +class QFontEngineFTRawFont; + /* * This struct represents one font file on disk (like Arial.ttf) and is shared between all the font engines * that show this font file (at different pixel sizes). @@ -84,7 +86,8 @@ struct QFreetypeFace QFontEngine::Properties properties() const; bool getSfntTable(uint tag, uchar *buffer, uint *length) const; - static QFreetypeFace *getFace(const QFontEngine::FaceId &face_id); + static QFreetypeFace *getFace(const QFontEngine::FaceId &face_id, + const QByteArray &fontData = QByteArray()); void release(const QFontEngine::FaceId &face_id); // locks the struct for usage. Any read/write operations require locking. @@ -119,6 +122,7 @@ struct QFreetypeFace static void addBitmapToPath(FT_GlyphSlot slot, const QFixedPoint &point, QPainterPath *path, bool = false); private: + friend class QFontEngineFTRawFont; friend class QScopedPointerDeleter; QFreetypeFace() : _lock(QMutex::Recursive) {} ~QFreetypeFace() {} @@ -300,7 +304,10 @@ private: QFontEngineFT(const QFontDef &fd); virtual ~QFontEngineFT(); - bool init(FaceId faceId, bool antiaalias, GlyphFormat defaultFormat = Format_None); + bool init(FaceId faceId, bool antiaalias, GlyphFormat defaultFormat = Format_None, + const QByteArray &fontData = QByteArray()); + bool init(FaceId faceId, bool antialias, GlyphFormat format, + QFreetypeFace *freetypeFace); virtual HB_Error getPointInOutline(HB_Glyph glyph, int flags, hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos, hb_uint32 *nPoints); @@ -312,6 +319,7 @@ private: }; void setDefaultHintStyle(HintStyle style); + HintStyle defaultHintStyle() const { return default_hint_style; } protected: void freeGlyphSets(); @@ -335,6 +343,9 @@ protected: bool embeddedbitmap; private: + friend class QFontEngineFTRawFont; + + QFontEngineFT::Glyph *loadGlyphMetrics(QGlyphSet *set, uint glyph, GlyphFormat format) const; int loadFlags(QGlyphSet *set, GlyphFormat format, int flags, bool &hsubpixel, int &vfactor) const; GlyphFormat defaultFormat; diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm index 7751bbe..673a7c8 100644 --- a/src/gui/text/qfontengine_mac.mm +++ b/src/gui/text/qfontengine_mac.mm @@ -922,27 +922,6 @@ static void addGlyphsToPathHelper(ATSUStyle style, glyph_t *glyphs, QFixedPoint DisposeATSCubicClosePathUPP(closePath); } -QFont QFontEngineMac::createExplicitFont() const -{ - FMFont fmFont = FMGetFontFromATSFontRef(fontID); - - FMFontFamily fmFamily; - FMFontStyle fmStyle; - QString familyName; - if (!FMGetFontFamilyInstanceFromFont(fmFont, &fmFamily, &fmStyle)) { - ATSFontFamilyRef familyRef = FMGetATSFontFamilyRefFromFontFamily(fmFamily); - QCFString cfFamilyName;; - ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &cfFamilyName); - familyName = cfFamilyName; - } else { - QCFString cfFontName; - ATSFontGetName(fontID, kATSOptionFlagsDefault, &cfFontName); - familyName = cfFontName; - } - - return createExplicitFontWithName(familyName); -} - void QFontEngineMac::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int numGlyphs, QPainterPath *path, QTextItem::RenderFlags) { diff --git a/src/gui/text/qfontengine_mac_p.h b/src/gui/text/qfontengine_mac_p.h index 6967348..385fa83 100644 --- a/src/gui/text/qfontengine_mac_p.h +++ b/src/gui/text/qfontengine_mac_p.h @@ -66,8 +66,6 @@ public: virtual qreal maxCharWidth() const; virtual QFixed averageCharWidth() const; - virtual QFont createExplicitFont() const; - virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int numGlyphs, QPainterPath *path, QTextItem::RenderFlags); diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index 7b29993..5b39fd3 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -185,9 +185,6 @@ public: virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs, QPainterPath *path, QTextItem::RenderFlags flags); - /* Creates a QFont object to represent this particular QFontEngine */ - virtual QFont createExplicitFont() const; - void getGlyphPositions(const QGlyphLayout &glyphs, const QTransform &matrix, QTextItem::RenderFlags flags, QVarLengthArray &glyphs_out, QVarLengthArray &positions); @@ -276,7 +273,6 @@ public: int glyphFormat; protected: - QFont createExplicitFontWithName(const QString &familyName) const; static const QVector &grayPalette(); QFixed lastRightBearing(const QGlyphLayout &glyphs, bool round = false); @@ -431,6 +427,7 @@ public: protected: friend class QPSPrintEnginePrivate; friend class QPSPrintEngineFontMulti; + friend class QRawFont; virtual void loadEngine(int at) = 0; QVector engines; }; diff --git a/src/gui/text/qfontengine_x11_p.h b/src/gui/text/qfontengine_x11_p.h index 2a4a9cd..ad68fac 100644 --- a/src/gui/text/qfontengine_x11_p.h +++ b/src/gui/text/qfontengine_x11_p.h @@ -157,6 +157,7 @@ private: class Q_GUI_EXPORT QFontEngineX11FT : public QFontEngineFT { public: + explicit QFontEngineX11FT(const QFontDef &fontDef) : QFontEngineFT(fontDef) {} explicit QFontEngineX11FT(FcPattern *pattern, const QFontDef &fd, int screen); ~QFontEngineX11FT(); diff --git a/src/gui/text/qfontenginedirectwrite.cpp b/src/gui/text/qfontenginedirectwrite.cpp index af5bab2..f0a3644 100644 --- a/src/gui/text/qfontenginedirectwrite.cpp +++ b/src/gui/text/qfontenginedirectwrite.cpp @@ -170,17 +170,12 @@ namespace { } -QFontEngineDirectWrite::QFontEngineDirectWrite(const QString &name, - IDWriteFactory *directWriteFactory, - IDWriteGdiInterop *directWriteGdiInterop, - IDWriteFont *directWriteFont, +QFontEngineDirectWrite::QFontEngineDirectWrite(IDWriteFactory *directWriteFactory, + IDWriteFontFace *directWriteFontFace, qreal pixelSize) - : m_name(name) - , m_directWriteFont(directWriteFont) - , m_directWriteFontFace(0) + : m_directWriteFontFace(directWriteFontFace) , m_directWriteFactory(directWriteFactory) , m_directWriteBitmapRenderTarget(0) - , m_directWriteGdiInterop(directWriteGdiInterop) , m_lineThickness(-1) , m_unitsPerEm(-1) , m_ascent(-1) @@ -188,24 +183,17 @@ QFontEngineDirectWrite::QFontEngineDirectWrite(const QString &name, , m_xHeight(-1) , m_lineGap(-1) { - m_directWriteFont->AddRef(); m_directWriteFactory->AddRef(); - m_directWriteGdiInterop->AddRef(); + m_directWriteFontFace->AddRef(); fontDef.pixelSize = pixelSize; - - HRESULT hr = m_directWriteFont->CreateFontFace(&m_directWriteFontFace); - if (FAILED(hr)) - qErrnoWarning("QFontEngineDirectWrite: CreateFontFace failed"); - collectMetrics(); } QFontEngineDirectWrite::~QFontEngineDirectWrite() { - m_directWriteFont->Release(); m_directWriteFactory->Release(); - m_directWriteGdiInterop->Release(); + m_directWriteFontFace->Release(); if (m_directWriteBitmapRenderTarget != 0) m_directWriteBitmapRenderTarget->Release(); @@ -213,10 +201,10 @@ QFontEngineDirectWrite::~QFontEngineDirectWrite() void QFontEngineDirectWrite::collectMetrics() { - if (m_directWriteFont != 0) { + if (m_directWriteFontFace != 0) { DWRITE_FONT_METRICS metrics; - m_directWriteFont->GetMetrics(&metrics); + m_directWriteFontFace->GetMetrics(&metrics); m_unitsPerEm = metrics.designUnitsPerEm; m_lineThickness = DESIGN_TO_LOGICAL(metrics.underlineThickness); @@ -616,19 +604,25 @@ const char *QFontEngineDirectWrite::name() const bool QFontEngineDirectWrite::canRender(const QChar *string, int len) { - for (int i=0; iHasCharacter(codePoint, &exists); - if (FAILED(hr)) { - qErrnoWarning("QFontEngineDirectWrite::canRender: HasCharacter failed"); - return false; - } else if (!exists) { - return false; + QVarLengthArray codePoints(len); + int actualLength = 0; + for (int i=0; i glyphIndices(actualLength); + HRESULT hr = m_directWriteFontFace->GetGlyphIndices(codePoints.data(), actualLength, + glyphIndices.data()); + if (FAILED(hr)) { + qErrnoWarning(hr, "QFontEngineDirectWrite::canRender: GetGlyphIndices failed"); + return false; + } else { + for (int i=0; iglyphIndexes == other.d->glyphIndexes && d->glyphPositions == other.d->glyphPositions + && d->overline == other.d->overline + && d->underline == other.d->underline + && d->strikeOut == other.d->strikeOut && d->font == other.d->font)); } @@ -171,18 +184,17 @@ QGlyphs &QGlyphs::operator+=(const QGlyphs &other) \sa setFont() */ -QFont QGlyphs::font() const +QRawFont QGlyphs::font() const { return d->font; } /*! - Sets the font in which to look up the glyph indexes to \a font. This must be an explicitly - resolvable font which defines glyphs for the specified glyph indexes. + Sets the font in which to look up the glyph indexes to \a font. \sa font(), setGlyphIndexes() */ -void QGlyphs::setFont(const QFont &font) +void QGlyphs::setFont(const QRawFont &font) { detach(); d->font = font; @@ -234,7 +246,78 @@ void QGlyphs::clear() detach(); d->glyphPositions = QVector(); d->glyphIndexes = QVector(); - d->font = QFont(); + d->font = QRawFont(); + d->strikeOut = false; + d->overline = false; + d->underline = false; +} + +/*! + Returns true if this QGlyphs should be painted with an overline decoration. + + \sa setOverline() +*/ +bool QGlyphs::overline() const +{ + return d->overline; +} + +/*! + Indicates that this QGlyphs should be painted with an overline decoration if \a overline is true. + Otherwise the QGlyphs should be painted with no overline decoration. + + \sa overline() +*/ +void QGlyphs::setOverline(bool overline) +{ + detach(); + d->overline = overline; +} + +/*! + Returns true if this QGlyphs should be painted with an underline decoration. + + \sa setUnderline() +*/ +bool QGlyphs::underline() const +{ + return d->underline; +} + +/*! + Indicates that this QGlyphs should be painted with an underline decoration if \a underline is + true. Otherwise the QGlyphs should be painted with no underline decoration. + + \sa underline() +*/ +void QGlyphs::setUnderline(bool underline) +{ + detach(); + d->underline = underline; +} + +/*! + Returns true if this QGlyphs should be painted with a strike out decoration. + + \sa setStrikeOut() +*/ +bool QGlyphs::strikeOut() const +{ + return d->strikeOut; +} + +/*! + Indicates that this QGlyphs should be painted with an strike out decoration if \a strikeOut is + true. Otherwise the QGlyphs should be painted with no strike out decoration. + + \sa strikeOut() +*/ +void QGlyphs::setStrikeOut(bool strikeOut) +{ + detach(); + d->strikeOut = strikeOut; } QT_END_NAMESPACE + +#endif // QT_NO_RAWFONT diff --git a/src/gui/text/qglyphs.h b/src/gui/text/qglyphs.h index 5f37136..4d7dcaf 100644 --- a/src/gui/text/qglyphs.h +++ b/src/gui/text/qglyphs.h @@ -45,7 +45,9 @@ #include #include #include -#include +#include + +#if !defined(QT_NO_RAWFONT) QT_BEGIN_HEADER @@ -61,8 +63,8 @@ public: QGlyphs(const QGlyphs &other); ~QGlyphs(); - QFont font() const; - void setFont(const QFont &font); + QRawFont font() const; + void setFont(const QRawFont &font); QVector glyphIndexes() const; void setGlyphIndexes(const QVector &glyphIndexes); @@ -76,6 +78,15 @@ public: bool operator==(const QGlyphs &other) const; bool operator!=(const QGlyphs &other) const; + void setOverline(bool overline); + bool overline() const; + + void setUnderline(bool underline); + bool underline() const; + + void setStrikeOut(bool strikeOut); + bool strikeOut() const; + private: friend class QGlyphsPrivate; friend class QTextLine; @@ -85,12 +96,12 @@ private: void detach(); QExplicitlySharedDataPointer d; - }; QT_END_NAMESPACE QT_END_HEADER +#endif // QT_NO_RAWFONT #endif // QGLYPHS_H diff --git a/src/gui/text/qglyphs_p.h b/src/gui/text/qglyphs_p.h index c632e2f..944f777 100644 --- a/src/gui/text/qglyphs_p.h +++ b/src/gui/text/qglyphs_p.h @@ -53,8 +53,12 @@ // We mean it. // -#include #include "qglyphs.h" +#include "qrawfont.h" + +#include + +#if !defined(QT_NO_RAWFONT) QT_BEGIN_HEADER @@ -64,17 +68,30 @@ class QGlyphsPrivate: public QSharedData { public: QGlyphsPrivate() + : overline(false) + , underline(false) + , strikeOut(false) { } QGlyphsPrivate(const QGlyphsPrivate &other) - : QSharedData(other), glyphIndexes(other.glyphIndexes), glyphPositions(other.glyphPositions), font(other.font) + : QSharedData(other) + , glyphIndexes(other.glyphIndexes) + , glyphPositions(other.glyphPositions) + , font(other.font) + , overline(other.overline) + , underline(other.underline) + , strikeOut(other.strikeOut) { } QVector glyphIndexes; QVector glyphPositions; - QFont font; + QRawFont font; + + uint overline : 1; + uint underline : 1; + uint strikeOut : 1; }; QT_END_NAMESPACE @@ -82,3 +99,5 @@ QT_END_NAMESPACE QT_END_HEADER #endif // QGLYPHS_P_H + +#endif // QT_NO_RAWFONT diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp new file mode 100644 index 0000000..4a715c2 --- /dev/null +++ b/src/gui/text/qrawfont.cpp @@ -0,0 +1,612 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** 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:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qglobal.h" + +#if !defined(QT_NO_RAWFONT) + +#include "qrawfont.h" +#include "qrawfont_p.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +/*! + \class QRawFont + \brief The QRawFont class provides access to a single physical instance of a font. + \since 4.8 + + \ingroup text + \mainclass + + \note QRawFont is a low level class. For most purposes QFont is a more appropriate class. + + Most commonly, when presenting text in a user interface, the exact fonts used + to render the characters is to some extent unknown. This can be the case for several + reasons: For instance, the actual, physical fonts present on the target system could be + unexpected to the developers, or the text could contain user selected styles, sizes or + writing systems that are not supported by font chosen in the code. + + Therefore, Qt's QFont class really represents a query for fonts. When text is interpreted, + Qt will do its best to match the text to the query, but depending on the support, different + fonts can be used behind the scenes. + + For most use cases, this is both expected and necessary, as it minimizes the possibility of + text in the user interface being undisplayable. In some cases, however, more direct control + over the process might be useful. It is for these use cases the QRawFont class exists. + + A QRawFont object represents a single, physical instance of a given font in a given pixel size. + I.e. in the typical case it represents a set of TrueType or OpenType font tables and uses a + user specified pixel size to convert metrics into logical pixel units. In can be used in + combination with the QGlyphs class to draw specific glyph indexes at specific positions, and + also have accessors to some relevant data in the physical font. + + QRawFont only provides support for the main font technologies: GDI and DirectWrite on Windows + platforms, FreeType on Symbian and Linux platforms and CoreText on Mac OS X. For other + font back-ends, the APIs will be disabled. + + QRawFont can be constructed in a number of ways: + \list + \o \l It can be constructed by calling QTextLayout::glyphs() or QTextFragment::glyphs(). The + returned QGlyphs objects will contain QRawFont objects which represent the actual fonts + used to render each portion of the text. + \o \l It can be constructed by passing a QFont object to QRawFont::fromFont(). The function + will return a QRawFont object representing the font that will be selected as response to + the QFont query and the selected writing system. + \o \l It can be constructed by passing a file name or QByteArray directly to the QRawFont + constructor, or by calling loadFromFile() or loadFromData(). In this case, the + font will not be registered in QFontDatabase, and it will not be available as part of + regular font selection. + \endlist + + QRawFont is considered local to the thread in which it is constructed (either using a + constructor, or by calling loadFromData() or loadFromFile()). The QRawFont cannot be moved to a + different thread, but will have to be recreated in the thread in question. + + \note For the requirement of caching glyph indexes and font selections for static text to avoid + reshaping and relayouting in the inner loop of an application, a better choice is the QStaticText + class, since it optimizes the memory cost of the cache and also provides the possibility of paint + engine specific caches for an additional speed-up. +*/ + +/*! + \enum QRawFont::AntialiasingType + + This enum represents the different ways a glyph can be rasterized in the function + alphaMapForGlyph(). + + \value PixelAntialiasing Will rasterize by measuring the coverage of the shape on whole pixels. + The returned image contains the alpha values of each pixel based on the coverage of + the glyph shape. + \value SubPixelAntialiasing Will rasterize by measuring the coverage of each subpixel, + returning a separate alpha value for each of the red, green and blue components of + each pixel. +*/ + +/*! + Constructs an invalid QRawFont. +*/ +QRawFont::QRawFont() + : d(new QRawFontPrivate) +{ +} + +/*! + Constructs a QRawFont representing the font contained in the file referenced by \a fileName, + with \a pixelSize size in pixels, and the selected \a hintingPreference. + + \note The referenced file must contain a TrueType or OpenType font. +*/ +QRawFont::QRawFont(const QString &fileName, + int pixelSize, + QFont::HintingPreference hintingPreference) + : d(new QRawFontPrivate) +{ + loadFromFile(fileName, pixelSize, hintingPreference); +} + +/*! + Constructs a QRawFont representing the font contained in \a fontData. + + \note The data must contain a TrueType or OpenType font. +*/ +QRawFont::QRawFont(const QByteArray &fontData, + int pixelSize, + QFont::HintingPreference hintingPreference) + : d(new QRawFontPrivate) +{ + loadFromData(fontData, pixelSize, hintingPreference); +} + +/*! + Creates a QRawFont which is a copy of \a other. +*/ +QRawFont::QRawFont(const QRawFont &other) +{ + d = other.d; +} + +/*! + Destroys the QRawFont +*/ +QRawFont::~QRawFont() +{ +} + +/*! + Assigns \a other to this QRawFont. +*/ +QRawFont &QRawFont::operator=(const QRawFont &other) +{ + d = other.d; + return *this; +} + +/*! + Returns true if the QRawFont is valid and false otherwise. +*/ +bool QRawFont::isValid() const +{ + Q_ASSERT(d->thread == 0 || d->thread == QThread::currentThread()); + return d->fontEngine != 0; +} + +/*! + Replaces the current QRawFont with the contents of the file references by \a fileName. + + The file must reference a TrueType or OpenType font. + + \sa loadFromData() +*/ +void QRawFont::loadFromFile(const QString &fileName, + int pixelSize, + QFont::HintingPreference hintingPreference) +{ + QFile file(fileName); + if (file.open(QIODevice::ReadOnly)) + loadFromData(file.readAll(), pixelSize, hintingPreference); +} + +/*! + Replaces the current QRawFont with the contents of \a fontData. + + The \a fontData must contain a TrueType or OpenType font. + + \sa loadFromFile() +*/ +void QRawFont::loadFromData(const QByteArray &fontData, + int pixelSize, + QFont::HintingPreference hintingPreference) +{ + detach(); + d->cleanUp(); + d->hintingPreference = hintingPreference; + d->thread = QThread::currentThread(); + d->platformLoadFromData(fontData, pixelSize, hintingPreference); +} + +/*! + This function returns a rasterized image of the glyph at a given \a glyphIndex in the underlying + font, if the QRawFont is valid, otherwise it will return an invalid QImage. + + If \a antialiasingType is set to QRawFont::SubPixelAntialiasing, then the resulting image will be + in QImage::Format_RGB32 and the RGB values of each pixel will represent the subpixel opacities of + the pixel in the rasterization of the glyph. Otherwise, the image will be in the format of + QImage::Format_A8 and each pixel will contain the opacity of the pixel in the rasterization. + + \sa pathForGlyph(), QPainter::drawGlyphs() +*/ +QImage QRawFont::alphaMapForGlyph(quint32 glyphIndex, AntialiasingType antialiasingType, + const QTransform &transform) const +{ + if (!isValid()) + return QImage(); + + if (antialiasingType == SubPixelAntialiasing) + return d->fontEngine->alphaRGBMapForGlyph(glyphIndex, QFixed(), 0, transform); + else + return d->fontEngine->alphaMapForGlyph(glyphIndex, QFixed(), transform); +} + +/*! + This function returns the shape of the glyph at a given \a glyphIndex in the underlying font + if the QRawFont is valid. Otherwise, it returns an empty QPainterPath. + + The returned glyph will always be unhinted. + + \sa alphaMapForGlyph(), QPainterPath::addText() +*/ +QPainterPath QRawFont::pathForGlyph(quint32 glyphIndex) const +{ + if (!isValid()) + return QPainterPath(); + + QFixedPoint position; + QPainterPath path; + d->fontEngine->addGlyphsToPath(&glyphIndex, &position, 1, &path, 0); + return path; +} + +/*! + Returns true if this QRawFont is equal to \a other. Otherwise, returns false. +*/ +bool QRawFont::operator==(const QRawFont &other) const +{ + return d->fontEngine == other.d->fontEngine; +} + +/*! + Returns the ascent of this QRawFont in pixel units. + + \sa QFontMetricsF::ascent() +*/ +qreal QRawFont::ascent() const +{ + if (!isValid()) + return 0.0; + + return d->fontEngine->ascent().toReal(); +} + +/*! + Returns the descent of this QRawFont in pixel units. + + \sa QFontMetricsF::descent() +*/ +qreal QRawFont::descent() const +{ + if (!isValid()) + return 0.0; + + return d->fontEngine->descent().toReal(); +} + +/*! + Returns the pixel size set for this QRawFont. The pixel size affects how glyphs are + rasterized, the size of glyphs returned by pathForGlyph(), and is used to convert + internal metrics from design units to logical pixel units. + + \sa setPixelSize() +*/ +int QRawFont::pixelSize() const +{ + if (!isValid()) + return -1; + + return d->fontEngine->fontDef.pixelSize; +} + +/*! + Returns the number of design units define the width and height of the em square + for this QRawFont. This value is used together with the pixel size when converting design metrics + to pixel units, as the internal metrics are specified in design units and the pixel size gives + the size of 1 em in pixels. + + \sa pixelSize(), setPixelSize() +*/ +qreal QRawFont::unitsPerEm() const +{ + if (!isValid()) + return 0.0; + + return d->fontEngine->emSquareSize().toReal(); +} + +/*! + Returns the family name of this QRawFont. +*/ +QString QRawFont::familyName() const +{ + if (!isValid()) + return QString(); + + return d->fontEngine->fontDef.family; +} + +/*! + Returns the style of this QRawFont. + + \sa QFont::style() +*/ +QFont::Style QRawFont::style() const +{ + if (!isValid()) + return QFont::StyleNormal; + + return QFont::Style(d->fontEngine->fontDef.style); +} + +/*! + Returns the weight of this QRawFont. + + \sa QFont::weight() +*/ +int QRawFont::weight() const +{ + if (!isValid()) + return -1; + + return int(d->fontEngine->fontDef.weight); +} + +/*! + Converts a string of unicode points to glyph indexes using the CMAP table in the + underlying font. Note that in cases where there are other tables in the font that affect the + shaping of the text, the returned glyph indexes will not correctly represent the rendering + of the text. To get the correctly shaped text, you can use QTextLayout to lay out and shape the + text, and then call QTextLayout::glyphs() to get the set of glyph index list and QRawFont pairs. + + \sa advancesForGlyphIndexes(), QGlyphs, QTextLayout::glyphs(), QTextFragment::glyphs() +*/ +QVector QRawFont::glyphIndexesForString(const QString &text) const +{ + if (!isValid()) + return QVector(); + + int nglyphs = text.size(); + QVarLengthGlyphLayoutArray glyphs(nglyphs); + if (!d->fontEngine->stringToCMap(text.data(), text.size(), &glyphs, &nglyphs, + QTextEngine::GlyphIndicesOnly)) { + glyphs.resize(nglyphs); + if (!d->fontEngine->stringToCMap(text.data(), text.size(), &glyphs, &nglyphs, + QTextEngine::GlyphIndicesOnly)) { + Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice"); + return QVector(); + } + } + + QVector glyphIndexes; + for (int i=0; i QRawFont::advancesForGlyphIndexes(const QVector &glyphIndexes) const +{ + if (!isValid()) + return QVector(); + + int numGlyphs = glyphIndexes.size(); + QVarLengthGlyphLayoutArray glyphs(numGlyphs); + qMemCopy(glyphs.glyphs, glyphIndexes.data(), numGlyphs * sizeof(quint32)); + + d->fontEngine->recalcAdvances(&glyphs, 0); + + QVector advances; + for (int i=0; ihintingPreference; +} + +/*! + Retrieves the sfnt table named \a tagName from the underlying physical font, or an empty + byte array if no such table was found. The returned font table's byte order is Big Endian, like + the sfnt format specifies. The \a tagName must be four characters long and should be formatted + in the default endianness of the current platform. +*/ +QByteArray QRawFont::fontTable(const char *tagName) const +{ + if (!isValid()) + return QByteArray(); + + const quint32 *tagId = reinterpret_cast(tagName); + return d->fontEngine->getSfntTable(qToBigEndian(*tagId)); +} + +// From qfontdatabase.cpp +extern QList qt_determine_writing_systems_from_truetype_bits(quint32 unicodeRange[4], quint32 codePageRange[2]); + +/*! + Returns a list of writing systems supported by the font according to designer supplied + information in the font file. Please note that this does not guarantee support for a + specific unicode point in the font. You can use the supportsCharacter() to check support + for a single, specific character. + + \note The list is determined based on the unicode ranges and codepage ranges set in the font's + OS/2 table and requires such a table to be present in the underlying font file. + + \sa supportsCharacter() +*/ +QList QRawFont::supportedWritingSystems() const +{ + if (isValid()) { + QByteArray os2Table = fontTable("OS/2"); + if (!os2Table.isEmpty() && os2Table.size() > 86) { + char *data = os2Table.data(); + quint32 *bigEndianUnicodeRanges = reinterpret_cast(data + 42); + quint32 *bigEndianCodepageRanges = reinterpret_cast(data + 78); + + quint32 unicodeRanges[4]; + quint32 codepageRanges[2]; + + for (int i=0; i<4; ++i) { + if (i < 2) + codepageRanges[i] = qFromBigEndian(bigEndianCodepageRanges[i]); + unicodeRanges[i] = qFromBigEndian(bigEndianUnicodeRanges[i]); + } + + return qt_determine_writing_systems_from_truetype_bits(unicodeRanges, codepageRanges); + } + } + + return QList(); +} + +/*! + Returns true if the font has a glyph that corresponds to the given \a character. + + \sa supportedWritingSystems() +*/ +bool QRawFont::supportsCharacter(const QChar &character) const +{ + if (!isValid()) + return false; + + return d->fontEngine->canRender(&character, 1); +} + +/*! + Returns true if the font has a glyph that corresponds to the UCS-4 encoded character \a ucs4. + + \sa supportedWritingSystems() +*/ +bool QRawFont::supportsCharacter(quint32 ucs4) const +{ + if (!isValid()) + return false; + + QString str = QString::fromUcs4(&ucs4, 1); + return d->fontEngine->canRender(str.constData(), str.size()); +} + +// qfontdatabase.cpp +extern int qt_script_for_writing_system(QFontDatabase::WritingSystem writingSystem); + +/*! + Fetches the physical representation based on a \a font query. The physical font returned is + the font that will be preferred by Qt in order to display text in the selected \a writingSystem. +*/ +QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writingSystem) +{ +#if defined(Q_WS_MAC) + QTextLayout layout(QFontDatabase::writingSystemSample(writingSystem), font); + layout.beginLayout(); + QTextLine line = layout.createLine(); + layout.endLayout(); + QList list = layout.glyphs(); + if (list.size()) { + // Pick the one matches the family name we originally requested, + // if none of them match, just pick the first one + for (int i = 0; i < list.size(); i++) { + QGlyphs glyphs = list.at(i); + QRawFont rawfont = glyphs.font(); + if (rawfont.familyName() == font.family()) + return rawfont; + } + return list.at(0).font(); + } + return QRawFont(); +#else + QFontPrivate *font_d = QFontPrivate::get(font); + int script = qt_script_for_writing_system(writingSystem); + QFontEngine *fe = font_d->engineForScript(script); + + if (fe != 0 && fe->type() == QFontEngine::Multi) { + QFontEngineMulti *multiEngine = static_cast(fe); + fe = multiEngine->engine(0); + if (fe == 0) { + multiEngine->loadEngine(0); + fe = multiEngine->engine(0); + } + } + + if (fe != 0) { + QRawFont rawFont; + rawFont.d.data()->fontEngine = fe; + rawFont.d.data()->fontEngine->ref.ref(); + rawFont.d.data()->hintingPreference = font.hintingPreference(); + return rawFont; + } else { + return QRawFont(); + } +#endif +} + +/*! + Sets the pixel size with which this font should be rendered to \a pixelSize. +*/ +void QRawFont::setPixelSize(int pixelSize) +{ + detach(); + d->platformSetPixelSize(pixelSize); +} + +/*! + \internal +*/ +void QRawFont::detach() +{ + if (d->ref != 1) + d.detach(); +} + +/*! + \internal +*/ +void QRawFontPrivate::cleanUp() +{ + platformCleanUp(); + if (fontEngine != 0) { + fontEngine->ref.deref(); + if (fontEngine->cache_count == 0 && fontEngine->ref == 0) + delete fontEngine; + fontEngine = 0; + } + hintingPreference = QFont::PreferDefaultHinting; +} + +#endif // QT_NO_RAWFONT + +QT_END_NAMESPACE diff --git a/src/gui/text/qrawfont.h b/src/gui/text/qrawfont.h new file mode 100644 index 0000000..96dc838 --- /dev/null +++ b/src/gui/text/qrawfont.h @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** 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:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QRAWFONT_H +#define QRAWFONT_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(QT_NO_RAWFONT) + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +class QRawFontPrivate; +class Q_GUI_EXPORT QRawFont +{ +public: + enum AntialiasingType { + PixelAntialiasing, + SubPixelAntialiasing + }; + + QRawFont(); + QRawFont(const QString &fileName, + int pixelSize, + QFont::HintingPreference hintingPreference = QFont::PreferDefaultHinting); + QRawFont(const QByteArray &fontData, + int pixelSize, + QFont::HintingPreference hintingPreference = QFont::PreferDefaultHinting); + QRawFont(const QRawFont &other); + ~QRawFont(); + + bool isValid() const; + + QRawFont &operator=(const QRawFont &other); + bool operator==(const QRawFont &other) const; + + QString familyName() const; + + QFont::Style style() const; + int weight() const; + + QVector glyphIndexesForString(const QString &text) const; + QVector advancesForGlyphIndexes(const QVector &glyphIndexes) const; + + QImage alphaMapForGlyph(quint32 glyphIndex, + AntialiasingType antialiasingType = SubPixelAntialiasing, + const QTransform &transform = QTransform()) const; + QPainterPath pathForGlyph(quint32 glyphIndex) const; + + void setPixelSize(int pixelSize); + int pixelSize() const; + + QFont::HintingPreference hintingPreference() const; + + qreal ascent() const; + qreal descent() const; + + qreal unitsPerEm() const; + + void loadFromFile(const QString &fileName, + int pixelSize, + QFont::HintingPreference hintingPreference); + + void loadFromData(const QByteArray &fontData, + int pixelSize, + QFont::HintingPreference hintingPreference); + + bool supportsCharacter(quint32 ucs4) const; + bool supportsCharacter(const QChar &character) const; + QList supportedWritingSystems() const; + + QByteArray fontTable(const char *tagName) const; + + static QRawFont fromFont(const QFont &font, + QFontDatabase::WritingSystem writingSystem = QFontDatabase::Any); + +private: + friend class QRawFontPrivate; + + void detach(); + + QExplicitlySharedDataPointer d; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QT_NO_RAWFONT + +#endif // QRAWFONT_H diff --git a/src/gui/text/qrawfont_ft.cpp b/src/gui/text/qrawfont_ft.cpp new file mode 100644 index 0000000..eefbd92 --- /dev/null +++ b/src/gui/text/qrawfont_ft.cpp @@ -0,0 +1,189 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** 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:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#if !defined(QT_NO_RAWFONT) + +#include "qrawfont_p.h" +#include "qfontengine_ft_p.h" + +#if defined(Q_WS_X11) +# include "qfontengine_x11_p.h" +#endif + +QT_BEGIN_NAMESPACE + +class QFontEngineFTRawFont + +#if defined(Q_WS_X11) + : public QFontEngineX11FT +#else + : public QFontEngineFT +#endif + +{ +public: + QFontEngineFTRawFont(const QFontDef &fontDef) +#if defined(Q_WS_X11) + : QFontEngineX11FT(fontDef) +#else + : QFontEngineFT(fontDef) +#endif + { + } + + void updateFamilyNameAndStyle() + { + fontDef.family = QString::fromAscii(freetype->face->family_name); + + if (freetype->face->style_flags & FT_STYLE_FLAG_ITALIC) + fontDef.style = QFont::StyleItalic; + + if (freetype->face->style_flags & FT_STYLE_FLAG_BOLD) + fontDef.weight = QFont::Bold; + } + + bool initFromData(const QByteArray &fontData) + { + FaceId faceId; + faceId.filename = ""; + faceId.index = 0; + + return init(faceId, true, Format_None, fontData); + } + + bool initFromFontEngine(QFontEngine *oldFontEngine) + { + QFontEngineFT *fe = static_cast(oldFontEngine); + + // Increase the reference of this QFreetypeFace since one more QFontEngineFT + // will be using it + fe->freetype->ref.ref(); + if (!init(fe->faceId(), fe->antialias, fe->defaultFormat, fe->freetype)) + return false; + + default_load_flags = fe->default_load_flags; + default_hint_style = fe->default_hint_style; + antialias = fe->antialias; + transform = fe->transform; + embolden = fe->embolden; + subpixelType = fe->subpixelType; + lcdFilterType = fe->lcdFilterType; + canUploadGlyphsToServer = fe->canUploadGlyphsToServer; + embeddedbitmap = fe->embeddedbitmap; + +#if defined(Q_WS_X11) + xglyph_format = static_cast(fe)->xglyph_format; +#endif + return true; + } +}; + + +void QRawFontPrivate::platformCleanUp() +{ + // Font engine handles all resources +} + +void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, int pixelSize, + QFont::HintingPreference hintingPreference) +{ + Q_ASSERT(fontEngine == 0); + + QFontDef fontDef; + fontDef.pixelSize = pixelSize; + + QFontEngineFTRawFont *fe = new QFontEngineFTRawFont(fontDef); + if (!fe->initFromData(fontData)) { + delete fe; + return; + } + + fe->updateFamilyNameAndStyle(); + + switch (hintingPreference) { + case QFont::PreferNoHinting: + fe->setDefaultHintStyle(QFontEngineFT::HintNone); + break; + case QFont::PreferFullHinting: + fe->setDefaultHintStyle(QFontEngineFT::HintFull); + break; + case QFont::PreferVerticalHinting: + fe->setDefaultHintStyle(QFontEngineFT::HintLight); + break; + default: + // Leave it as it is + break; + } + + fontEngine = fe; + fontEngine->ref.ref(); +} + +void QRawFontPrivate::platformSetPixelSize(int pixelSize) +{ + if (fontEngine == NULL) + return; + + QFontEngine *oldFontEngine = fontEngine; + + QFontDef fontDef; + fontDef.pixelSize = pixelSize; + QFontEngineFTRawFont *fe = new QFontEngineFTRawFont(fontDef); + if (!fe->initFromFontEngine(oldFontEngine)) { + delete fe; + return; + } + + fontEngine = fe; + fontEngine->fontDef = oldFontEngine->fontDef; + fontEngine->fontDef.pixelSize = pixelSize; + fontEngine->ref.ref(); + Q_ASSERT(fontEngine != oldFontEngine); + oldFontEngine->ref.deref(); + if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0) + delete oldFontEngine; +} + +QT_END_NAMESPACE + +#endif // QT_NO_RAWFONT diff --git a/src/gui/text/qrawfont_mac.cpp b/src/gui/text/qrawfont_mac.cpp new file mode 100644 index 0000000..56005c6 --- /dev/null +++ b/src/gui/text/qrawfont_mac.cpp @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#if !defined(QT_NO_RAWFONT) + +#include "qrawfont_p.h" +#include "qfontengine_coretext_p.h" + +QT_BEGIN_NAMESPACE + +void QRawFontPrivate::platformCleanUp() +{ +} + +extern int qt_defaultDpi(); + +void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, + int pixelSize, + QFont::HintingPreference hintingPreference) +{ + // Mac OS X ignores it + Q_UNUSED(hintingPreference); + + QCFType dataProvider = CGDataProviderCreateWithData(NULL, + fontData.constData(), fontData.size(), NULL); + + CGFontRef cgFont = CGFontCreateWithDataProvider(dataProvider); + + if (cgFont == NULL) { + qWarning("QRawFont::platformLoadFromData: CGFontCreateWithDataProvider failed"); + } else { + QFontDef def; + def.pixelSize = pixelSize; + def.pointSize = pixelSize * 72.0 / qt_defaultDpi(); + fontEngine = new QCoreTextFontEngine(cgFont, def); + CFRelease(cgFont); + fontEngine->ref.ref(); + } +} + +void QRawFontPrivate::platformSetPixelSize(int pixelSize) +{ + if (fontEngine == NULL) + return; + + QFontEngine *oldFontEngine = fontEngine; + + QFontDef fontDef = oldFontEngine->fontDef; + fontDef.pixelSize = pixelSize; + fontDef.pointSize = pixelSize * 72.0 / qt_defaultDpi(); + + QCoreTextFontEngine *ctFontEngine = static_cast(oldFontEngine); + Q_ASSERT(ctFontEngine->cgFont); + + fontEngine = new QCoreTextFontEngine(ctFontEngine->cgFont, fontDef); + fontEngine->ref.ref(); + Q_ASSERT(fontEngine != oldFontEngine); + oldFontEngine->ref.deref(); + if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0) + delete oldFontEngine; +} + +QT_END_NAMESPACE + +#endif // QT_NO_RAWFONT diff --git a/src/gui/text/qrawfont_p.h b/src/gui/text/qrawfont_p.h new file mode 100644 index 0000000..f9a9ab5 --- /dev/null +++ b/src/gui/text/qrawfont_p.h @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** 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:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QRAWFONTPRIVATE_P_H +#define QRAWFONTPRIVATE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qrawfont.h" +#include "qfontengine_p.h" +#include + +#if !defined(QT_NO_RAWFONT) + +QT_BEGIN_NAMESPACE + +namespace { class CustomFontFileLoader; } +class Q_AUTOTEST_EXPORT QRawFontPrivate +{ +public: + QRawFontPrivate() + : fontEngine(0) + , hintingPreference(QFont::PreferDefaultHinting) + , thread(0) +#if defined(Q_WS_WIN) + , fontHandle(NULL) + , ptrAddFontMemResourceEx(NULL) + , ptrRemoveFontMemResourceEx(NULL) +#endif + {} + + QRawFontPrivate(const QRawFontPrivate &other) + : hintingPreference(other.hintingPreference) + , thread(other.thread) +#if defined(Q_WS_WIN) + , fontHandle(NULL) + , ptrAddFontMemResourceEx(other.ptrAddFontMemResourceEx) + , ptrRemoveFontMemResourceEx(other.ptrRemoveFontMemResourceEx) + , uniqueFamilyName(other.uniqueFamilyName) +#endif + { + fontEngine = other.fontEngine; + if (fontEngine != 0) + fontEngine->ref.ref(); + } + + ~QRawFontPrivate() + { + Q_ASSERT(ref == 0); + cleanUp(); + } + + void cleanUp(); + void platformCleanUp(); + void platformLoadFromData(const QByteArray &fontData, + int pixelSize, + QFont::HintingPreference hintingPreference); + void platformSetPixelSize(int pixelSize); + + static QRawFontPrivate *get(const QRawFont &font) { return font.d.data(); } + + QFontEngine *fontEngine; + QFont::HintingPreference hintingPreference; + QThread *thread; + QAtomicInt ref; + +#if defined(Q_WS_WIN) + HANDLE fontHandle; + + typedef HANDLE (WINAPI *PtrAddFontMemResourceEx)(PVOID, DWORD, PVOID, DWORD *); + typedef BOOL (WINAPI *PtrRemoveFontMemResourceEx)(HANDLE); + + PtrAddFontMemResourceEx ptrAddFontMemResourceEx; + PtrRemoveFontMemResourceEx ptrRemoveFontMemResourceEx; + + QString uniqueFamilyName; + +#endif // Q_WS_WIN +}; + +QT_END_NAMESPACE + +#endif // QT_NO_RAWFONT + +#endif // QRAWFONTPRIVATE_P_H diff --git a/src/gui/text/qrawfont_win.cpp b/src/gui/text/qrawfont_win.cpp new file mode 100644 index 0000000..fb5c6f4 --- /dev/null +++ b/src/gui/text/qrawfont_win.cpp @@ -0,0 +1,750 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qrawfont_p.h" +#include + +#if !defined(QT_NO_DIRECTWRITE) +# include "qfontenginedirectwrite_p.h" +# include +#endif + +#if !defined(QT_NO_RAWFONT) + +QT_BEGIN_NAMESPACE + +namespace { + + template + struct BigEndian + { + quint8 data[sizeof(T)]; + + operator T() const + { + T littleEndian = 0; + for (int i=0; i &operator=(const T &t) + { + for (int i=0; i> (sizeof(T) - i - 1) * 8) & 0xff); + } + + return *this; + } + }; + +# pragma pack(1) + + // Common structure for all formats of the "name" table + struct NameTable + { + BigEndian format; + BigEndian count; + BigEndian stringOffset; + }; + + struct NameRecord + { + BigEndian platformID; + BigEndian encodingID; + BigEndian languageID; + BigEndian nameID; + BigEndian length; + BigEndian offset; + }; + + struct OffsetSubTable + { + BigEndian scalerType; + BigEndian numTables; + BigEndian searchRange; + BigEndian entrySelector; + BigEndian rangeShift; + }; + + struct TableDirectory + { + BigEndian identifier; + BigEndian checkSum; + BigEndian offset; + BigEndian length; + }; + + struct OS2Table + { + BigEndian version; + BigEndian avgCharWidth; + BigEndian weightClass; + BigEndian widthClass; + BigEndian type; + BigEndian subscriptXSize; + BigEndian subscriptYSize; + BigEndian subscriptXOffset; + BigEndian subscriptYOffset; + BigEndian superscriptXSize; + BigEndian superscriptYSize; + BigEndian superscriptXOffset; + BigEndian superscriptYOffset; + BigEndian strikeOutSize; + BigEndian strikeOutPosition; + BigEndian familyClass; + quint8 panose[10]; + BigEndian unicodeRanges[4]; + quint8 vendorID[4]; + BigEndian selection; + BigEndian firstCharIndex; + BigEndian lastCharIndex; + BigEndian typoAscender; + BigEndian typoDescender; + BigEndian typoLineGap; + BigEndian winAscent; + BigEndian winDescent; + BigEndian codepageRanges[2]; + BigEndian height; + BigEndian capHeight; + BigEndian defaultChar; + BigEndian breakChar; + BigEndian maxContext; + }; + +# pragma pack() + + class EmbeddedFont + { + public: + EmbeddedFont(const QByteArray &fontData); + + QString changeFamilyName(const QString &newFamilyName); + QByteArray data() const { return m_fontData; } + TableDirectory *tableDirectoryEntry(const QByteArray &tagName); + QString familyName(TableDirectory *nameTableDirectory = 0); + + private: + QByteArray m_fontData; + }; + + EmbeddedFont::EmbeddedFont(const QByteArray &fontData) : m_fontData(fontData) + { + } + + TableDirectory *EmbeddedFont::tableDirectoryEntry(const QByteArray &tagName) + { + Q_ASSERT(tagName.size() == 4); + + const BigEndian *tagIdPtr = + reinterpret_cast *>(tagName.constData()); + quint32 tagId = *tagIdPtr; + + OffsetSubTable *offsetSubTable = reinterpret_cast(m_fontData.data()); + TableDirectory *tableDirectory = reinterpret_cast(offsetSubTable + 1); + + TableDirectory *nameTableDirectoryEntry = 0; + for (int i=0; inumTables; ++i, ++tableDirectory) { + if (tableDirectory->identifier == tagId) { + nameTableDirectoryEntry = tableDirectory; + break; + } + } + + return nameTableDirectoryEntry; + } + + QString EmbeddedFont::familyName(TableDirectory *nameTableDirectoryEntry) + { + QString name; + + if (nameTableDirectoryEntry == 0) + nameTableDirectoryEntry = tableDirectoryEntry("name"); + + if (nameTableDirectoryEntry != 0) { + NameTable *nameTable = reinterpret_cast(m_fontData.data() + + nameTableDirectoryEntry->offset); + NameRecord *nameRecord = reinterpret_cast(nameTable + 1); + for (int i=0; icount; ++i, ++nameRecord) { + if (nameRecord->nameID == 1 + && nameRecord->platformID == 3 // Windows + && nameRecord->languageID == 0x0409) { // US English + const void *ptr = reinterpret_cast(nameTable) + + nameTable->stringOffset + + nameRecord->offset; + + const BigEndian *s = reinterpret_cast *>(ptr); + for (int j=0; jlength / sizeof(quint16); ++j) + name += QChar(s[j]); + + break; + } + } + } + + return name; + } + + QString EmbeddedFont::changeFamilyName(const QString &newFamilyName) + { + TableDirectory *nameTableDirectoryEntry = tableDirectoryEntry("name"); + if (nameTableDirectoryEntry == 0) + return QString(); + + QString oldFamilyName = familyName(nameTableDirectoryEntry); + + // Reserve size for name table header, five required name records and string + const int requiredRecordCount = 5; + quint16 nameIds[requiredRecordCount] = { 1, 2, 3, 4, 6 }; + + int sizeOfHeader = sizeof(NameTable) + sizeof(NameRecord) * requiredRecordCount; + int newFamilyNameSize = newFamilyName.size() * sizeof(quint16); + + const QString regularString = QString::fromLatin1("Regular"); + int regularStringSize = regularString.size() * sizeof(quint16); + + // Align table size of table to 32 bits (pad with 0) + int fullSize = ((sizeOfHeader + newFamilyNameSize + regularStringSize) & ~3) + 4; + + QByteArray newNameTable(fullSize, char(0)); + + { + NameTable *nameTable = reinterpret_cast(newNameTable.data()); + nameTable->count = requiredRecordCount; + nameTable->stringOffset = sizeOfHeader; + + NameRecord *nameRecord = reinterpret_cast(nameTable + 1); + for (int i=0; inameID = nameIds[i]; + nameRecord->encodingID = 1; + nameRecord->languageID = 0x0409; + nameRecord->platformID = 3; + nameRecord->length = newFamilyNameSize; + + // Special case for sub-family + if (nameIds[i] == 4) { + nameRecord->offset = newFamilyNameSize; + nameRecord->length = regularStringSize; + } + } + + // nameRecord now points to string data + BigEndian *stringStorage = reinterpret_cast *>(nameRecord); + const quint16 *sourceString = newFamilyName.utf16(); + for (int i=0; i(newNameTable.data()); + quint32 *tableEnd = reinterpret_cast(newNameTable.data() + fullSize); + + quint32 checkSum = 0; + while (p < tableEnd) + checkSum += *(p++); + + nameTableDirectoryEntry->checkSum = checkSum; + nameTableDirectoryEntry->offset = m_fontData.size(); + nameTableDirectoryEntry->length = fullSize; + + m_fontData.append(newNameTable); + + return oldFamilyName; + } + +#if !defined(QT_NO_DIRECTWRITE) + + class DirectWriteFontFileStream: public IDWriteFontFileStream + { + public: + DirectWriteFontFileStream(const QByteArray &fontData) + : m_fontData(fontData) + , m_referenceCount(0) + { + } + + ~DirectWriteFontFileStream() + { + } + + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **object); + ULONG STDMETHODCALLTYPE AddRef(); + ULONG STDMETHODCALLTYPE Release(); + + HRESULT STDMETHODCALLTYPE ReadFileFragment(const void **fragmentStart, UINT64 fileOffset, + UINT64 fragmentSize, OUT void **fragmentContext); + void STDMETHODCALLTYPE ReleaseFileFragment(void *fragmentContext); + HRESULT STDMETHODCALLTYPE GetFileSize(OUT UINT64 *fileSize); + HRESULT STDMETHODCALLTYPE GetLastWriteTime(OUT UINT64 *lastWriteTime); + + private: + QByteArray m_fontData; + ULONG m_referenceCount; + }; + + HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::QueryInterface(REFIID iid, void **object) + { + if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) { + *object = this; + AddRef(); + return S_OK; + } else { + *object = NULL; + return E_NOINTERFACE; + } + } + + ULONG STDMETHODCALLTYPE DirectWriteFontFileStream::AddRef() + { + return InterlockedIncrement(&m_referenceCount); + } + + ULONG STDMETHODCALLTYPE DirectWriteFontFileStream::Release() + { + ULONG newCount = InterlockedDecrement(&m_referenceCount); + if (newCount == 0) + delete this; + return newCount; + } + + HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::ReadFileFragment( + const void **fragmentStart, + UINT64 fileOffset, + UINT64 fragmentSize, + OUT void **fragmentContext) + { + *fragmentContext = NULL; + if (fragmentSize + fileOffset <= m_fontData.size()) { + *fragmentStart = m_fontData.data() + fileOffset; + return S_OK; + } else { + *fragmentStart = NULL; + return E_FAIL; + } + } + + void STDMETHODCALLTYPE DirectWriteFontFileStream::ReleaseFileFragment(void *) + { + } + + HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::GetFileSize(UINT64 *fileSize) + { + *fileSize = m_fontData.size(); + return S_OK; + } + + HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::GetLastWriteTime(UINT64 *lastWriteTime) + { + *lastWriteTime = 0; + return E_NOTIMPL; + } + + class DirectWriteFontFileLoader: public IDWriteFontFileLoader + { + public: + DirectWriteFontFileLoader() : m_referenceCount(0) {} + + ~DirectWriteFontFileLoader() + { + } + + inline void addKey(const void *key, const QByteArray &fontData) + { + Q_ASSERT(!m_fontDatas.contains(key)); + m_fontDatas.insert(key, fontData); + } + + inline void removeKey(const void *key) + { + m_fontDatas.remove(key); + } + + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **object); + ULONG STDMETHODCALLTYPE AddRef(); + ULONG STDMETHODCALLTYPE Release(); + + HRESULT STDMETHODCALLTYPE CreateStreamFromKey(void const *fontFileReferenceKey, + UINT32 fontFileReferenceKeySize, + OUT IDWriteFontFileStream **fontFileStream); + + private: + ULONG m_referenceCount; + QHash m_fontDatas; + }; + + HRESULT STDMETHODCALLTYPE DirectWriteFontFileLoader::QueryInterface(const IID &iid, + void **object) + { + if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) { + *object = this; + AddRef(); + return S_OK; + } else { + *object = NULL; + return E_NOINTERFACE; + } + } + + ULONG STDMETHODCALLTYPE DirectWriteFontFileLoader::AddRef() + { + return InterlockedIncrement(&m_referenceCount); + } + + ULONG STDMETHODCALLTYPE DirectWriteFontFileLoader::Release() + { + ULONG newCount = InterlockedDecrement(&m_referenceCount); + if (newCount == 0) + delete this; + return newCount; + } + + HRESULT STDMETHODCALLTYPE DirectWriteFontFileLoader::CreateStreamFromKey( + void const *fontFileReferenceKey, + UINT32 fontFileReferenceKeySize, + IDWriteFontFileStream **fontFileStream) + { + Q_UNUSED(fontFileReferenceKeySize); + + if (fontFileReferenceKeySize != sizeof(const void *)) { + qWarning("DirectWriteFontFileLoader::CreateStreamFromKey: Wrong key size"); + return E_FAIL; + } + + const void *key = *reinterpret_cast(fontFileReferenceKey); + *fontFileStream = NULL; + if (!m_fontDatas.contains(key)) + return E_FAIL; + + QByteArray fontData = m_fontDatas.value(key); + DirectWriteFontFileStream *stream = new DirectWriteFontFileStream(fontData); + stream->AddRef(); + *fontFileStream = stream; + + return S_OK; + } + + class CustomFontFileLoader + { + public: + CustomFontFileLoader() : m_directWriteFactory(0), m_directWriteFontFileLoader(0) + { + HRESULT hres = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, + __uuidof(IDWriteFactory), + reinterpret_cast(&m_directWriteFactory)); + if (FAILED(hres)) { + qErrnoWarning(hres, "CustomFontFileLoader::CustomFontFileLoader: " + "DWriteCreateFactory failed."); + } else { + m_directWriteFontFileLoader = new DirectWriteFontFileLoader(); + m_directWriteFactory->RegisterFontFileLoader(m_directWriteFontFileLoader); + } + } + + ~CustomFontFileLoader() + { + if (m_directWriteFactory != 0 && m_directWriteFontFileLoader != 0) + m_directWriteFactory->UnregisterFontFileLoader(m_directWriteFontFileLoader); + + if (m_directWriteFactory != 0) + m_directWriteFactory->Release(); + } + + void addKey(const void *key, const QByteArray &fontData) + { + if (m_directWriteFontFileLoader != 0) + m_directWriteFontFileLoader->addKey(key, fontData); + } + + void removeKey(const void *key) + { + if (m_directWriteFontFileLoader != 0) + m_directWriteFontFileLoader->removeKey(key); + } + + IDWriteFontFileLoader *loader() const + { + return m_directWriteFontFileLoader; + } + + private: + IDWriteFactory *m_directWriteFactory; + DirectWriteFontFileLoader *m_directWriteFontFileLoader; + }; + +#endif + +} // Anonymous namespace + + +// From qfontdatabase_win.cpp +extern QFontEngine *qt_load_font_engine_win(const QFontDef &request); +// From qfontdatabase.cpp +extern QFont::Weight weightFromInteger(int weight); + +void QRawFontPrivate::platformCleanUp() +{ + if (fontHandle != NULL) { + if (ptrRemoveFontMemResourceEx == NULL) { + void *func = QSystemLibrary::resolve(QLatin1String("gdi32"), "RemoveFontMemResourceEx"); + ptrRemoveFontMemResourceEx = + reinterpret_cast(func); + } + + if (ptrRemoveFontMemResourceEx == NULL) { + qWarning("QRawFont::platformCleanUp: Can't find RemoveFontMemResourceEx in gdi32"); + fontHandle = NULL; + } else { + ptrRemoveFontMemResourceEx(fontHandle); + fontHandle = NULL; + } + } +} + +void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData, + int pixelSize, + QFont::HintingPreference hintingPreference) +{ + QByteArray fontData(_fontData); + EmbeddedFont font(fontData); + +#if !defined(QT_NO_DIRECTWRITE) + if (hintingPreference == QFont::PreferDefaultHinting + || hintingPreference == QFont::PreferFullHinting) +#endif + { + GUID guid; + CoCreateGuid(&guid); + + uniqueFamilyName = QString::fromLatin1("f") + + QString::number(guid.Data1, 36) + QLatin1Char('-') + + QString::number(guid.Data2, 36) + QLatin1Char('-') + + QString::number(guid.Data3, 36) + QLatin1Char('-') + + QString::number(*reinterpret_cast(guid.Data4), 36); + + QString actualFontName = font.changeFamilyName(uniqueFamilyName); + if (actualFontName.isEmpty()) { + qWarning("QRawFont::platformLoadFromData: Can't change family name of font"); + return; + } + + if (ptrAddFontMemResourceEx == NULL || ptrRemoveFontMemResourceEx == NULL) { + void *func = QSystemLibrary::resolve(QLatin1String("gdi32"), "RemoveFontMemResourceEx"); + ptrRemoveFontMemResourceEx = + reinterpret_cast(func); + + func = QSystemLibrary::resolve(QLatin1String("gdi32"), "AddFontMemResourceEx"); + ptrAddFontMemResourceEx = + reinterpret_cast(func); + } + + Q_ASSERT(fontHandle == NULL); + if (ptrAddFontMemResourceEx != NULL && ptrRemoveFontMemResourceEx != NULL) { + DWORD count = 0; + fontData = font.data(); + fontHandle = ptrAddFontMemResourceEx(fontData.data(), fontData.size(), 0, &count); + + if (count == 0 && fontHandle != NULL) { + ptrRemoveFontMemResourceEx(fontHandle); + fontHandle = NULL; + } + } + + if (fontHandle == NULL) { + qWarning("QRawFont::platformLoadFromData: AddFontMemResourceEx failed"); + } else { + QFontDef request; + request.family = uniqueFamilyName; + request.pixelSize = pixelSize; + request.styleStrategy = QFont::NoFontMerging | QFont::PreferMatch; + request.hintingPreference = hintingPreference; + + fontEngine = qt_load_font_engine_win(request); + if (request.family != fontEngine->fontDef.family) { + qWarning("QRawFont::platformLoadFromData: Failed to load font. " + "Got fallback instead: %s", qPrintable(fontEngine->fontDef.family)); + if (fontEngine->cache_count == 0 && fontEngine->ref == 0) + delete fontEngine; + fontEngine = 0; + } else { + Q_ASSERT(fontEngine->cache_count == 0 && fontEngine->ref == 0); + + // Override the generated font name + fontEngine->fontDef.family = actualFontName; + fontEngine->ref.ref(); + } + } + } +#if !defined(QT_NO_DIRECTWRITE) + else { + CustomFontFileLoader fontFileLoader; + fontFileLoader.addKey(this, fontData); + + IDWriteFactory *factory = NULL; + HRESULT hres = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, + __uuidof(IDWriteFactory), + reinterpret_cast(&factory)); + if (FAILED(hres)) { + qErrnoWarning(hres, "QRawFont::platformLoadFromData: DWriteCreateFactory failed"); + return; + } + + IDWriteFontFile *fontFile = NULL; + void *key = this; + + hres = factory->CreateCustomFontFileReference(&key, sizeof(void *), + fontFileLoader.loader(), &fontFile); + if (FAILED(hres)) { + qErrnoWarning(hres, "QRawFont::platformLoadFromData: " + "CreateCustomFontFileReference failed"); + factory->Release(); + return; + } + + BOOL isSupportedFontType; + DWRITE_FONT_FILE_TYPE fontFileType; + DWRITE_FONT_FACE_TYPE fontFaceType; + UINT32 numberOfFaces; + fontFile->Analyze(&isSupportedFontType, &fontFileType, &fontFaceType, &numberOfFaces); + if (!isSupportedFontType) { + fontFile->Release(); + factory->Release(); + return; + } + + IDWriteFontFace *directWriteFontFace = NULL; + hres = factory->CreateFontFace(fontFaceType, 1, &fontFile, 0, DWRITE_FONT_SIMULATIONS_NONE, + &directWriteFontFace); + if (FAILED(hres)) { + qErrnoWarning(hres, "QRawFont::platformLoadFromData: CreateFontFace failed"); + fontFile->Release(); + factory->Release(); + return; + } + + fontFile->Release(); + + fontEngine = new QFontEngineDirectWrite(factory, directWriteFontFace, pixelSize); + + // Get font family from font data + fontEngine->fontDef.family = font.familyName(); + fontEngine->ref.ref(); + + directWriteFontFace->Release(); + factory->Release(); + } +#endif + + // Get style and weight info + if (fontEngine != 0) { + TableDirectory *os2TableEntry = font.tableDirectoryEntry("OS/2"); + if (os2TableEntry != 0) { + const OS2Table *os2Table = + reinterpret_cast(fontData.constData() + + os2TableEntry->offset); + + bool italic = os2Table->selection & 1; + bool oblique = os2Table->selection & 128; + + if (italic) + fontEngine->fontDef.style = QFont::StyleItalic; + else if (oblique) + fontEngine->fontDef.style = QFont::StyleOblique; + else + fontEngine->fontDef.style = QFont::StyleNormal; + + fontEngine->fontDef.weight = weightFromInteger(os2Table->weightClass); + } + } +} + +void QRawFontPrivate::platformSetPixelSize(int pixelSize) +{ + if (fontEngine == NULL) + return; + + QFontEngine *oldFontEngine = fontEngine; + +#if !defined(QT_NO_DIRECTWRITE) + if (fontEngine->type() == QFontEngine::Win) +#endif + + { + QFontDef request = fontEngine->fontDef; + QString actualFontName = request.family; + if (!uniqueFamilyName.isEmpty()) + request.family = uniqueFamilyName; + request.pixelSize = pixelSize; + + fontEngine = qt_load_font_engine_win(request); + if (fontEngine != NULL) { + fontEngine->fontDef.family = actualFontName; + fontEngine->ref.ref(); + } + } + +#if !defined(QT_NO_DIRECTWRITE) + else { + QFontEngineDirectWrite *dWriteFE = static_cast(fontEngine); + fontEngine = new QFontEngineDirectWrite(dWriteFE->m_directWriteFactory, + dWriteFE->m_directWriteFontFace, + pixelSize); + + fontEngine->fontDef = dWriteFE->fontDef; + fontEngine->fontDef.pixelSize = pixelSize; + fontEngine->ref.ref(); + } +#endif + + Q_ASSERT(fontEngine != oldFontEngine); + oldFontEngine->ref.deref(); + if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0) + delete oldFontEngine; +} + +QT_END_NAMESPACE + +#endif // QT_NO_RAWFONT diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index afe6949..93f71d3 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -54,12 +54,18 @@ #include "qpainterpath.h" #include "qglyphs.h" #include "qglyphs_p.h" +#include "qrawfont.h" +#include "qrawfont_p.h" #include #include #include "qfontengine_p.h" +#if !defined(QT_NO_FREETYPE) +# include "qfontengine_ft_p.h" +#endif + QT_BEGIN_NAMESPACE #define ObjectSelectionBrush (QTextFormat::ForegroundBrush + 1) @@ -1158,6 +1164,7 @@ static inline QRectF clipIfValid(const QRectF &rect, const QRectF &clip) \sa draw(), QPainter::drawGlyphs() */ +#if !defined(QT_NO_RAWFONT) QList QTextLayout::glyphs() const { QList glyphs; @@ -1166,6 +1173,7 @@ QList QTextLayout::glyphs() const return glyphs; } +#endif // QT_NO_RAWFONT /*! Draws the whole layout on the painter \a p at the position specified by \a pos. @@ -2257,6 +2265,7 @@ namespace { \sa QTextLayout::glyphs() */ +#if !defined(QT_NO_RAWFONT) QList QTextLine::glyphs(int from, int length) const { const QScriptLine &line = eng->lines[i]; @@ -2331,7 +2340,35 @@ QList QTextLine::glyphs(int from, int length) const QFontEngine *fontEngine = keys.at(i); // Make a font for this particular engine - QFont font = fontEngine->createExplicitFont(); + QRawFont font; + QRawFontPrivate *fontD = QRawFontPrivate::get(font); + fontD->fontEngine = fontEngine; + fontD->fontEngine->ref.ref(); + +#if defined(Q_WS_WIN) + if (fontEngine->supportsSubPixelPositions()) + fontD->hintingPreference = QFont::PreferVerticalHinting; + else + fontD->hintingPreference = QFont::PreferFullHinting; +#elif defined(Q_WS_MAC) + fontD->hintingPreference = QFont::PreferNoHinting; +#elif !defined(QT_NO_FREETYPE) + if (fontEngine->type() == QFontEngine::Freetype) { + QFontEngineFT *freeTypeEngine = static_cast(fontEngine); + switch (freeTypeEngine->defaultHintStyle()) { + case QFontEngineFT::HintNone: + fontD->hintingPreference = QFont::PreferNoHinting; + break; + case QFontEngineFT::HintLight: + fontD->hintingPreference = QFont::PreferVerticalHinting; + break; + case QFontEngineFT::HintMedium: + case QFontEngineFT::HintFull: + fontD->hintingPreference = QFont::PreferFullHinting; + break; + }; + } +#endif QList glyphLayouts = glyphLayoutHash.values(fontEngine); for (int j=0; j QTextLine::glyphs(int from, int length) const const QGlyphLayout &glyphLayout = glyphLayouts.at(j).glyphLayout; const QTextItem::RenderFlags &flags = glyphLayouts.at(j).flags; - font.setOverline(flags.testFlag(QTextItem::Overline)); - font.setUnderline(flags.testFlag(QTextItem::Underline)); - font.setStrikeOut(flags.testFlag(QTextItem::StrikeOut)); - QVarLengthArray glyphsArray; QVarLengthArray positionsArray; @@ -2361,19 +2394,22 @@ QList QTextLine::glyphs(int from, int length) const glyphIndexes.setGlyphIndexes(glyphs); glyphIndexes.setPositions(positions); - QPair key(fontEngine, int(flags)); + glyphIndexes.setOverline(flags.testFlag(QTextItem::Overline)); + glyphIndexes.setUnderline(flags.testFlag(QTextItem::Underline)); + glyphIndexes.setStrikeOut(flags.testFlag(QTextItem::StrikeOut)); + glyphIndexes.setFont(font); + QPair key(fontEngine, int(flags)); if (!glyphsHash.contains(key)) - glyphsHash.insert(key, QGlyphs()); - - QGlyphs &target = glyphsHash[key]; - target += glyphIndexes; - target.setFont(font); + glyphsHash.insert(key, glyphIndexes); + else + glyphsHash[key] += glyphIndexes; } } return glyphsHash.values(); } +#endif // QT_NO_RAWFONT /*! \fn void QTextLine::draw(QPainter *painter, const QPointF &position, const QTextLayout::FormatRange *selection) const diff --git a/src/gui/text/qtextlayout.h b/src/gui/text/qtextlayout.h index 0f64c33..9dd8ebd 100644 --- a/src/gui/text/qtextlayout.h +++ b/src/gui/text/qtextlayout.h @@ -167,7 +167,9 @@ public: qreal minimumWidth() const; qreal maximumWidth() const; +#if !defined(QT_NO_RAWFONT) QList glyphs() const; +#endif QTextEngine *engine() const { return d; } void setFlags(int flags); @@ -239,7 +241,10 @@ public: private: QTextLine(int line, QTextEngine *e) : i(line), eng(e) {} void layout_helper(int numGlyphs); + +#if !defined(QT_NO_RAWFONT) QList glyphs(int from, int length) const; +#endif friend class QTextLayout; friend class QTextFragment; diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp index 0081550..0a9dff8 100644 --- a/src/gui/text/qtextobject.cpp +++ b/src/gui/text/qtextobject.cpp @@ -1661,6 +1661,7 @@ QTextBlock::iterator &QTextBlock::iterator::operator--() \sa QGlyphs, QTextBlock::layout(), QTextLayout::position(), QPainter::drawGlyphs() */ +#if !defined(QT_NO_RAWFONT) QList QTextFragment::glyphs() const { if (!p || !n) @@ -1684,6 +1685,7 @@ QList QTextFragment::glyphs() const return ret; } +#endif // QT_NO_RAWFONT /*! Returns the position of this text fragment in the document. diff --git a/src/gui/text/qtextobject.h b/src/gui/text/qtextobject.h index fface3f..2e588c2 100644 --- a/src/gui/text/qtextobject.h +++ b/src/gui/text/qtextobject.h @@ -316,7 +316,9 @@ public: int charFormatIndex() const; QString text() const; +#if !defined(QT_NO_RAWFONT) QList glyphs() const; +#endif private: const QTextDocumentPrivate *p; diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri index 7fb2783..df9398c 100644 --- a/src/gui/text/text.pri +++ b/src/gui/text/text.pri @@ -41,7 +41,9 @@ HEADERS += \ text/qstatictext_p.h \ text/qstatictext.h \ text/qglyphs.h \ - text/qglyphs_p.h + text/qglyphs_p.h \ + text/qrawfont.h \ + text/qrawfont_p.h SOURCES += \ text/qfont.cpp \ @@ -72,12 +74,14 @@ SOURCES += \ text/qzip.cpp \ text/qtextodfwriter.cpp \ text/qstatictext.cpp \ - text/qglyphs.cpp + text/qglyphs.cpp \ + text/qrawfont.cpp win32 { SOURCES += \ text/qfont_win.cpp \ - text/qfontengine_win.cpp + text/qfontengine_win.cpp \ + text/qrawfont_win.cpp HEADERS += text/qfontengine_win_p.h } @@ -95,7 +99,8 @@ unix:x11 { SOURCES += \ text/qfont_x11.cpp \ text/qfontengine_x11.cpp \ - text/qfontengine_ft.cpp + text/qfontengine_ft.cpp \ + text/qrawfont_ft.cpp } !embedded:!qpa:!x11:mac { @@ -104,7 +109,8 @@ unix:x11 { OBJECTIVE_HEADERS += \ text/qfontengine_coretext_p.h SOURCES += \ - text/qfont_mac.cpp + text/qfont_mac.cpp \ + text/qrawfont_mac.cpp OBJECTIVE_SOURCES += \ text/qfontengine_coretext.mm \ text/qfontengine_mac.mm @@ -116,7 +122,8 @@ embedded { text/qfontengine_qws.cpp \ text/qfontengine_ft.cpp \ text/qfontengine_qpf.cpp \ - text/qabstractfontengine_qws.cpp + text/qabstractfontengine_qws.cpp \ + text/qrawfont_ft.cpp HEADERS += \ text/qfontengine_ft_p.h \ text/qfontengine_qpf_p.h \ @@ -143,7 +150,8 @@ symbian { text/qfont_s60.cpp contains(QT_CONFIG, freetype) { SOURCES += \ - text/qfontengine_ft.cpp + text/qfontengine_ft.cpp \ + text/qrawfont_ft.cpp HEADERS += \ text/qfontengine_ft_p.h DEFINES += \ diff --git a/tests/auto/gui.pro b/tests/auto/gui.pro index 186f00c..6230220 100644 --- a/tests/auto/gui.pro +++ b/tests/auto/gui.pro @@ -139,6 +139,7 @@ SUBDIRS=\ qpushbutton \ qquaternion \ qradiobutton \ + qrawfont \ qregexpvalidator \ qregion \ qscrollarea \ diff --git a/tests/auto/qglyphs/tst_qglyphs.cpp b/tests/auto/qglyphs/tst_qglyphs.cpp index 1c0aa9e..a9ae556 100644 --- a/tests/auto/qglyphs/tst_qglyphs.cpp +++ b/tests/auto/qglyphs/tst_qglyphs.cpp @@ -46,6 +46,8 @@ #include #include +#if !defined(QT_NO_RAWFONT) + // #define DEBUG_SAVE_IMAGE class tst_QGlyphs: public QObject @@ -116,7 +118,7 @@ static QGlyphs make_dummy_indexes() positions.append(QPointF(3, 4)); positions.append(QPointF(5, 6)); - glyphs.setFont(font); + glyphs.setFont(QRawFont::fromFont(font)); glyphs.setGlyphIndexes(glyphIndexes); glyphs.setPositions(positions); @@ -141,7 +143,7 @@ void tst_QGlyphs::copyConstructor() positions.append(QPointF(3, 4)); positions.append(QPointF(5, 6)); - glyphs.setFont(font); + glyphs.setFont(QRawFont::fromFont(font)); glyphs.setGlyphIndexes(glyphIndexes); glyphs.setPositions(positions); } @@ -180,14 +182,16 @@ void tst_QGlyphs::equalsOperator_data() positions[2] += QPointF(1, 1); busted.setPositions(positions); + QTest::newRow("Different positions") << one << busted << false; } { QGlyphs busted(two); - QFont font = busted.font(); - font.setPointSize(font.pointSize() * 2); - busted.setFont(font); + + QFont font; + font.setPixelSize(busted.font().pixelSize() * 2); + busted.setFont(QRawFont::fromFont(font)); QTest::newRow("Different fonts") << one << busted << false; } @@ -288,7 +292,7 @@ void tst_QGlyphs::drawNonExistentGlyphs() QGlyphs glyphs; glyphs.setGlyphIndexes(glyphIndexes); glyphs.setPositions(glyphPositions); - glyphs.setFont(m_testFont); + glyphs.setFont(QRawFont::fromFont(m_testFont)); QPixmap image(1000, 1000); image.fill(Qt::white); @@ -571,3 +575,4 @@ void tst_QGlyphs::drawRightToLeft() QTEST_MAIN(tst_QGlyphs) #include "tst_qglyphs.moc" +#endif // QT_NO_RAWFONT diff --git a/tests/auto/qrawfont/qrawfont.pro b/tests/auto/qrawfont/qrawfont.pro new file mode 100644 index 0000000..ccdccfb --- /dev/null +++ b/tests/auto/qrawfont/qrawfont.pro @@ -0,0 +1,13 @@ +load(qttest_p4) +QT = core gui + +SOURCES += \ + tst_qrawfont.cpp + +INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/harfbuzz/src + +wince*|symbian*: { + DEFINES += SRCDIR=\\\"\\\" +} else { + DEFINES += SRCDIR=\\\"$$PWD/\\\" +} diff --git a/tests/auto/qrawfont/testfont.ttf b/tests/auto/qrawfont/testfont.ttf new file mode 100644 index 0000000..d6042d2 Binary files /dev/null and b/tests/auto/qrawfont/testfont.ttf differ diff --git a/tests/auto/qrawfont/testfont_bold_italic.ttf b/tests/auto/qrawfont/testfont_bold_italic.ttf new file mode 100644 index 0000000..9f65ac8 Binary files /dev/null and b/tests/auto/qrawfont/testfont_bold_italic.ttf differ diff --git a/tests/auto/qrawfont/tst_qrawfont.cpp b/tests/auto/qrawfont/tst_qrawfont.cpp new file mode 100644 index 0000000..c20b41d --- /dev/null +++ b/tests/auto/qrawfont/tst_qrawfont.cpp @@ -0,0 +1,812 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include +#include + +#if !defined(QT_NO_RAWFONT) + +class tst_QRawFont: public QObject +{ + Q_OBJECT + +private slots: + void invalidRawFont(); + + void explicitRawFontNotLoadedInDatabase_data(); + void explicitRawFontNotLoadedInDatabase(); + + void explicitRawFontNotAvailableInSystem_data(); + void explicitRawFontNotAvailableInSystem(); + + void correctFontData_data(); + void correctFontData(); + + void glyphIndices(); + + void advances_data(); + void advances(); + + void textLayout(); + + void fontTable_data(); + void fontTable(); + + void supportedWritingSystems_data(); + void supportedWritingSystems(); + + void supportsCharacter_data(); + void supportsCharacter(); + + void supportsUcs4Character_data(); + void supportsUcs4Character(); + + void fromFont_data(); + void fromFont(); + + void copyConstructor_data(); + void copyConstructor(); + + void detach_data(); + void detach(); + + void unsupportedWritingSystem_data(); + void unsupportedWritingSystem(); +}; + +Q_DECLARE_METATYPE(QFont::HintingPreference) +Q_DECLARE_METATYPE(QFont::Style) +Q_DECLARE_METATYPE(QFont::Weight) +Q_DECLARE_METATYPE(QFontDatabase::WritingSystem) + +void tst_QRawFont::invalidRawFont() +{ + QRawFont font; + QVERIFY(!font.isValid()); + QCOMPARE(font.pixelSize(), -1); + QVERIFY(font.familyName().isEmpty()); + QCOMPARE(font.style(), QFont::StyleNormal); + QCOMPARE(font.weight(), -1); + QCOMPARE(font.ascent(), 0.0); + QCOMPARE(font.descent(), 0.0); + QVERIFY(font.glyphIndexesForString(QLatin1String("Test")).isEmpty()); +} + +void tst_QRawFont::explicitRawFontNotLoadedInDatabase_data() +{ + QTest::addColumn("hintingPreference"); + + QTest::newRow("Default hinting preference") << QFont::PreferDefaultHinting; + QTest::newRow("No hinting") << QFont::PreferNoHinting; + QTest::newRow("Vertical hinting") << QFont::PreferVerticalHinting; + QTest::newRow("Full hinting") << QFont::PreferFullHinting; +} + +void tst_QRawFont::explicitRawFontNotLoadedInDatabase() +{ + QFETCH(QFont::HintingPreference, hintingPreference); + + QRawFont font(QLatin1String(SRCDIR "testfont.ttf"), 10, hintingPreference); + QVERIFY(font.isValid()); + + QVERIFY(!QFontDatabase().families().contains(font.familyName())); +} + +void tst_QRawFont::explicitRawFontNotAvailableInSystem_data() +{ + QTest::addColumn("hintingPreference"); + + QTest::newRow("Default hinting preference") << QFont::PreferDefaultHinting; + QTest::newRow("No hinting") << QFont::PreferNoHinting; + QTest::newRow("Vertical hinting") << QFont::PreferVerticalHinting; + QTest::newRow("Full hinting") << QFont::PreferFullHinting; +} + +void tst_QRawFont::explicitRawFontNotAvailableInSystem() +{ + QFETCH(QFont::HintingPreference, hintingPreference); + + QRawFont rawfont(QLatin1String(SRCDIR "testfont.ttf"), 10, hintingPreference); + + { + QFont font(rawfont.familyName(), 10); + + QVERIFY(!font.exactMatch()); + QVERIFY(font.family() != QFontInfo(font).family()); + } +} + +void tst_QRawFont::correctFontData_data() +{ + QTest::addColumn("fileName"); + QTest::addColumn("expectedFamilyName"); + QTest::addColumn("style"); + QTest::addColumn("weight"); + QTest::addColumn("hintingPreference"); + QTest::addColumn("unitsPerEm"); + QTest::addColumn("pixelSize"); + + int hintingPreferences[] = { + int(QFont::PreferDefaultHinting), + int(QFont::PreferNoHinting), + int(QFont::PreferVerticalHinting), + int(QFont::PreferFullHinting), + -1 + }; + int *hintingPreference = hintingPreferences; + + while (*hintingPreference >= 0) { + QString fileName = QLatin1String(SRCDIR "testfont.ttf"); + QString title = fileName + + QLatin1String(": hintingPreference=") + + QString::number(*hintingPreference); + + QTest::newRow(qPrintable(title)) + << fileName + << QString::fromLatin1("QtBidiTestFont") + << QFont::StyleNormal + << QFont::Normal + << QFont::HintingPreference(*hintingPreference) + << 1000.0 + << 10; + + fileName = QLatin1String(SRCDIR "testfont_bold_italic.ttf"); + title = fileName + + QLatin1String(": hintingPreference=") + + QString::number(*hintingPreference); + + QTest::newRow(qPrintable(title)) + << fileName + << QString::fromLatin1("QtBidiTestFont") + << QFont::StyleItalic + << QFont::Bold + << QFont::HintingPreference(*hintingPreference) + << 1000.0 + << 10; + + ++hintingPreference; + } +} + +void tst_QRawFont::correctFontData() +{ + QFETCH(QString, fileName); + QFETCH(QString, expectedFamilyName); + QFETCH(QFont::Style, style); + QFETCH(QFont::Weight, weight); + QFETCH(QFont::HintingPreference, hintingPreference); + QFETCH(qreal, unitsPerEm); + QFETCH(int, pixelSize); + + QRawFont font(fileName, 10, hintingPreference); + QVERIFY(font.isValid()); + + QCOMPARE(font.familyName(), expectedFamilyName); + QCOMPARE(font.style(), style); + QCOMPARE(font.weight(), int(weight)); + QCOMPARE(font.hintingPreference(), hintingPreference); + QCOMPARE(font.unitsPerEm(), unitsPerEm); + QCOMPARE(font.pixelSize(), pixelSize); +} + +void tst_QRawFont::glyphIndices() +{ + QRawFont font(QLatin1String(SRCDIR "testfont.ttf"), 10); + QVERIFY(font.isValid()); + + QVector glyphIndices = font.glyphIndexesForString(QLatin1String("Foobar")); + QVector expectedGlyphIndices; + expectedGlyphIndices << 44 << 83 << 83 << 70 << 69 << 86; + + QCOMPARE(glyphIndices, expectedGlyphIndices); +} + +void tst_QRawFont::advances_data() +{ + QTest::addColumn("hintingPreference"); + + QTest::newRow("Default hinting preference") << QFont::PreferDefaultHinting; + QTest::newRow("No hinting") << QFont::PreferNoHinting; + QTest::newRow("Vertical hinting") << QFont::PreferVerticalHinting; + QTest::newRow("Full hinting") << QFont::PreferFullHinting; +} + +void tst_QRawFont::advances() +{ + QFETCH(QFont::HintingPreference, hintingPreference); + + QRawFont font(QLatin1String(SRCDIR "testfont.ttf"), 10, hintingPreference); + QVERIFY(font.isValid()); + + QRawFontPrivate *font_d = QRawFontPrivate::get(font); + QVERIFY(font_d->fontEngine != 0); + + QVector glyphIndices; + glyphIndices << 44 << 83 << 83 << 70 << 69 << 86; // "Foobar" + + bool supportsSubPixelPositions = font_d->fontEngine->supportsSubPixelPositions(); + QVector advances = font.advancesForGlyphIndexes(glyphIndices); + for (int i=0; i 8.0); + + QVERIFY(qFuzzyIsNull(advances.at(i).y())); + } +} + +void tst_QRawFont::textLayout() +{ + QFontDatabase fontDatabase; + int id = fontDatabase.addApplicationFont(SRCDIR "testfont.ttf"); + QVERIFY(id >= 0); + + QString familyName = QString::fromLatin1("QtBidiTestFont"); + QFont font(familyName); + font.setPixelSize(18); + QCOMPARE(QFontInfo(font).family(), familyName); + + QTextLayout layout(QLatin1String("Foobar")); + layout.setFont(font); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QList glyphss = layout.glyphs(); + QCOMPARE(glyphss.size(), 1); + + QGlyphs glyphs = glyphss.at(0); + + QRawFont rawFont = glyphs.font(); + QVERIFY(rawFont.isValid()); + QCOMPARE(rawFont.familyName(), familyName); + QCOMPARE(rawFont.pixelSize(), 18); + + QVector expectedGlyphIndices; + expectedGlyphIndices << 44 << 83 << 83 << 70 << 69 << 86; + + QCOMPARE(glyphs.glyphIndexes(), expectedGlyphIndices); + + QVERIFY(fontDatabase.removeApplicationFont(id)); +} + +void tst_QRawFont::fontTable_data() +{ + QTest::addColumn("tagName"); + QTest::addColumn("hintingPreference"); + QTest::addColumn("offset"); + QTest::addColumn("expectedValue"); + + QTest::newRow("Head table, magic number, default hinting") + << QByteArray("head") + << QFont::PreferDefaultHinting + << 12 + << (QSysInfo::ByteOrder == QSysInfo::BigEndian + ? 0x5F0F3CF5 + : 0xF53C0F5F); + + QTest::newRow("Head table, magic number, no hinting") + << QByteArray("head") + << QFont::PreferNoHinting + << 12 + << (QSysInfo::ByteOrder == QSysInfo::BigEndian + ? 0x5F0F3CF5 + : 0xF53C0F5F); + + QTest::newRow("Head table, magic number, vertical hinting") + << QByteArray("head") + << QFont::PreferVerticalHinting + << 12 + << (QSysInfo::ByteOrder == QSysInfo::BigEndian + ? 0x5F0F3CF5 + : 0xF53C0F5F); + + QTest::newRow("Head table, magic number, full hinting") + << QByteArray("head") + << QFont::PreferFullHinting + << 12 + << (QSysInfo::ByteOrder == QSysInfo::BigEndian + ? 0x5F0F3CF5 + : 0xF53C0F5F); +} + +void tst_QRawFont::fontTable() +{ + QFETCH(QByteArray, tagName); + QFETCH(QFont::HintingPreference, hintingPreference); + QFETCH(int, offset); + QFETCH(quint32, expectedValue); + + QRawFont font(QString::fromLatin1(SRCDIR "testfont.ttf"), 10, hintingPreference); + QVERIFY(font.isValid()); + + QByteArray table = font.fontTable(tagName); + QVERIFY(!table.isEmpty()); + + const quint32 *value = reinterpret_cast(table.constData() + offset); + QCOMPARE(*value, expectedValue); +} + +typedef QList WritingSystemList; +Q_DECLARE_METATYPE(WritingSystemList) + +void tst_QRawFont::supportedWritingSystems_data() +{ + QTest::addColumn("fileName"); + QTest::addColumn("writingSystems"); + QTest::addColumn("hintingPreference"); + + for (int hintingPreference=QFont::PreferDefaultHinting; + hintingPreference<=QFont::PreferFullHinting; + ++hintingPreference) { + + QTest::newRow(qPrintable(QString::fromLatin1("testfont.ttf, hintingPreference=%1") + .arg(hintingPreference))) + << QString::fromLatin1(SRCDIR "testfont.ttf") + << (QList() + << QFontDatabase::Latin + << QFontDatabase::Hebrew + << QFontDatabase::Vietnamese) // Vietnamese uses same unicode bits as Latin + << QFont::HintingPreference(hintingPreference); + + QTest::newRow(qPrintable(QString::fromLatin1("testfont_bold_italic.ttf, hintingPreference=%1") + .arg(hintingPreference))) + << QString::fromLatin1(SRCDIR "testfont_bold_italic.ttf") + << (QList() + << QFontDatabase::Latin + << QFontDatabase::Hebrew + << QFontDatabase::Devanagari + << QFontDatabase::Vietnamese) // Vietnamese uses same unicode bits as Latin + << QFont::HintingPreference(hintingPreference); + } +} + +void tst_QRawFont::supportedWritingSystems() +{ + QFETCH(QString, fileName); + QFETCH(WritingSystemList, writingSystems); + QFETCH(QFont::HintingPreference, hintingPreference); + + QRawFont font(fileName, 10, hintingPreference); + QVERIFY(font.isValid()); + + WritingSystemList actualWritingSystems = font.supportedWritingSystems(); + QCOMPARE(actualWritingSystems.size(), writingSystems.size()); + + foreach (QFontDatabase::WritingSystem writingSystem, writingSystems) + QVERIFY(actualWritingSystems.contains(writingSystem)); +} + +void tst_QRawFont::supportsCharacter_data() +{ + QTest::addColumn("fileName"); + QTest::addColumn("hintingPreference"); + QTest::addColumn("character"); + QTest::addColumn("shouldBeSupported"); + + const char *fileNames[2] = { + SRCDIR "testfont.ttf", + SRCDIR "testfont_bold_italic.ttf" + }; + + for (int hintingPreference=QFont::PreferDefaultHinting; + hintingPreference<=QFont::PreferFullHinting; + ++hintingPreference) { + + for (int i=0; i<2; ++i) { + QString fileName = QLatin1String(fileNames[i]); + + // Latin text + for (char ch='!'; ch<='~'; ++ch) { + QString title = QString::fromLatin1("%1, character=0x%2, hintingPreference=%3") + .arg(fileName).arg(QString::number(ch, 16)).arg(hintingPreference); + + QTest::newRow(qPrintable(title)) + << fileName + << QFont::HintingPreference(hintingPreference) + << QChar::fromLatin1(ch) + << true; + } + + // Hebrew text + for (quint16 ch=0x05D0; ch<=0x05EA; ++ch) { + QString title = QString::fromLatin1("%1, character=0x%2, hintingPreference=%3") + .arg(fileName).arg(QString::number(ch, 16)).arg(hintingPreference); + + QTest::newRow(qPrintable(title)) + << fileName + << QFont::HintingPreference(hintingPreference) + << QChar(ch) + << true; + } + + QTest::newRow(qPrintable(QString::fromLatin1("Missing character, %1, hintingPreference=%2") + .arg(fileName).arg(hintingPreference))) + << fileName + << QFont::HintingPreference(hintingPreference) + << QChar(0xD8) + << false; + } + } +} + +void tst_QRawFont::supportsCharacter() +{ + QFETCH(QString, fileName); + QFETCH(QFont::HintingPreference, hintingPreference); + QFETCH(QChar, character); + QFETCH(bool, shouldBeSupported); + + QRawFont font(fileName, 10, hintingPreference); + QVERIFY(font.isValid()); + + QCOMPARE(font.supportsCharacter(character), shouldBeSupported); +} + +void tst_QRawFont::supportsUcs4Character_data() +{ + QTest::addColumn("fileName"); + QTest::addColumn("hintingPreference"); + QTest::addColumn("ucs4"); + QTest::addColumn("shouldBeSupported"); + + // Gothic text + for (int hintingPreference=QFont::PreferDefaultHinting; + hintingPreference<=QFont::PreferFullHinting; + ++hintingPreference) { + for (quint32 ch=0x10330; ch<=0x1034A; ++ch) { + { + QString fileName = QString::fromLatin1(SRCDIR "testfont.ttf"); + QString title = QString::fromLatin1("%1, character=0x%2, hintingPreference=%3") + .arg(fileName).arg(QString::number(ch, 16)).arg(hintingPreference); + + QTest::newRow(qPrintable(title)) + << fileName + << QFont::HintingPreference(hintingPreference) + << ch + << true; + } + + { + QString fileName = QString::fromLatin1(SRCDIR "testfont_bold_italic.ttf"); + QString title = QString::fromLatin1("%1, character=0x%2, hintingPreference=%3") + .arg(fileName).arg(QString::number(ch, 16)).arg(hintingPreference); + + QTest::newRow(qPrintable(title)) + << fileName + << QFont::HintingPreference(hintingPreference) + << ch + << false; + } + } + } +} + +void tst_QRawFont::supportsUcs4Character() +{ + QFETCH(QString, fileName); + QFETCH(QFont::HintingPreference, hintingPreference); + QFETCH(quint32, ucs4); + QFETCH(bool, shouldBeSupported); + + QRawFont font(fileName, 10, hintingPreference); + QVERIFY(font.isValid()); + + QCOMPARE(font.supportsCharacter(ucs4), shouldBeSupported); +} + +void tst_QRawFont::fromFont_data() +{ + QTest::addColumn("fileName"); + QTest::addColumn("hintingPreference"); + QTest::addColumn("familyName"); + QTest::addColumn("writingSystem"); + + for (int i=QFont::PreferDefaultHinting; i<=QFont::PreferFullHinting; ++i) { + QString titleBase = QString::fromLatin1("%2, hintingPreference=%1, writingSystem=%3") + .arg(i); + { + QString fileName = QString::fromLatin1(SRCDIR "testfont.ttf"); + QFontDatabase::WritingSystem writingSystem = QFontDatabase::Any; + + QString title = titleBase.arg(fileName).arg(writingSystem); + QTest::newRow(qPrintable(title)) + << fileName + << QFont::HintingPreference(i) + << "QtBidiTestFont" + << writingSystem; + } + + { + QString fileName = QString::fromLatin1(SRCDIR "testfont.ttf"); + QFontDatabase::WritingSystem writingSystem = QFontDatabase::Hebrew; + + QString title = titleBase.arg(fileName).arg(writingSystem); + QTest::newRow(qPrintable(title)) + << fileName + << QFont::HintingPreference(i) + << "QtBidiTestFont" + << writingSystem; + } + + { + QString fileName = QString::fromLatin1(SRCDIR "testfont.ttf"); + QFontDatabase::WritingSystem writingSystem = QFontDatabase::Latin; + + QString title = titleBase.arg(fileName).arg(writingSystem); + QTest::newRow(qPrintable(title)) + << fileName + << QFont::HintingPreference(i) + << "QtBidiTestFont" + << writingSystem; + } + } +} + +void tst_QRawFont::fromFont() +{ + QFETCH(QString, fileName); + QFETCH(QFont::HintingPreference, hintingPreference); + QFETCH(QString, familyName); + QFETCH(QFontDatabase::WritingSystem, writingSystem); + + QFontDatabase fontDatabase; + int id = fontDatabase.addApplicationFont(fileName); + QVERIFY(id >= 0); + + QFont font(familyName); + font.setHintingPreference(hintingPreference); + font.setPixelSize(26); + + QRawFont rawFont = QRawFont::fromFont(font, writingSystem); + QVERIFY(rawFont.isValid()); + QCOMPARE(rawFont.familyName(), familyName); + QCOMPARE(rawFont.pixelSize(), 26); + + QVERIFY(fontDatabase.removeApplicationFont(id)); +} + +void tst_QRawFont::copyConstructor_data() +{ + QTest::addColumn("hintingPreference"); + + QTest::newRow("Default hinting preference") << QFont::PreferDefaultHinting; + QTest::newRow("No hinting preference") << QFont::PreferNoHinting; + QTest::newRow("Vertical hinting preference") << QFont::PreferVerticalHinting; + QTest::newRow("Full hinting preference") << QFont::PreferFullHinting; +} + +void tst_QRawFont::copyConstructor() +{ + QFETCH(QFont::HintingPreference, hintingPreference); + + { + QString rawFontFamilyName; + int rawFontPixelSize; + qreal rawFontAscent; + qreal rawFontDescent; + int rawFontTableSize; + + QRawFont outerRawFont; + { + QRawFont rawFont(QString::fromLatin1(SRCDIR "testfont.ttf"), 11, hintingPreference); + QVERIFY(rawFont.isValid()); + + rawFontFamilyName = rawFont.familyName(); + rawFontPixelSize = rawFont.pixelSize(); + rawFontAscent = rawFont.ascent(); + rawFontDescent = rawFont.descent(); + rawFontTableSize = rawFont.fontTable("glyf").size(); + QVERIFY(rawFontTableSize > 0); + + { + QRawFont otherRawFont(rawFont); + QVERIFY(otherRawFont.isValid()); + QCOMPARE(otherRawFont.pixelSize(), rawFontPixelSize); + QCOMPARE(otherRawFont.familyName(), rawFontFamilyName); + QCOMPARE(otherRawFont.hintingPreference(), hintingPreference); + QCOMPARE(otherRawFont.ascent(), rawFontAscent); + QCOMPARE(otherRawFont.descent(), rawFontDescent); + QCOMPARE(otherRawFont.fontTable("glyf").size(), rawFontTableSize); + } + + { + QRawFont otherRawFont = rawFont; + QVERIFY(otherRawFont.isValid()); + QCOMPARE(otherRawFont.pixelSize(), rawFontPixelSize); + QCOMPARE(otherRawFont.familyName(), rawFontFamilyName); + QCOMPARE(otherRawFont.hintingPreference(), hintingPreference); + QCOMPARE(otherRawFont.ascent(), rawFontAscent); + QCOMPARE(otherRawFont.descent(), rawFontDescent); + QCOMPARE(otherRawFont.fontTable("glyf").size(), rawFontTableSize); + } + + outerRawFont = rawFont; + } + + QVERIFY(outerRawFont.isValid()); + QCOMPARE(outerRawFont.pixelSize(), rawFontPixelSize); + QCOMPARE(outerRawFont.familyName(), rawFontFamilyName); + QCOMPARE(outerRawFont.hintingPreference(), hintingPreference); + QCOMPARE(outerRawFont.ascent(), rawFontAscent); + QCOMPARE(outerRawFont.descent(), rawFontDescent); + QCOMPARE(outerRawFont.fontTable("glyf").size(), rawFontTableSize); + } +} + +void tst_QRawFont::detach_data() +{ + QTest::addColumn("hintingPreference"); + + QTest::newRow("Default hinting preference") << QFont::PreferDefaultHinting; + QTest::newRow("No hinting preference") << QFont::PreferNoHinting; + QTest::newRow("Vertical hinting preference") << QFont::PreferVerticalHinting; + QTest::newRow("Full hinting preference") << QFont::PreferFullHinting; +} + +void tst_QRawFont::detach() +{ + QFETCH(QFont::HintingPreference, hintingPreference); + + { + QString rawFontFamilyName; + int rawFontPixelSize; + qreal rawFontAscent; + qreal rawFontDescent; + int rawFontTableSize; + + QRawFont outerRawFont; + { + QRawFont rawFont(QString::fromLatin1(SRCDIR "testfont.ttf"), 11, hintingPreference); + QVERIFY(rawFont.isValid()); + + rawFontFamilyName = rawFont.familyName(); + rawFontPixelSize = rawFont.pixelSize(); + rawFontAscent = rawFont.ascent(); + rawFontDescent = rawFont.descent(); + rawFontTableSize = rawFont.fontTable("glyf").size(); + QVERIFY(rawFontTableSize > 0); + + { + QRawFont otherRawFont(rawFont); + + otherRawFont.loadFromFile(QLatin1String(SRCDIR "testfont.ttf"), + rawFontPixelSize, hintingPreference); + + QVERIFY(otherRawFont.isValid()); + QCOMPARE(otherRawFont.pixelSize(), rawFontPixelSize); + QCOMPARE(otherRawFont.familyName(), rawFontFamilyName); + QCOMPARE(otherRawFont.hintingPreference(), hintingPreference); + QCOMPARE(otherRawFont.ascent(), rawFontAscent); + QCOMPARE(otherRawFont.descent(), rawFontDescent); + QCOMPARE(otherRawFont.fontTable("glyf").size(), rawFontTableSize); + } + + { + QRawFont otherRawFont = rawFont; + + otherRawFont.loadFromFile(QLatin1String(SRCDIR "testfont.ttf"), + rawFontPixelSize, hintingPreference); + + QVERIFY(otherRawFont.isValid()); + QCOMPARE(otherRawFont.pixelSize(), rawFontPixelSize); + QCOMPARE(otherRawFont.familyName(), rawFontFamilyName); + QCOMPARE(otherRawFont.hintingPreference(), hintingPreference); + QCOMPARE(otherRawFont.ascent(), rawFontAscent); + QCOMPARE(otherRawFont.descent(), rawFontDescent); + QCOMPARE(otherRawFont.fontTable("glyf").size(), rawFontTableSize); + } + + outerRawFont = rawFont; + + rawFont.loadFromFile(QLatin1String(SRCDIR "testfont.ttf"), rawFontPixelSize, + hintingPreference); + } + + QVERIFY(outerRawFont.isValid()); + QCOMPARE(outerRawFont.pixelSize(), rawFontPixelSize); + QCOMPARE(outerRawFont.familyName(), rawFontFamilyName); + QCOMPARE(outerRawFont.hintingPreference(), hintingPreference); + QCOMPARE(outerRawFont.ascent(), rawFontAscent); + QCOMPARE(outerRawFont.descent(), rawFontDescent); + QCOMPARE(outerRawFont.fontTable("glyf").size(), rawFontTableSize); + } +} + +void tst_QRawFont::unsupportedWritingSystem_data() +{ + QTest::addColumn("hintingPreference"); + + QTest::newRow("Default hinting preference") << QFont::PreferDefaultHinting; + QTest::newRow("No hinting preference") << QFont::PreferNoHinting; + QTest::newRow("Vertical hinting preference") << QFont::PreferVerticalHinting; + QTest::newRow("Full hinting preference") << QFont::PreferFullHinting; +} + +void tst_QRawFont::unsupportedWritingSystem() +{ + QFETCH(QFont::HintingPreference, hintingPreference); + + QFontDatabase fontDatabase; + int id = fontDatabase.addApplicationFont(QLatin1String(SRCDIR "testfont.ttf")); + + QFont font("QtBidiTestFont"); + font.setHintingPreference(hintingPreference); + font.setPixelSize(12); + + QRawFont rawFont = QRawFont::fromFont(font, QFontDatabase::Any); + QCOMPARE(rawFont.familyName(), QString::fromLatin1("QtBidiTestFont")); + QCOMPARE(rawFont.pixelSize(), 12); + + rawFont = QRawFont::fromFont(font, QFontDatabase::Hebrew); + QCOMPARE(rawFont.familyName(), QString::fromLatin1("QtBidiTestFont")); + QCOMPARE(rawFont.pixelSize(), 12); + + QString arabicText = QFontDatabase::writingSystemSample(QFontDatabase::Arabic); + + QTextLayout layout; + layout.setFont(font); + layout.setText(arabicText); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QList glyphss = layout.glyphs(); + QCOMPARE(glyphss.size(), 1); + + QGlyphs glyphs = glyphss.at(0); + QRawFont layoutFont = glyphs.font(); + QVERIFY(layoutFont.familyName() != QString::fromLatin1("QtBidiTestFont")); + QCOMPARE(layoutFont.pixelSize(), 12); + + rawFont = QRawFont::fromFont(font, QFontDatabase::Arabic); + QCOMPARE(rawFont.familyName(), layoutFont.familyName()); + QCOMPARE(rawFont.pixelSize(), 12); + + fontDatabase.removeApplicationFont(id); +} + +QTEST_MAIN(tst_QRawFont) +#include "tst_qrawfont.moc" + +#endif // QT_NO_RAWFONT -- cgit v0.12 From 069e4441f2e14a82b4ae39601734acb71c909bd9 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Mon, 18 Apr 2011 11:11:47 +1000 Subject: Rename test class. Fixes warning from tst_maketestselftest about test class name not matching TARGET. Change-Id: I7a81d87bb64d2902e842d097248e33eacb388746 Reviewed-by: Rohan McGovern --- .../tst_exceptionsafety_objects.cpp | 32 +++++++++++----------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp b/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp index 3e4ccf5..c78782e 100644 --- a/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp +++ b/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp @@ -60,7 +60,7 @@ QT_USE_NAMESPACE #include "3rdparty/memcheck.h" #endif -class tst_ExceptionSafetyObjects: public QObject +class tst_ExceptionSafety_Objects: public QObject { Q_OBJECT @@ -156,7 +156,7 @@ struct DirCreator : public AbstractTester } }; -void tst_ExceptionSafetyObjects::objects_data() +void tst_ExceptionSafety_Objects::objects_data() { QTest::addColumn("objectCreator"); @@ -274,9 +274,9 @@ public: } }; -QtMsgHandler tst_ExceptionSafetyObjects::testMessageHandler; +QtMsgHandler tst_ExceptionSafety_Objects::testMessageHandler; -void tst_ExceptionSafetyObjects::safeMessageHandler(QtMsgType type, const char *msg) +void tst_ExceptionSafety_Objects::safeMessageHandler(QtMsgType type, const char *msg) { // this temporarily suspends OOM testing while handling a message int currentIndex = mallocFailIndex; @@ -301,7 +301,7 @@ void debugUnexpected() (*defaultUnexpected)(); } -void tst_ExceptionSafetyObjects::initTestCase() +void tst_ExceptionSafety_Objects::initTestCase() { // set handlers for bad exception cases, you might want to step in and breakpoint the default handlers too defaultTerminate = std::set_terminate(&debugTerminate); @@ -345,12 +345,12 @@ void tst_ExceptionSafetyObjects::initTestCase() QCOMPARE(malloc2Failed, 1); } -void tst_ExceptionSafetyObjects::cleanupTestCase() +void tst_ExceptionSafety_Objects::cleanupTestCase() { qInstallMsgHandler(testMessageHandler); } -void tst_ExceptionSafetyObjects::objects() +void tst_ExceptionSafety_Objects::objects() { QSKIP("This test currently crashes", SkipAll); QFETCH(AbstractTester *, objectCreator); @@ -389,7 +389,7 @@ template <> struct WidgetCreator : public AbstractTester QScopedPointer ptr(new QDesktopWidget()); } }; -void tst_ExceptionSafetyObjects::widgets_data() +void tst_ExceptionSafety_Objects::widgets_data() { #ifdef Q_OS_SYMBIAN // Initialise the S60 rasteriser, which crashes if started while out of memory @@ -456,7 +456,7 @@ void tst_ExceptionSafetyObjects::widgets_data() NEWROW(QTreeWidget); } -void tst_ExceptionSafetyObjects::widgets() +void tst_ExceptionSafety_Objects::widgets() { QSKIP("This test currently crashes", SkipAll); QFETCH(AbstractTester *, widgetCreator); @@ -722,12 +722,12 @@ static void containerData() QTest::newRow("erase moveable") << static_cast(containerEraseTest); } -void tst_ExceptionSafetyObjects::vector_data() +void tst_ExceptionSafety_Objects::vector_data() { containerData(); } -void tst_ExceptionSafetyObjects::vector() +void tst_ExceptionSafety_Objects::vector() { QFETCH(TestFunction, testFunction); @@ -738,30 +738,30 @@ void tst_ExceptionSafetyObjects::vector() doOOMTest(testFunction, 0); } -void tst_ExceptionSafetyObjects::list_data() +void tst_ExceptionSafety_Objects::list_data() { containerData(); } -void tst_ExceptionSafetyObjects::list() +void tst_ExceptionSafety_Objects::list() { QFETCH(TestFunction, testFunction); doOOMTest(testFunction, 0); } -void tst_ExceptionSafetyObjects::linkedList_data() +void tst_ExceptionSafety_Objects::linkedList_data() { containerData(); } -void tst_ExceptionSafetyObjects::linkedList() +void tst_ExceptionSafety_Objects::linkedList() { QFETCH(TestFunction, testFunction); doOOMTest(testFunction, 0); } -QTEST_MAIN(tst_ExceptionSafetyObjects) +QTEST_MAIN(tst_ExceptionSafety_Objects) #include "tst_exceptionsafety_objects.moc" #endif // QT_NO_EXCEPTIONS -- cgit v0.12 From ced0a98b5274be6a62ae7e4a0f9fc3161d0e40cb Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Mon, 18 Apr 2011 14:27:44 +1000 Subject: Make test compile in namespaced build. Change-Id: I824864b8db755a8dc731e3c9de39e3dd7b16224a Reviewed-by: Rohan McGovern --- tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp b/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp index c78782e..ab589ed 100644 --- a/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp +++ b/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp @@ -549,7 +549,9 @@ struct IntegerMoveable }; int IntegerMoveable::instanceCount = 0; +QT_BEGIN_NAMESPACE Q_DECLARE_TYPEINFO(IntegerMoveable, Q_MOVABLE_TYPE); +QT_END_NAMESPACE template class Container> void containerInsertTest(QObject*) -- cgit v0.12 From 3788a90338e9328710b9d3335a63fb85ab7d97fc Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Mon, 18 Apr 2011 15:38:38 +1000 Subject: Partially re-enable exception safety test Re-enabling for object types that don't crash the test. Change-Id: I8c2f0d02171c973bf1ede227d4139b52cac5939f Reviewed-by: Rohan McGovern --- .../tst_exceptionsafety_objects.cpp | 46 +++++++++++++++++++++- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp b/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp index ab589ed..cb37049 100644 --- a/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp +++ b/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp @@ -352,7 +352,14 @@ void tst_ExceptionSafety_Objects::cleanupTestCase() void tst_ExceptionSafety_Objects::objects() { - QSKIP("This test currently crashes", SkipAll); + QLatin1String tag = QLatin1String(QTest::currentDataTag()); + if (tag == QLatin1String("QFile") + || tag == QLatin1String("QProcess") + || tag == QLatin1String("QSettings") + || tag == QLatin1String("QThread") + || tag == QLatin1String("QThreadPool")) + QSKIP("This type of object is not currently strongly exception safe", SkipSingle); + QFETCH(AbstractTester *, objectCreator); doOOMTest(*objectCreator, 0); @@ -458,7 +465,42 @@ void tst_ExceptionSafety_Objects::widgets_data() void tst_ExceptionSafety_Objects::widgets() { - QSKIP("This test currently crashes", SkipAll); + QLatin1String tag = QLatin1String(QTest::currentDataTag()); + if (tag == QLatin1String("QColumnView") + || tag == QLatin1String("QComboBox") + || tag == QLatin1String("QCommandLinkButton") + || tag == QLatin1String("QDateEdit") + || tag == QLatin1String("QDateTimeEdit") + || tag == QLatin1String("QDesktopWidget") + || tag == QLatin1String("QDoubleSpinBox") + || tag == QLatin1String("QFontComboBox") + || tag == QLatin1String("QGroupBox") + || tag == QLatin1String("QLineEdit") + || tag == QLatin1String("QListView") + || tag == QLatin1String("QListWidget") + || tag == QLatin1String("QMainWindow") + || tag == QLatin1String("QMenu") + || tag == QLatin1String("QMenuBar") + || tag == QLatin1String("QPlainTextEdit") + || tag == QLatin1String("QProgressBar") + || tag == QLatin1String("QPushButton") + || tag == QLatin1String("QScrollArea") + || tag == QLatin1String("QSpinBox") + || tag == QLatin1String("QStackedWidget") + || tag == QLatin1String("QStatusBar") + || tag == QLatin1String("QTableView") + || tag == QLatin1String("QTableWidget") + || tag == QLatin1String("QTabWidget") + || tag == QLatin1String("QTextBrowser") + || tag == QLatin1String("QTextEdit") + || tag == QLatin1String("QTimeEdit") + || tag == QLatin1String("QToolBar") + || tag == QLatin1String("QToolBox") + || tag == QLatin1String("QTreeView") + || tag == QLatin1String("QTreeWidget") + || tag == QLatin1String("QWorkspace")) + QSKIP("This type of widget is not currently strongly exception safe", SkipSingle); + QFETCH(AbstractTester *, widgetCreator); doOOMTest(*widgetCreator, 0, 00000); -- cgit v0.12 From 5a35876226939167f664b826807d511a81167b24 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 18 Apr 2011 09:51:13 +0200 Subject: Make sure #ifdef'd tests still have main() function Otherwise it won't link on QWS Reviewed-by: TrustMe --- tests/auto/qglyphs/tst_qglyphs.cpp | 10 +++++++--- tests/auto/qrawfont/tst_qrawfont.cpp | 8 +++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/tests/auto/qglyphs/tst_qglyphs.cpp b/tests/auto/qglyphs/tst_qglyphs.cpp index a9ae556..ffa0d00 100644 --- a/tests/auto/qglyphs/tst_qglyphs.cpp +++ b/tests/auto/qglyphs/tst_qglyphs.cpp @@ -46,14 +46,13 @@ #include #include -#if !defined(QT_NO_RAWFONT) - // #define DEBUG_SAVE_IMAGE class tst_QGlyphs: public QObject { Q_OBJECT +#if !defined(QT_NO_RAWFONT) private slots: void initTestCase(); void cleanupTestCase(); @@ -77,8 +76,12 @@ private slots: private: int m_testFontId; QFont m_testFont; +#endif // QT_NO_RAWFONT + }; +#if !defined(QT_NO_RAWFONT) + Q_DECLARE_METATYPE(QGlyphs); void tst_QGlyphs::initTestCase() @@ -572,7 +575,8 @@ void tst_QGlyphs::drawRightToLeft() } +#endif // QT_NO_RAWFONT + QTEST_MAIN(tst_QGlyphs) #include "tst_qglyphs.moc" -#endif // QT_NO_RAWFONT diff --git a/tests/auto/qrawfont/tst_qrawfont.cpp b/tests/auto/qrawfont/tst_qrawfont.cpp index c20b41d..3aa4006 100644 --- a/tests/auto/qrawfont/tst_qrawfont.cpp +++ b/tests/auto/qrawfont/tst_qrawfont.cpp @@ -44,12 +44,11 @@ #include #include -#if !defined(QT_NO_RAWFONT) - class tst_QRawFont: public QObject { Q_OBJECT +#if !defined(QT_NO_RAWFONT) private slots: void invalidRawFont(); @@ -92,8 +91,10 @@ private slots: void unsupportedWritingSystem_data(); void unsupportedWritingSystem(); +#endif // QT_NO_RAWFONT }; +#if !defined(QT_NO_RAWFONT) Q_DECLARE_METATYPE(QFont::HintingPreference) Q_DECLARE_METATYPE(QFont::Style) Q_DECLARE_METATYPE(QFont::Weight) @@ -806,7 +807,8 @@ void tst_QRawFont::unsupportedWritingSystem() fontDatabase.removeApplicationFont(id); } +#endif // QT_NO_RAWFONT + QTEST_MAIN(tst_QRawFont) #include "tst_qrawfont.moc" -#endif // QT_NO_RAWFONT -- cgit v0.12 From 01dfb9ca25bfaec5784f404dcd4bf41bbc2b6fcb Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Mon, 18 Apr 2011 17:21:03 +1000 Subject: Don't try to run exceptionsafety_objects test by default on windows. This test relies on some API specific to MSVC's debug runtime, which is not always guaranteed to be available. Change-Id: Ib0ae4694ad51f59198dadfce802f0dfdf0522002 Reviewed-by: Rohan McGovern --- tests/auto/other.pro | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/auto/other.pro b/tests/auto/other.pro index 4d8ff4e..89f9e53 100644 --- a/tests/auto/other.pro +++ b/tests/auto/other.pro @@ -3,7 +3,6 @@ TEMPLATE=subdirs SUBDIRS=\ - exceptionsafety_objects \ # baselineexample \ Just an example demonstrating qbaselinetest usage lancelot \ qaccessibility \ @@ -56,6 +55,8 @@ symbian { qs60mainapplication } +!win32-msvc*:!wince*:SUBDIRS += exceptionsafety_objects + # Following tests depends on private API !contains(QT_CONFIG, private_tests): SUBDIRS -= \ qcssparser \ -- cgit v0.12 From 10f3f270c8a319205590ae13bdeab063d5216441 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Mon, 18 Apr 2011 18:21:03 +1000 Subject: Cosmetic changes to exceptionsafety_objects test Sort test data alphabetically and remove excess whitespace. Change-Id: I0e244efca9e9adbe747a375a28a63f70992ef4f8 Reviewed-by: Trust Me --- .../tst_exceptionsafety_objects.cpp | 33 ++++++++++------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp b/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp index cb37049..2f094f3 100644 --- a/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp +++ b/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp @@ -164,12 +164,12 @@ void tst_ExceptionSafety_Objects::objects_data() NEWROW(QObject); NEWROW(QBuffer); NEWROW(QFile); + NEWROW(QFSFileEngine); NEWROW(QProcess); NEWROW(QSettings); NEWROW(QThread); NEWROW(QThreadPool); NEWROW(QTranslator); - NEWROW(QFSFileEngine); #define NEWROW2(T, CREATOR) QTest::newRow(#T) << static_cast(new CREATOR) NEWROW2(QBitArray, BitArrayCreator); @@ -177,7 +177,6 @@ void tst_ExceptionSafety_Objects::objects_data() NEWROW2(QCryptographicHash, CryptographicHashCreator); NEWROW2(QDataStream, DataStreamCreator); NEWROW2(QDir, DirCreator); - } // create and destructs an object, and lets each and every allocation @@ -363,7 +362,7 @@ void tst_ExceptionSafety_Objects::objects() QFETCH(AbstractTester *, objectCreator); doOOMTest(*objectCreator, 0); - + delete objectCreator; } @@ -400,9 +399,9 @@ void tst_ExceptionSafety_Objects::widgets_data() { #ifdef Q_OS_SYMBIAN // Initialise the S60 rasteriser, which crashes if started while out of memory - QImage image(20, 20, QImage::Format_RGB32); - QPainter p(&image); - p.drawText(0, 15, "foo"); + QImage image(20, 20, QImage::Format_RGB32); + QPainter p(&image); + p.drawText(0, 15, "foo"); #endif QTest::addColumn("widgetCreator"); @@ -413,23 +412,27 @@ void tst_ExceptionSafety_Objects::widgets_data() NEWROW(QWidget); NEWROW(QButtonGroup); - NEWROW(QDesktopWidget); NEWROW(QCheckBox); + NEWROW(QColumnView); NEWROW(QComboBox); NEWROW(QCommandLinkButton); NEWROW(QDateEdit); NEWROW(QDateTimeEdit); + NEWROW(QDesktopWidget); NEWROW(QDial); NEWROW(QDoubleSpinBox); NEWROW(QFocusFrame); NEWROW(QFontComboBox); NEWROW(QFrame); NEWROW(QGroupBox); - NEWROW(QLCDNumber); NEWROW(QLabel); NEWROW(QLCDNumber); NEWROW(QLineEdit); + NEWROW(QListView); + NEWROW(QListWidget); + NEWROW(QMainWindow); NEWROW(QMenu); + NEWROW(QMenuBar); NEWROW(QPlainTextEdit); NEWROW(QProgressBar); NEWROW(QPushButton); @@ -443,24 +446,18 @@ void tst_ExceptionSafety_Objects::widgets_data() NEWROW(QStackedWidget); NEWROW(QStatusBar); NEWROW(QTabBar); + NEWROW(QTableView); + NEWROW(QTableWidget); NEWROW(QTabWidget); NEWROW(QTextBrowser); NEWROW(QTextEdit); NEWROW(QTimeEdit); + NEWROW(QToolBar); NEWROW(QToolBox); NEWROW(QToolButton); - NEWROW(QStatusBar); - NEWROW(QToolBar); - NEWROW(QMenuBar); - NEWROW(QMainWindow); - NEWROW(QWorkspace); - NEWROW(QColumnView); - NEWROW(QListView); - NEWROW(QListWidget); - NEWROW(QTableView); - NEWROW(QTableWidget); NEWROW(QTreeView); NEWROW(QTreeWidget); + NEWROW(QWorkspace); } void tst_ExceptionSafety_Objects::widgets() -- cgit v0.12 From 3c659eb590aecbcdb40cb498901e757e780fa892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 18 Apr 2011 10:31:05 +0200 Subject: Made linearGradientSymmetry test pass on qreal=float platforms. We need to loosen the requirements a bit when qreal is float... Just skip the two failing test cases for now. Reviewed-by: Eskil Abrahamsen Blomfeldt --- tests/auto/qpainter/tst_qpainter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/qpainter/tst_qpainter.cpp b/tests/auto/qpainter/tst_qpainter.cpp index fa80635..64dacec 100644 --- a/tests/auto/qpainter/tst_qpainter.cpp +++ b/tests/auto/qpainter/tst_qpainter.cpp @@ -3989,7 +3989,7 @@ void tst_QPainter::linearGradientSymmetry_data() { QTest::addColumn("stops"); - { + if (sizeof(qreal) != sizeof(float)) { QGradientStops stops; stops << qMakePair(qreal(0.0), QColor(Qt::blue)); stops << qMakePair(qreal(0.2), QColor(220, 220, 220, 0)); @@ -4006,7 +4006,7 @@ void tst_QPainter::linearGradientSymmetry_data() QTest::newRow("two stops") << stops; } - { + if (sizeof(qreal) != sizeof(float)) { QGradientStops stops; stops << qMakePair(qreal(0.3), QColor(Qt::blue)); stops << qMakePair(qreal(0.6), QColor(Qt::black)); -- cgit v0.12 From 4024a08239c3e69bb2e0ca045ccbdf3fc900f675 Mon Sep 17 00:00:00 2001 From: Fabien Freling Date: Fri, 15 Apr 2011 15:05:03 +0200 Subject: Fix an race condition in the auto test. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Deleting the page in the wizard without removing it first leads to a crash when the wizard tries to access a deleted page. Reviewed-by: Samuel Rødal --- tests/auto/qwizard/tst_qwizard.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/auto/qwizard/tst_qwizard.cpp b/tests/auto/qwizard/tst_qwizard.cpp index bbac8a3..5667d40 100644 --- a/tests/auto/qwizard/tst_qwizard.cpp +++ b/tests/auto/qwizard/tst_qwizard.cpp @@ -2551,8 +2551,8 @@ void tst_QWizard::task177022_setFixedSize() QWizard wiz; QWizardPage page1; QWizardPage page2; - wiz.addPage(&page1); - wiz.addPage(&page2); + int page1_id = wiz.addPage(&page1); + int page2_id = wiz.addPage(&page2); wiz.setFixedSize(width, height); if (wiz.wizardStyle() == QWizard::AeroStyle) QEXPECT_FAIL("", "this probably relates to non-client area hack for AeroStyle titlebar " @@ -2579,6 +2579,8 @@ void tst_QWizard::task177022_setFixedSize() QCOMPARE(wiz.maximumWidth(), width); QCOMPARE(wiz.maximumHeight(), height); + wiz.removePage(page1_id); + wiz.removePage(page2_id); } void tst_QWizard::task248107_backButton() -- cgit v0.12 From 3197fe2af911673c6291db0102e90a0d7f6ae926 Mon Sep 17 00:00:00 2001 From: Fabien Freling Date: Mon, 18 Apr 2011 11:49:57 +0200 Subject: Revert "Switch the default graphics system to raster on Mac." This reverts commit a5d40fd3814ab7c8e865912c03a918bfd5994998. We have to fix the regressions due to the raster engine before putting it by default. --- src/gui/painting/qgraphicssystemfactory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qgraphicssystemfactory.cpp b/src/gui/painting/qgraphicssystemfactory.cpp index 6212674..62a60d7 100644 --- a/src/gui/painting/qgraphicssystemfactory.cpp +++ b/src/gui/painting/qgraphicssystemfactory.cpp @@ -74,7 +74,7 @@ QGraphicsSystem *QGraphicsSystemFactory::create(const QString& key) if (system.isEmpty()) { system = QLatin1String("runtime"); } -#elif defined (QT_GRAPHICSSYSTEM_RASTER) && !defined(Q_WS_WIN) && !defined(Q_OS_SYMBIAN) || defined(Q_WS_X11) || (defined (Q_WS_MAC) && defined(QT_MAC_USE_COCOA)) +#elif defined (QT_GRAPHICSSYSTEM_RASTER) && !defined(Q_WS_WIN) && !defined(Q_OS_SYMBIAN) || defined(Q_WS_X11) if (system.isEmpty()) { system = QLatin1String("raster"); } -- cgit v0.12 From e004701bd7ba9e4a7cd5ac1bf784829feae16cae Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Mon, 18 Apr 2011 11:21:16 +0200 Subject: Disable tst_QPixmap::onlyNullPixmapsOutsideGuiThread on Mac No need to check it anymore after the switch to raster engine. Reviewed-by: Eskil --- tests/auto/qpixmap/tst_qpixmap.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/qpixmap/tst_qpixmap.cpp b/tests/auto/qpixmap/tst_qpixmap.cpp index 4d032e8..4ba51de 100644 --- a/tests/auto/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/qpixmap/tst_qpixmap.cpp @@ -1337,7 +1337,7 @@ void tst_QPixmap::toSymbianCFbsBitmap() void tst_QPixmap::onlyNullPixmapsOutsideGuiThread() { -#if !defined(Q_WS_WIN) +#if !defined(Q_WS_WIN) && !defined(Q_WS_MAC) class Thread : public QThread { public: @@ -1370,7 +1370,7 @@ void tst_QPixmap::onlyNullPixmapsOutsideGuiThread() thread.wait(); #endif -#endif // !defined(Q_WS_WIN) +#endif // !defined(Q_WS_WIN) && !defined(Q_WS_MAC) } void tst_QPixmap::refUnref() -- cgit v0.12 From da8f333cfe17a53d475208efa36fa369a9ee4638 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 18 Apr 2011 15:40:26 +0300 Subject: Do not modify window size for fullscreen windows in setGeometry_sys Minimum sizes of widgets can cause windows to expand beyond screen limits in QWidgetPrivate::setGeometry_sys. Normally this is not noticeable as the window size is forced in various places to the clientRect, but there are certain sequences where the size set in setGeometry_sys is the final one, resulting in too large windows. Removed the modification of window size in setGeometry_sys for fullscreen windows for which the correct size is already requested. Task-number: QTBUG-18749 Reviewed-by: Sami Merila --- src/gui/kernel/qwidget_s60.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 83e46e5..96b0776 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -239,7 +239,16 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) if (w != oldSize.width() || h != oldSize.height()) data.window_state &= ~Qt::WindowMaximized; - if (extra) { // any size restrictions? + bool checkExtra = true; + if (q->isWindow() && (data.window_state & Qt::WindowFullScreen)) { + // Do not modity window size for fullscreen windows, if requested + // size is already equal to clientRect. + TRect r = static_cast(S60->appUi())->ClientRect(); + if (w == r.Width() && h == r.Height()) + checkExtra = false; + } + + if (checkExtra && extra) { // any size restrictions? w = qMin(w,extra->maxw); h = qMin(h,extra->maxh); w = qMax(w,extra->minw); -- cgit v0.12 From 62e87f8597f6c1c7622125a26747636d61a6c7ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 18 Apr 2011 15:23:55 +0200 Subject: Fixes compilation of wayland plugin after latest changes in wayland. --- src/plugins/platforms/wayland/qwaylandbuffer.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/platforms/wayland/qwaylandbuffer.h b/src/plugins/platforms/wayland/qwaylandbuffer.h index 8779d5f..faeb3e8 100644 --- a/src/plugins/platforms/wayland/qwaylandbuffer.h +++ b/src/plugins/platforms/wayland/qwaylandbuffer.h @@ -44,6 +44,7 @@ #include +#include #include class QWaylandBuffer { -- cgit v0.12 From 13190f3a8593b1b255929ebc52c9ad95a21b4669 Mon Sep 17 00:00:00 2001 From: con Date: Mon, 18 Apr 2011 16:12:15 +0200 Subject: Compile fix for QPA's session manager. Include QApplication, so the compiler definitely knows that it's a QObject. Reviewed-by: Paul Olav Tvete --- src/gui/kernel/qsessionmanager_qpa.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/kernel/qsessionmanager_qpa.cpp b/src/gui/kernel/qsessionmanager_qpa.cpp index ef532d7..68685b4 100644 --- a/src/gui/kernel/qsessionmanager_qpa.cpp +++ b/src/gui/kernel/qsessionmanager_qpa.cpp @@ -42,6 +42,8 @@ #include #include +#include + #ifndef QT_NO_SESSIONMANAGER QT_BEGIN_NAMESPACE -- cgit v0.12 From 41aa023ef6019ac9745b780c953f48b8bbc42a42 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 18 Apr 2011 17:05:38 +0200 Subject: Create a cleanup stack for each new thread on Symbian. The native thread implementation in Qt 4.8 did not call CTrapCleanup::New() which resulted in E32USER-CBASE 69 panics in applications when they tried to use the cleanup stack in a thread's run() function. In 4.7 this was working because OpenC's pthread implementation created a CTrapCleanup automatically. Now we do it also in the native Symbian thread implementation. Trask-number: QTBUG-18822 Reviewed-by: Murray Read --- src/corelib/thread/qthread_symbian.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/corelib/thread/qthread_symbian.cpp b/src/corelib/thread/qthread_symbian.cpp index 1474b36..436c105 100644 --- a/src/corelib/thread/qthread_symbian.cpp +++ b/src/corelib/thread/qthread_symbian.cpp @@ -319,6 +319,8 @@ void *QThreadPrivate::start(void *arg) data->quitNow = thr->d_func()->exited; } + CTrapCleanup *cleanup = CTrapCleanup::New(); + // ### TODO: allow the user to create a custom event dispatcher createEventDispatcher(data); @@ -327,6 +329,8 @@ void *QThreadPrivate::start(void *arg) QThreadPrivate::finish(arg); + delete cleanup; + return 0; } -- cgit v0.12 From 6d35b8078607e648a19d863f3437edb7e238f0f4 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Fri, 15 Apr 2011 14:09:43 +0100 Subject: Allow a network configuration to be included in a proxy query When Qt is compiled with bearer management support, the network configuration can be included as a parameter in QNetworkProxyQuery. This allows QNetworkProxyFactory::systemProxyForQuery to get the right proxy setting for a specific network. For example a mobile phone could have network configurations for home WLAN, work WLAN and 3G data access points, each with different proxy configurations. Task-number: QTBUG-18618 Reviewed-by: Peter Hartmann --- src/network/kernel/qnetworkproxy.cpp | 98 ++++++++++++++++++++++++++++ src/network/kernel/qnetworkproxy.h | 16 +++++ src/network/kernel/qnetworkproxy_symbian.cpp | 13 ++-- 3 files changed, 123 insertions(+), 4 deletions(-) diff --git a/src/network/kernel/qnetworkproxy.cpp b/src/network/kernel/qnetworkproxy.cpp index 68ff955..14db913 100644 --- a/src/network/kernel/qnetworkproxy.cpp +++ b/src/network/kernel/qnetworkproxy.cpp @@ -228,6 +228,10 @@ #include "qmutex.h" #include "qurl.h" +#ifndef QT_NO_BEARERMANAGEMENT +#include +#endif + QT_BEGIN_NAMESPACE class QSocks5SocketEngineHandler; @@ -716,6 +720,9 @@ public: QUrl remote; int localPort; QNetworkProxyQuery::QueryType type; +#ifndef QT_NO_BEARERMANAGEMENT + QNetworkConfiguration config; +#endif }; template<> void QSharedDataPointer::detach() @@ -777,6 +784,11 @@ template<> void QSharedDataPointer::detach() like choosing an caching HTTP proxy for HTTP-based connections, but a more powerful SOCKSv5 proxy for all others. + The network configuration specifies which configuration to use, + when bearer management is used. For example on a mobile phone + the proxy settings are likely to be different for the cellular + network vs WLAN. + Some of the criteria may not make sense in all of the types of query. The following table lists the criteria that are most commonly used, according to the type of query. @@ -902,6 +914,68 @@ QNetworkProxyQuery::QNetworkProxyQuery(quint16 bindPort, const QString &protocol d->type = queryType; } +#ifndef QT_NO_BEARERMANAGEMENT +/*! + Constructs a QNetworkProxyQuery with the URL \a requestUrl and + sets the query type to \a queryType. The specified \a networkConfiguration + is used to resolve the proxy settings. + + \sa protocolTag(), peerHostName(), peerPort(), networkConfiguration() +*/ +QNetworkProxyQuery::QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration, + const QUrl &requestUrl, QueryType queryType) +{ + d->config = networkConfiguration; + d->remote = requestUrl; + d->type = queryType; +} + +/*! + Constructs a QNetworkProxyQuery of type \a queryType and sets the + protocol tag to be \a protocolTag. This constructor is suitable + for QNetworkProxyQuery::TcpSocket queries, because it sets the + peer hostname to \a hostname and the peer's port number to \a + port. The specified \a networkConfiguration + is used to resolve the proxy settings. + + \sa networkConfiguration() +*/ +QNetworkProxyQuery::QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration, + const QString &hostname, int port, + const QString &protocolTag, + QueryType queryType) +{ + d->config = networkConfiguration; + d->remote.setScheme(protocolTag); + d->remote.setHost(hostname); + d->remote.setPort(port); + d->type = queryType; +} + +/*! + Constructs a QNetworkProxyQuery of type \a queryType and sets the + protocol tag to be \a protocolTag. This constructor is suitable + for QNetworkProxyQuery::TcpSocket queries because it sets the + local port number to \a bindPort. The specified \a networkConfiguration + is used to resolve the proxy settings. + + Note that \a bindPort is of type quint16 to indicate the exact + port number that is requested. The value of -1 (unknown) is not + allowed in this context. + + \sa localPort(), networkConfiguration() +*/ +QNetworkProxyQuery::QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration, + quint16 bindPort, const QString &protocolTag, + QueryType queryType) +{ + d->config = networkConfiguration; + d->remote.setScheme(protocolTag); + d->localPort = bindPort; + d->type = queryType; +} +#endif + /*! Constructs a QNetworkProxyQuery object that is a copy of \a other. */ @@ -1116,6 +1190,30 @@ void QNetworkProxyQuery::setUrl(const QUrl &url) d->remote = url; } +#ifndef QT_NO_BEARERMANAGEMENT +QNetworkConfiguration QNetworkProxyQuery::networkConfiguration() const +{ + return d ? d->config : QNetworkConfiguration(); +} + +/*! + Sets the network configuration component of this QNetworkProxyQuery + object to be \a networkConfiguration. The network configuration can + be used to return different proxy settings based on the network in + use, for example WLAN vs cellular networks on a mobile phone. + + In the case of "user choice" or "service network" configurations, + you should first start the QNetworkSession and obtain the active + configuration from its properties. + + \sa networkConfiguration +*/ +void QNetworkProxyQuery::setNetworkConfiguration(const QNetworkConfiguration &networkConfiguration) +{ + d->config = networkConfiguration; +} +#endif + /*! \class QNetworkProxyFactory \brief The QNetworkProxyFactory class provides fine-grained proxy selection. diff --git a/src/network/kernel/qnetworkproxy.h b/src/network/kernel/qnetworkproxy.h index 26562d5..e16b29e 100644 --- a/src/network/kernel/qnetworkproxy.h +++ b/src/network/kernel/qnetworkproxy.h @@ -54,6 +54,7 @@ QT_BEGIN_NAMESPACE QT_MODULE(Network) class QUrl; +class QNetworkConfiguration; class QNetworkProxyQueryPrivate; class Q_NETWORK_EXPORT QNetworkProxyQuery @@ -73,6 +74,16 @@ public: QNetworkProxyQuery(quint16 bindPort, const QString &protocolTag = QString(), QueryType queryType = TcpServer); QNetworkProxyQuery(const QNetworkProxyQuery &other); +#ifndef QT_NO_BEARERMANAGEMENT + QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration, + const QUrl &requestUrl, QueryType queryType = UrlRequest); + QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration, + const QString &hostname, int port, const QString &protocolTag = QString(), + QueryType queryType = TcpSocket); + QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration, + quint16 bindPort, const QString &protocolTag = QString(), + QueryType queryType = TcpServer); +#endif ~QNetworkProxyQuery(); QNetworkProxyQuery &operator=(const QNetworkProxyQuery &other); bool operator==(const QNetworkProxyQuery &other) const; @@ -97,6 +108,11 @@ public: QUrl url() const; void setUrl(const QUrl &url); +#ifndef QT_NO_BEARERMANAGEMENT + QNetworkConfiguration networkConfiguration() const; + void setNetworkConfiguration(const QNetworkConfiguration &networkConfiguration); +#endif + private: QSharedDataPointer d; }; diff --git a/src/network/kernel/qnetworkproxy_symbian.cpp b/src/network/kernel/qnetworkproxy_symbian.cpp index 79dfb27..4ba14c0 100644 --- a/src/network/kernel/qnetworkproxy_symbian.cpp +++ b/src/network/kernel/qnetworkproxy_symbian.cpp @@ -58,6 +58,7 @@ #include // CCDIAPRecord, CCDProxiesRecord #include // KCDTIdIAPRecord, KCDTIdProxiesRecord #include +#include #include using namespace CommsDat; @@ -88,7 +89,7 @@ class SymbianProxyQuery { public: static QNetworkConfiguration findCurrentConfiguration(QNetworkConfigurationManager& configurationManager); - static SymbianIapId getIapId(QNetworkConfigurationManager& configurationManager); + static SymbianIapId getIapId(QNetworkConfigurationManager &configurationManager, const QNetworkProxyQuery &query); static CCDIAPRecord *getIapRecordLC(TUint32 aIAPId, CMDBSession &aDb); static CMDBRecordSet *prepareQueryLC(TUint32 serviceId, TDesC& serviceType); static QList proxyQueryL(TUint32 aIAPId, const QNetworkProxyQuery &query); @@ -137,11 +138,15 @@ QNetworkConfiguration SymbianProxyQuery::findCurrentConfiguration(QNetworkConfig return currentConfig; } -SymbianIapId SymbianProxyQuery::getIapId(QNetworkConfigurationManager& configurationManager) +SymbianIapId SymbianProxyQuery::getIapId(QNetworkConfigurationManager& configurationManager, const QNetworkProxyQuery &query) { SymbianIapId iapId; - QNetworkConfiguration currentConfig = findCurrentConfiguration(configurationManager); + QNetworkConfiguration currentConfig = query.networkConfiguration(); + if (!currentConfig.isValid()) { + //If config is not specified, then try to find out an active or default one + currentConfig = findCurrentConfiguration(configurationManager); + } if (currentConfig.isValid()) { // Note: the following code assumes that the identifier is in format // I_xxxx where xxxx is the identifier of IAP. This is meant as a @@ -249,7 +254,7 @@ QList QNetworkProxyFactory::systemProxyForQuery(const QNetworkPro SymbianIapId iapId; TInt error; QNetworkConfigurationManager manager; - iapId = SymbianProxyQuery::getIapId(manager); + iapId = SymbianProxyQuery::getIapId(manager, query); if (iapId.isValid()) { TRAP(error, proxies = SymbianProxyQuery::proxyQueryL(iapId.iapId(), query)) if (error != KErrNone) { -- cgit v0.12 From c3ee4c09dc90d09b729ec70b2ebc27136bd2da2e Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Mon, 18 Apr 2011 15:23:33 +0100 Subject: Enable per network configuration proxy settings in QNetworkAccessManager Delayed the resolving of the proxy until the backend is being started. This is because the proxy settings are not known until after QNetworkAccessManager has brought the network online using QNetworkSession. On Nokia's symbian3 phones, the default network configuration is a service network containing a list of access points in priority order. For a typical user, this will include one or more WLAN networks and a cellular network - each of which can have different proxy settings. Task-number: QTBUG-18618 Reviewed-by: Peter Hartmann --- src/network/access/qnetworkaccessbackend.cpp | 76 +++++++++++++++++++--------- src/network/access/qnetworkaccessmanager.cpp | 4 -- 2 files changed, 53 insertions(+), 27 deletions(-) diff --git a/src/network/access/qnetworkaccessbackend.cpp b/src/network/access/qnetworkaccessbackend.cpp index 6220abe..2aea350 100644 --- a/src/network/access/qnetworkaccessbackend.cpp +++ b/src/network/access/qnetworkaccessbackend.cpp @@ -41,6 +41,7 @@ #include "qnetworkaccessbackend_p.h" #include "qnetworkaccessmanager_p.h" +#include "qnetworkconfigmanager.h" #include "qnetworkrequest.h" #include "qnetworkreply.h" #include "qnetworkreply_p.h" @@ -343,8 +344,6 @@ void QNetworkAccessBackend::sslErrors(const QList &errors) #endif } -#ifndef QT_NO_BEARERMANAGEMENT - /*! Starts the backend. Returns true if the backend is started. Returns false if the backend could not be started due to an unopened or roaming session. The caller should recall this @@ -352,31 +351,62 @@ void QNetworkAccessBackend::sslErrors(const QList &errors) */ bool QNetworkAccessBackend::start() { - if (!manager->networkSession) { - open(); - return true; - } - - // This is not ideal. - const QString host = reply->url.host(); - if (host == QLatin1String("localhost") || - QHostAddress(host) == QHostAddress::LocalHost || - QHostAddress(host) == QHostAddress::LocalHostIPv6) { - // Don't need an open session for localhost access. - open(); - return true; +#ifndef QT_NO_BEARERMANAGEMENT + // For bearer, check if session start is required + if (manager->networkSession) { + // session required + if (manager->networkSession->isOpen() && + manager->networkSession->state() == QNetworkSession::Connected) { + // Session is already open and ready to use. + // copy network session down to the backend + setProperty("_q_networksession", QVariant::fromValue(manager->networkSession)); + } else { + // Session not ready, but can skip for loopback connections + + // This is not ideal. + const QString host = reply->url.host(); + + if (host == QLatin1String("localhost") || + QHostAddress(host) == QHostAddress::LocalHost || + QHostAddress(host) == QHostAddress::LocalHostIPv6) { + // Don't need an open session for localhost access. + } else { + // need to wait for session to be opened + return false; + } + } } +#endif - if (manager->networkSession->isOpen() && - manager->networkSession->state() == QNetworkSession::Connected) { - //copy network session down to the backend - setProperty("_q_networksession", QVariant::fromValue(manager->networkSession)); - open(); - return true; +#ifndef QT_NO_NETWORKPROXY +#ifndef QT_NO_BEARERMANAGEMENT + // Get the proxy settings from the network session (in the case of service networks, + // the proxy settings change depending which AP was activated) + QNetworkSession *session = manager->networkSession.data(); + QNetworkConfiguration config; + if (session) { + QNetworkConfigurationManager configManager; + // The active configuration tells us what IAP is in use + QVariant v = session->sessionProperty(QLatin1String("ActiveConfiguration")); + if (v.isValid()) + config = configManager.configurationFromIdentifier(qvariant_cast(v)); + // Fallback to using the configuration if no active configuration + if (!config.isValid()) + config = session->configuration(); + // or unspecified configuration if that is no good either + if (!config.isValid()) + config = QNetworkConfiguration(); } + reply->proxyList = manager->queryProxy(QNetworkProxyQuery(config, url())); +#else // QT_NO_BEARERMANAGEMENT + // Without bearer management, the proxy depends only on the url + reply->proxyList = manager->queryProxy(QNetworkProxyQuery(url())); +#endif +#endif - return false; + // now start the request + open(); + return true; } -#endif QT_END_NAMESPACE diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 5a7521e..ba0fe7b 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -986,10 +986,6 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera // third step: find a backend priv->backend = d->findBackend(op, request); -#ifndef QT_NO_NETWORKPROXY - QList proxyList = d->queryProxy(QNetworkProxyQuery(request.url())); - priv->proxyList = proxyList; -#endif if (priv->backend) { priv->backend->setParent(reply); priv->backend->reply = priv; -- cgit v0.12 From 445e70499dde512b5c957721b53ac22f0df72ee7 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Mon, 18 Apr 2011 15:30:39 +0100 Subject: Fix QNetworkReplyImpl error handling The backend was never started when compiled without bearer management, now it is. Now emits the error signal in case of startup errors which would leave the state machine hanging. Previously it just printed a warning. Reviewed-by: Peter Hartmann --- src/network/access/qnetworkreplyimpl.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index 9eb505d..34fd7a7 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -90,10 +90,10 @@ void QNetworkReplyImplPrivate::_q_startOperation() return; } + if (!backend->start()) { #ifndef QT_NO_BEARERMANAGEMENT - if (!backend->start()) { // ### we should call that method even if bearer is not used // backend failed to start because the session state is not Connected. - // QNetworkAccessManager will call reply->backend->start() again for us when the session + // QNetworkAccessManager will call _q_startOperation again for us when the session // state changes. state = WaitingForSession; @@ -109,11 +109,20 @@ void QNetworkReplyImplPrivate::_q_startOperation() session->open(); } else { qWarning("Backend is waiting for QNetworkSession to connect, but there is none!"); + state = Working; + error(QNetworkReplyImpl::UnknownNetworkError, + QCoreApplication::translate("QNetworkReply", "Network session error.")); + finished(); } - +#else + qWarning("Backend start failed"); + state = Working; + error(QNetworkReplyImpl::UnknownNetworkError, + QCoreApplication::translate("QNetworkReply", "backend start error.")); + finished(); +#endif return; } -#endif if (backend && backend->isSynchronous()) { state = Finished; -- cgit v0.12 From 06c3a3a34ab908c517cfcb6900a79f68f1f31ae2 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Mon, 18 Apr 2011 15:46:19 +0100 Subject: Add autotests for configuration dependent network proxies 1. test that systemProxyForQuery returns something for all configs 2. test that QNetworkAccessManager uses the settings for the configuration it was started with. Task-number: QTBUG-18618 Reviewed-by: Peter Hartmann --- .../qnetworkproxyfactory/qnetworkproxyfactory.pro | 2 +- .../tst_qnetworkproxyfactory.cpp | 144 +++++++++++++++++++++ 2 files changed, 145 insertions(+), 1 deletion(-) diff --git a/tests/auto/qnetworkproxyfactory/qnetworkproxyfactory.pro b/tests/auto/qnetworkproxyfactory/qnetworkproxyfactory.pro index f05c423..17ad403 100644 --- a/tests/auto/qnetworkproxyfactory/qnetworkproxyfactory.pro +++ b/tests/auto/qnetworkproxyfactory/qnetworkproxyfactory.pro @@ -7,5 +7,5 @@ QT = core network SOURCES += tst_qnetworkproxyfactory.cpp -symbian: TARGET.CAPABILITY = NetworkServices +symbian: TARGET.CAPABILITY = NetworkServices ReadUserData diff --git a/tests/auto/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp b/tests/auto/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp index 2baee27..82a4193 100644 --- a/tests/auto/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp +++ b/tests/auto/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp @@ -41,20 +41,60 @@ #include +#include #include #include #include +#include +#include +#include +#include +#include +#include +#include + +Q_DECLARE_METATYPE(QNetworkConfiguration); +Q_DECLARE_METATYPE(QList); class tst_QNetworkProxyFactory : public QObject { Q_OBJECT + +public: + tst_QNetworkProxyFactory(); + + class QDebugProxyFactory : public QNetworkProxyFactory + { + public: + virtual QList queryProxy(const QNetworkProxyQuery &query = QNetworkProxyQuery()) + { + returnedList = QNetworkProxyFactory::systemProxyForQuery(query); + requestCounter++; + return returnedList; + } + QList returnedList; + int requestCounter; + }; + private slots: void systemProxyForQuery() const; +#ifndef QT_NO_BEARERMANAGEMENT + void fromConfigurations(); + void inNetworkAccessManager_data(); + void inNetworkAccessManager(); +#endif private: QString formatProxyName(const QNetworkProxy & proxy) const; + QDebugProxyFactory *factory; }; +tst_QNetworkProxyFactory::tst_QNetworkProxyFactory() +{ + factory = new QDebugProxyFactory; + QNetworkProxyFactory::setApplicationProxyFactory(factory); +} + QString tst_QNetworkProxyFactory::formatProxyName(const QNetworkProxy & proxy) const { QString proxyName; @@ -96,5 +136,109 @@ void tst_QNetworkProxyFactory::systemProxyForQuery() const QFAIL("One or more system proxy lookup failures occurred."); } +#ifndef QT_NO_BEARERMANAGEMENT + +//Purpose of this test is just to check systemProxyForQuery doesn't hang or crash +//with any given configuration including no configuration. +//We can't test it returns the right proxies without implementing the native proxy code +//again here, which would be testing our implementation against itself. +//Therefore it's just testing that something valid is returned (at least a NoProxy entry) +void tst_QNetworkProxyFactory::fromConfigurations() +{ + QNetworkConfigurationManager manager; + QList proxies; + QUrl url(QLatin1String("http://qt.nokia.com")); + //get from known configurations + foreach (QNetworkConfiguration config, manager.allConfigurations()) { + QNetworkProxyQuery query(config, url, QNetworkProxyQuery::UrlRequest); + proxies = QNetworkProxyFactory::systemProxyForQuery(query); + QVERIFY(!proxies.isEmpty()); + foreach (QNetworkProxy proxy, proxies) { + qDebug() << config.name() << " - " << config.identifier() << " - " << formatProxyName(proxy); + } + } + + //get from default configuration + QNetworkProxyQuery defaultquery(url, QNetworkProxyQuery::UrlRequest); + proxies = QNetworkProxyFactory::systemProxyForQuery(defaultquery); + QVERIFY(!proxies.isEmpty()); + foreach (QNetworkProxy proxy, proxies) { + qDebug() << "default - " << formatProxyName(proxy); + } + + //get from active configuration + QNetworkSession session(manager.defaultConfiguration()); + session.open(); + QVERIFY(session.waitForOpened(30000)); + proxies = QNetworkProxyFactory::systemProxyForQuery(defaultquery); + QVERIFY(!proxies.isEmpty()); + foreach (QNetworkProxy proxy, proxies) { + qDebug() << "active - " << formatProxyName(proxy); + } + + //get from known configurations while there is one active + foreach (QNetworkConfiguration config, manager.allConfigurations()) { + QNetworkProxyQuery query(config, url, QNetworkProxyQuery::UrlRequest); + proxies = QNetworkProxyFactory::systemProxyForQuery(query); + QVERIFY(!proxies.isEmpty()); + foreach (QNetworkProxy proxy, proxies) { + qDebug() << config.name() << " - " << config.identifier() << " - " << formatProxyName(proxy); + } + } +} + +void tst_QNetworkProxyFactory::inNetworkAccessManager_data() +{ + QTest::addColumn("config"); + QTest::addColumn >("proxies"); + QNetworkConfigurationManager manager; + //get from known configurations + foreach (QNetworkConfiguration config, manager.allConfigurations()) { + QNetworkProxyQuery query(config, QUrl(QString("http://qt.nokia.com")), QNetworkProxyQuery::UrlRequest); + QList proxies = QNetworkProxyFactory::systemProxyForQuery(query); + QTest::newRow(config.name().toUtf8()) << config << proxies; + } +} + +//Purpose of this test is to check that QNetworkAccessManager uses the proxy from the configuration it +//has been given. Needs two or more working configurations to be a good test. +void tst_QNetworkProxyFactory::inNetworkAccessManager() +{ + QFETCH(QNetworkConfiguration, config); + QFETCH(QList, proxies); + + int count = factory->requestCounter; + + QNetworkAccessManager manager; + manager.setConfiguration(config); + + //using an internet server, because cellular APs won't have a route to the test server. + QNetworkRequest req(QUrl(QString("http://qt.nokia.com"))); + QNetworkReply *reply = manager.get(req); + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(30); + delete reply; + + if (count == factory->requestCounter) { + //RND phones are preconfigured with several test access points which won't work without a matching SIM + //If the network fails to start, QNAM won't ask the factory for proxies so we can't test. + QSKIP("network configuration didn't start", SkipSingle); + } + + qDebug() << "testing network configuration for" << config.name(); + foreach (QNetworkProxy proxy, factory->returnedList) { + qDebug() << formatProxyName(proxy); + } + qDebug() << " "; + foreach (QNetworkProxy proxy, proxies) { + qDebug() << formatProxyName(proxy); + } + if (config.type() != QNetworkConfiguration::InternetAccessPoint) + QEXPECT_FAIL("","QNetworkProxyFactory::systemProxyForQuery doesn't work for service networks yet", Continue); + QCOMPARE(factory->returnedList, proxies); +} + +#endif //QT_NO_BEARERMANAGEMENT + QTEST_MAIN(tst_QNetworkProxyFactory) #include "tst_qnetworkproxyfactory.moc" -- cgit v0.12 From ed5dd84582881bc30a5ce85902b37aae9c243978 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Tue, 19 Apr 2011 12:05:59 +1000 Subject: Remove Q_ASSERT calls from gestures autotest Make the test report a useful warning, rather than terminating with an unintelligible assertion failure, if the GestureState enum is ever extended. Change-Id: Ib876a5f2986cbea4e181678a83a72e0d1444f1ee Task-number: QTBUG-17582 Reviewed-by: Rohan McGovern --- tests/auto/gestures/tst_gestures.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/gestures/tst_gestures.cpp b/tests/auto/gestures/tst_gestures.cpp index 7327a49..bff8a04 100644 --- a/tests/auto/gestures/tst_gestures.cpp +++ b/tests/auto/gestures/tst_gestures.cpp @@ -280,7 +280,7 @@ protected: eventsPtr->canceled << g->gestureType(); break; default: - Q_ASSERT(false); + qWarning() << "Unknown GestureState enum value:" << static_cast(g->state()); } } } else if (event->type() == CustomEvent::EventType) { @@ -823,7 +823,7 @@ public: emit gestureCanceled(e->type(), g); break; default: - Q_ASSERT(false); + qWarning() << "Unknown GestureState enum value:" << static_cast(g->state()); } } } else if (event->type() == CustomEvent::EventType) { -- cgit v0.12 From 1191dc0c278ddd22556d6c8e5ea5a898fa7b35f6 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Tue, 19 Apr 2011 13:39:35 +1000 Subject: Remove unused functions. Change-Id: I8cae0550c58238bd99bc759c21b022c54fe2de8b Reviewed-by: Trust Me --- tests/auto/qaccessibility/tst_qaccessibility.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/tests/auto/qaccessibility/tst_qaccessibility.cpp b/tests/auto/qaccessibility/tst_qaccessibility.cpp index 8d9603b..8e68363 100644 --- a/tests/auto/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/qaccessibility/tst_qaccessibility.cpp @@ -374,18 +374,6 @@ QAccessible::State state(QWidget * const widget) return state; } -void printState(QWidget * const widget) -{ - qDebug() << "State for" << widget->metaObject()->className() << stateNames(state(widget)); -} - -void printState(QAccessibleInterface * const iface, const int child = 0) -{ - qDebug() << "State for" << iface->object()->metaObject()->className() << "child" << child - << iface->text(QAccessible::Name, child) << stateNames(iface->state(child)); -} - - class QtTestAccessibleWidget: public QWidget { Q_OBJECT -- cgit v0.12 From d8dc5bfdff25d72e8276c6e80080d72315abe7e0 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Tue, 19 Apr 2011 13:55:05 +1000 Subject: Remove Q_ASSERT from accessibility autotest Instead of crashing when we can't get a QAccessibleInterface for a widget, output a useful warning and return a value that makes the test fail gracefully. Change-Id: I0b292cdd8f5a59e26bdc9b0b67cea2b58591df7d Task-number: QTBUG-17582 Reviewed-by: Rohan McGovern --- tests/auto/qaccessibility/tst_qaccessibility.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/auto/qaccessibility/tst_qaccessibility.cpp b/tests/auto/qaccessibility/tst_qaccessibility.cpp index 8e68363..fe0200a 100644 --- a/tests/auto/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/qaccessibility/tst_qaccessibility.cpp @@ -368,8 +368,9 @@ static QString stateNames(int state) QAccessible::State state(QWidget * const widget) { QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(widget); - Q_ASSERT(iface); - QAccessible::State state = iface->state(0); + if (!iface) + qWarning() << "Cannot get QAccessibleInterface for widget"; + QAccessible::State state = (iface ? iface->state(0) : static_cast(0)); delete iface; return state; } -- cgit v0.12 From 1a98c473fbcbb6a9edf1b7e42babbad7d901edb4 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Tue, 19 Apr 2011 14:09:44 +1000 Subject: Remove unused function. Change-Id: I197ca88e04a68dca0ea819d6e335a02607e597aa Reviewed-by: Trust Me --- tests/auto/qaccessibility/tst_qaccessibility.cpp | 42 ------------------------ 1 file changed, 42 deletions(-) diff --git a/tests/auto/qaccessibility/tst_qaccessibility.cpp b/tests/auto/qaccessibility/tst_qaccessibility.cpp index fe0200a..35c9e4d 100644 --- a/tests/auto/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/qaccessibility/tst_qaccessibility.cpp @@ -323,48 +323,6 @@ QString eventName(const int ev) } } -static QString stateNames(int state) -{ - QString stateString; - if (state == 0x00000000) stateString += " Normal"; - if (state & 0x00000001) stateString += " Unavailable"; - if (state & 0x00000002) stateString += " Selected"; - if (state & 0x00000004) stateString += " Focused"; - if (state & 0x00000008) stateString += " Pressed"; - if (state & 0x00000010) stateString += " Checked"; - if (state & 0x00000020) stateString += " Mixed"; - if (state & 0x00000040) stateString += " ReadOnly"; - if (state & 0x00000080) stateString += " HotTracked"; - if (state & 0x00000100) stateString += " DefaultButton"; - if (state & 0x00000200) stateString += " Expanded"; - if (state & 0x00000400) stateString += " Collapsed"; - if (state & 0x00000800) stateString += " Busy"; - if (state & 0x00001000) stateString += " Floating"; - if (state & 0x00002000) stateString += " Marqueed"; - if (state & 0x00004000) stateString += " Animated"; - if (state & 0x00008000) stateString += " Invisible"; - if (state & 0x00010000) stateString += " Offscreen"; - if (state & 0x00020000) stateString += " Sizeable"; - if (state & 0x00040000) stateString += " Moveable"; - if (state & 0x00080000) stateString += " SelfVoicing"; - if (state & 0x00100000) stateString += " Focusable"; - if (state & 0x00200000) stateString += " Selectable"; - if (state & 0x00400000) stateString += " Linked"; - if (state & 0x00800000) stateString += " Traversed"; - if (state & 0x01000000) stateString += " MultiSelectable"; - if (state & 0x02000000) stateString += " ExtSelectable"; - if (state & 0x04000000) stateString += " AlertLow"; - if (state & 0x08000000) stateString += " AlertMedium"; - if (state & 0x10000000) stateString += " AlertHigh"; - if (state & 0x20000000) stateString += " Protected"; - if (state & 0x3fffffff) stateString += " Valid"; - - if (stateString.isEmpty()) - stateString = "Unknown state " + QString::number(state); - - return stateString; -} - QAccessible::State state(QWidget * const widget) { QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(widget); -- cgit v0.12 From cf911bc0d297ed30e615fd115b0d3ae574cb2412 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Tue, 19 Apr 2011 15:31:09 +1000 Subject: If accessibility isn't built, don't try to test it Only build the autotest when the feature to be tested is in the Qt build. This is better than building and running an empty test. Change-Id: I67721f5f48296afcca64f761d12325f8e040f2d8 Reviewed-by: Rohan McGovern --- tests/auto/other.pro | 3 +- tests/auto/qaccessibility/qaccessibility.pro | 3 +- tests/auto/qaccessibility/tst_qaccessibility.cpp | 219 +---------------------- 3 files changed, 8 insertions(+), 217 deletions(-) diff --git a/tests/auto/other.pro b/tests/auto/other.pro index 89f9e53..655d666 100644 --- a/tests/auto/other.pro +++ b/tests/auto/other.pro @@ -5,7 +5,6 @@ TEMPLATE=subdirs SUBDIRS=\ # baselineexample \ Just an example demonstrating qbaselinetest usage lancelot \ - qaccessibility \ qalgorithms \ qcombobox \ qcssparser \ @@ -36,6 +35,8 @@ SUBDIRS=\ windowsmobile \ nativeimagehandleprovider +contains(QT_CONFIG, accessibility):SUBDIRS += qaccessibility + contains(QT_CONFIG, OdfWriter):SUBDIRS += qzip qtextodfwriter mac: { SUBDIRS += macgui \ diff --git a/tests/auto/qaccessibility/qaccessibility.pro b/tests/auto/qaccessibility/qaccessibility.pro index a4f606c..71d6f95 100644 --- a/tests/auto/qaccessibility/qaccessibility.pro +++ b/tests/auto/qaccessibility/qaccessibility.pro @@ -1,4 +1,5 @@ load(qttest_p4) +requires(contains(QT_CONFIG,accessibility)) SOURCES += tst_qaccessibility.cpp unix:!mac:LIBS+=-lm @@ -8,4 +9,4 @@ wince*: { accessneeded.files = $$QT_BUILD_TREE\\plugins\\accessible\\*.dll accessneeded.path = accessible DEPLOYMENT += accessneeded -} \ No newline at end of file +} diff --git a/tests/auto/qaccessibility/tst_qaccessibility.cpp b/tests/auto/qaccessibility/tst_qaccessibility.cpp index 35c9e4d..888f449 100644 --- a/tests/auto/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/qaccessibility/tst_qaccessibility.cpp @@ -347,7 +347,6 @@ public: } }; -#ifdef QTEST_ACCESSIBILITY class QtTestAccessibleWidgetIface: public QAccessibleWidget { public: @@ -365,7 +364,6 @@ public: return 0; } }; -#endif tst_QAccessibility::tst_QAccessibility() { @@ -377,17 +375,13 @@ tst_QAccessibility::~tst_QAccessibility() void tst_QAccessibility::initTestCase() { -#ifdef QTEST_ACCESSIBILITY QTestAccessibility::initialize(); QAccessible::installFactory(QtTestAccessibleWidgetIface::ifaceFactory); -#endif } void tst_QAccessibility::cleanupTestCase() { -#ifdef QTEST_ACCESSIBILITY QTestAccessibility::cleanup(); -#endif } void tst_QAccessibility::init() @@ -397,7 +391,6 @@ void tst_QAccessibility::init() void tst_QAccessibility::cleanup() { -#ifdef QTEST_ACCESSIBILITY const EventList list = QTestAccessibility::events(); if (!list.isEmpty()) { qWarning("%d accessibility event(s) were not handled in testfunction '%s':", list.count(), @@ -407,14 +400,10 @@ void tst_QAccessibility::cleanup() eventName(list.at(i).event).toAscii().constData(), list.at(i).event, list.at(i).child); } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::eventTest() { -#ifdef QTEST_ACCESSIBILITY QPushButton* button = new QPushButton(0); button->setObjectName(QString("Olaf")); @@ -430,14 +419,10 @@ void tst_QAccessibility::eventTest() QVERIFY_EVENT(button, 0, QAccessible::ObjectHide); delete button; -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::customWidget() { -#ifdef QTEST_ACCESSIBILITY QtTestAccessibleWidget* widget = new QtTestAccessibleWidget(0, "Heinz"); QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(widget); @@ -449,14 +434,10 @@ void tst_QAccessibility::customWidget() delete iface; delete widget; -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::deletedWidget() { -#ifdef QTEST_ACCESSIBILITY QtTestAccessibleWidget *widget = new QtTestAccessibleWidget(0, "Ralf"); QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(widget); QVERIFY(iface != 0); @@ -467,9 +448,6 @@ void tst_QAccessibility::deletedWidget() widget = 0; QVERIFY(!iface->isValid()); delete iface; -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } QWidget *tst_QAccessibility::createGUI() @@ -478,7 +456,6 @@ QWidget *tst_QAccessibility::createGUI() qWarning( "Should never get here without Qt3Support"); return 0; #else -# ifdef QTEST_ACCESSIBILITY QWidget *toplevel = new QWidget(0, Qt::X11BypassWindowManagerHint); QGridLayout *grid = new QGridLayout(toplevel, 2, 2); @@ -550,10 +527,6 @@ QWidget *tst_QAccessibility::createGUI() radioAM->setFocus(); QTestAccessibility::clearEvents(); return toplevel; -# else - Q_ASSERT(0); // this function cannot be called without accessibility support - return 0; -# endif #endif // !QT3_SUPPORT } @@ -562,7 +535,6 @@ void tst_QAccessibility::childAt() #if !defined(QT3_SUPPORT) QSKIP("This test needs Qt3Support", SkipAll); #else -#ifdef QTEST_ACCESSIBILITY QWidget *toplevel = createGUI(); QAccessibleInterface *acc_toplevel = QAccessible::queryAccessibleInterface(toplevel); QVERIFY(acc_toplevel); @@ -594,9 +566,6 @@ void tst_QAccessibility::childAt() delete acc_toplevel; delete toplevel; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif // !QT3_SUPPORT } @@ -605,7 +574,6 @@ void tst_QAccessibility::childCount() #if !defined(QT3_SUPPORT) QSKIP("This test needs Qt3Support", SkipAll); #else -#ifdef QTEST_ACCESSIBILITY QWidget *toplevel = createGUI(); QObject *topLeft = toplevel->child("topLeft"); QObject *topRight = toplevel->child("topRight"); @@ -638,9 +606,6 @@ void tst_QAccessibility::childCount() delete acc_bottomRight; delete toplevel; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif // !QT3_SUPPORT } @@ -649,7 +614,6 @@ void tst_QAccessibility::relationTo() #if !defined(QT3_SUPPORT) QSKIP("This test needs Qt3Support", SkipAll); #else -#ifdef QTEST_ACCESSIBILITY QWidget *toplevel = createGUI(); toplevel->resize(400,300); QObject *topLeft = toplevel->child("topLeft"); @@ -855,15 +819,11 @@ void tst_QAccessibility::relationTo() delete toplevel; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif // !QT3_SUPPORT } void tst_QAccessibility::navigateGeometric() { -#ifdef QTEST_ACCESSIBILITY { static const int skip = 20; //speed the test up significantly static const double step = Q_PI / 180; @@ -959,14 +919,10 @@ void tst_QAccessibility::navigateGeometric() delete w; } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::navigateSlider() { -#ifdef QTEST_ACCESSIBILITY { QSlider *slider = new QSlider(0); slider->setObjectName(QString("Slidy")); @@ -993,14 +949,10 @@ void tst_QAccessibility::navigateSlider() delete slider; } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::navigateCovered() { -#ifdef QTEST_ACCESSIBILITY { QWidget *w = new QWidget(0); w->setObjectName(QString("Harry")); @@ -1103,14 +1055,10 @@ void tst_QAccessibility::navigateCovered() delete w; } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::navigateHierarchy() { -#ifdef QTEST_ACCESSIBILITY { QWidget *w = new QWidget(0); w->setObjectName(QString("Hans")); @@ -1206,9 +1154,6 @@ void tst_QAccessibility::navigateHierarchy() delete w; } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } #define QSETCOMPARE(thetypename, elements, otherelements) \ @@ -1219,7 +1164,6 @@ void tst_QAccessibility::navigateControllers() #if !defined(QT3_SUPPORT) QSKIP("This test needs Qt3Support", SkipAll); #else -#ifdef QTEST_ACCESSIBILITY { Q3VBox vbox; QSlider slider(&vbox); @@ -1302,9 +1246,6 @@ void tst_QAccessibility::navigateControllers() delete acc_slider; } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif // !QT3_SUPPORT } @@ -1313,7 +1254,6 @@ void tst_QAccessibility::navigateLabels() #if !defined(QT3_SUPPORT) QSKIP("This test needs Qt3Support", SkipAll); #else -#ifdef QTEST_ACCESSIBILITY { Q3VBox vbox; Q3HBox hbox(&vbox); @@ -1435,9 +1375,6 @@ void tst_QAccessibility::navigateLabels() delete acc_lineedit3; } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif // !QT3_SUPPORT } @@ -1489,7 +1426,6 @@ static QWidget *createWidgets() void tst_QAccessibility::accessibleName() { -#ifdef QTEST_ACCESSIBILITY QWidget *toplevel = createWidgets(); toplevel->show(); #if defined(Q_WS_X11) @@ -1514,9 +1450,6 @@ void tst_QAccessibility::accessibleName() delete toplevel; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::text() @@ -1524,7 +1457,6 @@ void tst_QAccessibility::text() #if !defined(QT3_SUPPORT) QSKIP("This test needs Qt3Support", SkipAll); #else -#ifdef QTEST_ACCESSIBILITY QWidget *toplevel = createGUI(); toplevel->show(); #if defined(Q_WS_X11) @@ -1620,10 +1552,6 @@ void tst_QAccessibility::text() delete toplevel; QTestAccessibility::clearEvents(); - -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif // !QT3_SUPPORT } @@ -1632,7 +1560,6 @@ void tst_QAccessibility::setText() #if !defined(QT3_SUPPORT) QSKIP("This test needs Qt3Support", SkipAll); #else -#ifdef QTEST_ACCESSIBILITY QWidget *toplevel = createGUI(); toplevel->show(); QObject *bottomLeft = toplevel->findChild("bottomLeft"); @@ -1656,16 +1583,11 @@ void tst_QAccessibility::setText() delete acc_lineedit; delete toplevel; QTestAccessibility::clearEvents(); - -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif //QT3_SUPPORT } void tst_QAccessibility::hideShowTest() { -#ifdef QTEST_ACCESSIBILITY QWidget * const window = new QWidget(); QWidget * const child = new QWidget(window); @@ -1692,14 +1614,10 @@ void tst_QAccessibility::hideShowTest() delete window; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::userActionCount() { -#ifdef QTEST_ACCESSIBILITY QWidget widget; QAccessibleInterface *test = QAccessible::queryAccessibleInterface(&widget); @@ -1729,14 +1647,10 @@ void tst_QAccessibility::userActionCount() QCOMPARE(test->userActionCount(1), 0); QCOMPARE(test->userActionCount(-1), 0); delete test; test = 0; -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::actionText() { -#ifdef QTEST_ACCESSIBILITY QWidget widget; widget.show(); @@ -1753,24 +1667,15 @@ void tst_QAccessibility::actionText() QCOMPARE(test->actionText(QAccessible::SetFocus, QAccessible::Name, 0), QString("SetFocus")); delete test; test = 0; - -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::doAction() { -#ifdef QTEST_ACCESSIBILITY QSKIP("TODO: Implement me", SkipAll); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::buttonTest() { -//#ifdef QTEST_ACCESSIBILITY #if 0 QAccessibleInterface *test = 0; Q3VBox vbox; @@ -1949,9 +1854,7 @@ void tst_QAccessibility::buttonTest() test->release(); QTestAccessibility::clearEvents(); - #else -// QSKIP("Test needs accessibility support.", SkipAll); QSKIP("No action interface in Qt 4 yet.", SkipAll); #endif } @@ -1961,7 +1864,6 @@ void tst_QAccessibility::sliderTest() #if !defined(QT3_SUPPORT) QSKIP("This test needs Qt3Support", SkipAll); #else -#ifdef QTEST_ACCESSIBILITY QAccessibleInterface *test = 0; Q3VBox vbox; QLabel labelHorizontal("Horizontal", &vbox); @@ -1990,7 +1892,7 @@ void tst_QAccessibility::sliderTest() QCOMPARE(test->text(QAccessible::Value, 1), QString()); QCOMPARE(test->text(QAccessible::Value, 2), QString::number(sliderHorizontal.value())); QCOMPARE(test->text(QAccessible::Value, 3), QString()); -// Skip acton tests. +// Skip action tests. #if 0 QCOMPARE(test->defaultAction(0), QAccessible::SetFocus); QCOMPARE(test->defaultAction(1), QAccessible::Press); @@ -2037,7 +1939,7 @@ void tst_QAccessibility::sliderTest() QCOMPARE(test->text(QAccessible::Value, 1), QString()); QCOMPARE(test->text(QAccessible::Value, 2), QString::number(sliderVertical.value())); QCOMPARE(test->text(QAccessible::Value, 3), QString()); -// Skip acton tests. +// Skip action tests. #if 0 QCOMPARE(test->defaultAction(0), QAccessible::SetFocus); QCOMPARE(test->defaultAction(1), QAccessible::Press); @@ -2148,17 +2050,12 @@ void tst_QAccessibility::sliderTest() delete sliderInterface; } - QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif //!QT3_SUPPORT } void tst_QAccessibility::scrollBarTest() { -#ifdef QTEST_ACCESSIBILITY // Test that when we hide() a slider, the PageLeft, Indicator, and PageRight also gets the // Invisible state bit set. enum SubControls { LineUp = 1, @@ -2166,7 +2063,7 @@ void tst_QAccessibility::scrollBarTest() Position = 3, PageDown = 4, LineDown = 5 - }; + }; QScrollBar *scrollBar = new QScrollBar(); QAccessibleInterface * const scrollBarInterface = QAccessible::queryAccessibleInterface(scrollBar); @@ -2248,15 +2145,10 @@ void tst_QAccessibility::scrollBarTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif - } void tst_QAccessibility::tabTest() { -#ifdef QTEST_ACCESSIBILITY QTabBar *tabBar = new QTabBar(); tabBar->show(); @@ -2292,14 +2184,10 @@ void tst_QAccessibility::tabTest() delete tabBar; delete interface; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::menuTest() { -#ifdef QTEST_ACCESSIBILITY { QMainWindow mw; mw.resize(300, 200); @@ -2545,14 +2433,10 @@ void tst_QAccessibility::menuTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); -#endif } void tst_QAccessibility::spinBoxTest() { -#ifdef QTEST_ACCESSIBILITY QSpinBox * const spinBox = new QSpinBox(); spinBox->show(); @@ -2579,14 +2463,10 @@ void tst_QAccessibility::spinBoxTest() QVERIFY(events.contains(expectedEvent)); delete spinBox; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::doubleSpinBoxTest() { -#ifdef QTEST_ACCESSIBILITY QDoubleSpinBox *doubleSpinBox = new QDoubleSpinBox; doubleSpinBox->show(); @@ -2606,14 +2486,10 @@ void tst_QAccessibility::doubleSpinBoxTest() delete doubleSpinBox; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::textEditTest() { -#ifdef QTEST_ACCESSIBILITY { QTextEdit edit; QString text = "hello world\nhow are you today?\n"; @@ -2628,14 +2504,10 @@ void tst_QAccessibility::textEditTest() QCOMPARE(iface->text(QAccessible::Value, 6), QString()); } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::textBrowserTest() { -#ifdef QTEST_ACCESSIBILITY { QTextBrowser textBrowser; QString text = QLatin1String("Hello world\nhow are you today?\n"); @@ -2652,14 +2524,10 @@ void tst_QAccessibility::textBrowserTest() QCOMPARE(interface->text(QAccessible::Value, 6), QString()); } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::listViewTest() { -#if 1 //def QTEST_ACCESSIBILITY { QListView listView; QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&listView); @@ -2725,15 +2593,11 @@ void tst_QAccessibility::listViewTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::mdiAreaTest() { -#ifdef QTEST_ACCESSIBILITY { QMdiArea mdiArea; mdiArea.resize(400,300); @@ -2782,14 +2646,10 @@ void tst_QAccessibility::mdiAreaTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::mdiSubWindowTest() { -#ifdef QTEST_ACCESSIBILITY { QMdiArea mdiArea; mdiArea.show(); @@ -2912,14 +2772,10 @@ void tst_QAccessibility::mdiSubWindowTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::lineEditTest() { -#ifdef QTEST_ACCESSIBILITY QLineEdit *le = new QLineEdit; QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(le); QVERIFY(iface); @@ -2977,14 +2833,10 @@ void tst_QAccessibility::lineEditTest() delete le2; delete toplevel; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::workspaceTest() { -#ifdef QTEST_ACCESSIBILITY { QWorkspace workspace; workspace.resize(400,300); @@ -3038,14 +2890,10 @@ void tst_QAccessibility::workspaceTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::dialogButtonBoxTest() { -#ifdef QTEST_ACCESSIBILITY { QDialogButtonBox box(QDialogButtonBox::Reset | QDialogButtonBox::Help | @@ -3158,14 +3006,10 @@ void tst_QAccessibility::dialogButtonBoxTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::dialTest() { -#ifdef QTEST_ACCESSIBILITY { QDial dial; dial.setValue(20); @@ -3207,28 +3051,20 @@ void tst_QAccessibility::dialTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::rubberBandTest() { -#ifdef QTEST_ACCESSIBILITY QRubberBand rubberBand(QRubberBand::Rectangle); QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&rubberBand); QVERIFY(interface); QCOMPARE(interface->role(0), QAccessible::Border); delete interface; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::abstractScrollAreaTest() { -#ifdef QTEST_ACCESSIBILITY { QAbstractScrollArea abstractScrollArea; @@ -3386,14 +3222,10 @@ void tst_QAccessibility::abstractScrollAreaTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::scrollAreaTest() { -#ifdef QTEST_ACCESSIBILITY { QScrollArea scrollArea; scrollArea.show(); @@ -3407,14 +3239,10 @@ void tst_QAccessibility::scrollAreaTest() delete interface; } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::tableWidgetTest() { -#ifdef QTEST_ACCESSIBILITY { QWidget *topLevel = new QWidget; QTableWidget *w = new QTableWidget(8,4,topLevel); @@ -3454,10 +3282,6 @@ void tst_QAccessibility::tableWidgetTest() delete topLevel; } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif - } class QtTestTableModel: public QAbstractTableModel @@ -3540,7 +3364,6 @@ public: void tst_QAccessibility::tableViewTest() { -#ifdef QTEST_ACCESSIBILITY { QtTestTableModel *model = new QtTestTableModel(3, 4); QTableView *w = new QTableView(); @@ -3620,15 +3443,11 @@ void tst_QAccessibility::tableViewTest() delete model; } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::calendarWidgetTest() { #ifndef QT_NO_CALENDARWIDGET -#ifdef QTEST_ACCESSIBILITY { QCalendarWidget calendarWidget; @@ -3721,17 +3540,12 @@ void tst_QAccessibility::calendarWidgetTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif // QT_NO_CALENDARWIDGET } void tst_QAccessibility::dockWidgetTest() { #ifndef QT_NO_DOCKWIDGET - -#ifdef QTEST_ACCESSIBILITY // Set up a proper main window with two dock widgets QMainWindow *mw = new QMainWindow(); QFrame *central = new QFrame(mw); @@ -3799,19 +3613,14 @@ void tst_QAccessibility::dockWidgetTest() delete dock2; delete mw; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif // QT_NO_DOCKWIDGET } void tst_QAccessibility::pushButtonTest() { #if !defined(QT3_SUPPORT) - qWarning( "Should never get here without Qt3Support"); - return ; + QSKIP( "Should never get here without Qt3Support", SkipAll); #else -#ifdef QTEST_ACCESSIBILITY // Set up a proper main window with two dock widgets QWidget *toplevel = createGUI(); QObject *topRight = toplevel->findChild("topRight"); @@ -3845,15 +3654,11 @@ void tst_QAccessibility::pushButtonTest() delete accToplevel; delete toplevel; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif //QT3_SUPPORT } void tst_QAccessibility::comboBoxTest() { -#ifdef QTEST_ACCESSIBILITY #if defined(Q_OS_WINCE) if (!IsValidCEPlatform()) { QSKIP("Test skipped on Windows Mobile test hardware", SkipAll); @@ -3891,15 +3696,10 @@ void tst_QAccessibility::comboBoxTest() delete w; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif - } void tst_QAccessibility::treeWidgetTest() { -#ifdef QTEST_ACCESSIBILITY QWidget *w = new QWidget; QTreeWidget *tree = new QTreeWidget(w); QHBoxLayout *l = new QHBoxLayout(w); @@ -3957,14 +3757,10 @@ void tst_QAccessibility::treeWidgetTest() delete w; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::labelTest() { -#ifdef QTEST_ACCESSIBILITY QString text = "Hello World"; QLabel *label = new QLabel(text); label->show(); @@ -4003,14 +3799,10 @@ void tst_QAccessibility::labelTest() delete acc_label; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::accelerators() { -#ifdef QTEST_ACCESSIBILITY QWidget *window = new QWidget; QHBoxLayout *lay = new QHBoxLayout(window); QLabel *label = new QLabel(tr("&Line edit"), window); @@ -4043,9 +3835,6 @@ void tst_QAccessibility::accelerators() QTest::qWait(100); delete window; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); -#endif } -- cgit v0.12 From 3ca51d87296bcb3098d7de14294fef9294fd5ed4 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Tue, 19 Apr 2011 16:15:57 +1000 Subject: Ignore expected warning in accessibility autotest Change-Id: I4b614766d2451dde51ab1207267301a2fe7dd0f6 Reviewed-by: Rohan McGovern --- tests/auto/qaccessibility/tst_qaccessibility.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/qaccessibility/tst_qaccessibility.cpp b/tests/auto/qaccessibility/tst_qaccessibility.cpp index 888f449..ebd01bb 100644 --- a/tests/auto/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/qaccessibility/tst_qaccessibility.cpp @@ -3826,6 +3826,8 @@ void tst_QAccessibility::accelerators() QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QKeySequence(Qt::ALT).toString(QKeySequence::NativeText) + QLatin1String("A")); label->setText(tr("Q &&A")); QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QString()); + + QTest::ignoreMessage(QtWarningMsg, "QKeySequence::mnemonic: \"Q &A&B\" contains multiple occurrences of '&'"); label->setText(tr("Q &A&B")); QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QKeySequence(Qt::ALT).toString(QKeySequence::NativeText) + QLatin1String("A")); -- cgit v0.12 From bf1d860143ff40330c6e8f3e2872f2ae812adaa7 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Tue, 19 Apr 2011 17:15:24 +1000 Subject: Fix remaining warnings in accessibility autotest Prevent warnings about unhandled accessibility events by managing object lifetimes appropriately. Change-Id: If72a2a6a76527ff746b99634c2d0895354570724 Reviewed-by: Rohan McGovern --- tests/auto/qaccessibility/tst_qaccessibility.cpp | 72 +++++++++++++----------- 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/tests/auto/qaccessibility/tst_qaccessibility.cpp b/tests/auto/qaccessibility/tst_qaccessibility.cpp index ebd01bb..e5e3e77 100644 --- a/tests/auto/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/qaccessibility/tst_qaccessibility.cpp @@ -1651,10 +1651,10 @@ void tst_QAccessibility::userActionCount() void tst_QAccessibility::actionText() { - QWidget widget; - widget.show(); + QWidget *widget = new QWidget; + widget->show(); - QAccessibleInterface *test = QAccessible::queryAccessibleInterface(&widget); + QAccessibleInterface *test = QAccessible::queryAccessibleInterface(widget); QVERIFY(test); QVERIFY(test->isValid()); @@ -1666,7 +1666,10 @@ void tst_QAccessibility::actionText() QCOMPARE(test->actionText(QAccessible::DefaultAction, QAccessible::Name, 0), QString("SetFocus")); QCOMPARE(test->actionText(QAccessible::SetFocus, QAccessible::Name, 0), QString("SetFocus")); - delete test; test = 0; + delete test; + delete widget; + + QTestAccessibility::clearEvents(); } void tst_QAccessibility::doAction() @@ -1865,18 +1868,18 @@ void tst_QAccessibility::sliderTest() QSKIP("This test needs Qt3Support", SkipAll); #else QAccessibleInterface *test = 0; - Q3VBox vbox; - QLabel labelHorizontal("Horizontal", &vbox); - QSlider sliderHorizontal(Qt::Horizontal, &vbox); - labelHorizontal.setBuddy(&sliderHorizontal); + Q3VBox *vbox = new Q3VBox; + QLabel *labelHorizontal = new QLabel("Horizontal", vbox); + QSlider *sliderHorizontal = new QSlider(Qt::Horizontal, vbox); + labelHorizontal->setBuddy(sliderHorizontal); - QLabel labelVertical("Vertical", &vbox); - QSlider sliderVertical(Qt::Vertical, &vbox); - labelVertical.setBuddy(&sliderVertical); - vbox.show(); + QLabel *labelVertical = new QLabel("Vertical", vbox); + QSlider *sliderVertical = new QSlider(Qt::Vertical, vbox); + labelVertical->setBuddy(sliderVertical); + vbox->show(); // test horizontal slider - test = QAccessible::queryAccessibleInterface(&sliderHorizontal); + test = QAccessible::queryAccessibleInterface(sliderHorizontal); QVERIFY(test); QCOMPARE(test->childCount(), 3); QCOMPARE(test->role(0), QAccessible::Slider); @@ -1884,13 +1887,13 @@ void tst_QAccessibility::sliderTest() QCOMPARE(test->role(2), QAccessible::Indicator); QCOMPARE(test->role(3), QAccessible::PushButton); - QCOMPARE(test->text(QAccessible::Name, 0), labelHorizontal.text()); + QCOMPARE(test->text(QAccessible::Name, 0), labelHorizontal->text()); QCOMPARE(test->text(QAccessible::Name, 1), QSlider::tr("Page left")); QCOMPARE(test->text(QAccessible::Name, 2), QSlider::tr("Position")); QCOMPARE(test->text(QAccessible::Name, 3), QSlider::tr("Page right")); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal.value())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal->value())); QCOMPARE(test->text(QAccessible::Value, 1), QString()); - QCOMPARE(test->text(QAccessible::Value, 2), QString::number(sliderHorizontal.value())); + QCOMPARE(test->text(QAccessible::Value, 2), QString::number(sliderHorizontal->value())); QCOMPARE(test->text(QAccessible::Value, 3), QString()); // Skip action tests. #if 0 @@ -1904,26 +1907,26 @@ void tst_QAccessibility::sliderTest() QCOMPARE(test->actionText(QAccessible::Decrease, QAccessible::Name, 2), QSlider::tr("Decrease")); QCOMPARE(test->actionText(QAccessible::Press, QAccessible::Name, 3), QSlider::tr("Press")); QVERIFY(test->doAction(QAccessible::Press, 3)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal.pageStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal->pageStep())); QVERIFY(test->doAction(QAccessible::Press, 3)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(2*sliderHorizontal.pageStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(2*sliderHorizontal->pageStep())); QVERIFY(test->doAction(QAccessible::Press, 1)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal.pageStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal->pageStep())); QVERIFY(test->doAction(QAccessible::Press, 1)); QCOMPARE(test->text(QAccessible::Value, 0), QString::number(0)); QVERIFY(test->doAction(QAccessible::Increase, 2)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal.lineStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal->lineStep())); QVERIFY(test->doAction(QAccessible::Increase, 2)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(2*sliderHorizontal.lineStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(2*sliderHorizontal->lineStep())); QVERIFY(test->doAction(QAccessible::Decrease, 2)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal.lineStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal->lineStep())); QVERIFY(test->doAction(QAccessible::Decrease, 2)); QCOMPARE(test->text(QAccessible::Value, 0), QString::number(0)); #endif delete test; // test vertical slider - test = QAccessible::queryAccessibleInterface(&sliderVertical); + test = QAccessible::queryAccessibleInterface(sliderVertical); QVERIFY(test); QCOMPARE(test->childCount(), 3); QCOMPARE(test->role(0), QAccessible::Slider); @@ -1931,13 +1934,13 @@ void tst_QAccessibility::sliderTest() QCOMPARE(test->role(2), QAccessible::Indicator); QCOMPARE(test->role(3), QAccessible::PushButton); - QCOMPARE(test->text(QAccessible::Name, 0), labelVertical.text()); + QCOMPARE(test->text(QAccessible::Name, 0), labelVertical->text()); QCOMPARE(test->text(QAccessible::Name, 1), QSlider::tr("Page up")); QCOMPARE(test->text(QAccessible::Name, 2), QSlider::tr("Position")); QCOMPARE(test->text(QAccessible::Name, 3), QSlider::tr("Page down")); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical.value())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical->value())); QCOMPARE(test->text(QAccessible::Value, 1), QString()); - QCOMPARE(test->text(QAccessible::Value, 2), QString::number(sliderVertical.value())); + QCOMPARE(test->text(QAccessible::Value, 2), QString::number(sliderVertical->value())); QCOMPARE(test->text(QAccessible::Value, 3), QString()); // Skip action tests. #if 0 @@ -1951,23 +1954,28 @@ void tst_QAccessibility::sliderTest() QCOMPARE(test->actionText(QAccessible::Decrease, QAccessible::Name, 2), QSlider::tr("Decrease")); QCOMPARE(test->actionText(QAccessible::Press, QAccessible::Name, 3), QSlider::tr("Press")); QVERIFY(test->doAction(QAccessible::Press, 3)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical.pageStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical->pageStep())); QVERIFY(test->doAction(QAccessible::Press, 3)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(2*sliderVertical.pageStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(2*sliderVertical->pageStep())); QVERIFY(test->doAction(QAccessible::Press, 1)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical.pageStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical->pageStep())); QVERIFY(test->doAction(QAccessible::Press, 1)); QCOMPARE(test->text(QAccessible::Value, 0), QString::number(0)); QVERIFY(test->doAction(QAccessible::Increase, 2)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical.lineStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical->lineStep())); QVERIFY(test->doAction(QAccessible::Increase, 2)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(2*sliderVertical.lineStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(2*sliderVertical->lineStep())); QVERIFY(test->doAction(QAccessible::Decrease, 2)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical.lineStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical->lineStep())); QVERIFY(test->doAction(QAccessible::Decrease, 2)); QCOMPARE(test->text(QAccessible::Value, 0), QString::number(0)); #endif delete test; + delete sliderHorizontal; + delete sliderVertical; + delete labelHorizontal; + delete labelVertical; + delete vbox; // Test that when we hide() a slider, the PageLeft, Indicator, and PageRight also gets the // Invisible state bit set. -- cgit v0.12 From c480dd641f5d22d1ee72cb27bf39e24c6df65658 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Wed, 15 Dec 2010 15:11:45 +0100 Subject: Support visual cursor movement for BIDI text Bidi input can in some contexts be more intuitive if the cursor works in visual way: pressing left arrow key always make cursor move one character to the left regardless the language of text, pressing right arrow key always make cursor move to the right. It is also the behavior of Mac OS X. Based on the above reason and requests from Symbian we implemented this support for visual movement in BIDI text. 3 public properties are added to QTextDocument, QTextLayout and QLineEdit respectively: - QTextDocument::defaultCursorMoveStyle can be used to control the cursor behavior in all widgets based on QTextDocument, like QTextEdit, QPlainTextEdit, etc. When set to QTextCursor:: Visual, it will enable visual movement for all the cursors in the corresponding text edit. Default is QTextCursor::Logical. - QTextLayout::cursorMoveStyle is used for low-level cursor manipulation. When set to Visual, it will enable visual movement behavior for all the cursor related methods, including cursorToX, xToCursor and drawCursor. Default is Logical. - QLineEdit::cursorMoveStyle is used to control cursor movement behavior in QLineEdit. Default is Logical.: Task-number: QTBUG-13859 Reviewed-by: Eskil --- src/gui/text/qtextcursor.cpp | 42 ++- src/gui/text/qtextcursor.h | 4 + src/gui/text/qtextdocument.cpp | 23 ++ src/gui/text/qtextdocument.h | 5 +- src/gui/text/qtextdocument_p.cpp | 15 + src/gui/text/qtextdocument_p.h | 4 + src/gui/text/qtextengine.cpp | 297 ++++++++++++++++++++ src/gui/text/qtextengine_p.h | 60 ++++ src/gui/text/qtextlayout.cpp | 394 ++++++++++----------------- src/gui/text/qtextlayout.h | 6 + src/gui/widgets/qlinecontrol.cpp | 9 +- src/gui/widgets/qlinecontrol_p.h | 8 +- src/gui/widgets/qlineedit.cpp | 28 ++ src/gui/widgets/qlineedit.h | 4 + tests/auto/qcomplextext/tst_qcomplextext.cpp | 87 ++++++ tests/auto/qlineedit/tst_qlineedit.cpp | 136 +++++++++ tests/auto/qtextedit/tst_qtextedit.cpp | 149 +++++++++- 17 files changed, 998 insertions(+), 273 deletions(-) diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp index 6ddfdb0..4f6857a 100644 --- a/src/gui/text/qtextcursor.cpp +++ b/src/gui/text/qtextcursor.cpp @@ -362,20 +362,23 @@ bool QTextCursorPrivate::movePosition(QTextCursor::MoveOperation op, QTextCursor currentCharFormat = -1; bool adjustX = true; QTextBlock blockIt = block(); + bool visualMovement = priv->defaultCursorMoveStyle == QTextCursor::Visual; if (!blockIt.isValid()) return false; - if (op >= QTextCursor::Left && op <= QTextCursor::WordRight - && blockIt.textDirection() == Qt::RightToLeft) { - if (op == QTextCursor::Left) - op = QTextCursor::NextCharacter; - else if (op == QTextCursor::Right) - op = QTextCursor::PreviousCharacter; - else if (op == QTextCursor::WordLeft) + if (blockIt.textDirection() == Qt::RightToLeft) { + if (op == QTextCursor::WordLeft) op = QTextCursor::NextWord; else if (op == QTextCursor::WordRight) op = QTextCursor::PreviousWord; + + if (!visualMovement) { + if (op == QTextCursor::Left) + op = QTextCursor::NextCharacter; + else if (op == QTextCursor::Right) + op = QTextCursor::PreviousCharacter; + } } const QTextLayout *layout = blockLayout(blockIt); @@ -418,9 +421,12 @@ bool QTextCursorPrivate::movePosition(QTextCursor::MoveOperation op, QTextCursor break; } case QTextCursor::PreviousCharacter: - case QTextCursor::Left: newPosition = priv->previousCursorPosition(position, QTextLayout::SkipCharacters); break; + case QTextCursor::Left: + newPosition = visualMovement ? priv->leftCursorPosition(position) + : priv->previousCursorPosition(position, QTextLayout::SkipCharacters); + break; case QTextCursor::StartOfWord: { if (relativePos == 0) break; @@ -529,9 +535,12 @@ bool QTextCursorPrivate::movePosition(QTextCursor::MoveOperation op, QTextCursor break; } case QTextCursor::NextCharacter: - case QTextCursor::Right: newPosition = priv->nextCursorPosition(position, QTextLayout::SkipCharacters); break; + case QTextCursor::Right: + newPosition = visualMovement ? priv->rightCursorPosition(position) + : priv->nextCursorPosition(position, QTextLayout::SkipCharacters); + break; case QTextCursor::NextWord: case QTextCursor::WordRight: newPosition = priv->nextCursorPosition(position, QTextLayout::SkipWords); @@ -2558,4 +2567,19 @@ QTextDocument *QTextCursor::document() const return 0; // document went away } +/*! + \enum QTextCursor::MoveStyle + + This enum describes the movement style available to QTextCursor. 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 + 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. +*/ + QT_END_NAMESPACE diff --git a/src/gui/text/qtextcursor.h b/src/gui/text/qtextcursor.h index 4eaeb41..30f8272 100644 --- a/src/gui/text/qtextcursor.h +++ b/src/gui/text/qtextcursor.h @@ -86,6 +86,10 @@ 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 6dbd755..36f3c6c 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -586,6 +586,29 @@ 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. +*/ +QTextCursor::MoveStyle QTextDocument::defaultCursorMoveStyle() const +{ + Q_D(const QTextDocument); + return d->defaultCursorMoveStyle; +} + +/*! + \since 4.8 + + Set the default cursor movement style. +*/ +void QTextDocument::setDefaultCursorMoveStyle(QTextCursor::MoveStyle style) +{ + Q_D(QTextDocument); + d->defaultCursorMoveStyle = style; +} + +/*! \fn void QTextDocument::markContentsDirty(int position, int length) Marks the contents specified by the given \a position and \a length diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h index f87ccc9..e515b36 100644 --- a/src/gui/text/qtextdocument.h +++ b/src/gui/text/qtextdocument.h @@ -46,6 +46,7 @@ #include #include #include +#include QT_BEGIN_HEADER @@ -60,7 +61,6 @@ class QPainter; class QPrinter; class QAbstractTextDocumentLayout; class QPoint; -class QTextCursor; class QTextObject; class QTextFormat; class QTextFrame; @@ -269,6 +269,9 @@ public: QTextOption defaultTextOption() const; void setDefaultTextOption(const QTextOption &option); + QTextCursor::MoveStyle defaultCursorMoveStyle() const; + void setDefaultCursorMoveStyle(QTextCursor::MoveStyle style); + Q_SIGNALS: void contentsChange(int from, int charsRemoves, int charsAdded); void contentsChanged(); diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp index 2172f74..71af89f 100644 --- a/src/gui/text/qtextdocument_p.cpp +++ b/src/gui/text/qtextdocument_p.cpp @@ -209,6 +209,7 @@ QTextDocumentPrivate::QTextDocumentPrivate() defaultTextOption.setTabStop(80); // same as in qtextengine.cpp defaultTextOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); + defaultCursorMoveStyle = QTextCursor::Logical; indentWidth = 40; documentMargin = 4; @@ -1382,6 +1383,20 @@ int QTextDocumentPrivate::previousCursorPosition(int position, QTextLayout::Curs return it.layout()->previousCursorPosition(position-start, mode) + start; } +int QTextDocumentPrivate::leftCursorPosition(int position) const +{ + QTextBlock it = blocksFind(position); + int start = it.position(); + return it.layout()->leftCursorPosition(position-start) + start; +} + +int QTextDocumentPrivate::rightCursorPosition(int position) const +{ + QTextBlock it = blocksFind(position); + int start = it.position(); + return it.layout()->rightCursorPosition(position-start) + start; +} + void QTextDocumentPrivate::changeObjectFormat(QTextObject *obj, int format) { beginEditBlock(); diff --git a/src/gui/text/qtextdocument_p.h b/src/gui/text/qtextdocument_p.h index b464f2e..6563920 100644 --- a/src/gui/text/qtextdocument_p.h +++ b/src/gui/text/qtextdocument_p.h @@ -64,6 +64,7 @@ #include "private/qtextformat_p.h" #include "QtGui/qtextdocument.h" #include "QtGui/qtextobject.h" +#include "QtGui/qtextcursor.h" #include "QtCore/qmap.h" #include "QtCore/qvariant.h" #include "QtCore/qurl.h" @@ -244,6 +245,8 @@ public: int nextCursorPosition(int position, QTextLayout::CursorMode mode) const; int previousCursorPosition(int position, QTextLayout::CursorMode mode) const; + int leftCursorPosition(int position) const; + int rightCursorPosition(int position) const; void changeObjectFormat(QTextObject *group, int format); @@ -339,6 +342,7 @@ private: public: QTextOption defaultTextOption; + QTextCursor::MoveStyle defaultCursorMoveStyle; #ifndef QT_NO_CSSPARSER QCss::StyleSheet parsedDefaultStyleSheet; #endif diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 08d0eca..0e649f0 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1304,6 +1304,7 @@ static void init(QTextEngine *e) e->ignoreBidi = false; e->cacheGlyphs = false; e->forceJustification = false; + e->visualMovement = false; e->layoutData = 0; @@ -2737,6 +2738,180 @@ QFixed QTextEngine::leadingSpaceWidth(const QScriptLine &line) return width(line.from + pos, line.length - pos); } +QFixed QTextEngine::alignLine(const QScriptLine &line) +{ + QFixed x = 0; + justify(line); + // if width is QFIXED_MAX that means we used setNumColumns() and that implicitly makes this line left aligned. + if (!line.justified && line.width != QFIXED_MAX) { + int align = option.alignment(); + if (align & Qt::AlignJustify && isRightToLeft()) + align = Qt::AlignRight; + if (align & Qt::AlignRight) + x = line.width - (line.textAdvance + leadingSpaceWidth(line)); + else if (align & Qt::AlignHCenter) + x = (line.width - line.textAdvance)/2; + } + return x; +} + +QFixed QTextEngine::offsetInLigature(const QScriptItem *si, int pos, int max, int glyph_pos) +{ + unsigned short *logClusters = this->logClusters(si); + const QGlyphLayout &glyphs = shapedGlyphs(si); + + int offsetInCluster = 0; + for (int i = pos - 1; i >= 0; i--) { + if (logClusters[i] == glyph_pos) + offsetInCluster++; + else + break; + } + + // in the case that the offset is inside a (multi-character) glyph, + // interpolate the position. + if (offsetInCluster > 0) { + int clusterLength = 0; + for (int i = pos - offsetInCluster; i < max; i++) { + if (logClusters[i] == glyph_pos) + clusterLength++; + else + break; + } + if (clusterLength) + return glyphs.advances_x[glyph_pos] * offsetInCluster / clusterLength; + } + + return 0; +} + +int QTextEngine::previousLogicalPosition(int oldPos) const +{ + const HB_CharAttributes *attrs = attributes(); + if (!attrs || oldPos < 0) + return oldPos; + + if (oldPos <= 0) + return 0; + oldPos--; + while (oldPos && !attrs[oldPos].charStop) + oldPos--; + return oldPos; +} + +int QTextEngine::nextLogicalPosition(int oldPos) const +{ + const HB_CharAttributes *attrs = attributes(); + int len = block.isValid() ? block.length() - 1 + : layoutData->string.length(); + Q_ASSERT(len <= layoutData->string.length()); + if (!attrs || oldPos < 0 || oldPos >= len) + return oldPos; + + oldPos++; + while (oldPos < len && !attrs[oldPos].charStop) + oldPos++; + return oldPos; +} + +int QTextEngine::lineNumberForTextPosition(int pos) +{ + if (!layoutData) + itemize(); + if (pos == layoutData->string.length() && lines.size()) + return lines.size() - 1; + for (int i = 0; i < lines.size(); ++i) { + const QScriptLine& line = lines[i]; + if (line.from + line.length > pos) + return i; + } + return -1; +} + +void QTextEngine::insertionPointsForLine(int lineNum, QVector &insertionPoints) +{ + QTextLineItemIterator iterator(this, lineNum); + bool rtl = isRightToLeft(); + bool lastLine = lineNum >= lines.size() - 1; + + while (!iterator.atEnd()) { + iterator.next(); + const QScriptItem *si = &layoutData->items[iterator.item]; + if (si->analysis.bidiLevel % 2) { + int i = iterator.itemEnd - 1, min = iterator.itemStart; + if (lastLine && (rtl ? iterator.atBeginning() : iterator.atEnd())) + i++; + for (; i >= min; i--) + insertionPoints.push_back(i); + } else { + int i = iterator.itemStart, max = iterator.itemEnd; + if (lastLine && (rtl ? iterator.atBeginning() : iterator.atEnd())) + max++; + for (; i < max; i++) + insertionPoints.push_back(i); + } + } +} + +int QTextEngine::endOfLine(int lineNum) +{ + QVector insertionPoints; + insertionPointsForLine(lineNum, insertionPoints); + + if (insertionPoints.size() > 0) + return insertionPoints.last(); + return 0; +} + +int QTextEngine::beginningOfLine(int lineNum) +{ + QVector insertionPoints; + insertionPointsForLine(lineNum, insertionPoints); + + if (insertionPoints.size() > 0) + return insertionPoints.first(); + return 0; +} + +int QTextEngine::positionAfterVisualMovement(int pos, QTextCursor::MoveOperation op) +{ + if (!layoutData) + itemize(); + + bool moveRight = (op == QTextCursor::Right); + bool alignRight = isRightToLeft(); + if (!layoutData->hasBidi) + return moveRight ^ alignRight ? nextLogicalPosition(pos) : previousLogicalPosition(pos); + + int lineNum = lineNumberForTextPosition(pos); + Q_ASSERT(lineNum >= 0); + + QVector insertionPoints; + insertionPointsForLine(lineNum, insertionPoints); + int i, max = insertionPoints.size(); + for (i = 0; i < max; i++) + if (pos == insertionPoints[i]) { + if (moveRight) { + if (i + 1 < max) + return insertionPoints[i + 1]; + } else { + if (i > 0) + return insertionPoints[i - 1]; + } + + if (moveRight ^ alignRight) { + if (lineNum + 1 < lines.size()) + return alignRight ? endOfLine(lineNum + 1) : beginningOfLine(lineNum + 1); + } + else { + if (lineNum > 0) + return alignRight ? beginningOfLine(lineNum - 1) : endOfLine(lineNum - 1); + } + } + + return pos; +} + QStackTextEngine::QStackTextEngine(const QString &string, const QFont &f) : QTextEngine(string, f), _layoutData(string, _memory, MemSize) @@ -2841,5 +3016,127 @@ glyph_metrics_t glyph_metrics_t::transformed(const QTransform &matrix) const return m; } +QTextLineItemIterator::QTextLineItemIterator(QTextEngine *_eng, int _lineNum, const QPointF &pos, + const QTextLayout::FormatRange *_selection) + : eng(_eng), + line(eng->lines[_lineNum]), + si(0), + lineNum(_lineNum), + lineEnd(line.from + line.length), + firstItem(eng->findItem(line.from)), + lastItem(eng->findItem(lineEnd - 1)), + nItems((firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0), + logicalItem(-1), + item(-1), + visualOrder(nItems), + levels(nItems), + selection(_selection) +{ + pos_x = x = QFixed::fromReal(pos.x()); + + x += line.x; + + x += eng->alignLine(line); + + for (int i = 0; i < nItems; ++i) + levels[i] = eng->layoutData->items[i+firstItem].analysis.bidiLevel; + QTextEngine::bidiReorder(nItems, levels.data(), visualOrder.data()); + + eng->shapeLine(line); +} + +QScriptItem &QTextLineItemIterator::next() +{ + x += itemWidth; + + ++logicalItem; + item = visualOrder[logicalItem] + firstItem; + itemLength = eng->length(item); + si = &eng->layoutData->items[item]; + if (!si->num_glyphs) + eng->shape(item); + + if (si->analysis.flags >= QScriptAnalysis::TabOrObject) { + itemWidth = si->width; + return *si; + } + + unsigned short *logClusters = eng->logClusters(si); + QGlyphLayout glyphs = eng->shapedGlyphs(si); + + itemStart = qMax(line.from, si->position); + glyphsStart = logClusters[itemStart - si->position]; + if (lineEnd < si->position + itemLength) { + itemEnd = lineEnd; + glyphsEnd = logClusters[itemEnd-si->position]; + } else { + itemEnd = si->position + itemLength; + glyphsEnd = si->num_glyphs; + } + // show soft-hyphen at line-break + if (si->position + itemLength >= lineEnd + && eng->layoutData->string.at(lineEnd - 1) == 0x00ad) + glyphs.attributes[glyphsEnd - 1].dontPrint = false; + + itemWidth = 0; + for (int g = glyphsStart; g < glyphsEnd; ++g) + itemWidth += glyphs.effectiveAdvance(g); + + return *si; +} + +bool QTextLineItemIterator::getSelectionBounds(QFixed *selectionX, QFixed *selectionWidth) const +{ + *selectionX = *selectionWidth = 0; + + if (!selection) + return false; + + if (si->analysis.flags >= QScriptAnalysis::TabOrObject) { + if (si->position >= selection->start + selection->length + || si->position + itemLength <= selection->start) + return false; + + *selectionX = x; + *selectionWidth = itemWidth; + } else { + unsigned short *logClusters = eng->logClusters(si); + QGlyphLayout glyphs = eng->shapedGlyphs(si); + + int from = qMax(itemStart, selection->start) - si->position; + int to = qMin(itemEnd, selection->start + selection->length) - si->position; + if (from >= to) + return false; + + int start_glyph = logClusters[from]; + int end_glyph = (to == eng->length(item)) ? si->num_glyphs : logClusters[to]; + QFixed soff; + QFixed swidth; + if (si->analysis.bidiLevel %2) { + for (int g = glyphsEnd - 1; g >= end_glyph; --g) + soff += glyphs.effectiveAdvance(g); + for (int g = end_glyph - 1; g >= start_glyph; --g) + swidth += glyphs.effectiveAdvance(g); + } else { + for (int g = glyphsStart; g < start_glyph; ++g) + soff += glyphs.effectiveAdvance(g); + for (int g = start_glyph; g < end_glyph; ++g) + swidth += glyphs.effectiveAdvance(g); + } + + // If the starting character is in the middle of a ligature, + // selection should only contain the right part of that ligature + // glyph, so we need to get the width of the left part here and + // add it to *selectionX + QFixed leftOffsetInLigature = eng->offsetInLigature(si, from, to, start_glyph); + *selectionX = x + soff + leftOffsetInLigature; + *selectionWidth = swidth - leftOffsetInLigature; + // If the ending character is also part of a ligature, swidth does + // not contain that part yet, we also need to find out the width of + // that left part + *selectionWidth += eng->offsetInLigature(si, to, eng->length(item), end_glyph); + } + return true; +} QT_END_NAMESPACE diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index 366c5c3..c476485 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -64,6 +64,7 @@ #include "QtGui/qpaintengine.h" #include "QtGui/qtextobject.h" #include "QtGui/qtextoption.h" +#include "QtGui/qtextcursor.h" #include "QtCore/qset.h" #include "QtCore/qdebug.h" #ifndef QT_BUILD_COMPAT_LIB @@ -471,6 +472,7 @@ public: void shape(int item) const; void justify(const QScriptLine &si); + QFixed alignLine(const QScriptLine &line); QFixed width(int charFrom, int numChars) const; glyph_metrics_t boundingBox(int from, int len) const; @@ -586,12 +588,18 @@ public: uint cacheGlyphs : 1; uint stackEngine : 1; uint forceJustification : 1; + uint visualMovement : 1; int *underlinePositions; mutable LayoutData *layoutData; inline bool hasFormats() const { return (block.docHandle() || specialData); } + inline bool visualCursorMovement() const + { + return (visualMovement || + (block.docHandle() ? block.docHandle()->defaultCursorMoveStyle == QTextCursor::Visual : false)); + } struct SpecialData { int preeditPosition; @@ -611,6 +619,13 @@ public: void shapeLine(const QScriptLine &line); QFixed leadingSpaceWidth(const QScriptLine &line); + QFixed offsetInLigature(const QScriptItem *si, int pos, int max, int glyph_pos); + int previousLogicalPosition(int oldPos) const; + int nextLogicalPosition(int oldPos) const; + int lineNumberForTextPosition(int pos); + int positionAfterVisualMovement(int oldPos, QTextCursor::MoveOperation op); + void insertionPointsForLine(int lineNum, QVector &insertionPoints); + private: void setBoundary(int strPos) const; void addRequiredBoundaries() const; @@ -625,6 +640,8 @@ private: void splitItem(int item, int pos) const; void resolveAdditionalFormats() const; + int endOfLine(int lineNum); + int beginningOfLine(int lineNum); }; class QStackTextEngine : public QTextEngine { @@ -635,6 +652,49 @@ public: void *_memory[MemSize]; }; +struct QTextLineItemIterator +{ + QTextLineItemIterator(QTextEngine *eng, int lineNum, const QPointF &pos = QPointF(), + const QTextLayout::FormatRange *_selection = 0); + + inline bool atEnd() const { return logicalItem >= nItems - 1; } + inline bool atBeginning() const { return logicalItem <= 0; } + QScriptItem &next(); + + bool getSelectionBounds(QFixed *selectionX, QFixed *selectionWidth) const; + inline bool isOutsideSelection() const { + QFixed tmp1, tmp2; + return !getSelectionBounds(&tmp1, &tmp2); + } + + QTextEngine *eng; + + QFixed x; + QFixed pos_x; + const QScriptLine &line; + QScriptItem *si; + + int lineNum; + int lineEnd; + int firstItem; + int lastItem; + int nItems; + int logicalItem; + int item; + int itemLength; + + int glyphsStart; + int glyphsEnd; + int itemStart; + int itemEnd; + + QFixed itemWidth; + + QVarLengthArray visualOrder; + QVarLengthArray levels; + + const QTextLayout::FormatRange *selection; +}; Q_DECLARE_OPERATORS_FOR_FLAGS(QTextEngine::ShaperFlags) diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 93f71d3..bd224c6 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -72,23 +72,6 @@ QT_BEGIN_NAMESPACE #define SuppressText 0x5012 #define SuppressBackground 0x513 -static QFixed alignLine(QTextEngine *eng, const QScriptLine &line) -{ - QFixed x = 0; - eng->justify(line); - // if width is QFIXED_MAX that means we used setNumColumns() and that implicitly makes this line left aligned. - if (!line.justified && line.width != QFIXED_MAX) { - int align = eng->option.alignment(); - if (align & Qt::AlignJustify && eng->isRightToLeft()) - align = Qt::AlignRight; - if (align & Qt::AlignRight) - x = line.width - (line.textAdvance + eng->leadingSpaceWidth(line)); - else if (align & Qt::AlignHCenter) - x = (line.width - line.textAdvance)/2; - } - return x; -} - /*! \class QTextLayout::FormatRange \reentrant @@ -596,6 +579,30 @@ bool QTextLayout::cacheEnabled() const } /*! + Set the visual 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. + + \sa setCursorMoveStyle() +*/ +void QTextLayout::setCursorMoveStyle(QTextCursor::MoveStyle style) +{ + d->visualMovement = style == QTextCursor::Visual ? true : false; +} + +/*! + The cursor movement style of this QTextLayout. The default is + QTextCursor::Logical. + + \sa setCursorMoveStyle() +*/ +QTextCursor::MoveStyle QTextLayout::cursorMoveStyle() const +{ + return d->visualMovement ? QTextCursor::Visual : QTextCursor::Logical; +} + +/*! Begins the layout process. \sa endLayout() @@ -718,6 +725,34 @@ int QTextLayout::previousCursorPosition(int oldPos, CursorMode mode) const } /*! + Returns the cursor position to the right of \a oldPos, next to it. + It's dependent on the visual position of characters, after bi-directional + reordering. + + \sa leftCursorPosition(), nextCursorPosition() +*/ +int QTextLayout::rightCursorPosition(int oldPos) const +{ + int newPos = d->positionAfterVisualMovement(oldPos, QTextCursor::Right); +// qDebug("%d -> %d", oldPos, newPos); + return newPos; +} + +/*! + Returns the cursor position to the left of \a oldPos, next to it. + It's dependent on the visual position of characters, after bi-directional + reordering. + + \sa rightCursorPosition(), previousCursorPosition() +*/ +int QTextLayout::leftCursorPosition(int oldPos) const +{ + int newPos = d->positionAfterVisualMovement(oldPos, QTextCursor::Left); +// qDebug("%d -> %d", oldPos, newPos); + return newPos; +} + +/*!/ Returns true if position \a pos is a valid cursor position. In a Unicode context some positions in the text are not valid @@ -815,16 +850,8 @@ QTextLine QTextLayout::lineAt(int i) const */ QTextLine QTextLayout::lineForTextPosition(int pos) const { - for (int i = 0; i < d->lines.size(); ++i) { - const QScriptLine& line = d->lines[i]; - if (line.from + (int)line.length > pos) - return QTextLine(i, d); - } - if (!d->layoutData) - d->itemize(); - if (pos == d->layoutData->string.length() && d->lines.size()) - return QTextLine(d->lines.size()-1, d); - return QTextLine(); + int lineNum = d->lineNumberForTextPosition(pos); + return lineNum >= 0 ? lineAt(lineNum) : QTextLine(); } /*! @@ -919,201 +946,6 @@ void QTextLayout::setFlags(int flags) } } -struct QTextLineItemIterator -{ - QTextLineItemIterator(QTextEngine *eng, int lineNum, const QPointF &pos = QPointF(), - const QTextLayout::FormatRange *_selection = 0); - - inline bool atEnd() const { return logicalItem >= nItems - 1; } - QScriptItem &next(); - - bool getSelectionBounds(QFixed *selectionX, QFixed *selectionWidth) const; - inline bool isOutsideSelection() const { - QFixed tmp1, tmp2; - return !getSelectionBounds(&tmp1, &tmp2); - } - - QTextEngine *eng; - - QFixed x; - QFixed pos_x; - const QScriptLine &line; - QScriptItem *si; - - int lineEnd; - int firstItem; - int lastItem; - int nItems; - int logicalItem; - int item; - int itemLength; - - int glyphsStart; - int glyphsEnd; - int itemStart; - int itemEnd; - - QFixed itemWidth; - - QVarLengthArray visualOrder; - QVarLengthArray levels; - - const QTextLayout::FormatRange *selection; -}; - -QTextLineItemIterator::QTextLineItemIterator(QTextEngine *_eng, int lineNum, const QPointF &pos, - const QTextLayout::FormatRange *_selection) - : eng(_eng), - line(eng->lines[lineNum]), - si(0), - lineEnd(line.from + line.length), - firstItem(eng->findItem(line.from)), - lastItem(eng->findItem(lineEnd - 1)), - nItems((firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0), - logicalItem(-1), - item(-1), - visualOrder(nItems), - levels(nItems), - selection(_selection) -{ - pos_x = x = QFixed::fromReal(pos.x()); - - x += line.x; - - x += alignLine(eng, line); - - for (int i = 0; i < nItems; ++i) - levels[i] = eng->layoutData->items[i+firstItem].analysis.bidiLevel; - QTextEngine::bidiReorder(nItems, levels.data(), visualOrder.data()); - - eng->shapeLine(line); -} - -QScriptItem &QTextLineItemIterator::next() -{ - x += itemWidth; - - ++logicalItem; - item = visualOrder[logicalItem] + firstItem; - itemLength = eng->length(item); - si = &eng->layoutData->items[item]; - if (!si->num_glyphs) - eng->shape(item); - - if (si->analysis.flags >= QScriptAnalysis::TabOrObject) { - itemWidth = si->width; - return *si; - } - - unsigned short *logClusters = eng->logClusters(si); - QGlyphLayout glyphs = eng->shapedGlyphs(si); - - itemStart = qMax(line.from, si->position); - glyphsStart = logClusters[itemStart - si->position]; - if (lineEnd < si->position + itemLength) { - itemEnd = lineEnd; - glyphsEnd = logClusters[itemEnd-si->position]; - } else { - itemEnd = si->position + itemLength; - glyphsEnd = si->num_glyphs; - } - // show soft-hyphen at line-break - if (si->position + itemLength >= lineEnd - && eng->layoutData->string.at(lineEnd - 1) == 0x00ad) - glyphs.attributes[glyphsEnd - 1].dontPrint = false; - - itemWidth = 0; - for (int g = glyphsStart; g < glyphsEnd; ++g) - itemWidth += glyphs.effectiveAdvance(g); - - return *si; -} - -static QFixed offsetInLigature(const unsigned short *logClusters, - const QGlyphLayout &glyphs, - int pos, int max, int glyph_pos) -{ - int offsetInCluster = 0; - for (int i = pos - 1; i >= 0; i--) { - if (logClusters[i] == glyph_pos) - offsetInCluster++; - else - break; - } - - // in the case that the offset is inside a (multi-character) glyph, - // interpolate the position. - if (offsetInCluster > 0) { - int clusterLength = 0; - for (int i = pos - offsetInCluster; i < max; i++) { - if (logClusters[i] == glyph_pos) - clusterLength++; - else - break; - } - if (clusterLength) - return glyphs.advances_x[glyph_pos] * offsetInCluster / clusterLength; - } - - return 0; -} - -bool QTextLineItemIterator::getSelectionBounds(QFixed *selectionX, QFixed *selectionWidth) const -{ - *selectionX = *selectionWidth = 0; - - if (!selection) - return false; - - if (si->analysis.flags >= QScriptAnalysis::TabOrObject) { - if (si->position >= selection->start + selection->length - || si->position + itemLength <= selection->start) - return false; - - *selectionX = x; - *selectionWidth = itemWidth; - } else { - unsigned short *logClusters = eng->logClusters(si); - QGlyphLayout glyphs = eng->shapedGlyphs(si); - - int from = qMax(itemStart, selection->start) - si->position; - int to = qMin(itemEnd, selection->start + selection->length) - si->position; - if (from >= to) - return false; - - int start_glyph = logClusters[from]; - int end_glyph = (to == eng->length(item)) ? si->num_glyphs : logClusters[to]; - QFixed soff; - QFixed swidth; - if (si->analysis.bidiLevel %2) { - for (int g = glyphsEnd - 1; g >= end_glyph; --g) - soff += glyphs.effectiveAdvance(g); - for (int g = end_glyph - 1; g >= start_glyph; --g) - swidth += glyphs.effectiveAdvance(g); - } else { - for (int g = glyphsStart; g < start_glyph; ++g) - soff += glyphs.effectiveAdvance(g); - for (int g = start_glyph; g < end_glyph; ++g) - swidth += glyphs.effectiveAdvance(g); - } - - // If the starting character is in the middle of a ligature, - // selection should only contain the right part of that ligature - // glyph, so we need to get the width of the left part here and - // add it to *selectionX - QFixed leftOffsetInLigature = offsetInLigature(logClusters, glyphs, from, - to, start_glyph); - *selectionX = x + soff + leftOffsetInLigature; - *selectionWidth = swidth - leftOffsetInLigature; - // If the ending character is also part of a ligature, swidth does - // not contain that part yet, we also need to find out the width of - // that left part - *selectionWidth += offsetInLigature(logClusters, glyphs, to, - eng->length(item), end_glyph); - } - return true; -} - static void addSelectedRegionsToPath(QTextEngine *eng, int lineNumber, const QPointF &pos, QTextLayout::FormatRange *selection, QPainterPath *region, QRectF boundingRect) { @@ -1382,18 +1214,9 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition QFixed pos_y = QFixed::fromReal(position.y()); cursorPosition = qBound(0, cursorPosition, d->layoutData->string.length()); - int line = 0; - if (cursorPosition == d->layoutData->string.length()) { - line = d->lines.size() - 1; - } else { - // ### binary search - for (line = 0; line < d->lines.size(); line++) { - const QScriptLine &sl = d->lines[line]; - if (sl.from <= cursorPosition && sl.from + (int)sl.length > cursorPosition) - break; - } - } - + int line = d->lineNumberForTextPosition(cursorPosition); + if (line < 0) + line = 0; if (line >= d->lines.size()) return; @@ -1402,7 +1225,15 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition qreal x = position.x() + l.cursorToX(cursorPosition); - int itm = d->findItem(cursorPosition - 1); + int itm; + + if (d->visualCursorMovement()) { + if (cursorPosition == sl.from + sl.length) + cursorPosition--; + itm = d->findItem(cursorPosition); + } else + itm = d->findItem(cursorPosition - 1); + QFixed base = sl.base(); QFixed descent = sl.descent; bool rightToLeft = d->isRightToLeft(); @@ -1512,7 +1343,7 @@ QRectF QTextLine::rect() const QRectF QTextLine::naturalTextRect() const { const QScriptLine& sl = eng->lines[i]; - QFixed x = sl.x + alignLine(eng, sl); + QFixed x = sl.x + eng->alignLine(sl); QFixed width = sl.textWidth; if (sl.justified) @@ -2632,9 +2463,10 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const eng->itemize(); const QScriptLine &line = eng->lines[i]; + bool lastLine = i >= eng->lines.size() - 1; QFixed x = line.x; - x += alignLine(eng, line); + x += eng->alignLine(line); if (!i && !eng->layoutData->items.size()) { *cursorPos = 0; @@ -2720,21 +2552,29 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const logClusters = eng->logClusters(si); glyphs = eng->shapedGlyphs(si); if (si->analysis.flags >= QScriptAnalysis::TabOrObject) { - if(pos == l) + if (pos == (reverse ? 0 : l)) x += si->width; } else { + bool rtl = eng->isRightToLeft(); + bool visual = eng->visualCursorMovement(); if (reverse) { int end = qMin(lineEnd, si->position + l) - si->position; int glyph_end = end == l ? si->num_glyphs : logClusters[end]; - for (int i = glyph_end - 1; i >= glyph_pos; i--) + int glyph_start = glyph_pos; + if (visual && !rtl && !(lastLine && itm == (visualOrder[nItems - 1] + firstItem))) + glyph_start++; + for (int i = glyph_end - 1; i >= glyph_start; i--) x += glyphs.effectiveAdvance(i); } else { int start = qMax(line.from - si->position, 0); int glyph_start = logClusters[start]; - for (int i = glyph_start; i < glyph_pos; i++) + int glyph_end = glyph_pos; + if (!visual || !rtl || (lastLine && itm == visualOrder[0] + firstItem)) + glyph_end--; + for (int i = glyph_start; i <= glyph_end; i++) x += glyphs.effectiveAdvance(i); } - x += offsetInLigature(logClusters, glyphs, pos, line.length, glyph_pos); + x += eng->offsetInLigature(si, pos, line.length, glyph_pos); } *cursorPos = pos + si->position; @@ -2753,6 +2593,8 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const { QFixed x = QFixed::fromReal(_x); const QScriptLine &line = eng->lines[i]; + bool lastLine = i >= eng->lines.size() - 1; + int lineNum = i; if (!eng->layoutData) eng->itemize(); @@ -2770,7 +2612,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const return 0; x -= line.x; - x -= alignLine(eng, line); + x -= eng->alignLine(line); // qDebug("xToCursor: x=%f, cpos=%d", x.toReal(), cpos); QVarLengthArray visualOrder(nItems); @@ -2779,6 +2621,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const levels[i] = eng->layoutData->items[i+firstItem].analysis.bidiLevel; QTextEngine::bidiReorder(nItems, levels.data(), visualOrder.data()); + bool visual = eng->visualCursorMovement(); if (x <= 0) { // left of first item int item = visualOrder[0]+firstItem; @@ -2795,8 +2638,13 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const || (line.justified && x < line.width)) { // has to be in one of the runs QFixed pos; + bool rtl = eng->isRightToLeft(); eng->shapeLine(line); + QVector insertionPoints; + if (visual && rtl) + eng->insertionPointsForLine(lineNum, insertionPoints); + int nchars = 0; for (int i = 0; i < nItems; ++i) { int item = visualOrder[i]+firstItem; QScriptItem &si = eng->layoutData->items[item]; @@ -2826,6 +2674,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const if (pos + item_width < x) { pos += item_width; + nchars += end; continue; } // qDebug(" inside run"); @@ -2870,27 +2719,60 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const } else { QFixed dist = INT_MAX/256; if (si.analysis.bidiLevel % 2) { - pos += item_width; - while (gs <= ge) { - if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) { - glyph_pos = gs; - dist = qAbs(x-pos); + if (!visual || rtl || (lastLine && i == nItems - 1)) { + pos += item_width; + while (gs <= ge) { + if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) { + glyph_pos = gs; + dist = qAbs(x-pos); + } + pos -= glyphs.effectiveAdvance(gs); + ++gs; + } + } else { + while (ge >= gs) { + if (glyphs.attributes[ge].clusterStart && qAbs(x-pos) < dist) { + glyph_pos = ge; + dist = qAbs(x-pos); + } + pos += glyphs.effectiveAdvance(ge); + --ge; } - pos -= glyphs.effectiveAdvance(gs); - ++gs; } } else { - while (gs <= ge) { - if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) { - glyph_pos = gs; - dist = qAbs(x-pos); + if (!visual || !rtl || (lastLine && i == 0)) { + while (gs <= ge) { + if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) { + glyph_pos = gs; + dist = qAbs(x-pos); + } + pos += glyphs.effectiveAdvance(gs); + ++gs; } - pos += glyphs.effectiveAdvance(gs); - ++gs; + } else { + QFixed oldPos = pos; + while (gs <= ge) { + pos += glyphs.effectiveAdvance(gs); + if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) { + glyph_pos = gs; + dist = qAbs(x-pos); + } + ++gs; + } + pos = oldPos; } } - if (qAbs(x-pos) < dist) + if (qAbs(x-pos) < dist) { + if (visual) { + if (!rtl && i < nItems - 1) { + nchars += end; + continue; + } + if (rtl && nchars > 0) + return insertionPoints[lastLine ? nchars : nchars - 1]; + } return si.position + end; + } } Q_ASSERT(glyph_pos != -1); int j; diff --git a/src/gui/text/qtextlayout.h b/src/gui/text/qtextlayout.h index 9dd8ebd..6aa81f9 100644 --- a/src/gui/text/qtextlayout.h +++ b/src/gui/text/qtextlayout.h @@ -50,6 +50,7 @@ #include #include #include +#include QT_BEGIN_HEADER @@ -136,6 +137,9 @@ public: void setCacheEnabled(bool enable); bool cacheEnabled() const; + void setCursorMoveStyle(QTextCursor::MoveStyle style); + QTextCursor::MoveStyle cursorMoveStyle() const; + void beginLayout(); void endLayout(); void clearLayout(); @@ -153,6 +157,8 @@ public: bool isValidCursorPosition(int pos) const; int nextCursorPosition(int oldPos, CursorMode mode = SkipCharacters) const; int previousCursorPosition(int oldPos, CursorMode mode = SkipCharacters) const; + int leftCursorPosition(int oldPos) const; + int rightCursorPosition(int oldPos) const; void draw(QPainter *p, const QPointF &pos, const QVector &selections = QVector(), const QRectF &clip = QRectF()) const; diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp index 3eac64a..a1b3ff8 100644 --- a/src/gui/widgets/qlinecontrol.cpp +++ b/src/gui/widgets/qlinecontrol.cpp @@ -1577,6 +1577,7 @@ void QLineControl::processKeyEvent(QKeyEvent* event) } bool unknown = false; + bool visual = cursorMoveStyle() == QTextCursor::Visual; if (false) { } @@ -1641,11 +1642,11 @@ void QLineControl::processKeyEvent(QKeyEvent* event) #endif moveCursor(selectionEnd(), false); } else { - cursorForward(0, layoutDirection() == Qt::LeftToRight ? 1 : -1); + cursorForward(0, visual ? 1 : (layoutDirection() == Qt::LeftToRight ? 1 : -1)); } } else if (event == QKeySequence::SelectNextChar) { - cursorForward(1, layoutDirection() == Qt::LeftToRight ? 1 : -1); + cursorForward(1, visual ? 1 : (layoutDirection() == Qt::LeftToRight ? 1 : -1)); } else if (event == QKeySequence::MoveToPreviousChar) { #if !defined(Q_WS_WIN) || defined(QT_NO_COMPLETER) @@ -1656,11 +1657,11 @@ void QLineControl::processKeyEvent(QKeyEvent* event) #endif moveCursor(selectionStart(), false); } else { - cursorForward(0, layoutDirection() == Qt::LeftToRight ? -1 : 1); + cursorForward(0, visual ? -1 : (layoutDirection() == Qt::LeftToRight ? -1 : 1)); } } else if (event == QKeySequence::SelectPreviousChar) { - cursorForward(1, layoutDirection() == Qt::LeftToRight ? -1 : 1); + cursorForward(1, visual ? -1 : (layoutDirection() == Qt::LeftToRight ? -1 : 1)); } else if (event == QKeySequence::MoveToNextWord) { if (echoMode() == QLineEdit::Normal) diff --git a/src/gui/widgets/qlinecontrol_p.h b/src/gui/widgets/qlinecontrol_p.h index 3c505c8..0042f17 100644 --- a/src/gui/widgets/qlinecontrol_p.h +++ b/src/gui/widgets/qlinecontrol_p.h @@ -160,6 +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); } void moveCursor(int pos, bool mark = false); void cursorForward(bool mark, int steps) @@ -167,10 +169,12 @@ public: int c = m_cursor; if (steps > 0) { while (steps--) - c = m_textLayout.nextCursorPosition(c); + c = cursorMoveStyle() == QTextCursor::Visual ? m_textLayout.rightCursorPosition(c) + : m_textLayout.nextCursorPosition(c); } else if (steps < 0) { while (steps++) - c = m_textLayout.previousCursorPosition(c); + c = cursorMoveStyle() == QTextCursor::Visual ? 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 07bd273..43c3f52 100644 --- a/src/gui/widgets/qlineedit.cpp +++ b/src/gui/widgets/qlineedit.cpp @@ -1112,6 +1112,34 @@ void QLineEdit::setDragEnabled(bool b) /*! + \property QLineEdit::cursorMoveStyle + \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 + 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, + 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 +{ + Q_D(const QLineEdit); + return d->control->cursorMoveStyle(); +} + +void QLineEdit::setCursorMoveStyle(QTextCursor::MoveStyle style) +{ + Q_D(QLineEdit); + d->control->setCursorMoveStyle(style); +} + +/*! \property QLineEdit::acceptableInput \brief whether the input satisfies the inputMask and the validator. diff --git a/src/gui/widgets/qlineedit.h b/src/gui/widgets/qlineedit.h index 636cee7..73a736c 100644 --- a/src/gui/widgets/qlineedit.h +++ b/src/gui/widgets/qlineedit.h @@ -43,6 +43,7 @@ #define QLINEEDIT_H #include +#include #include #include @@ -158,6 +159,9 @@ public: void setDragEnabled(bool b); bool dragEnabled() const; + void setCursorMoveStyle(QTextCursor::MoveStyle style); + QTextCursor::MoveStyle cursorMoveStyle() const; + QString inputMask() const; void setInputMask(const QString &inputMask); bool hasAcceptableInput() const; diff --git a/tests/auto/qcomplextext/tst_qcomplextext.cpp b/tests/auto/qcomplextext/tst_qcomplextext.cpp index 3d8e290..04943c5 100644 --- a/tests/auto/qcomplextext/tst_qcomplextext.cpp +++ b/tests/auto/qcomplextext/tst_qcomplextext.cpp @@ -71,6 +71,10 @@ private slots: void bidiReorderString(); void bidiCursor_qtbug2795(); void bidiCursor_PDF(); + void bidiCursorMovement_data(); + void bidiCursorMovement(); + void bidiCursorLogicalMovement_data(); + void bidiCursorLogicalMovement(); }; tst_QComplexText::tst_QComplexText() @@ -185,6 +189,89 @@ void tst_QComplexText::bidiCursor_qtbug2795() QVERIFY(x1 == x2); } +void tst_QComplexText::bidiCursorMovement_data() +{ + QTest::addColumn("logical"); + QTest::addColumn("basicDir"); + + const LV *data = logical_visual; + while ( data->name ) { + //next we fill it with data + QTest::newRow( data->name ) + << QString::fromUtf8( data->logical ) + << (int) data->basicDir; + data++; + } +} + +void tst_QComplexText::bidiCursorMovement() +{ + QFETCH(QString, logical); + QFETCH(int, basicDir); + + QTextLayout layout(logical); + + QTextOption option = layout.textOption(); + option.setTextDirection(basicDir == QChar::DirL ? Qt::LeftToRight : Qt::RightToLeft); + layout.setTextOption(option); + bool moved; + int oldPos, newPos = 0; + qreal x, newX; + + layout.beginLayout(); + QTextLine line = layout.createLine(); + layout.endLayout(); + + newX = line.cursorToX(0); + do { + oldPos = newPos; + x = newX; + newX = line.cursorToX(oldPos); + if (basicDir == QChar::DirL) { + QVERIFY(newX >= x); + newPos = layout.rightCursorPosition(oldPos); + } else + { + QVERIFY(newX <= x); + newPos = layout.leftCursorPosition(oldPos); + } + moved = (oldPos != newPos); + } while (moved); +} + +void tst_QComplexText::bidiCursorLogicalMovement_data() +{ + bidiCursorMovement_data(); +} + +void tst_QComplexText::bidiCursorLogicalMovement() +{ + QFETCH(QString, logical); + QFETCH(int, basicDir); + + QTextLayout layout(logical); + + QTextOption option = layout.textOption(); + option.setTextDirection(basicDir == QChar::DirL ? Qt::LeftToRight : Qt::RightToLeft); + layout.setTextOption(option); + bool moved; + int oldPos, newPos = 0; + + do { + oldPos = newPos; + newPos = layout.nextCursorPosition(oldPos); + QVERIFY(newPos >= oldPos); + moved = (oldPos != newPos); + } while (moved); + + do { + oldPos = newPos; + newPos = layout.previousCursorPosition(oldPos); + QVERIFY(newPos <= oldPos); + moved = (oldPos != newPos); + } while (moved); +} + void tst_QComplexText::bidiCursor_PDF() { QString str = QString::fromUtf8("\342\200\252hello\342\200\254"); diff --git a/tests/auto/qlineedit/tst_qlineedit.cpp b/tests/auto/qlineedit/tst_qlineedit.cpp index 9176174..f45481c 100644 --- a/tests/auto/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/qlineedit/tst_qlineedit.cpp @@ -282,6 +282,12 @@ private slots: void validateAndSet(); #endif + void bidiVisualMovement_data(); + void bidiVisualMovement(); + + void bidiLogicalMovement_data(); + void bidiLogicalMovement(); + protected slots: #ifdef QT3_SUPPORT void lostFocus(); @@ -3760,5 +3766,135 @@ void tst_QLineEdit::QTBUG13520_textNotVisible() } +void tst_QLineEdit::bidiVisualMovement_data() +{ + QTest::addColumn("logical"); + QTest::addColumn("basicDir"); + QTest::addColumn("positionList"); + + QTest::newRow("Latin text") + << QString::fromUtf8("abc") + << (int) QChar::DirL + << (IntList() << 0 << 1 << 2 << 3); + QTest::newRow("Hebrew text, one item") + << QString::fromUtf8("\327\220\327\221\327\222") + << (int) QChar::DirR + << (QList() << 0 << 1 << 2 << 3); + QTest::newRow("Hebrew text after Latin text") + << QString::fromUtf8("abc\327\220\327\221\327\222") + << (int) QChar::DirL + << (QList() << 0 << 1 << 2 << 6 << 5 << 4 << 3); + QTest::newRow("Latin text after Hebrew text") + << QString::fromUtf8("\327\220\327\221\327\222abc") + << (int) QChar::DirR + << (QList() << 0 << 1 << 2 << 6 << 5 << 4 << 3); + QTest::newRow("LTR, 3 items") + << QString::fromUtf8("abc\327\220\327\221\327\222abc") + << (int) QChar::DirL + << (QList() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 9); + QTest::newRow("RTL, 3 items") + << QString::fromUtf8("\327\220\327\221\327\222abc\327\220\327\221\327\222") + << (int) QChar::DirR + << (QList() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 9); + QTest::newRow("LTR, 4 items") + << QString::fromUtf8("abc\327\220\327\221\327\222abc\327\220\327\221\327\222") + << (int) QChar::DirL + << (QList() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 12 << 11 << 10 << 9); + QTest::newRow("RTL, 4 items") + << QString::fromUtf8("\327\220\327\221\327\222abc\327\220\327\221\327\222abc") + << (int) QChar::DirR + << (QList() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 12 << 11 << 10 << 9); +} + +void tst_QLineEdit::bidiVisualMovement() +{ + QFETCH(QString, logical); + QFETCH(int, basicDir); + QFETCH(IntList, positionList); + + QLineEdit le; + le.setText(logical); + + le.setCursorMoveStyle(QTextCursor::Visual); + le.setCursorPosition(0); + + bool moved; + int i = 0, oldPos, newPos = 0; + + do { + oldPos = newPos; + QVERIFY(oldPos == positionList[i]); + if (basicDir == QChar::DirL) { + QTest::keyClick(&le, Qt::Key_Right); + } else + QTest::keyClick(&le, Qt::Key_Left); + newPos = le.cursorPosition(); + moved = (oldPos != newPos); + i++; + } while (moved); + + QVERIFY(i == positionList.size()); + + do { + i--; + oldPos = newPos; + QVERIFY(oldPos == positionList[i]); + if (basicDir == QChar::DirL) { + QTest::keyClick(&le, Qt::Key_Left); + } else + { + QTest::keyClick(&le, Qt::Key_Right); + } + newPos = le.cursorPosition(); + moved = (oldPos != newPos); + } while (moved && i >= 0); +} + +void tst_QLineEdit::bidiLogicalMovement_data() +{ + bidiVisualMovement_data(); +} + +void tst_QLineEdit::bidiLogicalMovement() +{ + QFETCH(QString, logical); + QFETCH(int, basicDir); + + QLineEdit le; + le.setText(logical); + + le.setCursorMoveStyle(QTextCursor::Logical); + le.setCursorPosition(0); + + bool moved; + int i = 0, oldPos, newPos = 0; + + do { + oldPos = newPos; + QVERIFY(oldPos == i); + if (basicDir == QChar::DirL) { + QTest::keyClick(&le, Qt::Key_Right); + } else + QTest::keyClick(&le, Qt::Key_Left); + newPos = le.cursorPosition(); + moved = (oldPos != newPos); + i++; + } while (moved); + + do { + i--; + oldPos = newPos; + QVERIFY(oldPos == i); + if (basicDir == QChar::DirL) { + QTest::keyClick(&le, Qt::Key_Left); + } else + { + QTest::keyClick(&le, Qt::Key_Right); + } + newPos = le.cursorPosition(); + moved = (oldPos != newPos); + } while (moved && i >= 0); +} + QTEST_MAIN(tst_QLineEdit) #include "tst_qlineedit.moc" diff --git a/tests/auto/qtextedit/tst_qtextedit.cpp b/tests/auto/qtextedit/tst_qtextedit.cpp index 9ca17b9..5a64593 100644 --- a/tests/auto/qtextedit/tst_qtextedit.cpp +++ b/tests/auto/qtextedit/tst_qtextedit.cpp @@ -42,7 +42,6 @@ #include - #include #include #include @@ -69,6 +68,7 @@ typedef QList pairListType; Q_DECLARE_METATYPE(pairListType); Q_DECLARE_METATYPE(keyPairType); Q_DECLARE_METATYPE(QList); +Q_DECLARE_METATYPE(QList); #ifdef Q_WS_MAC #include @@ -205,6 +205,11 @@ private slots: #ifndef QT_NO_CONTEXTMENU void taskQTBUG_7902_contextMenuCrash(); #endif + void bidiVisualMovement_data(); + void bidiVisualMovement(); + + void bidiLogicalMovement_data(); + void bidiLogicalMovement(); private: void createSelection(); @@ -2235,5 +2240,147 @@ void tst_QTextEdit::taskQTBUG_7902_contextMenuCrash() } #endif +void tst_QTextEdit::bidiVisualMovement_data() +{ + QTest::addColumn("logical"); + QTest::addColumn("basicDir"); + QTest::addColumn >("positionList"); + + QTest::newRow("Latin text") + << QString::fromUtf8("abc") + << (int) QChar::DirL + << (QList() << 0 << 1 << 2 << 3); + QTest::newRow("Hebrew text, one item") + << QString::fromUtf8("\327\220\327\221\327\222") + << (int) QChar::DirR + << (QList() << 0 << 1 << 2 << 3); + QTest::newRow("Hebrew text after Latin text") + << QString::fromUtf8("abc\327\220\327\221\327\222") + << (int) QChar::DirL + << (QList() << 0 << 1 << 2 << 6 << 5 << 4 << 3); + QTest::newRow("Latin text after Hebrew text") + << QString::fromUtf8("\327\220\327\221\327\222abc") + << (int) QChar::DirR + << (QList() << 0 << 1 << 2 << 6 << 5 << 4 << 3); + QTest::newRow("LTR, 3 items") + << QString::fromUtf8("abc\327\220\327\221\327\222abc") + << (int) QChar::DirL + << (QList() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 9); + QTest::newRow("RTL, 3 items") + << QString::fromUtf8("\327\220\327\221\327\222abc\327\220\327\221\327\222") + << (int) QChar::DirR + << (QList() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 9); + QTest::newRow("LTR, 4 items") + << QString::fromUtf8("abc\327\220\327\221\327\222abc\327\220\327\221\327\222") + << (int) QChar::DirL + << (QList() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 12 << 11 << 10 << 9); + QTest::newRow("RTL, 4 items") + << QString::fromUtf8("\327\220\327\221\327\222abc\327\220\327\221\327\222abc") + << (int) QChar::DirR + << (QList() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 12 << 11 << 10 << 9); +} + +void tst_QTextEdit::bidiVisualMovement() +{ + QFETCH(QString, logical); + QFETCH(int, basicDir); + QFETCH(QList, positionList); + + ed->setText(logical); + + QTextOption option = ed->document()->defaultTextOption(); + option.setTextDirection(basicDir == QChar::DirL ? Qt::LeftToRight : Qt::RightToLeft); + ed->document()->setDefaultTextOption(option); + + ed->document()->setDefaultCursorMoveStyle(QTextCursor::Visual); + ed->moveCursor(QTextCursor::Start); + ed->show(); + + bool moved; + int i = 0, oldPos, newPos = 0; + + do { + oldPos = newPos; + QVERIFY(oldPos == positionList[i]); + if (basicDir == QChar::DirL) { + ed->moveCursor(QTextCursor::Right); + } else + { + ed->moveCursor(QTextCursor::Left); + } + newPos = ed->textCursor().position(); + moved = (oldPos != newPos); + i++; + } while (moved); + + QVERIFY(i == positionList.size()); + + do { + i--; + oldPos = newPos; + QVERIFY(oldPos == positionList[i]); + if (basicDir == QChar::DirL) { + ed->moveCursor(QTextCursor::Left); + } else + { + ed->moveCursor(QTextCursor::Right); + } + newPos = ed->textCursor().position(); + moved = (oldPos != newPos); + } while (moved && i >= 0); +} + +void tst_QTextEdit::bidiLogicalMovement_data() +{ + bidiVisualMovement_data(); +} + +void tst_QTextEdit::bidiLogicalMovement() +{ + QFETCH(QString, logical); + QFETCH(int, basicDir); + + ed->setText(logical); + + QTextOption option = ed->document()->defaultTextOption(); + option.setTextDirection(basicDir == QChar::DirL ? Qt::LeftToRight : Qt::RightToLeft); + ed->document()->setDefaultTextOption(option); + + ed->document()->setDefaultCursorMoveStyle(QTextCursor::Logical); + ed->moveCursor(QTextCursor::Start); + ed->show(); + + bool moved; + int i = 0, oldPos, newPos = 0; + + do { + oldPos = newPos; + QVERIFY(oldPos == i); + if (basicDir == QChar::DirL) { + ed->moveCursor(QTextCursor::Right); + } else + { + ed->moveCursor(QTextCursor::Left); + } + newPos = ed->textCursor().position(); + moved = (oldPos != newPos); + i++; + } while (moved); + + do { + i--; + oldPos = newPos; + QVERIFY(oldPos == i); + if (basicDir == QChar::DirL) { + ed->moveCursor(QTextCursor::Left); + } else + { + ed->moveCursor(QTextCursor::Right); + } + newPos = ed->textCursor().position(); + moved = (oldPos != newPos); + } while (moved && i >= 0); +} + QTEST_MAIN(tst_QTextEdit) #include "tst_qtextedit.moc" -- cgit v0.12 From 4b264b241067ed58f8a72fc7b221565112d936f4 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Mon, 18 Apr 2011 17:08:30 +0200 Subject: Turn on HarfBuzz support for Mac/Cocoa It's possible to enable HarfBuzz text layout on Mac by either: - Set QT_ENABLE_HARFBUZZ environment variable when running a Qt app. - configure with -harfbuzz to build Qt, then HarfBuzz support will be turned on by default. HarfBuzz will only be used when the font explicitly requested is supported by HarfBuzz (aka. TrueType/OpenType font), other fonts (AAT fonts) will still be handled by Core Text. Using HarfBuzz for text layout will hopefully solve most tricky complex text shaping bugs on Mac. Task-number: QTBUG-17728 Reviewed-by: Eskil --- configure | 16 +++++++++++++++- src/gui/text/qtextengine.cpp | 34 +++++++++++++++++++++++++++++++++- src/gui/text/text.pri | 3 +++ 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 99b79fc..9b923ab 100755 --- a/configure +++ b/configure @@ -804,6 +804,7 @@ CFG_MAC_XARCH=auto CFG_MAC_CARBON=no CFG_MAC_COCOA=yes COMMANDLINE_MAC_CARBON=no +CFG_MAC_HARFBUZZ=no CFG_SXE=no CFG_PREFIX_INSTALL=yes CFG_SDK= @@ -1040,7 +1041,7 @@ while [ "$#" -gt 0 ]; do VAL=no ;; #Qt style yes options - -incremental|-qvfb|-profile|-shared|-static|-sm|-xinerama|-xshape|-xsync|-xinput|-egl|-reduce-exports|-pch|-separate-debug-info|-stl|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-nis|-qdbus|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-qt3support|-debug-and-release|-exceptions|-cocoa|-carbon|-universal|-prefix-install|-silent|-armfpa|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-ptmalloc|-xmlpatterns|-phonon|-phonon-backend|-multimedia|-audio-backend|-svg|-declarative|-declarative-debug|-javascript-jit|-script|-scripttools|-rpath|-force-pkg-config|-s60|-usedeffiles) + -incremental|-qvfb|-profile|-shared|-static|-sm|-xinerama|-xshape|-xsync|-xinput|-egl|-reduce-exports|-pch|-separate-debug-info|-stl|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-nis|-qdbus|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-qt3support|-debug-and-release|-exceptions|-cocoa|-carbon|-universal|-harfbuzz|-prefix-install|-silent|-armfpa|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-ptmalloc|-xmlpatterns|-phonon|-phonon-backend|-multimedia|-audio-backend|-svg|-declarative|-declarative-debug|-javascript-jit|-script|-scripttools|-rpath|-force-pkg-config|-s60|-usedeffiles) VAR=`echo $1 | sed "s,^-\(.*\),\1,"` VAL=yes ;; @@ -1498,6 +1499,13 @@ while [ "$#" -gt 0 ]; do UNKNOWN_OPT=yes fi ;; + harfbuzz) + if [ "$PLATFORM_MAC" = "yes" ] && [ "$CFG_MAC_CARBON" != "yes" ] && [ "$VAL" = "yes" ]; then + CFG_MAC_HARFBUZZ="$VAL" + else + UNKNOWN_OPT=yes + fi + ;; framework) if [ "$PLATFORM_MAC" = "yes" ] || [ "$PLATFORM_QPA" = "yes" ]; then @@ -4245,6 +4253,11 @@ Qt/Mac only: -sdk ......... Build Qt using Apple provided SDK . This option requires gcc 4. To use a different SDK with gcc 3.3, set the SDKROOT environment variable. + -harfbuzz .......... Use HarfBuzz to do text layout instead of Core Text when possible. + It is only available to Cocoa builds. + * -no-harfbuzz ....... Disable HarfBuzz on Mac. It can still be enabled by setting + QT_ENABLE_HARFBUZZ environment variable. + EOF fi @@ -7209,6 +7222,7 @@ fi [ "$CFG_NAS" = "system" ] && QT_CONFIG="$QT_CONFIG nas" [ "$CFG_OPENSSL" = "yes" ] && QT_CONFIG="$QT_CONFIG openssl" [ "$CFG_OPENSSL" = "linked" ] && QT_CONFIG="$QT_CONFIG openssl-linked" +[ "$CFG_MAC_HARFBUZZ" = "yes" ] && QT_CONFIG="$QT_CONFIG harfbuzz" if [ "$PLATFORM_X11" = "yes" ]; then [ "$CFG_SM" = "yes" ] && QT_CONFIG="$QT_CONFIG x11sm" diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 0e649f0..dab4bb7 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -856,6 +856,21 @@ void QTextEngine::shapeLine(const QScriptLine &line) } } +#if !defined(QT_ENABLE_HARFBUZZ_FOR_MAC) +static bool enableHarfBuzz() +{ + static enum { Yes, No, Unknown } status = Unknown; + + if (status == Unknown) { + QByteArray v = qgetenv("QT_ENABLE_HARFBUZZ"); + bool value = !v.isEmpty() && v != "0" && v != "false"; + if (value) status = Yes; + else status = No; + } + return status == Yes; +} +#endif + void QTextEngine::shapeText(int item) const { Q_ASSERT(item < layoutData->items.size()); @@ -865,7 +880,24 @@ void QTextEngine::shapeText(int item) const return; #if defined(Q_WS_MAC) - shapeTextMac(item); +#if !defined(QT_ENABLE_HARFBUZZ_FOR_MAC) + if (enableHarfBuzz()) { +#endif + QFontEngine *actualFontEngine = fontEngine(si, &si.ascent, &si.descent, &si.leading); + if (actualFontEngine->type() == QFontEngine::Multi) + actualFontEngine = static_cast(actualFontEngine)->engine(0); + + HB_Face face = actualFontEngine->harfbuzzFace(); + HB_Script script = (HB_Script) si.analysis.script; + if (face->supported_scripts[script]) + shapeTextWithHarfbuzz(item); + else + shapeTextMac(item); +#if !defined(QT_ENABLE_HARFBUZZ_FOR_MAC) + } else { + shapeTextMac(item); + } +#endif #elif defined(Q_WS_WINCE) shapeTextWithCE(item); #else diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri index df9398c..83be5b4 100644 --- a/src/gui/text/text.pri +++ b/src/gui/text/text.pri @@ -114,6 +114,9 @@ unix:x11 { OBJECTIVE_SOURCES += \ text/qfontengine_coretext.mm \ text/qfontengine_mac.mm + contains(QT_CONFIG, harfbuzz) { + DEFINES += QT_ENABLE_HARFBUZZ_FOR_MAC + } } embedded { -- cgit v0.12 From 0201d5f5a8c95bd4f6b94726ed0db2b83cd3efc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Tue, 19 Apr 2011 11:45:29 +0200 Subject: Skip linearGradientSymmetry test on QWS. QWS defines GRADIENT_STOPTABLE_SIZE to be 256, which is not enough resolution for this test to pass. Reviewed-by: Eskil Abrahamsen Blomfeldt --- tests/auto/qpainter/tst_qpainter.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/auto/qpainter/tst_qpainter.cpp b/tests/auto/qpainter/tst_qpainter.cpp index 64dacec..76bc5d63 100644 --- a/tests/auto/qpainter/tst_qpainter.cpp +++ b/tests/auto/qpainter/tst_qpainter.cpp @@ -4016,6 +4016,9 @@ void tst_QPainter::linearGradientSymmetry_data() void tst_QPainter::linearGradientSymmetry() { +#ifdef Q_WS_QWS + QSKIP("QWS has limited resolution in the gradient color table", SkipAll); +#else QFETCH(QGradientStops, stops); QImage a(64, 8, QImage::Format_ARGB32_Premultiplied); @@ -4037,6 +4040,7 @@ void tst_QPainter::linearGradientSymmetry() b = b.mirrored(true); QCOMPARE(a, b); +#endif } void tst_QPainter::gradientInterpolation() -- cgit v0.12 From b86c9120710bf1481df5f6541618169a82fd65b8 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Tue, 19 Apr 2011 12:48:19 +0200 Subject: Don't transform glyph positions for Core Graphics paint engine Since it already transformed text positions based on transform matrix on QPainter. Reviewed-by: Eskil --- src/gui/painting/qpainter.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index cbd16ae..25bf6be 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -156,7 +156,8 @@ static bool qt_paintengine_supports_transformations(QPaintEngine::Type type) { return type == QPaintEngine::OpenGL2 || type == QPaintEngine::OpenVG - || type == QPaintEngine::OpenGL; + || type == QPaintEngine::OpenGL + || type == QPaintEngine::CoreGraphics; } #ifndef QT_NO_DEBUG @@ -5817,7 +5818,7 @@ void QPainter::drawGlyphs(const QPointF &position, const QGlyphs &glyphs) bool paintEngineSupportsTransformations = d->extended != 0 ? qt_paintengine_supports_transformations(d->extended->type()) - : false; + : qt_paintengine_supports_transformations(d->engine->type()); for (int i=0; i Date: Tue, 19 Apr 2011 15:19:31 +0200 Subject: Fix compilation with Qt3Support Reviewed-by: Fabien Freling --- src/qt3support/text/q3richtext.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qt3support/text/q3richtext.cpp b/src/qt3support/text/q3richtext.cpp index 668a322..6c77405 100644 --- a/src/qt3support/text/q3richtext.cpp +++ b/src/qt3support/text/q3richtext.cpp @@ -63,6 +63,7 @@ #include "qstyleoption.h" #include "q3stylesheet.h" #include "qtextstream.h" +#include #include #include -- cgit v0.12 From 39202973e3fb7ff37033290b29efa1b9edc674fb Mon Sep 17 00:00:00 2001 From: mread Date: Tue, 19 Apr 2011 13:12:24 +0100 Subject: Symbian's QElapsedTimer::restart() fixed to return ms rather than us Symbian's QElapsedTimer::restart() had accidently been changed to return a microsecond count rather than milliseconds, when the elapsed timer resolution was increased. This fixes it back to milliseconds. Reviewed-by: Shane Kearns --- src/corelib/tools/qelapsedtimer_symbian.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/qelapsedtimer_symbian.cpp b/src/corelib/tools/qelapsedtimer_symbian.cpp index b831e03..3667b05 100644 --- a/src/corelib/tools/qelapsedtimer_symbian.cpp +++ b/src/corelib/tools/qelapsedtimer_symbian.cpp @@ -95,7 +95,7 @@ qint64 QElapsedTimer::restart() qint64 oldt1 = t1; t1 = getMicrosecondFromTick(); t2 = 0; - return t1 - oldt1; + return (t1 - oldt1) / 1000; } qint64 QElapsedTimer::nsecsElapsed() const -- cgit v0.12 From 62d0923a822a5a0f1466fa36ac24e96472d1a6d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Tue, 19 Apr 2011 07:57:39 -0400 Subject: wayland: Add native access interface for Wayland plugin --- .../platforms/wayland/qwaylandintegration.cpp | 7 +++ .../platforms/wayland/qwaylandintegration.h | 3 + .../platforms/wayland/qwaylandnativeinterface.cpp | 72 ++++++++++++++++++++++ .../platforms/wayland/qwaylandnativeinterface.h | 60 ++++++++++++++++++ src/plugins/platforms/wayland/wayland.pro | 2 + 5 files changed, 144 insertions(+) create mode 100644 src/plugins/platforms/wayland/qwaylandnativeinterface.cpp create mode 100644 src/plugins/platforms/wayland/qwaylandnativeinterface.h diff --git a/src/plugins/platforms/wayland/qwaylandintegration.cpp b/src/plugins/platforms/wayland/qwaylandintegration.cpp index 3f3ee5e..b6401f6 100644 --- a/src/plugins/platforms/wayland/qwaylandintegration.cpp +++ b/src/plugins/platforms/wayland/qwaylandintegration.cpp @@ -44,6 +44,7 @@ #include "qwaylanddisplay.h" #include "qwaylandshmsurface.h" #include "qwaylandshmwindow.h" +#include "qwaylandnativeinterface.h" #include "qgenericunixfontdatabase.h" @@ -62,9 +63,15 @@ QWaylandIntegration::QWaylandIntegration(bool useOpenGL) : mFontDb(new QGenericUnixFontDatabase()) , mDisplay(new QWaylandDisplay()) , mUseOpenGL(useOpenGL) + , mNativeInterface(new QWaylandNativeInterface) { } +QPlatformNativeInterface * QWaylandIntegration::nativeInterface() const +{ + return mNativeInterface; +} + QList QWaylandIntegration::screens() const { diff --git a/src/plugins/platforms/wayland/qwaylandintegration.h b/src/plugins/platforms/wayland/qwaylandintegration.h index fc9b8d6..71f6d9c 100644 --- a/src/plugins/platforms/wayland/qwaylandintegration.h +++ b/src/plugins/platforms/wayland/qwaylandintegration.h @@ -63,12 +63,15 @@ public: QPlatformFontDatabase *fontDatabase() const; + QPlatformNativeInterface *nativeInterface() const; + private: bool hasOpenGL() const; QPlatformFontDatabase *mFontDb; QWaylandDisplay *mDisplay; bool mUseOpenGL; + QPlatformNativeInterface *mNativeInterface; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp b/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp new file mode 100644 index 0000000..c3bfba0 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandnativeinterface.h" + +#include "qwaylanddisplay.h" +#include "qwaylandwindow.h" +#include + +void *QWaylandNativeInterface::nativeResourceForWidget(const QByteArray &resourceString, QWidget *widget) +{ + QByteArray lowerCaseResource = resourceString.toLower(); + + if (lowerCaseResource == "display") + return qPlatformScreenForWidget(widget)->display()->wl_display(); + if (lowerCaseResource == "surface") { + return ((QWaylandWindow *) widget->platformWindow())->wl_surface(); + } + + return NULL; +} + + +QWaylandScreen * QWaylandNativeInterface::qPlatformScreenForWidget(QWidget *widget) +{ + QWaylandScreen *screen; + + if (widget) { + screen = static_cast(QPlatformScreen::platformScreenForWidget(widget)); + } else { + screen = static_cast(QApplicationPrivate::platformIntegration()->screens()[0]); + } + return screen; +} diff --git a/src/plugins/platforms/wayland/qwaylandnativeinterface.h b/src/plugins/platforms/wayland/qwaylandnativeinterface.h new file mode 100644 index 0000000..ac4cdb9 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandnativeinterface.h @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDNATIVEINTERFACE_H +#define QWAYLANDNATIVEINTERFACE_H + +#include "qwaylandscreen.h" + +#include + +class QWaylandNativeInterface : public QPlatformNativeInterface +{ +public: + void *nativeResourceForWidget(const QByteArray &resourceString, + QWidget *widget); + +private: + static QWaylandScreen *qPlatformScreenForWidget(QWidget *widget); +}; + + +#endif // QWAYLANDNATIVEINTERFACE_H diff --git a/src/plugins/platforms/wayland/wayland.pro b/src/plugins/platforms/wayland/wayland.pro index 5945438..8d2d4b5 100644 --- a/src/plugins/platforms/wayland/wayland.pro +++ b/src/plugins/platforms/wayland/wayland.pro @@ -8,6 +8,7 @@ DEFINES += $$QMAKE_DEFINES_WAYLAND SOURCES = main.cpp \ qwaylandintegration.cpp \ + qwaylandnativeinterface.cpp \ qwaylandshmsurface.cpp \ qwaylandinputdevice.cpp \ qwaylandcursor.cpp \ @@ -17,6 +18,7 @@ SOURCES = main.cpp \ qwaylandshmwindow.cpp HEADERS = qwaylandintegration.h \ + qwaylandnativeinterface.h \ qwaylandcursor.h \ qwaylanddisplay.h \ qwaylandwindow.h \ -- cgit v0.12 From bdd956da27f6f4629b85bd571eb1dfbd30f9c071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Tue, 19 Apr 2011 07:58:21 -0400 Subject: wayland: Remove unused EGLConfig field --- .../platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h index 549d039..856321d 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h @@ -63,7 +63,6 @@ private: QWaylandEglIntegration *mEglIntegration; QWaylandGLContext *mGLContext; struct wl_egl_window *mWaylandEglWindow; - EGLConfig mConfig; const QWaylandWindow *mParentWindow; }; -- cgit v0.12 From 80b3d84dac89ca517826280e09f712826ce61f57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Tue, 19 Apr 2011 08:01:29 -0400 Subject: wayland: Include eglconvenience.pri instead of pulling in individual file --- .../platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri b/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri index bc97864..cd07011 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri @@ -1,12 +1,11 @@ +include (../../../eglconvenience/eglconvenience.pri) + LIBS += -lwayland-egl -lEGL INCLUDEPATH += $$PWD SOURCES += $$PWD/qwaylandeglintegration.cpp \ $$PWD/qwaylandglcontext.cpp \ - $$PWD/qwaylandeglwindow.cpp \ - $$PWD/../../../eglconvenience/qeglconvenience.cpp + $$PWD/qwaylandeglwindow.cpp HEADERS += $$PWD/qwaylandeglintegration.h \ $$PWD/qwaylandglcontext.h \ - $$PWD/qwaylandeglwindow.h \ - $$PWD/../../../eglconvenience/qeglconvenience.h \ - gl_integration/wayland_egl/qwaylandeglinclude.h + $$PWD/qwaylandeglwindow.h -- cgit v0.12 From 77c2f1ea69df5adb49daddc25a14daae3f1c42da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Tue, 19 Apr 2011 08:05:51 -0400 Subject: wayland: Discard motion and button events receive with a NULL pointer focus If we destroy a surface we NULL out mPointerFocus and mKeyboardFocus pointers, but the server may still send a few events out before it receives the destroy request. Discard such events. --- src/plugins/platforms/wayland/qwaylandinputdevice.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp index 6c2f341..fc305fe 100644 --- a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp +++ b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp @@ -101,6 +101,12 @@ void QWaylandInputDevice::inputHandleMotion(void *data, QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; QWaylandWindow *window = inputDevice->mPointerFocus; + if (window == NULL) { + /* We destroyed the pointer focus surface, but the server + * didn't get the message yet. */ + return; + } + inputDevice->mSurfacePos = QPoint(surface_x, surface_y); inputDevice->mGlobalPos = QPoint(x, y); inputDevice->mTime = time; @@ -120,6 +126,12 @@ void QWaylandInputDevice::inputHandleButton(void *data, QWaylandWindow *window = inputDevice->mPointerFocus; Qt::MouseButton qt_button; + if (window == NULL) { + /* We destroyed the pointer focus surface, but the server + * didn't get the message yet. */ + return; + } + switch (button) { case 272: qt_button = Qt::LeftButton; @@ -229,6 +241,12 @@ void QWaylandInputDevice::inputHandleKey(void *data, QEvent::Type type; char s[2]; + if (window == NULL) { + /* We destroyed the keyboard focus surface, but the server + * didn't get the message yet. */ + return; + } + code = key + inputDevice->mXkb->min_key_code; level = 0; -- cgit v0.12 From fe5567572030a30c643ae8d98b57e95e49bab905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Tue, 19 Apr 2011 08:07:05 -0400 Subject: wayland: Drop a debug qWarning() --- src/plugins/platforms/wayland/qwaylandinputdevice.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp index fc305fe..2d7df1d 100644 --- a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp +++ b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp @@ -268,9 +268,6 @@ void QWaylandInputDevice::inputHandleKey(void *data, sym = translateKey(sym, s, sizeof s); - qWarning("keycode %d, sym %d, string %d, modifiers 0x%x", - code, sym, s[0], (int) inputDevice->mModifiers); - if (window) { QWindowSystemInterface::handleKeyEvent(window->widget(), time, type, sym, -- cgit v0.12 From 0edbaca5e7b718bb9bbbeaccc9e322b525b4327e Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Thu, 14 Apr 2011 09:48:58 +0200 Subject: Revert "Fixed a crash in QListView" This caused regressions in the QListView This reverts commit 5b3872b2d7523d44ba454a76613e7a3fa45387f7. --- src/gui/itemviews/qabstractitemview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index 5142107..081a6d9 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -1542,7 +1542,6 @@ bool QAbstractItemView::event(QEvent *event) break; case QEvent::LayoutDirectionChange: case QEvent::ApplicationLayoutDirectionChange: - case QEvent::Resize: updateGeometries(); break; case QEvent::StyleChange: @@ -2397,6 +2396,7 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event) void QAbstractItemView::resizeEvent(QResizeEvent *event) { QAbstractScrollArea::resizeEvent(event); + updateGeometries(); } /*! -- cgit v0.12 From 986ab48f1128bdd56fa408fca8f4a564e874dd4d Mon Sep 17 00:00:00 2001 From: Honglei Zhang Date: Tue, 19 Apr 2011 17:29:27 +0300 Subject: Fix memory leak bugs in XmlPatterns In XmlPatterns implementation, QExplicitlySharedDataPointer and QSharedData classes are widely used. The over use of these classes has cuased couple of cyclic references. Some codes are refactored to use plain C++ pointer to break the reference loop. Task-number: QTBUG-15191 Reviewed-by: Laszlo Agocs and Sami Merila --- src/xmlpatterns/data/qitem_p.h | 4 ++++ src/xmlpatterns/expr/qdynamiccontextstore.cpp | 8 ++++---- src/xmlpatterns/expr/qdynamiccontextstore_p.h | 2 +- src/xmlpatterns/expr/qevaluationcache.cpp | 2 +- src/xmlpatterns/expr/qevaluationcache_p.h | 2 +- src/xmlpatterns/expr/qletclause.cpp | 2 +- tests/auto/qxmlquery/tst_qxmlquery.cpp | 4 ++-- tests/auto/xmlpatternsdiagnosticsts/xmlpatternsdiagnosticsts.pro | 2 ++ tests/auto/xmlpatternsschemats/xmlpatternsschemats.pro | 2 ++ tests/auto/xmlpatternsxqts/xmlpatternsxqts.pro | 2 ++ 10 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/xmlpatterns/data/qitem_p.h b/src/xmlpatterns/data/qitem_p.h index 8184b25..fb3866e 100644 --- a/src/xmlpatterns/data/qitem_p.h +++ b/src/xmlpatterns/data/qitem_p.h @@ -408,6 +408,10 @@ namespace QPatternist inline void reset() { + /* Delete the atomicValue if necessary*/ + if(isAtomicValue() && !atomicValue->ref.deref()) + delete atomicValue; + /* Note that this function should be equal to the default * constructor. */ node.model = 0; diff --git a/src/xmlpatterns/expr/qdynamiccontextstore.cpp b/src/xmlpatterns/expr/qdynamiccontextstore.cpp index 762b7d6..7e7ead7 100644 --- a/src/xmlpatterns/expr/qdynamiccontextstore.cpp +++ b/src/xmlpatterns/expr/qdynamiccontextstore.cpp @@ -51,24 +51,24 @@ using namespace QPatternist; DynamicContextStore::DynamicContextStore(const Expression::Ptr &operand, const DynamicContext::Ptr &context) : SingleContainer(operand), - m_context(context) + m_context(context.data()) { Q_ASSERT(context); } bool DynamicContextStore::evaluateEBV(const DynamicContext::Ptr &) const { - return m_operand->evaluateEBV(m_context); + return m_operand->evaluateEBV(DynamicContext::Ptr(m_context)); } Item::Iterator::Ptr DynamicContextStore::evaluateSequence(const DynamicContext::Ptr &) const { - return m_operand->evaluateSequence(m_context); + return m_operand->evaluateSequence(DynamicContext::Ptr(m_context)); } Item DynamicContextStore::evaluateSingleton(const DynamicContext::Ptr &) const { - return m_operand->evaluateSingleton(m_context); + return m_operand->evaluateSingleton(DynamicContext::Ptr(m_context)); } SequenceType::Ptr DynamicContextStore::staticType() const diff --git a/src/xmlpatterns/expr/qdynamiccontextstore_p.h b/src/xmlpatterns/expr/qdynamiccontextstore_p.h index 1d5d035..40bfcd1 100644 --- a/src/xmlpatterns/expr/qdynamiccontextstore_p.h +++ b/src/xmlpatterns/expr/qdynamiccontextstore_p.h @@ -86,7 +86,7 @@ namespace QPatternist virtual const SourceLocationReflection *actualReflection() const; private: - const DynamicContext::Ptr m_context; + DynamicContext *m_context; }; } diff --git a/src/xmlpatterns/expr/qevaluationcache.cpp b/src/xmlpatterns/expr/qevaluationcache.cpp index 2d1bb56..cb95af6 100644 --- a/src/xmlpatterns/expr/qevaluationcache.cpp +++ b/src/xmlpatterns/expr/qevaluationcache.cpp @@ -49,7 +49,7 @@ template EvaluationCache::EvaluationCache(const Expression::Ptr &op, const VariableDeclaration::Ptr &varDecl, const VariableSlotID aSlot) : SingleContainer(op) - , m_declaration(varDecl) + , m_declaration(varDecl.constData()) , m_varSlot(aSlot) { Q_ASSERT(m_declaration); diff --git a/src/xmlpatterns/expr/qevaluationcache_p.h b/src/xmlpatterns/expr/qevaluationcache_p.h index 86aeaf8..af4cfa0 100644 --- a/src/xmlpatterns/expr/qevaluationcache_p.h +++ b/src/xmlpatterns/expr/qevaluationcache_p.h @@ -124,7 +124,7 @@ namespace QPatternist private: static DynamicContext::Ptr topFocusContext(const DynamicContext::Ptr &context); - const VariableDeclaration::Ptr m_declaration; + const VariableDeclaration* m_declaration; /** * This variable must not be called m_slot. If it so, a compiler bug on * HP-UX-aCC-64 is triggered in the constructor initializor. See the diff --git a/src/xmlpatterns/expr/qletclause.cpp b/src/xmlpatterns/expr/qletclause.cpp index d3e939b..b789b48 100644 --- a/src/xmlpatterns/expr/qletclause.cpp +++ b/src/xmlpatterns/expr/qletclause.cpp @@ -60,7 +60,7 @@ LetClause::LetClause(const Expression::Ptr &operand1, DynamicContext::Ptr LetClause::bindVariable(const DynamicContext::Ptr &context) const { - context->setExpressionVariable(m_varDecl->slot, Expression::Ptr(new DynamicContextStore(m_operand1, context))); + context->setExpressionVariable(m_varDecl->slot, m_operand1); return context; } diff --git a/tests/auto/qxmlquery/tst_qxmlquery.cpp b/tests/auto/qxmlquery/tst_qxmlquery.cpp index e3c97d2..2e0d1aa 100644 --- a/tests/auto/qxmlquery/tst_qxmlquery.cpp +++ b/tests/auto/qxmlquery/tst_qxmlquery.cpp @@ -3301,8 +3301,8 @@ void tst_QXmlQuery::bindVariableQXmlQueryInvalidate() const QXmlQuery query2; query2.setQuery("'query2'"); - query.bindVariable(QLatin1String("name"), query); - QVERIFY(!query.isValid()); + query2.bindVariable(QLatin1String("name"), query); + QVERIFY(!query2.isValid()); } void tst_QXmlQuery::unknownSourceLocation() const diff --git a/tests/auto/xmlpatternsdiagnosticsts/xmlpatternsdiagnosticsts.pro b/tests/auto/xmlpatternsdiagnosticsts/xmlpatternsdiagnosticsts.pro index 3e252f6..48c79d5 100644 --- a/tests/auto/xmlpatternsdiagnosticsts/xmlpatternsdiagnosticsts.pro +++ b/tests/auto/xmlpatternsdiagnosticsts/xmlpatternsdiagnosticsts.pro @@ -25,3 +25,5 @@ wince*|symbian { catalog.path = . DEPLOYMENT += catalog } + +requires(contains(QT_CONFIG,private_tests)) diff --git a/tests/auto/xmlpatternsschemats/xmlpatternsschemats.pro b/tests/auto/xmlpatternsschemats/xmlpatternsschemats.pro index f36211e..0fb5fef 100644 --- a/tests/auto/xmlpatternsschemats/xmlpatternsschemats.pro +++ b/tests/auto/xmlpatternsschemats/xmlpatternsschemats.pro @@ -25,3 +25,5 @@ INCLUDEPATH += $$QT_SOURCE_TREE/tests/auto/xmlpatternssdk/ \ $$QT_SOURCE_TREE/tests/auto/xmlpatternsxqts \ ../xmlpatternsxqts \ ../xmlpatternssdk + +requires(contains(QT_CONFIG,private_tests)) diff --git a/tests/auto/xmlpatternsxqts/xmlpatternsxqts.pro b/tests/auto/xmlpatternsxqts/xmlpatternsxqts.pro index e81888a..0ced633 100644 --- a/tests/auto/xmlpatternsxqts/xmlpatternsxqts.pro +++ b/tests/auto/xmlpatternsxqts/xmlpatternsxqts.pro @@ -19,3 +19,5 @@ INCLUDEPATH += $$(QTDIR)/include/QtXmlPatterns/private \ CONFIG += testlib QT += xml TARGET = tst_xmlpatternsxqts + +requires(contains(QT_CONFIG,private_tests)) -- cgit v0.12 From c0021af006e9cc10ddc6123bf712af6ce77757c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Tue, 19 Apr 2011 16:48:57 +0200 Subject: Added missing function in QWaylandWindow. --- src/plugins/platforms/wayland/qwaylandwindow.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/platforms/wayland/qwaylandwindow.h b/src/plugins/platforms/wayland/qwaylandwindow.h index 1e60508..47d49a7 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.h +++ b/src/plugins/platforms/wayland/qwaylandwindow.h @@ -74,6 +74,9 @@ public: void damage(const QRegion ®ion); void waitForFrameSync(); + + struct wl_surface *wl_surface() const { return mSurface; } + protected: struct wl_surface *mSurface; virtual void newSurfaceCreated(); -- cgit v0.12 From 70f42ced8e01ddf0098b143e5804c22d55ebf16f Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Tue, 19 Apr 2011 18:02:33 +1000 Subject: Remove Q_ASSERT from qatomicint/pointer autotests Some code in these tests is not intended to be executed, but rather to detect compiler warnings. Instead of having an obscure fatal error if this code is run in a debug build, it now has a clear fatal error if run in any build. Change-Id: I1c9d27bb14ebf3313865b68e3e57668ba1d14e25 Task-number: QTBUG-17582 Reviewed-by: Rohan McGovern --- tests/auto/qatomicint/tst_qatomicint.cpp | 3 +-- tests/auto/qatomicpointer/tst_qatomicpointer.cpp | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/auto/qatomicint/tst_qatomicint.cpp b/tests/auto/qatomicint/tst_qatomicint.cpp index 717187a..5ccb997 100644 --- a/tests/auto/qatomicint/tst_qatomicint.cpp +++ b/tests/auto/qatomicint/tst_qatomicint.cpp @@ -116,8 +116,7 @@ tst_QAtomicInt::~tst_QAtomicInt() void tst_QAtomicInt::warningFreeHelper() { - Q_ASSERT(false); - // The code below is bogus, and shouldn't be run. We're looking for warnings, only. + qFatal("This code is bogus, and shouldn't be run. We're looking for compiler warnings only."); QBasicAtomicInt i = Q_BASIC_ATOMIC_INITIALIZER(0); diff --git a/tests/auto/qatomicpointer/tst_qatomicpointer.cpp b/tests/auto/qatomicpointer/tst_qatomicpointer.cpp index af8fabc..05f8294 100644 --- a/tests/auto/qatomicpointer/tst_qatomicpointer.cpp +++ b/tests/auto/qatomicpointer/tst_qatomicpointer.cpp @@ -98,8 +98,7 @@ struct WFHC void tst_QAtomicPointer::warningFreeHelper() { - Q_ASSERT(false); - // The code below is bogus, and shouldn't be run. We're looking for warnings, only. + qFatal("This code is bogus, and shouldn't be run. We're looking for compiler warnings only."); QBasicAtomicPointer p = Q_BASIC_ATOMIC_INITIALIZER(0); -- cgit v0.12 From 34c077faae538adc12d4aa28113640570dfc8728 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Wed, 20 Apr 2011 11:05:55 +1000 Subject: Remove Q_ASSERT from qcompleter autotest. Replace obscure failure on bad test data in debug builds with an informative warning in all builds. Change-Id: I9001820f34de2f78bf296a2f0e095ce73d9ac4bd Task-number: QTBUG-17582 Reviewed-by: Rohan McGovern --- tests/auto/qcompleter/tst_qcompleter.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/auto/qcompleter/tst_qcompleter.cpp b/tests/auto/qcompleter/tst_qcompleter.cpp index afcc433..9cb2468 100644 --- a/tests/auto/qcompleter/tst_qcompleter.cpp +++ b/tests/auto/qcompleter/tst_qcompleter.cpp @@ -277,7 +277,9 @@ retry: case 'L': row = completer->completionCount() - 1; break; case 'F': row = 0; break; default: - Q_ASSERT(false); + QFAIL(qPrintable(QString( + "Problem with 'step' value in test data: %1 (only P, N, L and F are allowed)." + ).arg(step[i]))); } completer->setCurrentRow(row); } -- cgit v0.12 From 67bc4990f7541cca089882a8c3be1b2b8d98cd4c Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Wed, 20 Apr 2011 11:39:14 +1000 Subject: Only ignore warning when it can actually be produced. Fix regression introduced in 3ca51d87296bcb3098d7de14294fef9294fd5ed4. The warning is only generated in builds where QT_NO_DEBUG is not defined. Change-Id: I9aa3db369094f4046062b5dc1dc694342208ee45 Task-number: QTBUG-17582 Reviewed-by: Rohan McGovern --- tests/auto/qaccessibility/tst_qaccessibility.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/qaccessibility/tst_qaccessibility.cpp b/tests/auto/qaccessibility/tst_qaccessibility.cpp index e5e3e77..2645090 100644 --- a/tests/auto/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/qaccessibility/tst_qaccessibility.cpp @@ -3835,7 +3835,9 @@ void tst_QAccessibility::accelerators() label->setText(tr("Q &&A")); QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QString()); +#ifndef QT_NO_DEBUG QTest::ignoreMessage(QtWarningMsg, "QKeySequence::mnemonic: \"Q &A&B\" contains multiple occurrences of '&'"); +#endif label->setText(tr("Q &A&B")); QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QKeySequence(Qt::ALT).toString(QKeySequence::NativeText) + QLatin1String("A")); -- cgit v0.12 From a5bd4abed834ce3670b2f28d4f932d612a033b36 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Wed, 20 Apr 2011 12:16:58 +1000 Subject: Remove Q_ASSERT from QCompleter autotest If a combobox had no completer, this test would assert in a debug build and crash in a release build. This commit makes the test report a test failure and avoid terminating in all builds. Change-Id: Ib2924412e3d55f10875675cb65079259cd4ef552 Task-number: QTBUG-17582 Reviewed-by: Rohan McGovern --- tests/auto/qcompleter/tst_qcompleter.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/auto/qcompleter/tst_qcompleter.cpp b/tests/auto/qcompleter/tst_qcompleter.cpp index 9cb2468..b0d40d0 100644 --- a/tests/auto/qcompleter/tst_qcompleter.cpp +++ b/tests/auto/qcompleter/tst_qcompleter.cpp @@ -1278,10 +1278,11 @@ public: { setEditable(true); setInsertPolicy(NoInsert); - Q_ASSERT(completer()); - completer()->setCompletionMode(QCompleter::PopupCompletion); - completer()->setCompletionRole(Qt::DisplayRole); - connect(lineEdit(), SIGNAL(editingFinished()), SLOT(setCompletionPrefix())); + if (completer()) { + completer()->setCompletionMode(QCompleter::PopupCompletion); + completer()->setCompletionRole(Qt::DisplayRole); + connect(lineEdit(), SIGNAL(editingFinished()), SLOT(setCompletionPrefix())); + } } private slots: void setCompletionPrefix() { completer()->setCompletionPrefix(lineEdit()->text()); } @@ -1290,6 +1291,7 @@ private slots: void tst_QCompleter::task246056_setCompletionPrefix() { task246056_ComboBox *comboBox = new task246056_ComboBox; + QVERIFY(comboBox->completer()); comboBox->addItem(""); comboBox->addItem("a1"); comboBox->addItem("a2"); -- cgit v0.12 From 5a530f6171a9569d1a35cd8cd1015ec796b048cc Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Wed, 20 Apr 2011 15:11:23 +1000 Subject: Remove Q_ASSERT from qcopchannel autotest This code would assert in a debug build and potentially crash in a release build. (The behaviour of QStringList::at() with an out-of-bounds index is undefined.) This commit makes the program exit with a useful error message in all builds. Change-Id: Ia57a2e5693eb25d3eb0b9ba701ed485dfbc1e846 Task-number: QTBUG-17582 Reviewed-by: Rohan McGovern --- tests/auto/qcopchannel/testSend/main.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/auto/qcopchannel/testSend/main.cpp b/tests/auto/qcopchannel/testSend/main.cpp index 91628e5..a56883b 100644 --- a/tests/auto/qcopchannel/testSend/main.cpp +++ b/tests/auto/qcopchannel/testSend/main.cpp @@ -49,7 +49,11 @@ int main(int argc, char** argv) #ifdef Q_WS_QWS QApplication app(argc, argv); QStringList args = app.arguments(); - Q_ASSERT(args.count() == 3 || args.count() == 4); + if (args.count() != 3 && args.count() != 4) { + fprintf(stdout,qPrintable(QString("Usage: %1 channel message [data]").arg(args.at(0)))); + fflush(stdout); + return 1; + } QString channelName = args.at(1); QString msg = args.at(2); QByteArray data; -- cgit v0.12 From e754832eff8e1a35fc2681ae69b6e3b1ad666ddb Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Wed, 20 Apr 2011 16:03:42 +1000 Subject: Remove Q_ASSERT from datetimeedit autotest The assert and the last four parameters of makeList() are not needed. The function is always used to make lists of three integers and the data are all >= 0. Change-Id: I93ae5a5f541cde2ff61bd9dd21164ed4a9b57403 Task-number: QTBUG-17582 Reviewed-by: Rohan McGovern --- tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp b/tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp index 98632ae..abbf00d 100644 --- a/tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp +++ b/tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp @@ -2699,17 +2699,10 @@ void tst_QDateTimeEdit::task98554() QCOMPARE(testWidget->time(), QTime(0, 0, 10, 0)); } -static QList makeList(int val1, int val2 = -1, int val3 = -1, int val4 = -1, int val5 = -1, int val6 = -1, int val7 = -1) +static QList makeList(int val1, int val2, int val3) { QList ret; - Q_ASSERT(val1 >= 0); - ret << val1; - if (val2 < 0) {return ret;} else {ret << val2;} - if (val3 < 0) {return ret;} else {ret << val3;} - if (val4 < 0) {return ret;} else {ret << val4;} - if (val5 < 0) {return ret;} else {ret << val5;} - if (val6 < 0) {return ret;} else {ret << val6;} - if (val7 >= 0) {ret << val2;} + ret << val1 << val2 << val3; return ret; } -- cgit v0.12 From 0061f7e015b10ccaa45dc35b68cac467ebad424a Mon Sep 17 00:00:00 2001 From: Honglei Zhang Date: Wed, 20 Apr 2011 09:44:29 +0300 Subject: Fix autotest failure in XmlPattern qxmlquery The bug fix for the memory leak in qxmlquery tried to fix a memory leak in autotest test driver. The fix broke the autotest logic and causes failure. This one fix the commit 986ab48f112... Task-number: QTBUG-15191 Reviewed-by: Sami Merila --- tests/auto/qxmlquery/tst_qxmlquery.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/qxmlquery/tst_qxmlquery.cpp b/tests/auto/qxmlquery/tst_qxmlquery.cpp index 2e0d1aa..5828367 100644 --- a/tests/auto/qxmlquery/tst_qxmlquery.cpp +++ b/tests/auto/qxmlquery/tst_qxmlquery.cpp @@ -3301,8 +3301,8 @@ void tst_QXmlQuery::bindVariableQXmlQueryInvalidate() const QXmlQuery query2; query2.setQuery("'query2'"); - query2.bindVariable(QLatin1String("name"), query); - QVERIFY(!query2.isValid()); + query.bindVariable(QLatin1String("name"), query2); + QVERIFY(!query.isValid()); } void tst_QXmlQuery::unknownSourceLocation() const -- cgit v0.12 From 1e847c00dcf4948b8892d0a552576e1d3ea554b9 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Wed, 20 Apr 2011 10:19:02 +0200 Subject: Remove extra comma at the end of enum list It fails compilerwarnings test. Reviewed-by: TrustMe --- src/gui/text/qtextcursor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/text/qtextcursor.h b/src/gui/text/qtextcursor.h index 30f8272..9e4c0b8 100644 --- a/src/gui/text/qtextcursor.h +++ b/src/gui/text/qtextcursor.h @@ -88,7 +88,7 @@ public: }; enum MoveStyle { Logical, - Visual, + Visual }; void setPosition(int pos, MoveMode mode = MoveAnchor); -- cgit v0.12 From 69c759f5b84c2f6a44377e5f72cfe9d5bf7344c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Wed, 20 Apr 2011 09:17:13 +0200 Subject: Lighthouse: Fix virtual desktopwidget --- src/gui/kernel/qdesktopwidget_qpa.cpp | 12 ++++-------- src/gui/kernel/qdesktopwidget_qpa_p.h | 1 - 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/gui/kernel/qdesktopwidget_qpa.cpp b/src/gui/kernel/qdesktopwidget_qpa.cpp index cff05f5..6257a8b 100644 --- a/src/gui/kernel/qdesktopwidget_qpa.cpp +++ b/src/gui/kernel/qdesktopwidget_qpa.cpp @@ -51,6 +51,8 @@ QT_USE_NAMESPACE void QDesktopWidgetPrivate::updateScreenList() { + Q_Q(QDesktopWidget); + QList screenList = QApplicationPrivate::platformIntegration()->screens(); int targetLength = screenList.length(); int currentLength = screens.length(); @@ -72,19 +74,15 @@ void QDesktopWidgetPrivate::updateScreenList() } QRegion virtualGeometry; - bool doVirtualGeometry = QApplicationPrivate::platformIntegration()->isVirtualDesktop(); // update the geometry of each screen widget for (int i = 0; i < screens.length(); i++) { QRect screenGeometry = screenList.at(i)->geometry(); screens.at(i)->setGeometry(screenGeometry); - if (doVirtualGeometry) - virtualGeometry += screenGeometry; + virtualGeometry += screenGeometry; } - virtualScreen.setGeometry(virtualGeometry.boundingRect()); - Q_Q(QDesktopWidget); - q->setGeometry(virtualScreen.geometry()); + q->setGeometry(virtualGeometry.boundingRect()); } QDesktopWidget::QDesktopWidget() @@ -118,8 +116,6 @@ int QDesktopWidget::numScreens() const QWidget *QDesktopWidget::screen(int screen) { Q_D(QDesktopWidget); - if (QApplicationPrivate::platformIntegration()->isVirtualDesktop()) - return &d->virtualScreen; if (screen < 0 || screen >= d->screens.length()) return d->screens.at(0); return d->screens.at(screen); diff --git a/src/gui/kernel/qdesktopwidget_qpa_p.h b/src/gui/kernel/qdesktopwidget_qpa_p.h index abee8a1..d6ed686 100644 --- a/src/gui/kernel/qdesktopwidget_qpa_p.h +++ b/src/gui/kernel/qdesktopwidget_qpa_p.h @@ -76,7 +76,6 @@ public: void updateScreenList(); QList screens; - QDesktopScreenWidget virtualScreen; }; #endif // QDESKTOPWIDGET_QPA_P_H -- cgit v0.12 From 6181805f9ea66b37ee164bd67bdac2ac9d53fb65 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Wed, 20 Apr 2011 16:27:07 +1000 Subject: Remove Q_ASSERT from QDom autotest The Q_ASSERT here should really be a QVERIFY. Expanded the trivial helper function to make it more obvious what the test does. Change-Id: Ia6017fe820a83b4d6101e5edcfcb68993eef233a Task-number: QTBUG-17582 Reviewed-by: Rohan McGovern --- tests/auto/qdom/tst_qdom.cpp | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/tests/auto/qdom/tst_qdom.cpp b/tests/auto/qdom/tst_qdom.cpp index 18aa84a..f3b3e00 100644 --- a/tests/auto/qdom/tst_qdom.cpp +++ b/tests/auto/qdom/tst_qdom.cpp @@ -137,7 +137,6 @@ private slots: private: static QDomDocument generateRequest(); - static QDomDocument doc(const QString &title, const QByteArray &ba); static int hasAttributesHelper( const QDomNode& node ); static bool compareDocuments( const QDomDocument &doc1, const QDomDocument &doc2 ); static bool compareNodes( const QDomNode &node1, const QDomNode &node2, bool deep ); @@ -1591,14 +1590,6 @@ void tst_QDom::reportDuplicateAttributes() const QVERIFY2(!isSuccess, "Duplicate attributes are well-formedness errors, and should be reported as such."); } -QDomDocument tst_QDom::doc(const QString &title, const QByteArray &ba) -{ - QDomDocument doc(title); - const bool ret = doc.setContent(ba, true); - Q_ASSERT(ret); - return doc; -} - void tst_QDom::namespacedAttributes() const { static const char *const xml = @@ -1611,8 +1602,13 @@ void tst_QDom::namespacedAttributes() const " >>> SIMPLE BASIC OP - SEND - DUT AS SINK\n" "\n"; - QDomDocument one = doc("document", xml); - QDomDocument two = doc("document2", one.toByteArray(2)); + QDomDocument one("document"); + QString error; + bool docParsed = one.setContent(QByteArray(xml), true, &error); + QVERIFY2(docParsed, qPrintable(error)); + QDomDocument two("document2"); + docParsed = two.setContent(one.toByteArray(2), true, &error); + QVERIFY2(docParsed, qPrintable(error)); QVERIFY(isDeepEqual(one, two)); } -- cgit v0.12 From b1eb564830ff1b754de14919ce5c1547e9758f7c Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Thu, 21 Apr 2011 11:15:35 +1000 Subject: Fix logic error in large file autotest The function generating data blocks was filling the block to 16 bytes short of the blockSize, then appending three 8 byte values, causing the block to grow 8 bytes beyond blockSize and then truncating it back to blockSize. This commit makes the code fill the block to 24 bytes short of the blockSize, so that the block will always end up at the correct size and truncation is not needed. Change-Id: I9fe6e6d6cf7bc445513b53e0a910d205c4c8002f Reviewed-by: Rohan McGovern --- tests/auto/qfile/largefile/tst_largefile.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/auto/qfile/largefile/tst_largefile.cpp b/tests/auto/qfile/largefile/tst_largefile.cpp index a9ad017..47f2e73 100644 --- a/tests/auto/qfile/largefile/tst_largefile.cpp +++ b/tests/auto/qfile/largefile/tst_largefile.cpp @@ -206,14 +206,13 @@ static inline QByteArray generateDataBlock(int blockSize, QString text, qint64 u QByteArray filler("0123456789"); block.append(filler.right(10 - block.size() % 10)); - topUpWith(block, filler, blockSize - 2 * sizeof(qint64)); + topUpWith(block, filler, blockSize - 3 * sizeof(qint64)); appendRaw(block, counter); appendRaw(block, userBits); appendRaw(block, randomBits); - Q_ASSERT( block.size() >= blockSize ); - block.resize(blockSize); + Q_ASSERT( block.size() == blockSize ); ++counter; return block; -- cgit v0.12 From 59634e825f1efa6f32befc8767cafedfeb9b7d59 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Thu, 21 Apr 2011 13:00:06 +1000 Subject: Use meaningful variable names Make the meaning of the code more obvious and avoid a compiler warning about the variable "w" being overridden. Change-Id: Ib76d3aa1cae46e263b2ab61b675d9ef74032aacc Reviewed-by: Rohan McGovern --- .../tst_qgraphicsanchorlayout.cpp | 42 +++++++++++----------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index e7c63d5..67e9b0a 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -132,33 +132,33 @@ static void setAnchor(QGraphicsAnchorLayout *l, anchor->setSpacing(spacing); } -static bool checkReverseDirection(QGraphicsWidget *w) +static bool checkReverseDirection(QGraphicsWidget *widget) { - QGraphicsLayout *l = w->layout(); - Q_ASSERT(l); + QGraphicsLayout *layout = widget->layout(); + Q_ASSERT(layout); qreal left, top, right, bottom; - l->getContentsMargins(&left, &top, &right, &bottom); - w->setLayoutDirection(Qt::LeftToRight); + layout->getContentsMargins(&left, &top, &right, &bottom); + widget->setLayoutDirection(Qt::LeftToRight); QApplication::processEvents(); - const QRectF lg = l->geometry(); + const QRectF layoutGeometry = layout->geometry(); QMap geometries; - for (int i = 0; i < l->count(); ++i) { - QGraphicsLayoutItem *w = l->itemAt(i); - geometries.insert(w, w->geometry()); + for (int i = 0; i < layout->count(); ++i) { + QGraphicsLayoutItem *item = layout->itemAt(i); + geometries.insert(item, item->geometry()); } - w->setLayoutDirection(Qt::RightToLeft); + widget->setLayoutDirection(Qt::RightToLeft); QApplication::processEvents(); - lg.adjusted(+right, +top, -left, -bottom); - for (int i = 0; i < l->count(); ++i) { - QGraphicsLayoutItem *w = l->itemAt(i); - const QRectF rtlGeom = w->geometry(); - const QRectF ltrGeom = geometries.value(w); - QRectF expectedGeom = ltrGeom; - expectedGeom.moveRight(lg.right() - (0 + ltrGeom.left())); - if (expectedGeom != rtlGeom) { - qDebug() << "layout->geometry():" << lg - << "expected:" << expectedGeom - << "actual:" << rtlGeom; + layoutGeometry.adjusted(+right, +top, -left, -bottom); + for (int i = 0; i < layout->count(); ++i) { + QGraphicsLayoutItem *item = layout->itemAt(i); + const QRectF rightToLeftGeometry = item->geometry(); + const QRectF leftToRightGeometry = geometries.value(item); + QRectF expectedGeometry = leftToRightGeometry; + expectedGeometry.moveRight(layoutGeometry.right() - leftToRightGeometry.left()); + if (expectedGeometry != rightToLeftGeometry) { + qDebug() << "layout->geometry():" << layoutGeometry + << "expected:" << expectedGeometry + << "actual:" << rightToLeftGeometry; return false; } } -- cgit v0.12 From 60e5ed805af1e11aaec426b823df209b4c895c29 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Thu, 21 Apr 2011 14:49:41 +1000 Subject: Only ignore warning when it can actually be produced. Fix regression introduced in 3ca51d87296bcb3098d7de14294fef9294fd5ed4. The warning is only generated in builds where QT_NO_DEBUG is not defined *and* the target is not Mac OS X. Change-Id: I7245f2eab8ea47ab7495fef874b2f8a29186b659 Task-number: QTBUG-17582 Reviewed-by: Rohan McGovern --- tests/auto/qaccessibility/tst_qaccessibility.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qaccessibility/tst_qaccessibility.cpp b/tests/auto/qaccessibility/tst_qaccessibility.cpp index 2645090..254fdf7 100644 --- a/tests/auto/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/qaccessibility/tst_qaccessibility.cpp @@ -3835,7 +3835,7 @@ void tst_QAccessibility::accelerators() label->setText(tr("Q &&A")); QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QString()); -#ifndef QT_NO_DEBUG +#if !defined(QT_NO_DEBUG) && !defined(Q_WS_MAC) QTest::ignoreMessage(QtWarningMsg, "QKeySequence::mnemonic: \"Q &A&B\" contains multiple occurrences of '&'"); #endif label->setText(tr("Q &A&B")); -- cgit v0.12 From 774b5b8c6a627fc90fb7382bc907db5d2e8193bf Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 21 Apr 2011 11:50:11 +0200 Subject: doc: Minor cleanup in QGlyphs docs Just a minor clean-up in the QGlyphs docs. Mainly to try to trigger CI. Reviewed-by: TrustMe --- src/gui/text/qglyphs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/text/qglyphs.cpp b/src/gui/text/qglyphs.cpp index b8a418d..a82b265 100644 --- a/src/gui/text/qglyphs.cpp +++ b/src/gui/text/qglyphs.cpp @@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE /*! \class QGlyphs - \brief the QGlyphs class provides direct access to the internal glyphs in a font + \brief The QGlyphs class provides direct access to the internal glyphs in a font. \since 4.8 \ingroup text -- cgit v0.12 From 8a9a6afcf02f089f932bc81431ab46a60af32134 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 20 Apr 2011 16:21:36 +0100 Subject: 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 --- src/corelib/kernel/qeventdispatcher_symbian.cpp | 6 ++ tests/auto/qsocketnotifier/qsocketnotifier.pro | 2 +- tests/auto/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 79f2596..7166e7d 100644 --- a/src/corelib/kernel/qeventdispatcher_symbian.cpp +++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp @@ -1084,6 +1084,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 c43c96a..27484c8 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 5594dc3..b31a6e6 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 -- cgit v0.12 From 1a1683c2d57debbb3e7f3ae6001eb2c8685dca02 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 22 Apr 2011 11:20:37 +0200 Subject: doc: Simplify language in QGlyphs docs Mainly to trigger CI. Reviewed-by: TrustMe --- src/gui/text/qglyphs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/text/qglyphs.cpp b/src/gui/text/qglyphs.cpp index a82b265..cfea6ec 100644 --- a/src/gui/text/qglyphs.cpp +++ b/src/gui/text/qglyphs.cpp @@ -76,8 +76,8 @@ QT_BEGIN_NAMESPACE QTextLayout::glyphs() or QTextFragment::glyphs() can be used to convert unicode encoded text into a list of QGlyphs objects, and QPainter::drawGlyphs() can be used to draw the glyphs. - \note Please note that QRawFont is considered local to the thread in which it is constructed, - which in turn means that a new QRawFont will have to be created and set on the QGlyphs if it is + \note Please note that QRawFont is considered local to the thread in which it is constructed. + This in turn means that a new QRawFont will have to be created and set on the QGlyphs if it is moved to a different thread. If the QGlyphs contains a reference to a QRawFont from a different thread than the current, it will not be possible to draw the glyphs using a QPainter, as the QRawFont is considered invalid and inaccessible in this case. -- cgit v0.12 From 715e52aa56e205f2948f338d4e1e2fc157753645 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Thu, 21 Apr 2011 13:25:23 +0200 Subject: Fix tst_QTableWidget::task219380_removeLastRow Again, dure to the fix to QTBUG-18551. Reviewed-by: Olivier --- tests/auto/qtablewidget/tst_qtablewidget.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/auto/qtablewidget/tst_qtablewidget.cpp b/tests/auto/qtablewidget/tst_qtablewidget.cpp index baa99ea..40aece4 100644 --- a/tests/auto/qtablewidget/tst_qtablewidget.cpp +++ b/tests/auto/qtablewidget/tst_qtablewidget.cpp @@ -41,6 +41,7 @@ #include +#include "../../shared/util.h" #include #include #include @@ -1471,10 +1472,8 @@ void tst_QTableWidget::task219380_removeLastRow() testWidget->removeRow(19); //we remove the last row - QApplication::processEvents(); // See QTBUG-18551 and its fix - //we make sure the editor is at the cell position - QCOMPARE(testWidget->cellWidget(18, 0)->geometry(), testWidget->visualItemRect(&item)); + QTRY_COMPARE(testWidget->cellWidget(18, 0)->geometry(), testWidget->visualItemRect(&item)); } void tst_QTableWidget::task262056_sortDuplicate() -- cgit v0.12 From 224226727f07e8940e0d3131fe7587b11cc4a6ca Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Tue, 19 Apr 2011 14:40:19 +0200 Subject: Take leading space width into account for painting and selection When painting horizontally centered RTL text and selection with trailing spaces, we need to take that space width into account because line.textAdvance doesn't include it. Task-number: QTBUG-18612 Reviewed-by: Eskil --- src/gui/text/qtextengine.cpp | 4 +++- src/gui/text/qtextlayout.cpp | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index dab4bb7..ce012a8 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -2777,12 +2777,14 @@ QFixed QTextEngine::alignLine(const QScriptLine &line) // if width is QFIXED_MAX that means we used setNumColumns() and that implicitly makes this line left aligned. if (!line.justified && line.width != QFIXED_MAX) { int align = option.alignment(); + if (align & Qt::AlignLeft) + x -= leadingSpaceWidth(line); if (align & Qt::AlignJustify && isRightToLeft()) align = Qt::AlignRight; if (align & Qt::AlignRight) x = line.width - (line.textAdvance + leadingSpaceWidth(line)); else if (align & Qt::AlignHCenter) - x = (line.width - line.textAdvance)/2; + x = (line.width - (line.textAdvance + leadingSpaceWidth(line)))/2; } return x; } diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index bd224c6..122382f 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -1060,6 +1060,7 @@ void QTextLayout::draw(QPainter *p, const QPointF &pos, const QVectorleadingSpaceWidth(sl).toReal(), 0); bool isLastLineInBlock = (line == d->lines.size()-1); int sl_length = sl.length + (isLastLineInBlock? 1 : 0); // the infamous newline -- cgit v0.12 From 800ad68e4f000e65b0a83ef1da2a29d595964156 Mon Sep 17 00:00:00 2001 From: Martin Petersson Date: Tue, 26 Apr 2011 12:03:17 +0200 Subject: Fix compile warning on Windows Reviewed-by: Prasanth Ullattil --- src/corelib/io/qfilesystemengine_win.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 82c6eba..1dbc40f 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -583,6 +583,7 @@ QString QFileSystemEngine::owner(const QFileSystemEntry &entry, QAbstractFileEng } } #else + Q_UNUSED(entry); Q_UNUSED(own); #endif return name; -- cgit v0.12 From 2c2026df66f237b7313397dd74f6bc3212b94596 Mon Sep 17 00:00:00 2001 From: Fabien Freling Date: Tue, 26 Apr 2011 12:34:00 +0200 Subject: Set the default graphics system to raster. This change is specific to Mac OS X/Cocoa. Reviewed-by: Lars Knoll --- src/gui/painting/qgraphicssystemfactory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qgraphicssystemfactory.cpp b/src/gui/painting/qgraphicssystemfactory.cpp index 62a60d7..6212674 100644 --- a/src/gui/painting/qgraphicssystemfactory.cpp +++ b/src/gui/painting/qgraphicssystemfactory.cpp @@ -74,7 +74,7 @@ QGraphicsSystem *QGraphicsSystemFactory::create(const QString& key) if (system.isEmpty()) { system = QLatin1String("runtime"); } -#elif defined (QT_GRAPHICSSYSTEM_RASTER) && !defined(Q_WS_WIN) && !defined(Q_OS_SYMBIAN) || defined(Q_WS_X11) +#elif defined (QT_GRAPHICSSYSTEM_RASTER) && !defined(Q_WS_WIN) && !defined(Q_OS_SYMBIAN) || defined(Q_WS_X11) || (defined (Q_WS_MAC) && defined(QT_MAC_USE_COCOA)) if (system.isEmpty()) { system = QLatin1String("raster"); } -- cgit v0.12 From 0c62e02b80570bf8b92eff7acceb9018df61c89e Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 26 Apr 2011 15:35:51 +0200 Subject: Make text rendering working outside the gui thread on Symbian. It was previously not possible to render text (QPainter::drawText) in a secondary thread on Symbian, it always resulted in some kind of panic. This patch corrects it. For S60 5.0 and earlier the behavior is not changed, threaded text rendering is only supported on Symbian^3 and newer. This also means QFontDatabase::supportsThreadedFontRendering() will return true from now on, but only on Symbian^3 and higher. Task-number: QTBUG-18516 Reviewed-by: mread --- src/gui/kernel/qapplication_s60.cpp | 3 +++ src/gui/kernel/qt_s60_p.h | 26 ++++++++++++++++++++++++++ src/gui/text/qfontdatabase_s60.cpp | 30 +++++++++++++++++++----------- 3 files changed, 48 insertions(+), 11 deletions(-) diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 0688061..937f485 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -2606,6 +2606,9 @@ QS60ThreadLocalData::QS60ThreadLocalData() QS60ThreadLocalData::~QS60ThreadLocalData() { + for (int i = 0; i < releaseFuncs.count(); ++i) + releaseFuncs[i](); + releaseFuncs.clear(); if (!usingCONEinstances) { delete screenDevice; wsSession.Close(); diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h index ee0b862..288ee99 100644 --- a/src/gui/kernel/qt_s60_p.h +++ b/src/gui/kernel/qt_s60_p.h @@ -90,6 +90,10 @@ static const int qt_symbian_max_screens = 4; //this macro exists because EColor16MAP enum value doesn't exist in Symbian OS 9.2 #define Q_SYMBIAN_ECOLOR16MAP TDisplayMode(13) +class QSymbianTypeFaceExtras; +typedef QHash QSymbianTypeFaceExtrasHash; +typedef void (*QThreadLocalReleaseFunc)(); + class Q_AUTOTEST_EXPORT QS60ThreadLocalData { public: @@ -98,6 +102,8 @@ public: bool usingCONEinstances; RWsSession wsSession; CWsScreenDevice *screenDevice; + QSymbianTypeFaceExtrasHash fontData; + QVector releaseFuncs; }; class QS60Data @@ -168,6 +174,8 @@ public: inline CWsScreenDevice* screenDevice(const QWidget *widget); inline CWsScreenDevice* screenDevice(int screenNumber); static inline int screenNumberForWidget(const QWidget *widget); + inline QSymbianTypeFaceExtrasHash& fontData(); + inline void addThreadLocalReleaseFunc(QThreadLocalReleaseFunc func); static inline CCoeAppUi* appUi(); static inline CEikMenuBar* menuBar(); #ifdef Q_WS_S60 @@ -454,6 +462,24 @@ inline int QS60Data::screenNumberForWidget(const QWidget *widget) return qt_widget_private(const_cast(w))->symbianScreenNumber; } +inline QSymbianTypeFaceExtrasHash& QS60Data::fontData() +{ + if (!tls.hasLocalData()) { + tls.setLocalData(new QS60ThreadLocalData); + } + return tls.localData()->fontData; +} + +inline void QS60Data::addThreadLocalReleaseFunc(QThreadLocalReleaseFunc func) +{ + if (!tls.hasLocalData()) { + tls.setLocalData(new QS60ThreadLocalData); + } + QS60ThreadLocalData *data = tls.localData(); + if (!data->releaseFuncs.contains(func)) + data->releaseFuncs.append(func); +} + inline CCoeAppUi* QS60Data::appUi() { return CCoeEnv::Static()-> AppUi(); diff --git a/src/gui/text/qfontdatabase_s60.cpp b/src/gui/text/qfontdatabase_s60.cpp index 6d3970e..3c7255b 100644 --- a/src/gui/text/qfontdatabase_s60.cpp +++ b/src/gui/text/qfontdatabase_s60.cpp @@ -152,7 +152,6 @@ public: COpenFontRasterizer *m_rasterizer; mutable QList m_extras; - mutable QHash m_extrasHash; mutable QSet m_applicationFontFamilies; }; @@ -255,8 +254,9 @@ void QSymbianFontDatabaseExtrasImplementation::clear() static_cast(db->symbianExtras); if (!dbExtras) return; // initializeDb() has never been called + QSymbianTypeFaceExtrasHash &extrasHash = S60->fontData(); if (QSymbianTypeFaceExtras::symbianFontTableApiAvailable()) { - qDeleteAll(dbExtras->m_extrasHash); + qDeleteAll(extrasHash); } else { typedef QList::iterator iterator; for (iterator p = dbExtras->m_extras.begin(); p != dbExtras->m_extras.end(); ++p) { @@ -265,11 +265,16 @@ void QSymbianFontDatabaseExtrasImplementation::clear() } dbExtras->m_extras.clear(); } - dbExtras->m_extrasHash.clear(); + extrasHash.clear(); } void qt_cleanup_symbianFontDatabase() { + static bool cleanupDone = false; + if (cleanupDone) + return; + cleanupDone = true; + QFontDatabasePrivate *db = privateDb(); if (!db) return; @@ -320,9 +325,12 @@ COpenFont* OpenFontFromBitmapFont(const CBitmapFont* aBitmapFont) const QSymbianTypeFaceExtras *QSymbianFontDatabaseExtrasImplementation::extras(const QString &aTypeface, bool bold, bool italic) const { + QSymbianTypeFaceExtrasHash &extrasHash = S60->fontData(); + if (extrasHash.isEmpty() && QThread::currentThread() != QApplication::instance()->thread()) + S60->addThreadLocalReleaseFunc(clear); const QString typeface = qt_symbian_fontNameWithAppFontMarker(aTypeface); const QString searchKey = typeface + QString::number(int(bold)) + QString::number(int(italic)); - if (!m_extrasHash.contains(searchKey)) { + if (!extrasHash.contains(searchKey)) { TFontSpec searchSpec(qt_QString2TPtrC(typeface), 1); if (bold) searchSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold); @@ -336,7 +344,7 @@ const QSymbianTypeFaceExtras *QSymbianFontDatabaseExtrasImplementation::extras(c QScopedPointer sFont(font); QSymbianTypeFaceExtras *extras = new QSymbianTypeFaceExtras(font); sFont.take(); - m_extrasHash.insert(searchKey, extras); + extrasHash.insert(searchKey, extras); } else { const TInt err = m_store->GetNearestFontToDesignHeightInPixels(font, searchSpec); Q_ASSERT(err == KErrNone && font); @@ -350,20 +358,20 @@ const QSymbianTypeFaceExtras *QSymbianFontDatabaseExtrasImplementation::extras(c const TOpenFontFaceAttrib* const attrib = openFont->FaceAttrib(); const QString foundKey = QString((const QChar*)attrib->FullName().Ptr(), attrib->FullName().Length()); - if (!m_extrasHash.contains(foundKey)) { + if (!extrasHash.contains(foundKey)) { QScopedPointer sFont(font); QSymbianTypeFaceExtras *extras = new QSymbianTypeFaceExtras(font, openFont); sFont.take(); m_extras.append(extras); - m_extrasHash.insert(searchKey, extras); - m_extrasHash.insert(foundKey, extras); + extrasHash.insert(searchKey, extras); + extrasHash.insert(foundKey, extras); } else { m_store->ReleaseFont(font); - m_extrasHash.insert(searchKey, m_extrasHash.value(foundKey)); + extrasHash.insert(searchKey, extrasHash.value(foundKey)); } } } - return m_extrasHash.value(searchKey); + return extrasHash.value(searchKey); } void QSymbianFontDatabaseExtrasImplementation::removeAppFontData( @@ -956,7 +964,7 @@ bool QFontDatabase::removeAllApplicationFonts() bool QFontDatabase::supportsThreadedFontRendering() { - return false; + return QSymbianTypeFaceExtras::symbianFontTableApiAvailable(); } static -- cgit v0.12 From 5d144faf3c524ab557b88f69c4b755e20237e846 Mon Sep 17 00:00:00 2001 From: mae Date: Tue, 26 Apr 2011 15:41:21 +0200 Subject: Fix insert and scroll to bottom case When using QtextCursor::insert() with a large text followed by setting the vertical scrollbar to its maximum value (scroll to bottom), QPlainTextEdit would not behave properly if a document size change was triggered by the insertion due to line wrapping. This was visible in Qt Creator. Auto test included. Reviewed-by: con --- src/gui/widgets/qplaintextedit.cpp | 5 +++++ tests/auto/qplaintextedit/tst_qplaintextedit.cpp | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp index 7435691..e7761a1 100644 --- a/src/gui/widgets/qplaintextedit.cpp +++ b/src/gui/widgets/qplaintextedit.cpp @@ -648,6 +648,11 @@ void QPlainTextEditPrivate::setTopBlock(int blockNumber, int lineNumber, int dx) } control->topBlock = blockNumber; topLine = lineNumber; + + bool vbarSignalsBlocked = vbar->blockSignals(true); + vbar->setValue(block.firstLineNumber() + lineNumber); + vbar->blockSignals(vbarSignalsBlocked); + if (dx || dy) viewport->scroll(q->isRightToLeft() ? -dx : dx, dy); else diff --git a/tests/auto/qplaintextedit/tst_qplaintextedit.cpp b/tests/auto/qplaintextedit/tst_qplaintextedit.cpp index d3e4fd0..8da5ba5 100644 --- a/tests/auto/qplaintextedit/tst_qplaintextedit.cpp +++ b/tests/auto/qplaintextedit/tst_qplaintextedit.cpp @@ -150,6 +150,7 @@ private slots: void lineWrapProperty(); void selectionChanged(); void blockCountChanged(); + void insertAndScrollToBottom(); private: void createSelection(); @@ -1504,5 +1505,22 @@ void tst_QPlainTextEdit::blockCountChanged() } +void tst_QPlainTextEdit::insertAndScrollToBottom() +{ + ed->setPlainText("First Line"); + ed->show(); + QString text; + for(int i = 0; i < 2000; ++i) { + text += QLatin1String("this is another line of text to be appended. It is quite long and will probably wrap around, meaning the number of lines is larger than the number of blocks in the text.\n"); + } + QTextCursor cursor = ed->textCursor(); + cursor.beginEditBlock(); + cursor.insertText(text); + cursor.endEditBlock(); + ed->verticalScrollBar()->setValue(ed->verticalScrollBar()->maximum()); + QCOMPARE(ed->verticalScrollBar()->value(), ed->verticalScrollBar()->maximum()); +} + + QTEST_MAIN(tst_QPlainTextEdit) #include "tst_qplaintextedit.moc" -- cgit v0.12 From b4b4e3311f06ef79e307f90eb216b05ed2990358 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 11 Apr 2011 14:42:04 +0300 Subject: Implement support for enable_backup CONFIG value. The enable_backup CONFIG value can be used to generate deployment for backup registration file for an application. BACKUP_REGISTRATION_FILE_SYMBIAN and BACKUP_REGISTRATION_FILE_MAEMO variables can be used to specify a custom backup registration files. Only works on Symbian and Maemo platforms. Task-number: QTBUG-17214 Reviewed-by: Oswald Buddenhagen --- doc/src/development/qmake-manual.qdoc | 49 ++++++++++++++++++++++++++ mkspecs/common/symbian/backup_registration.xml | 8 +++++ mkspecs/features/enable_backup.prf | 43 ++++++++++++++++++++++ 3 files changed, 100 insertions(+) create mode 100644 mkspecs/common/symbian/backup_registration.xml create mode 100644 mkspecs/features/enable_backup.prf diff --git a/doc/src/development/qmake-manual.qdoc b/doc/src/development/qmake-manual.qdoc index 2bc8a34..0149da2 100644 --- a/doc/src/development/qmake-manual.qdoc +++ b/doc/src/development/qmake-manual.qdoc @@ -1120,6 +1120,44 @@ \tableofcontents{3} + + \target BACKUP_REGISTRATION_FILE_MAEMO + \section1 BACKUP_REGISTRATION_FILE_MAEMO + + \e {This is only used on the Maemo platform.} + + This variable is used to specify the backup registration file to use with + \c enable_backup \c CONFIG value for Maemo platform. The default value is: + \c{$$_PRO_FILE_PWD_/backup_registration/maemo/$$basename(TARGET).conf}. + + Unfortunately it is not possible to have a common registration file for Maemo like there is + for Symbian, so the developer must always provide one if the platform default backup support is + not sufficient. + + For documentation about how to create backup registration files and how the device + backup works in general, see: + (\l{http://wiki.maemo.org/Documentation/Maemo_5_Developer_Guide/Generic_Platform_Components/Using_Backup_Application}{Using Backup Application}) + + \target BACKUP_REGISTRATION_FILE_SYMBIAN + \section1 BACKUP_REGISTRATION_FILE_SYMBIAN + + \e {This is only used on the Symbian platform.} + + This variable is used to specify the backup registration file to use with + \c enable_backup \c CONFIG value for Symbian platform. The default value is + determined as follows: + + If a custom registration file \c{$$_PRO_FILE_PWD_/backup_registration/symbian/backup_registration.xml} + exists, it is used. Otherwise, the common registration file \c{$$[QT_INSTALL_DATA]/mkspecs/common/symbian/backup_registration.xml} + is used. This common registration file will define backing up of application binaries, + resources, and all files under application private directory. Also note that \c{C:/Data} + contents are backed up by default on Symbian devices, so no registration is needed for any + files found there. + + For documentation about how to create backup registration files and how the device + backup works in general, see: + (\l{http://library.forum.nokia.com/index.jsp?topic=/S60_5th_Edition_Cpp_Developers_Library/GUID-35228542-8C95-4849-A73F-2B4F082F0C44/sdk/doc_source/guide/Connectivity-subsystem-guide/Connectivity/PC_Connectivity_How-To_Write_Backup_Aware_Software.html}{How-To Write Backup-aware Software}) + \target BLD_INF_RULES \section1 BLD_INF_RULES @@ -1341,6 +1379,17 @@ so some \c{.ts} files may be ignored by qmake. \endtable + These options only have an effect on Symbian and Maemo platforms: + + \table 95% + \header \o Option \o Description + \row \o enable_backup \o Generates deployment for backup registration file + to enable backing up the application during device backup. + See \l{#BACKUP_REGISTRATION_FILE_MAEMO}{BACKUP_REGISTRATION_FILE_MAEMO} + and \l{#BACKUP_REGISTRATION_FILE_SYMBIAN}{BACKUP_REGISTRATION_FILE_SYMBIAN} + for more information about backup. + \endtable + These options have an effect on Linux/Unix platforms: \table 95% diff --git a/mkspecs/common/symbian/backup_registration.xml b/mkspecs/common/symbian/backup_registration.xml new file mode 100644 index 0000000..794e11d --- /dev/null +++ b/mkspecs/common/symbian/backup_registration.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/mkspecs/features/enable_backup.prf b/mkspecs/features/enable_backup.prf new file mode 100644 index 0000000..7700ca2 --- /dev/null +++ b/mkspecs/features/enable_backup.prf @@ -0,0 +1,43 @@ +# Generate deployment for backup registration file for mobile devices +symbian|maemo5|linux-g++-maemo { + symbian { + isEmpty(BACKUP_REGISTRATION_FILE_SYMBIAN) { + # Do not require a custom registration file in Symbian builds as the + # default file can be used as is in vast majority of projects. + # However, if the custom file exists in the default location, use that. + + CUSTOM_BACKUP_REG_FILE = $$_PRO_FILE_PWD_/backup_registration/symbian/backup_registration.xml + + exists($$CUSTOM_BACKUP_REG_FILE) { + BACKUP_REGISTRATION_FILE = $$CUSTOM_BACKUP_REG_FILE + } else { + BACKUP_REGISTRATION_FILE = $$[QT_INSTALL_DATA]/mkspecs/common/symbian/backup_registration.xml + } + } else { + BACKUP_REGISTRATION_FILE = $$BACKUP_REGISTRATION_FILE_SYMBIAN + } + + contains(TEMPLATE, app) { + enable_backup_deployment.path = /private/$$replace(TARGET.UID3, 0x,) + } else { + enable_backup_deployment.path = /private/10202D56/import/packages/$$replace(TARGET.UID3, 0x,) + } + DEPLOYMENT += enable_backup_deployment + } else { + isEmpty(BACKUP_REGISTRATION_FILE_MAEMO) { + BACKUP_REGISTRATION_FILE = $$_PRO_FILE_PWD_/backup_registration/maemo/$$basename(TARGET).conf + } else { + BACKUP_REGISTRATION_FILE = $$BACKUP_REGISTRATION_FILE_MAEMO + } + + enable_backup_deployment.path = /etc/osso-backup/applications + INSTALLS += enable_backup_deployment + } + + # Make sure that BACKUP_REGISTRATION_FILE has absolute path, otherwise the following exists check will not work. + !contains(BACKUP_REGISTRATION_FILE, "(^/|^\\\\|^.:).*"): BACKUP_REGISTRATION_FILE = $$_PRO_FILE_PWD_/$$BACKUP_REGISTRATION_FILE + + !exists($$BACKUP_REGISTRATION_FILE): warning(The backup registration file \'$$BACKUP_REGISTRATION_FILE\' was not found. Please provide a valid backup registration file.) + + enable_backup_deployment.files = $$BACKUP_REGISTRATION_FILE +} -- cgit v0.12 From 903d4dc2196df2775255c24c707bfeb571992bb7 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 26 Apr 2011 16:01:08 +0200 Subject: Added autotest for threaded text rendering. Task-number: QTBUG-18516 Reviewed-by: TRUSTME --- tests/auto/qpainter/tst_qpainter.cpp | 41 ++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/tests/auto/qpainter/tst_qpainter.cpp b/tests/auto/qpainter/tst_qpainter.cpp index c21514b..33e4c49 100644 --- a/tests/auto/qpainter/tst_qpainter.cpp +++ b/tests/auto/qpainter/tst_qpainter.cpp @@ -72,6 +72,7 @@ #include #include #include +#include #if defined(Q_OS_SYMBIAN) # define SRCDIR "." @@ -264,6 +265,8 @@ private slots: void QTBUG17053_zeroDashPattern(); + void drawTextOutsideGuiThread(); + private: void fillData(); void setPenColor(QPainter& p); @@ -4706,6 +4709,44 @@ void tst_QPainter::QTBUG17053_zeroDashPattern() QCOMPARE(image, original); } +class TextDrawerThread : public QThread +{ +public: + void run(); + QImage rendering; +}; + +void TextDrawerThread::run() +{ + rendering = QImage(100, 100, QImage::Format_ARGB32_Premultiplied); + rendering.fill(0); + QPainter p(&rendering); + p.fillRect(10, 10, 100, 100, Qt::blue); + p.setPen(Qt::green); + p.drawText(20, 20, "some text"); + p.end(); +} + +void tst_QPainter::drawTextOutsideGuiThread() +{ + if (!QFontDatabase::supportsThreadedFontRendering()) + QSKIP("No threaded font rendering", SkipAll); + + QImage referenceRendering(100, 100, QImage::Format_ARGB32_Premultiplied); + referenceRendering.fill(0); + QPainter p(&referenceRendering); + p.fillRect(10, 10, 100, 100, Qt::blue); + p.setPen(Qt::green); + p.drawText(20, 20, "some text"); + p.end(); + + TextDrawerThread t; + t.start(); + t.wait(); + + QCOMPARE(referenceRendering, t.rendering); +} + QTEST_MAIN(tst_QPainter) #include "tst_qpainter.moc" -- cgit v0.12 From 1124f41253edd0e03704db72b0e1b6b4b518bd0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Tue, 26 Apr 2011 17:20:11 +0200 Subject: Removed warning from QPixmap::handle(). With the new fromX11Pixmap function there are valid use-cases where checking the handle() is useful also with the raster graphicssystem. Reviewed-by: Thiago Macieira --- src/gui/image/qpixmap.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 34804e5..c34f6ac 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -1224,12 +1224,8 @@ Qt::HANDLE QPixmap::handle() const { #if defined(Q_WS_X11) const QPixmapData *pd = pixmapData(); - if (pd) { - if (pd->classId() == QPixmapData::X11Class) - return static_cast(pd)->handle(); - else - qWarning("QPixmap::handle(): Pixmap is not an X11 class pixmap"); - } + if (pd && pd->classId() == QPixmapData::X11Class) + return static_cast(pd)->handle(); #endif return 0; } -- cgit v0.12 From a18f36048aa23fb088527c26274e49ce626ddf4d Mon Sep 17 00:00:00 2001 From: Emmanuel BOURGERIE Date: Wed, 27 Apr 2011 14:04:00 +1000 Subject: Fixed QTBUG-11935 Change-Id: Ia7bdb0ceecf2892f6be73d1816764a2bab6275f1 Merge-request: 1010 Reviewed-by: Charles Yin --- src/sql/drivers/mysql/qsql_mysql.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp index 495b1a6..2a969ee 100644 --- a/src/sql/drivers/mysql/qsql_mysql.cpp +++ b/src/sql/drivers/mysql/qsql_mysql.cpp @@ -1374,12 +1374,16 @@ QStringList QMYSQLDriver::tables(QSql::TableType type) const } else { QSqlQuery q(createResult()); if(type & QSql::Tables) { - q.exec(QLatin1String("select table_name from information_schema.tables where table_type = 'BASE TABLE'")); + QString sql = QLatin1String("select table_name from information_schema.tables where table_schema = ':schema' and table_type = 'BASE TABLE'"); + sql.replace(QLatin1String(":schema"), QLatin1String(d->mysql->db)); + q.exec(sql); while(q.next()) tl.append(q.value(0).toString()); } if(type & QSql::Views) { - q.exec(QLatin1String("select table_name from information_schema.tables where table_type = 'VIEW'")); + QString sql = QLatin1String("select table_name from information_schema.tables where table_schema = ':schema' and table_type = 'VIEW'"); + sql.replace(QLatin1String(":schema"), QLatin1String(d->mysql->db)); + q.exec(sql); while(q.next()) tl.append(q.value(0).toString()); } -- cgit v0.12 From c0ca29efdeb442a6b88ccadff409e3f7ef828ce8 Mon Sep 17 00:00:00 2001 From: Emmanuel BOURGERIE Date: Wed, 27 Apr 2011 14:04:02 +1000 Subject: Fixed QTBUG-11935 : "With MySQL version > 50000 the QMYSQLDriver:: tables() returns tables in all databases on the server" This bugfix has been rewritten to match contributors advise. Change-Id: I3a9cf900ff7eae47c9ffdbcf34bcb1b4396d9837 Merge-request: 1010 Reviewed-by: Charles Yin --- src/sql/drivers/mysql/qsql_mysql.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp index 2a969ee..441e355 100644 --- a/src/sql/drivers/mysql/qsql_mysql.cpp +++ b/src/sql/drivers/mysql/qsql_mysql.cpp @@ -1374,16 +1374,16 @@ QStringList QMYSQLDriver::tables(QSql::TableType type) const } else { QSqlQuery q(createResult()); if(type & QSql::Tables) { - QString sql = QLatin1String("select table_name from information_schema.tables where table_schema = ':schema' and table_type = 'BASE TABLE'"); - sql.replace(QLatin1String(":schema"), QLatin1String(d->mysql->db)); + QString sql = QLatin1String("select table_name from information_schema.tables where table_schema = '") + QLatin1String(d->mysql->db) + QLatin1String("' and table_type = 'BASE TABLE'"); q.exec(sql); + while(q.next()) tl.append(q.value(0).toString()); } if(type & QSql::Views) { - QString sql = QLatin1String("select table_name from information_schema.tables where table_schema = ':schema' and table_type = 'VIEW'"); - sql.replace(QLatin1String(":schema"), QLatin1String(d->mysql->db)); + QString sql = QLatin1String("select table_name from information_schema.tables where table_schema = '") + QLatin1String(d->mysql->db) + QLatin1String("' and table_type = 'VIEW'"); q.exec(sql); + while(q.next()) tl.append(q.value(0).toString()); } -- cgit v0.12 From f6b7ce204ee88be0fedb4cfcff382f208fa4ed33 Mon Sep 17 00:00:00 2001 From: Girish Ramakrishnan Date: Wed, 27 Apr 2011 15:53:43 +1000 Subject: Clear the root index when the model is reset. Task-number: QTBUG-18839 Change-Id: I46608d7481d820fa74a9be60df1e018e70a761c6 Merge-request: 2598 Reviewed-by: Martin Jones --- src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp | 5 +++++ .../qdeclarativevisualdatamodel/tst_qdeclarativevisualdatamodel.cpp | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp index 97ce059..4c839a1 100644 --- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp +++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp @@ -1398,7 +1398,12 @@ void QDeclarativeVisualDataModel::_q_layoutChanged() void QDeclarativeVisualDataModel::_q_modelReset() { + Q_D(QDeclarativeVisualDataModel); + d->m_root = QModelIndex(); emit modelReset(); + emit rootIndexChanged(); + if (d->m_abstractItemModel && d->m_abstractItemModel->canFetchMore(d->m_root)) + d->m_abstractItemModel->fetchMore(d->m_root); } void QDeclarativeVisualDataModel::_q_createdPackage(int index, QDeclarativePackage *package) diff --git a/tests/auto/declarative/qdeclarativevisualdatamodel/tst_qdeclarativevisualdatamodel.cpp b/tests/auto/declarative/qdeclarativevisualdatamodel/tst_qdeclarativevisualdatamodel.cpp index 85d7876..7b384f8 100644 --- a/tests/auto/declarative/qdeclarativevisualdatamodel/tst_qdeclarativevisualdatamodel.cpp +++ b/tests/auto/declarative/qdeclarativevisualdatamodel/tst_qdeclarativevisualdatamodel.cpp @@ -190,6 +190,11 @@ void tst_qdeclarativevisualdatamodel::rootIndex() QMetaObject::invokeMethod(obj, "setRootToParent"); QVERIFY(qvariant_cast(obj->rootIndex()) == QModelIndex()); + QMetaObject::invokeMethod(obj, "setRoot"); + QVERIFY(qvariant_cast(obj->rootIndex()) == model.index(0,0)); + model.clear(); // will emit modelReset() + QVERIFY(qvariant_cast(obj->rootIndex()) == QModelIndex()); + delete obj; } -- cgit v0.12 From 3b437a7706efbaaafdc4861393cbe21354cf4ee2 Mon Sep 17 00:00:00 2001 From: con Date: Tue, 19 Apr 2011 16:15:09 +0200 Subject: Support GL ES 2 with uikit. For GL ES 2 teach the paint device about the fact that it is doing rendering backed by a framebuffer object, not a system framebuffer (which doesn't exist). --- src/plugins/platforms/uikit/quikiteventloop.mm | 7 +- src/plugins/platforms/uikit/quikitintegration.mm | 2 +- src/plugins/platforms/uikit/quikitscreen.mm | 4 +- src/plugins/platforms/uikit/quikitwindow.h | 11 +++- src/plugins/platforms/uikit/quikitwindow.mm | 77 +++++++++++++--------- src/plugins/platforms/uikit/quikitwindowsurface.mm | 43 +++++++++++- 6 files changed, 101 insertions(+), 43 deletions(-) diff --git a/src/plugins/platforms/uikit/quikiteventloop.mm b/src/plugins/platforms/uikit/quikiteventloop.mm index 8d2603c..2b9728c 100644 --- a/src/plugins/platforms/uikit/quikiteventloop.mm +++ b/src/plugins/platforms/uikit/quikiteventloop.mm @@ -69,13 +69,8 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { Q_UNUSED(launchOptions) + Q_UNUSED(application) foreach (QWidget *widget, qApp->topLevelWidgets()) { - QRect geom = widget->geometry(); - CGRect bar = application.statusBarFrame; - if (geom.y() <= bar.size.height) { - geom.setY(bar.size.height); - widget->setGeometry(geom); - } QUIKitWindow *platformWindow = static_cast(widget->platformWindow()); platformWindow->ensureNativeWindow(); } diff --git a/src/plugins/platforms/uikit/quikitintegration.mm b/src/plugins/platforms/uikit/quikitintegration.mm index d4b4192..3a432d1 100644 --- a/src/plugins/platforms/uikit/quikitintegration.mm +++ b/src/plugins/platforms/uikit/quikitintegration.mm @@ -66,7 +66,7 @@ QUIKitIntegration::~QUIKitIntegration() QPixmapData *QUIKitIntegration::createPixmapData(QPixmapData::PixelType type) const { - return new QRasterPixmapData(type); + return new QRasterPixmapData(type); } QPlatformWindow *QUIKitIntegration::createPlatformWindow(QWidget *widget, WId winId) const diff --git a/src/plugins/platforms/uikit/quikitscreen.mm b/src/plugins/platforms/uikit/quikitscreen.mm index 21494c9..78389f2 100644 --- a/src/plugins/platforms/uikit/quikitscreen.mm +++ b/src/plugins/platforms/uikit/quikitscreen.mm @@ -54,7 +54,7 @@ QUIKitScreen::QUIKitScreen(int screenIndex) NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; UIScreen *screen = [[UIScreen screens] objectAtIndex:screenIndex]; CGRect bounds = [screen bounds]; - m_geometry = QRect(0, 0, bounds.size.width, bounds.size.height); + m_geometry = QRect(bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height); m_format = QImage::Format_ARGB32; @@ -62,7 +62,7 @@ QUIKitScreen::QUIKitScreen(int screenIndex) const qreal inch = 25.4; qreal dpi = 160.; - int dragDistance = 14; + int dragDistance = 12; if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { dpi = 132.; dragDistance = 10; diff --git a/src/plugins/platforms/uikit/quikitwindow.h b/src/plugins/platforms/uikit/quikitwindow.h index 9e73754..5c6496a 100644 --- a/src/plugins/platforms/uikit/quikitwindow.h +++ b/src/plugins/platforms/uikit/quikitwindow.h @@ -47,6 +47,8 @@ #import #import #import +#import +#import #import @interface EAGLView : UIView @@ -59,6 +61,7 @@ GLuint mFramebuffer, mColorRenderbuffer, mDepthRenderbuffer; + id delegate; // ------- Text Input ---------- UITextAutocapitalizationType autocapitalizationType; UITextAutocorrectionType autocorrectionType; @@ -77,6 +80,8 @@ - (void)setWindow:(QPlatformWindow *)window; - (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons; +@property (readonly,getter=fbo) GLint fbo; +@property (nonatomic, assign) id delegate; // ------- Text Input ---------- @@ -90,6 +95,10 @@ @end +@protocol EAGLViewDelegate +- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer; +@end + class EAGLPlatformContext; QT_BEGIN_NAMESPACE @@ -103,7 +112,7 @@ public: ~QUIKitWindow(); UIWindow *nativeWindow() const { return mWindow; } - UIView *nativeView() const { return mView; } + EAGLView *nativeView() const { return mView; } void setGeometry(const QRect &rect); UIWindow *ensureNativeWindow(); diff --git a/src/plugins/platforms/uikit/quikitwindow.mm b/src/plugins/platforms/uikit/quikitwindow.mm index 52d1846..1f57baa 100644 --- a/src/plugins/platforms/uikit/quikitwindow.mm +++ b/src/plugins/platforms/uikit/quikitwindow.mm @@ -79,7 +79,11 @@ public: mFormat.setStereo(false); mFormat.setDirectRendering(false); +#if defined(QT_OPENGL_ES_2) + EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; +#else EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; +#endif [mView setContext:aContext]; } @@ -116,6 +120,8 @@ private: @implementation EAGLView +@synthesize delegate; + + (Class)layerClass { return [CAEAGLLayer class]; @@ -156,8 +162,8 @@ private: { if (mContext) { [EAGLContext setCurrentContext:mContext]; - glBindRenderbufferOES(GL_RENDERBUFFER_OES, mColorRenderbuffer); - [mContext presentRenderbuffer:GL_RENDERBUFFER_OES]; + glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer); + [mContext presentRenderbuffer:GL_RENDERBUFFER]; } } @@ -167,15 +173,15 @@ private: { [EAGLContext setCurrentContext:mContext]; if (mFramebuffer) { - glDeleteFramebuffersOES(1, &mFramebuffer); + glDeleteFramebuffers(1, &mFramebuffer); mFramebuffer = 0; } if (mColorRenderbuffer) { - glDeleteRenderbuffersOES(1, &mColorRenderbuffer); + glDeleteRenderbuffers(1, &mColorRenderbuffer); mColorRenderbuffer = 0; } if (mDepthRenderbuffer) { - glDeleteRenderbuffersOES(1, &mDepthRenderbuffer); + glDeleteRenderbuffers(1, &mDepthRenderbuffer); mDepthRenderbuffer = 0; } } @@ -186,24 +192,27 @@ private: if (mContext && !mFramebuffer) { [EAGLContext setCurrentContext:mContext]; - glGenFramebuffersOES(1, &mFramebuffer); - glBindFramebufferOES(GL_FRAMEBUFFER_OES, mFramebuffer); - - glGenRenderbuffersOES(1, &mColorRenderbuffer); - glBindRenderbufferOES(GL_RENDERBUFFER_OES, mColorRenderbuffer); - [mContext renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer *)self.layer]; - glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &mFramebufferWidth); - glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &mFramebufferHeight); - glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, mColorRenderbuffer); - - glGenRenderbuffersOES(1, &mDepthRenderbuffer); - glBindRenderbufferOES(GL_RENDERBUFFER_OES, mDepthRenderbuffer); - glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH24_STENCIL8_OES, mFramebufferWidth, mFramebufferHeight); - glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, mDepthRenderbuffer); - glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_STENCIL_ATTACHMENT_OES, GL_RENDERBUFFER_OES, mDepthRenderbuffer); - - if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) - NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)); + glGenFramebuffers(1, &mFramebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + + glGenRenderbuffers(1, &mColorRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer); + [mContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer]; + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &mFramebufferWidth); + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &mFramebufferHeight); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mColorRenderbuffer); + + glGenRenderbuffers(1, &mDepthRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, mDepthRenderbuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, mFramebufferWidth, mFramebufferHeight); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderbuffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderbuffer); + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); + if (delegate && [delegate respondsToSelector:@selector(eaglView:usesFramebuffer:)]) { + [delegate eaglView:self usesFramebuffer:mFramebuffer]; + } } } @@ -214,11 +223,16 @@ private: [EAGLContext setCurrentContext:mContext]; if (!mFramebuffer) [self createFramebuffer]; - glBindFramebufferOES(GL_FRAMEBUFFER_OES, mFramebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); glViewport(0, 0, mFramebufferWidth, mFramebufferHeight); } } +- (GLint)fbo +{ + return mFramebuffer; +} + - (void)setWindow:(QPlatformWindow *)window { mWindow = window; @@ -322,6 +336,7 @@ QUIKitWindow::QUIKitWindow(QWidget *tlw) : CGRect screenBounds = [mScreen->uiScreen() bounds]; QRect geom(screenBounds.origin.x, screenBounds.origin.y, screenBounds.size.width, screenBounds.size.height); setGeometry(geom); + mView = [[EAGLView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)]; // TODO ensure the native window if the application is already running } @@ -334,7 +349,7 @@ QUIKitWindow::~QUIKitWindow() void QUIKitWindow::setGeometry(const QRect &rect) { - if (mWindow) { + if (mWindow && rect != geometry()) { mWindow.frame = CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); mView.frame = CGRectMake(0, 0, rect.width(), rect.height()); [mView deleteFramebuffer]; @@ -347,14 +362,16 @@ UIWindow *QUIKitWindow::ensureNativeWindow() { if (!mWindow) { // window - QRect geom = geometry(); - CGRect frame = CGRectMake(geom.x(), geom.y(), geom.width(), geom.height()); - mWindow = [[UIWindow alloc] initWithFrame:frame]; + CGRect frame = [mScreen->uiScreen() applicationFrame]; + QRect geom = QRect(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height); + widget()->setGeometry(geom); + mWindow = [[UIWindow alloc] init]; mWindow.screen = mScreen->uiScreen(); - mWindow.frame = frame; // for some reason setting the screen resets frame.origin + mWindow.frame = frame; // for some reason setting the screen resets frame.origin, so we need to set the frame afterwards // view - mView = [[EAGLView alloc] initWithFrame:CGRectMake(0, 0, geom.width(), geom.height())]; + [mView deleteFramebuffer]; + mView.frame = CGRectMake(0, 0, frame.size.width, frame.size.height); // fill [mView setMultipleTouchEnabled:YES]; [mView setWindow:this]; [mWindow addSubview:mView]; diff --git a/src/plugins/platforms/uikit/quikitwindowsurface.mm b/src/plugins/platforms/uikit/quikitwindowsurface.mm index bb7dcd7..8caa15f 100644 --- a/src/plugins/platforms/uikit/quikitwindowsurface.mm +++ b/src/plugins/platforms/uikit/quikitwindowsurface.mm @@ -47,27 +47,64 @@ #include +class EAGLPaintDevice; + +@interface PaintDeviceHelper : NSObject { + EAGLPaintDevice *device; +} + +@property (nonatomic, assign) EAGLPaintDevice *device; + +- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer; + +@end + class EAGLPaintDevice : public QGLPaintDevice { public: EAGLPaintDevice(QPlatformWindow *window) :QGLPaintDevice(), mWindow(window) { +#if defined(QT_OPENGL_ES_2) + helper = [[PaintDeviceHelper alloc] init]; + helper.device = this; + EAGLView *view = static_cast(window)->nativeView(); + view.delegate = helper; + m_thisFBO = view.fbo; +#endif } + ~EAGLPaintDevice() + { +#if defined(QT_OPENGL_ES_2) + [helper release]; +#endif + } + + void setFramebuffer(GLuint buffer) { m_thisFBO = buffer; } int devType() const { return QInternal::OpenGL; } QSize size() const { return mWindow->geometry().size(); } QGLContext* context() const { return QGLContext::fromPlatformGLContext(mWindow->glContext()); } QPaintEngine *paintEngine() const { return qt_qgl_paint_engine(); } - void beginPaint(){ - QGLPaintDevice::beginPaint(); - } private: QPlatformWindow *mWindow; + PaintDeviceHelper *helper; }; +@implementation PaintDeviceHelper +@synthesize device; + +- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer +{ + Q_UNUSED(view) + if (device) + device->setFramebuffer(buffer); +} + +@end + QT_BEGIN_NAMESPACE QUIKitWindowSurface::QUIKitWindowSurface(QWidget *window) -- cgit v0.12 From dcdb62c3d1a76d951c4b65bc1b1bd930e2ad14ec Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Wed, 27 Apr 2011 08:47:46 +0200 Subject: Make sure layoutData exist before checking for string direction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise accessing that through QTextEngine::alignLine may cause crash. Reviewed-by: Samuel Rødal --- src/gui/text/qtextengine.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index ce012a8..cc150c5 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1598,6 +1598,8 @@ bool QTextEngine::isRightToLeft() const default: break; } + if (!layoutData) + itemize(); // this places the cursor in the right position depending on the keyboard layout if (layoutData->string.isEmpty()) return QApplication::keyboardInputDirection() == Qt::RightToLeft; -- cgit v0.12 From 2506b86828ca8140c2f22d85a4378df40899b132 Mon Sep 17 00:00:00 2001 From: Martin Petersson Date: Wed, 27 Apr 2011 12:36:53 +0200 Subject: QNetworkConfigurationManager: Fix network polling. startPolling() is called by each engine, so before it would start multiple singleshot timers. So I moved the timer to the class and check if it has already been started before it is activated again. So that we just use one timer. Task-number: QTBUG-17219 Reviewed-by: Iiro Kause Reviewed-by: Kranthi Kuntala --- src/network/bearer/qnetworkconfigmanager_p.cpp | 14 ++++++++++++-- src/network/bearer/qnetworkconfigmanager_p.h | 2 ++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp index c108ad3..e9b6703 100644 --- a/src/network/bearer/qnetworkconfigmanager_p.cpp +++ b/src/network/bearer/qnetworkconfigmanager_p.cpp @@ -60,7 +60,7 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, #endif QNetworkConfigurationManagerPrivate::QNetworkConfigurationManagerPrivate() - : QObject(), mutex(QMutex::Recursive), forcedPolling(0), firstUpdate(true) + : QObject(), pollTimer(0), mutex(QMutex::Recursive), forcedPolling(0), firstUpdate(true) { qRegisterMetaType("QNetworkConfiguration"); qRegisterMetaType("QNetworkConfigurationPrivatePointer"); @@ -442,9 +442,19 @@ void QNetworkConfigurationManagerPrivate::startPolling() { QMutexLocker locker(&mutex); + if(!pollTimer) { + pollTimer = new QTimer(this); + pollTimer->setInterval(10000); + pollTimer->setSingleShot(true); + connect(pollTimer, SIGNAL(timeout()), this, SLOT(pollEngines())); + } + + if(pollTimer->isActive()) + return; + foreach (QBearerEngine *engine, sessionEngines) { if (engine->requiresPolling() && (forcedPolling || engine->configurationsInUse())) { - QTimer::singleShot(10000, this, SLOT(pollEngines())); + pollTimer->start(); break; } } diff --git a/src/network/bearer/qnetworkconfigmanager_p.h b/src/network/bearer/qnetworkconfigmanager_p.h index 81f38c5..abc4b9b 100644 --- a/src/network/bearer/qnetworkconfigmanager_p.h +++ b/src/network/bearer/qnetworkconfigmanager_p.h @@ -64,6 +64,7 @@ QT_BEGIN_NAMESPACE class QBearerEngine; +class QTimer; class Q_NETWORK_EXPORT QNetworkConfigurationManagerPrivate : public QObject { @@ -107,6 +108,7 @@ private Q_SLOTS: private: void startPolling(); + QTimer *pollTimer; private: mutable QMutex mutex; -- cgit v0.12 From 27a24f1d009741b6e712300e7bc58b7e7e7d4c0b Mon Sep 17 00:00:00 2001 From: Honglei Zhang Date: Wed, 27 Apr 2011 09:19:57 +0300 Subject: Fix memory leak in XSD component of XmlPatterns There are couple of memory leaks in XmlPatterns when parsing XSD files. The reason is that the module over uses the shared data pointer and generates many cyclic reference loop. Some part of the code is refactored. Instead of using shared data pointer, normal C++ pointer is used to break the ownership loop. This is bug fix for QTBUG-8948. Task-number: QTBUG-8948 Reviewed-by: Sami Merila and Laszlo Agocs --- src/xmlpatterns/schema/qxsdattribute.cpp | 4 ++-- src/xmlpatterns/schema/qxsdattribute_p.h | 2 +- src/xmlpatterns/schema/qxsdcomplextype.cpp | 4 ++-- src/xmlpatterns/schema/qxsdcomplextype_p.h | 2 +- src/xmlpatterns/schema/qxsdelement.cpp | 8 ++++---- src/xmlpatterns/schema/qxsdelement_p.h | 8 ++++---- src/xmlpatterns/schema/qxsdparticlechecker.cpp | 6 +++--- src/xmlpatterns/schema/qxsdsimpletype.cpp | 4 ++-- src/xmlpatterns/schema/qxsdsimpletype_p.h | 2 +- src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp | 10 +++++----- 10 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/xmlpatterns/schema/qxsdattribute.cpp b/src/xmlpatterns/schema/qxsdattribute.cpp index 68f9e3d..fb768d4 100644 --- a/src/xmlpatterns/schema/qxsdattribute.cpp +++ b/src/xmlpatterns/schema/qxsdattribute.cpp @@ -59,12 +59,12 @@ XsdAttribute::Scope::Variety XsdAttribute::Scope::variety() const void XsdAttribute::Scope::setParent(const NamedSchemaComponent::Ptr &parent) { - m_parent = parent; + m_parent = parent.data(); } NamedSchemaComponent::Ptr XsdAttribute::Scope::parent() const { - return m_parent; + return NamedSchemaComponent::Ptr(m_parent); } void XsdAttribute::ValueConstraint::setVariety(Variety variety) diff --git a/src/xmlpatterns/schema/qxsdattribute_p.h b/src/xmlpatterns/schema/qxsdattribute_p.h index d64d335..a21fe70 100644 --- a/src/xmlpatterns/schema/qxsdattribute_p.h +++ b/src/xmlpatterns/schema/qxsdattribute_p.h @@ -131,7 +131,7 @@ namespace QPatternist private: Variety m_variety; - NamedSchemaComponent::Ptr m_parent; + NamedSchemaComponent *m_parent; }; diff --git a/src/xmlpatterns/schema/qxsdcomplextype.cpp b/src/xmlpatterns/schema/qxsdcomplextype.cpp index 42aeb60..0932060 100644 --- a/src/xmlpatterns/schema/qxsdcomplextype.cpp +++ b/src/xmlpatterns/schema/qxsdcomplextype.cpp @@ -140,12 +140,12 @@ SchemaType::Ptr XsdComplexType::wxsSuperType() const void XsdComplexType::setContext(const NamedSchemaComponent::Ptr &component) { - m_context = component; + m_context = component.data(); } NamedSchemaComponent::Ptr XsdComplexType::context() const { - return m_context; + return NamedSchemaComponent::Ptr(m_context); } void XsdComplexType::setContentType(const ContentType::Ptr &type) diff --git a/src/xmlpatterns/schema/qxsdcomplextype_p.h b/src/xmlpatterns/schema/qxsdcomplextype_p.h index d28d2fc..d02583c 100644 --- a/src/xmlpatterns/schema/qxsdcomplextype_p.h +++ b/src/xmlpatterns/schema/qxsdcomplextype_p.h @@ -386,7 +386,7 @@ namespace QPatternist private: SchemaType::Ptr m_superType; - NamedSchemaComponent::Ptr m_context; + NamedSchemaComponent *m_context; DerivationMethod m_derivationMethod; bool m_isAbstract; XsdAttributeUse::List m_attributeUses; diff --git a/src/xmlpatterns/schema/qxsdelement.cpp b/src/xmlpatterns/schema/qxsdelement.cpp index 1ebec06..b0c5661 100644 --- a/src/xmlpatterns/schema/qxsdelement.cpp +++ b/src/xmlpatterns/schema/qxsdelement.cpp @@ -57,12 +57,12 @@ XsdElement::Scope::Variety XsdElement::Scope::variety() const void XsdElement::Scope::setParent(const NamedSchemaComponent::Ptr &parent) { - m_parent = parent; + m_parent = parent.data(); } NamedSchemaComponent::Ptr XsdElement::Scope::parent() const { - return m_parent; + return NamedSchemaComponent::Ptr(m_parent); } void XsdElement::ValueConstraint::setVariety(Variety variety) @@ -233,10 +233,10 @@ XsdElement::List XsdElement::substitutionGroupAffiliations() const void XsdElement::addSubstitutionGroup(const XsdElement::Ptr &element) { - m_substitutionGroups.insert(element); + m_substitutionGroups.insert(element.data()); } -XsdElement::List XsdElement::substitutionGroups() const +XsdElement::WeakList XsdElement::substitutionGroups() const { return m_substitutionGroups.toList(); } diff --git a/src/xmlpatterns/schema/qxsdelement_p.h b/src/xmlpatterns/schema/qxsdelement_p.h index 93c5983..3794c96 100644 --- a/src/xmlpatterns/schema/qxsdelement_p.h +++ b/src/xmlpatterns/schema/qxsdelement_p.h @@ -85,7 +85,7 @@ namespace QPatternist public: typedef QExplicitlySharedDataPointer Ptr; typedef QList List; - + typedef QList WeakList; /** * Describes the constraint type of the element. @@ -138,7 +138,7 @@ namespace QPatternist private: Variety m_variety; - NamedSchemaComponent::Ptr m_parent; + NamedSchemaComponent *m_parent; }; /** @@ -379,7 +379,7 @@ namespace QPatternist /** * Returns the substitution groups of the element. */ - XsdElement::List substitutionGroups() const; + XsdElement::WeakList substitutionGroups() const; private: SchemaType::Ptr m_type; @@ -392,7 +392,7 @@ namespace QPatternist SchemaType::DerivationConstraints m_substitutionGroupExclusions; XsdIdentityConstraint::List m_identityConstraints; XsdElement::List m_substitutionGroupAffiliations; - QSet m_substitutionGroups; + QSet m_substitutionGroups; }; } diff --git a/src/xmlpatterns/schema/qxsdparticlechecker.cpp b/src/xmlpatterns/schema/qxsdparticlechecker.cpp index 15c2afe..d4beae7 100644 --- a/src/xmlpatterns/schema/qxsdparticlechecker.cpp +++ b/src/xmlpatterns/schema/qxsdparticlechecker.cpp @@ -309,12 +309,12 @@ static bool hasDuplicatedElementsInternal(const XsdParticle::Ptr &particle, cons const XsdTerm::Ptr term = particle->term(); if (term->isElement()) { const XsdElement::Ptr mainElement(term); - XsdElement::List substGroups = mainElement->substitutionGroups(); + XsdElement::WeakList substGroups = mainElement->substitutionGroups(); if (substGroups.isEmpty()) - substGroups << mainElement; + substGroups << mainElement.data(); for (int i = 0; i < substGroups.count(); ++i) { - const XsdElement::Ptr element = substGroups.at(i); + const XsdElement::Ptr element(substGroups.at(i)); if (hash.contains(element->name(namePool))) { if (element->type()->name(namePool) != hash.value(element->name(namePool))->type()->name(namePool)) { conflictingElement = element; diff --git a/src/xmlpatterns/schema/qxsdsimpletype.cpp b/src/xmlpatterns/schema/qxsdsimpletype.cpp index 6fd5658..3e77aca 100644 --- a/src/xmlpatterns/schema/qxsdsimpletype.cpp +++ b/src/xmlpatterns/schema/qxsdsimpletype.cpp @@ -72,12 +72,12 @@ SchemaType::Ptr XsdSimpleType::wxsSuperType() const void XsdSimpleType::setContext(const NamedSchemaComponent::Ptr &component) { - m_context = component; + m_context = component.data(); } NamedSchemaComponent::Ptr XsdSimpleType::context() const { - return m_context; + return NamedSchemaComponent::Ptr(m_context); } void XsdSimpleType::setPrimitiveType(const AnySimpleType::Ptr &type) diff --git a/src/xmlpatterns/schema/qxsdsimpletype_p.h b/src/xmlpatterns/schema/qxsdsimpletype_p.h index 6305fc7..a5b72a7 100644 --- a/src/xmlpatterns/schema/qxsdsimpletype_p.h +++ b/src/xmlpatterns/schema/qxsdsimpletype_p.h @@ -202,7 +202,7 @@ namespace QPatternist private: SchemaType::Ptr m_superType; - NamedSchemaComponent::Ptr m_context; + NamedSchemaComponent* m_context; AnySimpleType::Ptr m_primitiveType; AnySimpleType::Ptr m_itemType; AnySimpleType::List m_memberTypes; diff --git a/src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp b/src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp index fed8a41..b6c8704 100644 --- a/src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp +++ b/src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp @@ -166,14 +166,14 @@ XsdStateMachine::StateId XsdStateMachineBuilder::buildTerm(const X const XsdElement::Ptr element(term); if (m_mode == CheckingMode) { - const XsdElement::List substGroups = element->substitutionGroups(); + const XsdElement::WeakList substGroups = element->substitutionGroups(); for (int i = 0; i < substGroups.count(); ++i) - m_stateMachine->addTransition(b, substGroups.at(i), endState); + m_stateMachine->addTransition(b, XsdElement::Ptr(substGroups.at(i)), endState); } else if (m_mode == ValidatingMode) { - const XsdElement::List substGroups = element->substitutionGroups(); + const XsdElement::WeakList substGroups = element->substitutionGroups(); for (int i = 0; i < substGroups.count(); ++i) { - if (XsdSchemaHelper::substitutionGroupOkTransitive(element, substGroups.at(i), m_namePool)) - m_stateMachine->addTransition(b, substGroups.at(i), endState); + if (XsdSchemaHelper::substitutionGroupOkTransitive(element, XsdElement::Ptr(substGroups.at(i)), m_namePool)) + m_stateMachine->addTransition(b, XsdElement::Ptr(substGroups.at(i)), endState); } } -- cgit v0.12 From a36ac6c34bafa801c2c30d76f59e4a3594efc4d5 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Wed, 27 Apr 2011 11:39:09 +0200 Subject: Another ugly hack to make bidi cursor work with Core Text If the text is wrapped with LRE/LRO/RLE/RLO override/embed marks, Core Text in Mac OS X 10.5 doesn't produce an empty glyph at the beginning of the glyphs (while it does in Mac OS X 10.6), thus we need to prepend an empty glyph here, otherwise cursor position calculation will consider the first two characters as a ligature of the same glyph. Reviewed-by: Eskil --- src/gui/text/qfontengine_coretext.mm | 27 ++++++++++++++++++++++++--- tests/auto/qcomplextext/tst_qcomplextext.cpp | 1 + 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/gui/text/qfontengine_coretext.mm b/src/gui/text/qfontengine_coretext.mm index 20b3730..cf04fb2 100644 --- a/src/gui/text/qfontengine_coretext.mm +++ b/src/gui/text/qfontengine_coretext.mm @@ -180,6 +180,8 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); typeSetter = CTTypesetterCreateWithAttributedStringAndOptions(attributedString, options); } else +#else + Q_UNUSED(flags); #endif typeSetter = CTTypesetterCreateWithAttributedString(attributedString); @@ -219,6 +221,25 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay Q_ASSERT((CTRunGetStatus(run) & kCTRunStatusRightToLeft) == rtl); CFRange stringRange = CTRunGetStringRange(run); + int prepend = 0; +#if MAC_OS_X_VERSION_MAX_ALLOWED == MAC_OS_X_VERSION_10_5 + UniChar beginGlyph = CFStringGetCharacterAtIndex(cfstring, stringRange.location); + QChar dir = QChar::direction(beginGlyph); + bool beginWithOverride = dir == QChar::DirLRO || dir == QChar::DirRLO || dir == QChar::DirLRE || dir == QChar::DirRLE; + if (beginWithOverride) { + logClusters[stringRange.location] = 0; + outGlyphs[0] = 0xFFFF; + outAdvances_x[0] = 0; + outAdvances_y[0] = 0; + outAttributes[0].clusterStart = true; + outAttributes[0].dontPrint = true; + outGlyphs++; + outAdvances_x++; + outAdvances_y++; + outAttributes++; + prepend = 1; + } +#endif UniChar endGlyph = CFStringGetCharacterAtIndex(cfstring, stringRange.location + stringRange.length - 1); bool endWithPDF = QChar::direction(endGlyph) == QChar::DirPDF; if (endWithPDF) @@ -271,9 +292,9 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay CFIndex k = 0; CFIndex i = 0; - for (i = stringRange.location; + for (i = stringRange.location + prepend; (i < stringRange.location + stringRange.length) && (k < glyphCount); ++i) { - if (tmpIndices[k * rtlSign + rtlOffset] == i || i == stringRange.location) { + if (tmpIndices[k * rtlSign + rtlOffset] == i || i == stringRange.location + prepend) { logClusters[i] = k + firstGlyphIndex; outAttributes[k].clusterStart = true; ++k; @@ -308,7 +329,7 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay : QFixed::fromReal(lastGlyphAdvance.width); if (endWithPDF) { - logClusters[stringRange.location + stringRange.length - 1] = glyphCount; + logClusters[stringRange.location + stringRange.length - 1] = glyphCount + prepend; outGlyphs[glyphCount] = 0xFFFF; outAdvances_x[glyphCount] = 0; outAdvances_y[glyphCount] = 0; diff --git a/tests/auto/qcomplextext/tst_qcomplextext.cpp b/tests/auto/qcomplextext/tst_qcomplextext.cpp index 04943c5..58b31b4 100644 --- a/tests/auto/qcomplextext/tst_qcomplextext.cpp +++ b/tests/auto/qcomplextext/tst_qcomplextext.cpp @@ -214,6 +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); bool moved; int oldPos, newPos = 0; qreal x, newX; -- cgit v0.12 From 597acb83e032869325f97ef71d71bfa8da44cee2 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 27 Apr 2011 12:56:58 +0200 Subject: Legal: add the license header to the hand-edits Reviewed-by: Trust Me --- src/3rdparty/phonon/phonon/audiooutputadaptor.cpp | 25 +++++++++++++++++++++++ src/3rdparty/phonon/phonon/audiooutputadaptor_p.h | 25 +++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/src/3rdparty/phonon/phonon/audiooutputadaptor.cpp b/src/3rdparty/phonon/phonon/audiooutputadaptor.cpp index 2c01773..959172d 100644 --- a/src/3rdparty/phonon/phonon/audiooutputadaptor.cpp +++ b/src/3rdparty/phonon/phonon/audiooutputadaptor.cpp @@ -1,3 +1,28 @@ +/* This file is part of the KDE project + The following license applies to the edits made to the generated + source code: + + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + Copyright (C) 2009 Matthias Kretz. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), Nokia Corporation + (or its successors, if any) and the KDE Free Qt Foundation, which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . + +*/ /* * This file was generated by dbusidl2cpp version 0.4 * when processing input file org.kde.Phonon.AudioOutput.xml diff --git a/src/3rdparty/phonon/phonon/audiooutputadaptor_p.h b/src/3rdparty/phonon/phonon/audiooutputadaptor_p.h index 7178e9b..140a74f 100644 --- a/src/3rdparty/phonon/phonon/audiooutputadaptor_p.h +++ b/src/3rdparty/phonon/phonon/audiooutputadaptor_p.h @@ -1,3 +1,28 @@ +/* This file is part of the KDE project + The following license applies to the edits made to the generated + source code: + + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + Copyright (C) 2009 Matthias Kretz. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), Nokia Corporation + (or its successors, if any) and the KDE Free Qt Foundation, which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . + +*/ /* * This file was generated by dbusidl2cpp version 0.4 * when processing input file org.kde.Phonon.AudioOutput.xml -- cgit v0.12 From 02bb8e4c5f4584f3c0a7ed16bcba20c7f43456cd Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Wed, 27 Apr 2011 13:58:50 +0300 Subject: Fix BlendBench::unalignedBlendArgb32 test case The test case freed the wrong pointer, causing crash in Symbian devices. Task-number: QTBUG-17489 Reviewed-by: Janne Koskinen --- tests/benchmarks/gui/image/blendbench/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/benchmarks/gui/image/blendbench/main.cpp b/tests/benchmarks/gui/image/blendbench/main.cpp index a16fd5a..06c36e7 100644 --- a/tests/benchmarks/gui/image/blendbench/main.cpp +++ b/tests/benchmarks/gui/image/blendbench/main.cpp @@ -208,9 +208,9 @@ void BlendBench::unalignedBlendArgb32() uchar *srcMemory = static_cast(qMallocAligned((dimension * dimension * sizeof(quint32)) + 16, 16)); QFETCH(int, offset); - srcMemory += (offset * sizeof(quint32)); + uchar *imageSrcMemory = srcMemory + (offset * sizeof(quint32)); - QImage src(srcMemory, dimension, dimension, QImage::Format_ARGB32_Premultiplied); + QImage src(imageSrcMemory, dimension, dimension, QImage::Format_ARGB32_Premultiplied); src.fill(0x87654321); QPainter painter(&destination); -- cgit v0.12 From 8f95a19d330480bd86650c3d2e4e147d3bca5789 Mon Sep 17 00:00:00 2001 From: Jens Georg Date: Wed, 13 Apr 2011 10:14:43 +0200 Subject: Fix QDateTime::toString for Qt::ISODate Fixes QTBUG-18290 and the "missing Z" from QTBUG-9698 Merge-request: 1149 Reviewed-by: Zeno Albisser --- src/corelib/tools/qdatetime.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index a3a8884..ff868c0 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -2497,6 +2497,21 @@ QString QDateTime::toString(Qt::DateFormat f) const return QString(); // failed to convert buf += QLatin1Char('T'); buf += d->time.toString(Qt::ISODate); + switch (d->spec) { + case QDateTimePrivate::UTC: + buf += QLatin1Char('Z'); + break; + case QDateTimePrivate::OffsetFromUTC: { + int sign = d->utcOffset >= 0 ? 1: -1; + buf += QString::fromLatin1("%1%2:%3"). + arg(sign == 1 ? QLatin1Char('+') : QLatin1Char('-')). + arg(d->utcOffset * sign / SECS_PER_HOUR, 2, 10, QLatin1Char('0')). + arg((d->utcOffset / 60) % 60, 2, 10, QLatin1Char('0')); + break; + } + default: + break; + } } #ifndef QT_NO_TEXTDATE else if (f == Qt::TextDate) { -- cgit v0.12 From 3d4149afe62b4fc5d519a2a155b8f8c32e7e95c4 Mon Sep 17 00:00:00 2001 From: Jens Georg Date: Wed, 13 Apr 2011 10:14:44 +0200 Subject: Update documentation of QDateTime::toString Merge-request: 1149 Reviewed-by: Zeno Albisser --- src/corelib/tools/qdatetime.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index ff868c0..d9a054a 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -2460,7 +2460,11 @@ void QDateTime::setTime_t(uint secsSince1Jan1970UTC) If the \a format is Qt::ISODate, the string format corresponds to the ISO 8601 extended specification for representations of - dates and times, taking the form YYYY-MM-DDTHH:MM:SS. + dates and times, taking the form YYYY-MM-DDTHH:MM:SS[Z|[+|-]HH:MM], + depending on the timeSpec() of the QDateTime. If the timeSpec() + is Qt::UTC, Z will be appended to the string; if the timeSpec() is + Qt::OffsetFromUTC the offset in hours and minutes from UTC will + be appended to the string. If the \a format is Qt::SystemLocaleShortDate or Qt::SystemLocaleLongDate, the string format depends on the locale -- cgit v0.12 From d9e0c2ea4d64b8fdfb31b28e71373735be38101b Mon Sep 17 00:00:00 2001 From: Jens Georg Date: Wed, 13 Apr 2011 10:14:46 +0200 Subject: Add test for ISODate change in QDateTime::toString Merge-request: 1149 Reviewed-by: Zeno Albisser --- tests/auto/qdatetime/tst_qdatetime.cpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tests/auto/qdatetime/tst_qdatetime.cpp b/tests/auto/qdatetime/tst_qdatetime.cpp index f8836a6..d612911 100644 --- a/tests/auto/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/qdatetime/tst_qdatetime.cpp @@ -85,6 +85,8 @@ private slots: void setTime_t(); void setMSecsSinceEpoch_data(); void setMSecsSinceEpoch(); + void toString_isoDate_data(); + void toString_isoDate(); void toString_enumformat(); void toString_strformat_data(); void toString_strformat(); @@ -506,6 +508,36 @@ void tst_QDateTime::setMSecsSinceEpoch() QCOMPARE(dt, reference.addMSecs(msecs)); } +void tst_QDateTime::toString_isoDate_data() +{ + QTest::addColumn("dt"); + QTest::addColumn("formatted"); + + QTest::newRow("localtime") + << QDateTime(QDate(1978, 11, 9), QTime(13, 28, 34)) + << QString("1978-11-09T13:28:34"); + QTest::newRow("UTC") + << QDateTime(QDate(1978, 11, 9), QTime(13, 28, 34), Qt::UTC) + << QString("1978-11-09T13:28:34Z"); + QDateTime dt(QDate(1978, 11, 9), QTime(13, 28, 34)); + dt.setUtcOffset(19800); + QTest::newRow("positive OffsetFromUTC") + << dt + << QString("1978-11-09T13:28:34+05:30"); + dt.setUtcOffset(-7200); + QTest::newRow("negative OffsetFromUTC") + << dt + << QString("1978-11-09T13:28:34-02:00"); +} + +void tst_QDateTime::toString_isoDate() +{ + QFETCH(QDateTime, dt); + QFETCH(QString, formatted); + + QCOMPARE(dt.toString(Qt::ISODate), formatted); +} + void tst_QDateTime::toString_enumformat() { QDateTime dt1(QDate(1995, 5, 20), QTime(12, 34, 56)); -- cgit v0.12 From 4a1ae3d1b4e8e032b1c978fcc7e1812e37e1f047 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 27 Apr 2011 15:18:58 +0200 Subject: Make translucent windows working properly with OpenVG. The OpenVG engine correctly uses vgClear() to fill the surface with transparent pixels whenever the window has the WA_TranslucentBackground attribute enabled. However both scissoring and masking affects the operation of vgClear(). Drawing artifacts were previously visible due this, simply because scissoring was left enabled by the VG paint engine, and the filling with transparent pixels happens in the window surface's beginPaint() that is called between the paint engine's end() (for the previous paint) and begin() (for the next paint). Task-number: QT-4907 Reviewed-by: Jani Hautakangas --- src/openvg/qpaintengine_vg.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index ebdfa5f..648415c 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -1533,6 +1533,8 @@ bool QVGPaintEngine::begin(QPaintDevice *pdev) bool QVGPaintEngine::end() { + vgSeti(VG_SCISSORING, VG_FALSE); + vgSeti(VG_MASKING, VG_FALSE); return true; } @@ -3759,6 +3761,8 @@ void QVGPaintEngine::beginNativePainting() #if !defined(QVG_NO_DRAW_GLYPHS) d->setTransform(VG_MATRIX_GLYPH_USER_TO_SURFACE, d->pathTransform); #endif + vgSeti(VG_SCISSORING, VG_FALSE); + vgSeti(VG_MASKING, VG_FALSE); d->rawVG = true; } @@ -3819,6 +3823,7 @@ void QVGPaintEngine::restoreState(QPaintEngine::DirtyFlags dirty) if ((dirty & QPaintEngine::DirtyBrushOrigin) != 0) brushOriginChanged(); d->fillRule = 0; + d->clearColor = QColor(); if ((dirty & QPaintEngine::DirtyOpacity) != 0) opacityChanged(); if ((dirty & QPaintEngine::DirtyTransform) != 0) -- cgit v0.12 From d45ec470519d1075ebf299b74cbb846a0c7d99af Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 27 Apr 2011 15:02:32 +0200 Subject: Upload VGImage data when drawing pixmaps that are being painted into. When a painter is open on a pixmap's underlying QVolatileImage, it is better to upload the VGImage content every time the pixmap is drawn on the screen, in order to enable showing animations that are created by continously rendering into the same pixmap and keeping the same painter open. Task-number: QT-4002 Reviewed-by: Jason Barron --- src/gui/image/qvolatileimage.cpp | 5 +++++ src/gui/image/qvolatileimage_p.h | 1 + src/openvg/qpixmapdata_vg.cpp | 2 +- src/s60installs/bwins/QtGuiu.def | 1 + src/s60installs/eabi/QtGuiu.def | 1 + tests/auto/qpixmap/tst_qpixmap.cpp | 46 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 55 insertions(+), 1 deletion(-) diff --git a/src/gui/image/qvolatileimage.cpp b/src/gui/image/qvolatileimage.cpp index 098e9a1..f5076e1 100644 --- a/src/gui/image/qvolatileimage.cpp +++ b/src/gui/image/qvolatileimage.cpp @@ -103,6 +103,11 @@ QVolatileImage &QVolatileImage::operator=(const QVolatileImage &rhs) return *this; } +bool QVolatileImage::paintingActive() const +{ + return d->pengine && d->pengine->isActive(); +} + bool QVolatileImage::isNull() const { return d->image.isNull(); diff --git a/src/gui/image/qvolatileimage_p.h b/src/gui/image/qvolatileimage_p.h index fc5d6b1..d835f45 100644 --- a/src/gui/image/qvolatileimage_p.h +++ b/src/gui/image/qvolatileimage_p.h @@ -71,6 +71,7 @@ public: ~QVolatileImage(); QVolatileImage &operator=(const QVolatileImage &rhs); + bool paintingActive() const; bool isNull() const; QImage::Format format() const; int width() const; diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp index 80f5b2f..eae10c8 100644 --- a/src/openvg/qpixmapdata_vg.cpp +++ b/src/openvg/qpixmapdata_vg.cpp @@ -377,7 +377,7 @@ VGImage QVGPixmapData::toVGImage() QVGImagePool::instance()->useImage(this); } - if (!source.isNull() && recreate) { + if (!source.isNull() && (recreate || source.paintingActive())) { source.beginDataAccess(); vgImageSubData (vgImage, diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def index 26a0761..45a8d7b 100644 --- a/src/s60installs/bwins/QtGuiu.def +++ b/src/s60installs/bwins/QtGuiu.def @@ -12981,4 +12981,5 @@ EXPORTS ?depth@QVolatileImage@@QBEHXZ @ 12980 NONAME ; int QVolatileImage::depth(void) const ?releaseCachedResources@QGraphicsSystem@@UAEXXZ @ 12981 NONAME ; void QGraphicsSystem::releaseCachedResources(void) ?qt_s60_setPartialScreenInputMode@@YAX_N@Z @ 12982 NONAME ; void qt_s60_setPartialScreenInputMode(bool) + ?paintingActive@QVolatileImage@@QBE_NXZ @ 12983 NONAME ; bool QVolatileImage::paintingActive(void) const diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def index b6a24ab..82ded24 100644 --- a/src/s60installs/eabi/QtGuiu.def +++ b/src/s60installs/eabi/QtGuiu.def @@ -12182,4 +12182,5 @@ EXPORTS _ZNK14QVolatileImage9constBitsEv @ 12181 NONAME _ZN15QGraphicsSystem22releaseCachedResourcesEv @ 12182 NONAME _Z32qt_s60_setPartialScreenInputModeb @ 12183 NONAME + _ZNK14QVolatileImage14paintingActiveEv @ 12184 NONAME diff --git a/tests/auto/qpixmap/tst_qpixmap.cpp b/tests/auto/qpixmap/tst_qpixmap.cpp index 0b5c30b..d103cb7 100644 --- a/tests/auto/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/qpixmap/tst_qpixmap.cpp @@ -194,6 +194,8 @@ private slots: #if defined(Q_OS_SYMBIAN) && !defined(QT_NO_OPENVG) void vgImageReadBack(); #endif + + void drawPixmapWhilePainterOpen(); }; static bool lenientCompare(const QPixmap &actual, const QPixmap &expected) @@ -1881,5 +1883,49 @@ void tst_QPixmap::vgImageReadBack() } #endif // Symbian & OpenVG +class PixmapWidget : public QWidget +{ +public: + PixmapWidget(QPixmap &pixmap) : QWidget(0), m_pixmap(pixmap) + { + resize(pixmap.width(), pixmap.height()); + } + +protected: + void paintEvent(QPaintEvent *) + { + QPainter p(this); + p.drawPixmap(0, 0, m_pixmap); + } + +private: + QPixmap &m_pixmap; +}; + +void tst_QPixmap::drawPixmapWhilePainterOpen() +{ + int size = 100; + QPixmap pix(size, size); + pix.fill(Qt::red); + + PixmapWidget w(pix); + w.show(); + QTest::qWaitForWindowShown(&w); + QTest::qWait(1000); + + QPainter p(&pix); + p.fillRect(0, 0, size, size, Qt::blue); + w.update(); + QTest::qWait(1000); + + p.fillRect(0, 0, size, size, Qt::green); + w.update(); + QTest::qWait(1000); + + QPixmap actual = QPixmap::grabWindow(w.effectiveWinId(), 0, 0, size, size); + + QVERIFY(lenientCompare(actual, pix)); +} + QTEST_MAIN(tst_QPixmap) #include "tst_qpixmap.moc" -- cgit v0.12 From c501403cb5a0c9ec21b00e0c2f640ae85566e0cf Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Wed, 27 Apr 2011 16:05:09 +0200 Subject: Use maximum ascent/descent/leading from fallback fonts in shaping When shaping a QScriptItem with a multi font engine, currently we only take the ascent/descent/leading from the primary (first) font engine in that multi font engine, however, subsequent engines used during shaping may have larger ascent/descent/leading, disregarding them may cause clipping issues in some cases. It's fixed by checking each font engine used in the shaping process and take the maximum value instead of the first one. On ATSUI we merely make it compile. Task-number: QTBUG-16719 Reviewed-by: Eskil --- src/gui/text/qfontengine_coretext.mm | 13 ++++++++++--- src/gui/text/qfontengine_coretext_p.h | 3 ++- src/gui/text/qfontengine_mac.mm | 2 +- src/gui/text/qfontengine_mac_p.h | 2 +- src/gui/text/qtextengine.cpp | 4 ++++ src/gui/text/qtextengine_mac.cpp | 4 ++-- 6 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/gui/text/qfontengine_coretext.mm b/src/gui/text/qfontengine_coretext.mm index cf04fb2..51e14b1 100644 --- a/src/gui/text/qfontengine_coretext.mm +++ b/src/gui/text/qfontengine_coretext.mm @@ -162,8 +162,10 @@ uint QCoreTextFontEngineMulti::fontIndexForFont(CTFontRef font) const return engines.count() - 1; } -bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags, - unsigned short *logClusters, const HB_CharAttributes *) const +bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, + int *nglyphs, QTextEngine::ShaperFlags flags, + unsigned short *logClusters, const HB_CharAttributes *, + QScriptItem *si) const { QCFType cfstring = CFStringCreateWithCharactersNoCopy(0, reinterpret_cast(str), @@ -254,7 +256,12 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay if (!runAttribs) runAttribs = attributeDict; CTFontRef runFont = static_cast(CFDictionaryGetValue(runAttribs, NSFontAttributeName)); - const uint fontIndex = (fontIndexForFont(runFont) << 24); + uint fontIndex = fontIndexForFont(runFont); + const QFontEngine *engine = engineAt(fontIndex); + fontIndex <<= 24; + si->ascent = qMax(engine->ascent(), si->ascent); + si->descent = qMax(engine->descent(), si->descent); + si->leading = qMax(engine->leading(), si->leading); //NSLog(@"Run Font Name = %@", CTFontCopyFamilyName(runFont)); if (endWithPDF) glyphCount--; diff --git a/src/gui/text/qfontengine_coretext_p.h b/src/gui/text/qfontengine_coretext_p.h index 1503c3f..3fd70d6 100644 --- a/src/gui/text/qfontengine_coretext_p.h +++ b/src/gui/text/qfontengine_coretext_p.h @@ -118,7 +118,8 @@ public: QTextEngine::ShaperFlags flags) const; bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags, - unsigned short *logClusters, const HB_CharAttributes *charAttributes) const; + unsigned short *logClusters, const HB_CharAttributes *charAttributes, + QScriptItem *si) const; virtual const char *name() const { return "CoreText"; } protected: diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm index 673a7c8..9f094ad 100644 --- a/src/gui/text/qfontengine_mac.mm +++ b/src/gui/text/qfontengine_mac.mm @@ -377,7 +377,7 @@ bool QFontEngineMacMulti::stringToCMap(const QChar *str, int len, QGlyphLayout * } bool QFontEngineMacMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags, - unsigned short *logClusters, const HB_CharAttributes *charAttributes) const + unsigned short *logClusters, const HB_CharAttributes *charAttributes, QScriptItem *) const { if (*nglyphs < len) { *nglyphs = len; diff --git a/src/gui/text/qfontengine_mac_p.h b/src/gui/text/qfontengine_mac_p.h index 385fa83..292ea98 100644 --- a/src/gui/text/qfontengine_mac_p.h +++ b/src/gui/text/qfontengine_mac_p.h @@ -131,7 +131,7 @@ public: virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const; bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags, - unsigned short *logClusters, const HB_CharAttributes *charAttributes) const; + unsigned short *logClusters, const HB_CharAttributes *charAttributes, QScriptItem *) const; virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const; virtual void doKerning(QGlyphLayout *, QTextEngine::ShaperFlags) const; diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index cc150c5..ff27bc6 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1274,6 +1274,10 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const actualFontEngine = static_cast(font)->engine(engineIdx); } + si.ascent = qMax(actualFontEngine->ascent(), si.ascent); + si.descent = qMax(actualFontEngine->descent(), si.descent); + si.leading = qMax(actualFontEngine->leading(), si.leading); + shaper_item.font = actualFontEngine->harfbuzzFont(); shaper_item.face = actualFontEngine->harfbuzzFace(); diff --git a/src/gui/text/qtextengine_mac.cpp b/src/gui/text/qtextengine_mac.cpp index 97e8c5b..2c6e579 100644 --- a/src/gui/text/qtextengine_mac.cpp +++ b/src/gui/text/qtextengine_mac.cpp @@ -605,11 +605,11 @@ void QTextEngine::shapeTextMac(int item) const unsigned short *log_clusters = logClusters(&si); bool stringToCMapFailed = false; - if (!fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, attributes())) { + if (!fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, attributes(), &si)) { ensureSpace(num_glyphs); g = availableGlyphs(&si); stringToCMapFailed = !fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, - attributes()); + attributes(), &si); } if (!stringToCMapFailed) { -- cgit v0.12 From f0faf4011e1128ab5e58ce3912d379481f8320cb Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 27 Apr 2011 14:21:54 +0200 Subject: Make QtQuick2 compile on QPA Moved the logic to set pixel size into the font engines to avoid making the platform plugin interface too complex, and added a function in QPA to make an isolated font engine based on font data. Currently none of the QPA back-ends supports it, but it compiles and spits out a warning if you try to create a QRawFont from data there. This isn't used in QtQuick2 anyway. Reviewed-by: Jiang Jiang --- src/corelib/global/qglobal.h | 3 +- src/gui/text/qfontengine_coretext.mm | 9 ++++ src/gui/text/qfontengine_coretext_p.h | 2 + src/gui/text/qfontengine_ft.cpp | 35 +++++++++++++++ src/gui/text/qfontengine_ft_p.h | 6 ++- src/gui/text/qfontengine_p.h | 2 + src/gui/text/qfontengine_win.cpp | 17 ++++++++ src/gui/text/qfontengine_win_p.h | 3 ++ src/gui/text/qfontengine_x11.cpp | 14 ++++++ src/gui/text/qfontengine_x11_p.h | 2 + src/gui/text/qfontenginedirectwrite.cpp | 11 +++++ src/gui/text/qfontenginedirectwrite_p.h | 2 + src/gui/text/qplatformfontdatabase_qpa.cpp | 10 +++++ src/gui/text/qplatformfontdatabase_qpa.h | 2 + src/gui/text/qrawfont.cpp | 13 +++++- src/gui/text/qrawfont_ft.cpp | 51 ---------------------- src/gui/text/qrawfont_mac.cpp | 22 ---------- src/gui/text/qrawfont_p.h | 4 -- src/gui/text/qrawfont_qpa.cpp | 69 ++++++++++++++++++++++++++++++ src/gui/text/qrawfont_win.cpp | 47 +------------------- src/gui/text/text.pri | 3 +- 21 files changed, 201 insertions(+), 126 deletions(-) create mode 100644 src/gui/text/qrawfont_qpa.cpp diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index d8ffd6d..5b19b3c 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -2745,7 +2745,8 @@ QT_LICENSED_MODULE(DBus) #if !(defined(Q_WS_WIN) && !defined(Q_WS_WINCE)) \ && !(defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)) \ - && !(defined(Q_WS_X11) && !defined(QT_NO_FREETYPE)) + && !(defined(Q_WS_X11) && !defined(QT_NO_FREETYPE)) \ + && !(defined(Q_WS_QPA)) # define QT_NO_RAWFONT #endif diff --git a/src/gui/text/qfontengine_coretext.mm b/src/gui/text/qfontengine_coretext.mm index 51e14b1..d4df218 100644 --- a/src/gui/text/qfontengine_coretext.mm +++ b/src/gui/text/qfontengine_coretext.mm @@ -865,6 +865,15 @@ QFixed QCoreTextFontEngine::emSquareSize() const return QFixed::QFixed(int(CTFontGetUnitsPerEm(ctfont))); } +QFontEngine *QCoreTextFontEngine::cloneWithSize(qreal pixelSize) const +{ + QFontDef newFontDef = fontDef; + newFontDef.pixelSize = pixelSize; + newFontDef.pointSize = pixelSize * 72.0 / qt_defaultDpi(); + + return new QCoreTextFontEngine(cgFont, fontDef); +} + QT_END_NAMESPACE #endif// !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) diff --git a/src/gui/text/qfontengine_coretext_p.h b/src/gui/text/qfontengine_coretext_p.h index 3fd70d6..bb80a9b 100644 --- a/src/gui/text/qfontengine_coretext_p.h +++ b/src/gui/text/qfontengine_coretext_p.h @@ -91,6 +91,8 @@ public: virtual qreal minLeftBearing() const; virtual QFixed emSquareSize() const; + virtual QFontEngine *cloneWithSize(qreal pixelSize) const; + private: friend class QRawFontPrivate; diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 8f2da9b..58bcca8 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -2069,6 +2069,41 @@ HB_Error QFontEngineFT::getPointInOutline(HB_Glyph glyph, int flags, hb_uint32 p return result; } +bool QFontEngineFT::initFromFontEngine(const QFontEngineFT *fe) +{ + if (!init(fe->faceId(), fe->antialias, fe->defaultFormat, fe->freetype)) + return false; + + // Increase the reference of this QFreetypeFace since one more QFontEngineFT + // will be using it + freetype->ref.ref(); + + default_load_flags = fe->default_load_flags; + default_hint_style = fe->default_hint_style; + antialias = fe->antialias; + transform = fe->transform; + embolden = fe->embolden; + subpixelType = fe->subpixelType; + lcdFilterType = fe->lcdFilterType; + canUploadGlyphsToServer = fe->canUploadGlyphsToServer; + embeddedbitmap = fe->embeddedbitmap; + + return true; +} + +QFontEngine *QFontEngineFT::cloneWithSize(qreal pixelSize) const +{ + QFontDef fontDef; + fontDef.pixelSize = pixelSize; + QFontEngineFT *fe = new QFontEngineFT(fontDef); + if (!fe->initFromFontEngine(this)) { + delete fe; + return 0; + } else { + return fe; + } +} + QT_END_NAMESPACE #endif // QT_NO_FREETYPE diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h index 887efed..6dbca7a 100644 --- a/src/gui/text/qfontengine_ft_p.h +++ b/src/gui/text/qfontengine_ft_p.h @@ -122,7 +122,7 @@ struct QFreetypeFace static void addBitmapToPath(FT_GlyphSlot slot, const QFixedPoint &point, QPainterPath *path, bool = false); private: - friend class QFontEngineFTRawFont; + friend class QFontEngineFT; friend class QScopedPointerDeleter; QFreetypeFace() : _lock(QMutex::Recursive) {} ~QFreetypeFace() {} @@ -319,6 +319,10 @@ private: }; void setDefaultHintStyle(HintStyle style); + + virtual QFontEngine *cloneWithSize(qreal pixelSize) const; + bool initFromFontEngine(const QFontEngineFT *fontEngine); + HintStyle defaultHintStyle() const { return default_hint_style; } protected: diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index 5b39fd3..6db0aa6 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -235,6 +235,8 @@ public: virtual int glyphCount() const; + virtual QFontEngine *cloneWithSize(qreal /*pixelSize*/) const { return 0; } + HB_Font harfbuzzFont() const; HB_Face harfbuzzFace() const; diff --git a/src/gui/text/qfontengine_win.cpp b/src/gui/text/qfontengine_win.cpp index 82d9da0..54d7ec2 100644 --- a/src/gui/text/qfontengine_win.cpp +++ b/src/gui/text/qfontengine_win.cpp @@ -1284,6 +1284,23 @@ QImage QFontEngineWin::alphaRGBMapForGlyph(glyph_t glyph, QFixed, int margin, co return rgbMask; } +// From qfontdatabase_win.cpp +extern QFontEngine *qt_load_font_engine_win(const QFontDef &request); +QFontEngine *QFontEngineWin::cloneWithSize(qreal pixelSize) const +{ + QFontDef request = fontDef; + QString actualFontName = request.family; + if (!uniqueFamilyName.isEmpty()) + request.family = uniqueFamilyName; + request.pixelSize = pixelSize; + + QFontEngine *fontEngine = qt_load_font_engine_win(request); + if (fontEngine != NULL) + fontEngine->fontDef.family = actualFontName; + + return fontEngine; +} + // -------------------------------------- Multi font engine QFontEngineMultiWin::QFontEngineMultiWin(QFontEngine *first, const QStringList &fallbacks) diff --git a/src/gui/text/qfontengine_win_p.h b/src/gui/text/qfontengine_win_p.h index 28d8000..114149d 100644 --- a/src/gui/text/qfontengine_win_p.h +++ b/src/gui/text/qfontengine_win_p.h @@ -106,6 +106,8 @@ public: virtual QImage alphaMapForGlyph(glyph_t, const QTransform &xform); virtual QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform); + virtual QFontEngine *cloneWithSize(qreal pixelSize) const; + #ifndef Q_CC_MINGW virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0); #endif @@ -118,6 +120,7 @@ public: #endif QString _name; + QString uniqueFamilyName; HFONT hfont; LOGFONT logfont; uint stockFont : 1; diff --git a/src/gui/text/qfontengine_x11.cpp b/src/gui/text/qfontengine_x11.cpp index 9f3f8d3..4260b85 100644 --- a/src/gui/text/qfontengine_x11.cpp +++ b/src/gui/text/qfontengine_x11.cpp @@ -1196,6 +1196,20 @@ bool QFontEngineX11FT::uploadGlyphToServer(QGlyphSet *set, uint glyphid, Glyph * #endif } +QFontEngine *QFontEngineX11FT::cloneWithSize(qreal pixelSize) const +{ + QFontDef fontDef; + fontDef.pixelSize = pixelSize; + QFontEngineX11FT *fe = new QFontEngineX11FT(fontDef); + if (!fe->initFromFontEngine(this)) { + delete fe; + return 0; + } else { + fe->xglyph_format = xglyph_format; + return fe; + } +} + #endif // QT_NO_FONTCONFIG QT_END_NAMESPACE diff --git a/src/gui/text/qfontengine_x11_p.h b/src/gui/text/qfontengine_x11_p.h index ad68fac..d7eb39d 100644 --- a/src/gui/text/qfontengine_x11_p.h +++ b/src/gui/text/qfontengine_x11_p.h @@ -161,6 +161,8 @@ public: explicit QFontEngineX11FT(FcPattern *pattern, const QFontDef &fd, int screen); ~QFontEngineX11FT(); + QFontEngine *cloneWithSize(qreal pixelSize) const; + #ifndef QT_NO_XRENDER int xglyph_format; #endif diff --git a/src/gui/text/qfontenginedirectwrite.cpp b/src/gui/text/qfontenginedirectwrite.cpp index f0a3644..aab00c0 100644 --- a/src/gui/text/qfontenginedirectwrite.cpp +++ b/src/gui/text/qfontenginedirectwrite.cpp @@ -630,6 +630,17 @@ QFontEngine::Type QFontEngineDirectWrite::type() const return QFontEngine::DirectWrite; } +QFontEngine *QFontEngineDirectWrite::cloneWithSize(qreal pixelSize) const +{ + QFontEngine *fontEngine = new QFontEngineDirectWrite(m_directWriteFactory, m_directWriteFontFace, + pixelSize); + + fontEngine->fontDef = fontDef; + fontEngine->fontDef.pixelSize = pixelSize; + + return fontEngine; +} + QT_END_NAMESPACE #endif // QT_NO_DIRECTWRITE diff --git a/src/gui/text/qfontenginedirectwrite_p.h b/src/gui/text/qfontenginedirectwrite_p.h index c440a6c..53a4b0a 100644 --- a/src/gui/text/qfontenginedirectwrite_p.h +++ b/src/gui/text/qfontenginedirectwrite_p.h @@ -101,6 +101,8 @@ public: QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform); + QFontEngine *cloneWithSize(qreal pixelSize) const; + bool canRender(const QChar *string, int len); Type type() const; diff --git a/src/gui/text/qplatformfontdatabase_qpa.cpp b/src/gui/text/qplatformfontdatabase_qpa.cpp index 6fa25e7..82ec279 100644 --- a/src/gui/text/qplatformfontdatabase_qpa.cpp +++ b/src/gui/text/qplatformfontdatabase_qpa.cpp @@ -218,6 +218,16 @@ QFontEngine *QPlatformFontDatabase::fontEngine(const QFontDef &fontDef, QUnicode return engine; } +QFontEngine *QPlatformFontDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize, + QFont::HintingPreference hintingPreference) +{ + Q_UNUSED(fontData); + Q_UNUSED(pixelSize); + Q_UNUSED(hintingPreference); + qWarning("This plugin does not support font engines created directly from font data"); + return 0; +} + /*! */ diff --git a/src/gui/text/qplatformfontdatabase_qpa.h b/src/gui/text/qplatformfontdatabase_qpa.h index e0e4f04..046311f 100644 --- a/src/gui/text/qplatformfontdatabase_qpa.h +++ b/src/gui/text/qplatformfontdatabase_qpa.h @@ -92,6 +92,8 @@ public: virtual QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName); virtual void releaseHandle(void *handle); + virtual QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference); + virtual QString fontDir() const; //callback diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp index 4a715c2..6ac2677 100644 --- a/src/gui/text/qrawfont.cpp +++ b/src/gui/text/qrawfont.cpp @@ -579,8 +579,19 @@ QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writ */ void QRawFont::setPixelSize(int pixelSize) { + if (d->fontEngine == 0) + return; + detach(); - d->platformSetPixelSize(pixelSize); + QFontEngine *oldFontEngine = d->fontEngine; + + d->fontEngine = d->fontEngine->cloneWithSize(pixelSize); + if (d->fontEngine != 0) + d->fontEngine->ref.ref(); + + oldFontEngine->ref.deref(); + if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0) + delete oldFontEngine; } /*! diff --git a/src/gui/text/qrawfont_ft.cpp b/src/gui/text/qrawfont_ft.cpp index eefbd92..23d47eb 100644 --- a/src/gui/text/qrawfont_ft.cpp +++ b/src/gui/text/qrawfont_ft.cpp @@ -90,32 +90,6 @@ public: return init(faceId, true, Format_None, fontData); } - - bool initFromFontEngine(QFontEngine *oldFontEngine) - { - QFontEngineFT *fe = static_cast(oldFontEngine); - - // Increase the reference of this QFreetypeFace since one more QFontEngineFT - // will be using it - fe->freetype->ref.ref(); - if (!init(fe->faceId(), fe->antialias, fe->defaultFormat, fe->freetype)) - return false; - - default_load_flags = fe->default_load_flags; - default_hint_style = fe->default_hint_style; - antialias = fe->antialias; - transform = fe->transform; - embolden = fe->embolden; - subpixelType = fe->subpixelType; - lcdFilterType = fe->lcdFilterType; - canUploadGlyphsToServer = fe->canUploadGlyphsToServer; - embeddedbitmap = fe->embeddedbitmap; - -#if defined(Q_WS_X11) - xglyph_format = static_cast(fe)->xglyph_format; -#endif - return true; - } }; @@ -159,31 +133,6 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, int pixel fontEngine->ref.ref(); } -void QRawFontPrivate::platformSetPixelSize(int pixelSize) -{ - if (fontEngine == NULL) - return; - - QFontEngine *oldFontEngine = fontEngine; - - QFontDef fontDef; - fontDef.pixelSize = pixelSize; - QFontEngineFTRawFont *fe = new QFontEngineFTRawFont(fontDef); - if (!fe->initFromFontEngine(oldFontEngine)) { - delete fe; - return; - } - - fontEngine = fe; - fontEngine->fontDef = oldFontEngine->fontDef; - fontEngine->fontDef.pixelSize = pixelSize; - fontEngine->ref.ref(); - Q_ASSERT(fontEngine != oldFontEngine); - oldFontEngine->ref.deref(); - if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0) - delete oldFontEngine; -} - QT_END_NAMESPACE #endif // QT_NO_RAWFONT diff --git a/src/gui/text/qrawfont_mac.cpp b/src/gui/text/qrawfont_mac.cpp index 56005c6..1ed4185 100644 --- a/src/gui/text/qrawfont_mac.cpp +++ b/src/gui/text/qrawfont_mac.cpp @@ -78,28 +78,6 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, } } -void QRawFontPrivate::platformSetPixelSize(int pixelSize) -{ - if (fontEngine == NULL) - return; - - QFontEngine *oldFontEngine = fontEngine; - - QFontDef fontDef = oldFontEngine->fontDef; - fontDef.pixelSize = pixelSize; - fontDef.pointSize = pixelSize * 72.0 / qt_defaultDpi(); - - QCoreTextFontEngine *ctFontEngine = static_cast(oldFontEngine); - Q_ASSERT(ctFontEngine->cgFont); - - fontEngine = new QCoreTextFontEngine(ctFontEngine->cgFont, fontDef); - fontEngine->ref.ref(); - Q_ASSERT(fontEngine != oldFontEngine); - oldFontEngine->ref.deref(); - if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0) - delete oldFontEngine; -} - QT_END_NAMESPACE #endif // QT_NO_RAWFONT diff --git a/src/gui/text/qrawfont_p.h b/src/gui/text/qrawfont_p.h index f9a9ab5..e29ea9c 100644 --- a/src/gui/text/qrawfont_p.h +++ b/src/gui/text/qrawfont_p.h @@ -83,7 +83,6 @@ public: , fontHandle(NULL) , ptrAddFontMemResourceEx(other.ptrAddFontMemResourceEx) , ptrRemoveFontMemResourceEx(other.ptrRemoveFontMemResourceEx) - , uniqueFamilyName(other.uniqueFamilyName) #endif { fontEngine = other.fontEngine; @@ -102,7 +101,6 @@ public: void platformLoadFromData(const QByteArray &fontData, int pixelSize, QFont::HintingPreference hintingPreference); - void platformSetPixelSize(int pixelSize); static QRawFontPrivate *get(const QRawFont &font) { return font.d.data(); } @@ -120,8 +118,6 @@ public: PtrAddFontMemResourceEx ptrAddFontMemResourceEx; PtrRemoveFontMemResourceEx ptrRemoveFontMemResourceEx; - QString uniqueFamilyName; - #endif // Q_WS_WIN }; diff --git a/src/gui/text/qrawfont_qpa.cpp b/src/gui/text/qrawfont_qpa.cpp new file mode 100644 index 0000000..103619c --- /dev/null +++ b/src/gui/text/qrawfont_qpa.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** 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:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#if !defined(QT_NO_RAWFONT) + +#include "qrawfont_p.h" +#include +#include + +QT_BEGIN_NAMESPACE + +void QRawFontPrivate::platformCleanUp() +{ +} + +void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, int pixelSize, + QFont::HintingPreference hintingPreference) +{ + Q_ASSERT(fontEngine == 0); + + QPlatformFontDatabase *pfdb = QApplicationPrivate::platformIntegration()->fontDatabase(); + fontEngine = pfdb->fontEngine(fontData, pixelSize, hintingPreference); + if (fontEngine != 0) + fontEngine->ref.ref(); +} + +QT_END_NAMESPACE + +#endif // QT_NO_RAWFONT diff --git a/src/gui/text/qrawfont_win.cpp b/src/gui/text/qrawfont_win.cpp index fb5c6f4..d8acf57 100644 --- a/src/gui/text/qrawfont_win.cpp +++ b/src/gui/text/qrawfont_win.cpp @@ -559,7 +559,7 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData, GUID guid; CoCreateGuid(&guid); - uniqueFamilyName = QString::fromLatin1("f") + QString uniqueFamilyName = QString::fromLatin1("f") + QString::number(guid.Data1, 36) + QLatin1Char('-') + QString::number(guid.Data2, 36) + QLatin1Char('-') + QString::number(guid.Data3, 36) + QLatin1Char('-') @@ -613,6 +613,7 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData, Q_ASSERT(fontEngine->cache_count == 0 && fontEngine->ref == 0); // Override the generated font name + static_cast(fontEngine)->uniqueFamilyName = uniqueFamilyName; fontEngine->fontDef.family = actualFontName; fontEngine->ref.ref(); } @@ -701,50 +702,6 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData, } } -void QRawFontPrivate::platformSetPixelSize(int pixelSize) -{ - if (fontEngine == NULL) - return; - - QFontEngine *oldFontEngine = fontEngine; - -#if !defined(QT_NO_DIRECTWRITE) - if (fontEngine->type() == QFontEngine::Win) -#endif - - { - QFontDef request = fontEngine->fontDef; - QString actualFontName = request.family; - if (!uniqueFamilyName.isEmpty()) - request.family = uniqueFamilyName; - request.pixelSize = pixelSize; - - fontEngine = qt_load_font_engine_win(request); - if (fontEngine != NULL) { - fontEngine->fontDef.family = actualFontName; - fontEngine->ref.ref(); - } - } - -#if !defined(QT_NO_DIRECTWRITE) - else { - QFontEngineDirectWrite *dWriteFE = static_cast(fontEngine); - fontEngine = new QFontEngineDirectWrite(dWriteFE->m_directWriteFactory, - dWriteFE->m_directWriteFontFace, - pixelSize); - - fontEngine->fontDef = dWriteFE->fontDef; - fontEngine->fontDef.pixelSize = pixelSize; - fontEngine->ref.ref(); - } -#endif - - Q_ASSERT(fontEngine != oldFontEngine); - oldFontEngine->ref.deref(); - if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0) - delete oldFontEngine; -} - QT_END_NAMESPACE #endif // QT_NO_RAWFONT diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri index 83be5b4..e5d57d0 100644 --- a/src/gui/text/text.pri +++ b/src/gui/text/text.pri @@ -139,7 +139,8 @@ qpa { SOURCES += \ text/qfont_qpa.cpp \ text/qfontengine_qpa.cpp \ - text/qplatformfontdatabase_qpa.cpp + text/qplatformfontdatabase_qpa.cpp \ + text/qrawfont_qpa.cpp HEADERS += \ text/qplatformfontdatabase_qpa.h -- cgit v0.12 From feabda665de62a0f6a82d831b45926697f30b45b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= Date: Wed, 27 Apr 2011 15:53:28 +0200 Subject: Added QStringRef::toLatin1 and QStringRef::toUtf8 These helper functions make it convenient to avoid making an unnecessary copy of the string before converting it to a QByteArray. The current most obvious way to do this would be: // QStringRef text QByteArray latin1 = text.toString().toLatin1(); Though the copy can also be avoided by doing: const QString textData = QString::fromRawData(text.unicode(), text.size()); QByteArray latin1 = textData.toLatin1(); Now the faster method can be achieved using the new obvious way: QByteArray latin1 = text.toLatin1(); Reviewed-by: Thiago Macieira Reviewed-by: Robin Burchell --- src/corelib/tools/qstring.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ src/corelib/tools/qstring.h | 2 ++ 2 files changed, 43 insertions(+) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 5493ba9..7569555 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -8014,6 +8014,47 @@ QString QStringRef::toString() const { return QString(m_string->unicode() + m_position, m_size); } +/*! + Returns a Latin-1 representation of the string reference as a QByteArray. + + The returned byte array is undefined if the string reference contains + non-Latin1 characters. Those characters may be suppressed or replaced with a + question mark. + + \sa QString::toLatin1(), toUtf8() + \since 4.8 +*/ +QByteArray QStringRef::toLatin1() const +{ + if (!m_string) + return QByteArray(); + return toLatin1_helper(m_string->unicode() + m_position, m_size); +} + +/*! + Returns a UTF-8 representation of the string reference as a QByteArray. + + UTF-8 is a Unicode codec and can represent all characters in a Unicode + string like QString. + + However, in the Unicode range, there are certain codepoints that are not + considered characters. The Unicode standard reserves the last two + codepoints in each Unicode Plane (U+FFFE, U+FFFF, U+1FFFE, U+1FFFF, + U+2FFFE, etc.), as well as 16 codepoints in the range U+FDD0..U+FDDF, + inclusive, as non-characters. If any of those appear in the string, they + may be discarded and will not appear in the UTF-8 representation, or they + may be replaced by one or more replacement characters. + + \sa QString::toUtf8(), toLatin1(), QTextCodec + \since 4.8 +*/ +QByteArray QStringRef::toUtf8() const +{ + if (isNull()) + return QByteArray(); + return QUtf8::convertFromUnicode(m_string->unicode() + m_position, m_size, 0); +} + /*! \relates QStringRef diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 66cfa74..2b3026c 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -1167,6 +1167,8 @@ public: inline void clear() { m_string = 0; m_position = m_size = 0; } QString toString() const; + QByteArray toLatin1() const; + QByteArray toUtf8() const; inline bool isEmpty() const { return m_size == 0; } inline bool isNull() const { return m_string == 0 || m_string->isNull(); } -- cgit v0.12 From ddd253e14318af45e5c56df736028b88257068c4 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 27 Apr 2011 17:02:35 +0200 Subject: Fixes warnings about unused variables Reviewed-by: Samuel --- src/gui/painting/qdrawhelper_sse2.cpp | 4 ---- src/gui/painting/qpaintbuffer.cpp | 10 ---------- src/gui/painting/qpaintengine_x11.cpp | 3 --- src/gui/painting/qpainterpath.cpp | 1 + src/gui/painting/qstroker.cpp | 1 + 5 files changed, 2 insertions(+), 17 deletions(-) diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp index aad6bc9..efc6a61 100644 --- a/src/gui/painting/qdrawhelper_sse2.cpp +++ b/src/gui/painting/qdrawhelper_sse2.cpp @@ -112,8 +112,6 @@ void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl, // First, align dest to 16 bytes: ALIGNMENT_PROLOGUE_16BYTES(dst, x, w) { - quint32 s = src[x]; - s = BYTE_MUL(s, const_alpha); dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], one_minus_const_alpha); } @@ -127,8 +125,6 @@ void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl, } } for (; x(ti); - qreal justificationWidth = 0; - if (si.justified) - justificationWidth = si.width.toReal(); - debug << "Cmd_DrawTextItem:" << pos << " " << text; break; } case QPaintBufferPrivate::Cmd_SystemStateChanged: { diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp index 94828fb..6ba9a99 100644 --- a/src/gui/painting/qpaintengine_x11.cpp +++ b/src/gui/painting/qpaintengine_x11.cpp @@ -1611,8 +1611,6 @@ void QX11PaintEnginePrivate::fillPolygon_dev(const QPointF *polygonPoints, int p && (fill.style() != Qt::NoBrush) && ((has_fill_texture && fill.texture().hasAlpha()) || antialias || !solid_fill || has_alpha_pen != has_alpha_brush)) { - QRect br = tessellator->tessellate((QPointF *)clippedPoints, clippedCount, - mode == QPaintEngine::WindingMode); if (tessellator->size > 0) { XRenderPictureAttributes attrs; attrs.poly_edge = antialias ? PolyEdgeSmooth : PolyEdgeSharp; @@ -1771,7 +1769,6 @@ void QX11PaintEngine::drawPath(const QPainterPath &path) Q_D(QX11PaintEngine); if (path.isEmpty()) return; - QTransform old_matrix = d->matrix; if (d->has_brush) d->fillPath(path, QX11PaintEnginePrivate::BrushGC, true); diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp index 27aed32..9fbac13 100644 --- a/src/gui/painting/qpainterpath.cpp +++ b/src/gui/painting/qpainterpath.cpp @@ -1126,6 +1126,7 @@ void QPainterPath::addText(const QPointF &point, const QFont &f, const QString & QTextEngine *eng = layout.engine(); layout.beginLayout(); QTextLine line = layout.createLine(); + Q_UNUSED(line); layout.endLayout(); const QScriptLine &sl = eng->lines[0]; if (!sl.length || !eng->layoutData) diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp index fca46b4..dd723ed 100644 --- a/src/gui/painting/qstroker.cpp +++ b/src/gui/painting/qstroker.cpp @@ -552,6 +552,7 @@ void QStroker::joinPoints(qfixed focal_x, qfixed focal_y, const QLineF &nextLine // // line to the beginning of the arc segment, (should not be needed). // emitLineTo(qt_real_to_fixed(curve_start.x()), qt_real_to_fixed(curve_start.y())); + Q_UNUSED(curve_start); for (int i=0; i Date: Wed, 27 Apr 2011 18:29:27 +0200 Subject: Fixes warnings In QString, it would comlain that: assuming signed overflow does not occur when assuming that (X - c) > X is always false Changing to unsigned comparison fix the warning Others are about unused variables Reviewed-by: Thiago --- src/corelib/io/qfilesystemengine_unix.cpp | 1 + src/corelib/tools/qlocale.cpp | 2 -- src/corelib/tools/qstring.h | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index c9ebaa4..742b05e 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -356,6 +356,7 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM const QByteArray &path = entry.nativeFilePath(); nativeFilePath = path.constData(); nativeFilePathLength = path.size(); + Q_UNUSED(nativeFilePathLength); } bool entryExists = true; // innocent until proven otherwise diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 5c4085a..c8ed94b 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -2782,8 +2782,6 @@ bool QLocalePrivate::numberToCLocale(const QString &num, if (idx == l) return false; - const QChar _group = group(); - while (idx < l) { const QChar &in = uc[idx]; diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 66cfa74..6418a8c 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -695,9 +695,9 @@ inline QString::QString(const QLatin1String &aLatin1) : d(fromLatin1_helper(aLat inline int QString::length() const { return d->size; } inline const QChar QString::at(int i) const -{ Q_ASSERT(i >= 0 && i < size()); return d->data[i]; } +{ Q_ASSERT(uint(i) < uint(size())); return d->data[i]; } inline const QChar QString::operator[](int i) const -{ Q_ASSERT(i >= 0 && i < size()); return d->data[i]; } +{ Q_ASSERT(uint(i) < uint(size())); return d->data[i]; } inline const QChar QString::operator[](uint i) const { Q_ASSERT(i < uint(size())); return d->data[i]; } inline bool QString::isEmpty() const -- cgit v0.12 From 61c6d66b7efd8de4a83b021e7c4ef2b1a803ece2 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 27 Apr 2011 18:33:54 +0200 Subject: Fixes warnings about unused variables Reviewed-by: Peter Hartmann --- src/network/access/qhttpnetworkconnection.cpp | 1 - src/network/kernel/qhostinfo.cpp | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 83156c6..07dd729 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -117,7 +117,6 @@ QHttpNetworkConnectionPrivate::~QHttpNetworkConnectionPrivate() void QHttpNetworkConnectionPrivate::init() { - Q_Q(QHttpNetworkConnection); for (int i = 0; i < channelCount; i++) { channels[i].setConnection(this->q_func()); channels[i].ssl = encrypt; diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp index a16d4ca..8569817 100644 --- a/src/network/kernel/qhostinfo.cpp +++ b/src/network/kernel/qhostinfo.cpp @@ -290,6 +290,7 @@ QHostInfo QHostInfoPrivate::fromName(const QString &name, QSharedPointer networkSession) { + Q_UNUSED(networkSession); return QHostInfoAgent::fromName(hostName); } #endif -- cgit v0.12 From e8019cf8feb402303e6d253f5ca58bebfda42679 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 27 Apr 2011 18:35:42 +0200 Subject: Fixes warnings about unused variables Reviewed-by: jbache --- src/gui/styles/qcleanlooksstyle.cpp | 16 ---------------- src/gui/styles/qcommonstyle.cpp | 20 -------------------- src/gui/styles/qgtkpainter.cpp | 5 ----- src/gui/styles/qgtkstyle.cpp | 3 --- src/gui/styles/qplastiquestyle.cpp | 11 ----------- src/gui/styles/qwindowsstyle.cpp | 2 -- src/gui/widgets/qdockarealayout.cpp | 5 ----- src/gui/widgets/qdockwidget.cpp | 1 - src/gui/widgets/qplaintextedit.cpp | 1 + src/gui/widgets/qtextedit.cpp | 1 - src/gui/widgets/qworkspace.cpp | 1 - 11 files changed, 1 insertion(+), 65 deletions(-) diff --git a/src/gui/styles/qcleanlooksstyle.cpp b/src/gui/styles/qcleanlooksstyle.cpp index cc5fe10..786aab3 100644 --- a/src/gui/styles/qcleanlooksstyle.cpp +++ b/src/gui/styles/qcleanlooksstyle.cpp @@ -841,7 +841,6 @@ void QCleanlooksStyle::drawPrimitive(PrimitiveElement elem, case PE_PanelButtonTool: painter->save(); if ((option->state & State_Enabled || option->state & State_On) || !(option->state & State_AutoRaise)) { - QRect rect = option->rect; QPen oldPen = painter->pen(); if (widget && widget->inherits("QDockWidgetTitleButton")) { @@ -1241,7 +1240,6 @@ void QCleanlooksStyle::drawPrimitive(PrimitiveElement elem, if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast(option)) { QColor borderColor = darkOutline.lighter(110); QColor alphaCornerColor = mergedColors(borderColor, option->palette.background().color()); - QColor innerShadow = mergedColors(borderColor, option->palette.base().color()); int borderThickness = proxy()->pixelMetric(PM_TabBarBaseOverlap, twf, widget); bool reverse = (twf->direction == Qt::RightToLeft); @@ -1879,7 +1877,6 @@ void QCleanlooksStyle::drawControl(ControlElement element, const QStyleOption *o } else { alphaCornerColor = mergedColors(option->palette.background().color(), borderColor); } - QColor alphaTextColor = mergedColors(option->palette.background().color(), option->palette.text().color()); if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) { painter->fillRect(menuItem->rect, menuBackground); int w = 0; @@ -2220,7 +2217,6 @@ void QCleanlooksStyle::drawControl(ControlElement element, const QStyleOption *o && tabBarAlignment == Qt::AlignLeft); QColor light = tab->palette.light().color(); - QColor midlight = tab->palette.midlight().color(); QColor background = tab->palette.background().color(); int borderThinkness = proxy()->pixelMetric(PM_TabBarBaseOverlap, tab, widget); @@ -2444,14 +2440,6 @@ void QCleanlooksStyle::drawComplexControl(ComplexControl control, const QStyleOp QColor gradientStartColor = option->palette.button().color().lighter(108); QColor gradientStopColor = mergedColors(option->palette.button().color().darker(108), dark.lighter(150), 70); - QColor highlightedGradientStartColor = option->palette.button().color(); - QColor highlightedGradientStopColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 85); - - QColor highlightedDarkInnerBorderColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 35); - QColor highlightedLightInnerBorderColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 58); - - QColor buttonShadowAlpha = option->palette.background().color().darker(105); - QPalette palette = option->palette; switch (control) { @@ -3437,7 +3425,6 @@ void QCleanlooksStyle::drawComplexControl(ComplexControl control, const QStyleOp if (const QStyleOptionSlider *slider = qstyleoption_cast(option)) { QRect groove = proxy()->subControlRect(CC_Slider, option, SC_SliderGroove, widget); QRect handle = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle, widget); - QRect ticks = proxy()->subControlRect(CC_Slider, option, SC_SliderTickmarks, widget); bool horizontal = slider->orientation == Qt::Horizontal; bool ticksAbove = slider->tickPosition & QSlider::TicksAbove; @@ -3539,8 +3526,6 @@ void QCleanlooksStyle::drawComplexControl(ComplexControl control, const QStyleOp QRect pixmapRect(0, 0, handle.width(), handle.height()); QPainter handlePainter(&cache); - QColor highlightedGradientStartColor = option->palette.button().color(); - QColor highlightedGradientStopColor = option->palette.light().color(); QColor gradientStartColor = mergedColors(option->palette.button().color().lighter(155), dark.lighter(155), 50); QColor gradientStopColor = gradientStartColor.darker(108); @@ -3557,7 +3542,6 @@ void QCleanlooksStyle::drawComplexControl(ComplexControl control, const QStyleOp } // gradient fill - QRect innerBorder = gradRect; QRect r = pixmapRect.adjusted(1, 1, -1, -1); qt_cleanlooks_draw_gradient(&handlePainter, gradRect, diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp index 8f99d6a..7944a0b 100644 --- a/src/gui/styles/qcommonstyle.cpp +++ b/src/gui/styles/qcommonstyle.cpp @@ -901,24 +901,6 @@ QSize QCommonStylePrivate::viewItemSize(const QStyleOptionViewItemV4 *option, in return QSize(0, 0); } -static QSizeF viewItemTextLayout(QTextLayout &textLayout, int lineWidth) -{ - qreal height = 0; - qreal widthUsed = 0; - textLayout.beginLayout(); - while (true) { - QTextLine line = textLayout.createLine(); - if (!line.isValid()) - break; - line.setLineWidth(lineWidth); - line.setPosition(QPointF(0, height)); - height += line.height(); - widthUsed = qMax(widthUsed, line.naturalTextWidth()); - } - textLayout.endLayout(); - return QSizeF(widthUsed, height); -} - void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewItemV4 *option, const QRect &rect) const { Q_Q(const QCommonStyle); @@ -936,8 +918,6 @@ void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewIt textLayout.setFont(option->font); textLayout.setText(option->text); - QSizeF textLayoutSize = viewItemTextLayout(textLayout, textRect.width()); - QString elidedText; qreal height = 0; qreal width = 0; diff --git a/src/gui/styles/qgtkpainter.cpp b/src/gui/styles/qgtkpainter.cpp index 68ade04..6258fe4 100644 --- a/src/gui/styles/qgtkpainter.cpp +++ b/src/gui/styles/qgtkpainter.cpp @@ -586,7 +586,6 @@ void QGtkPainter::paintShadow(GtkWidget *gtkWidget, const gchar* part, if (!rect.isValid()) return; - QRect r = rect; QPixmap cache; QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size()) % pmKey; if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) { @@ -605,7 +604,6 @@ void QGtkPainter::paintFlatBox(GtkWidget *gtkWidget, const gchar* part, { if (!rect.isValid()) return; - QRect r = rect; QPixmap cache; QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size()) % pmKey; if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) { @@ -632,7 +630,6 @@ void QGtkPainter::paintExtention(GtkWidget *gtkWidget, if (!rect.isValid()) return; - QRect r = rect; QPixmap cache; QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget) % HexString(gap_pos); @@ -660,7 +657,6 @@ void QGtkPainter::paintOption(GtkWidget *gtkWidget, const QRect &radiorect, if (!rect.isValid()) return; - QRect r = rect; QPixmap cache; QString pixmapName = uniqueName(detail, state, shadow, rect.size()); GdkRectangle gtkCliprect = {0, 0, rect.width(), rect.height()}; @@ -692,7 +688,6 @@ void QGtkPainter::paintCheckbox(GtkWidget *gtkWidget, const QRect &checkrect, if (!rect.isValid()) return; - QRect r = rect; QPixmap cache; QString pixmapName = uniqueName(detail, state, shadow, rect.size()); GdkRectangle gtkCliprect = {0, 0, rect.width(), rect.height()}; diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index 277e302..d6dd527 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -782,7 +782,6 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, GtkStateType state = gtkPainter.gtkState(option); style = gtkTreeHeader->style; GtkArrowType type = GTK_ARROW_UP; - QRect r = header->rect; QImage arrow; // This sorting indicator inversion is intentional, and follows the GNOME HIG. // See http://library.gnome.org/devel/hig-book/stable/controls-lists.html.en#controls-lists-sortable @@ -1857,7 +1856,6 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom editArea.setRight(upRect.left()); } if (spinBox->frame) { - GtkShadowType shadow = GTK_SHADOW_OUT; GtkStateType state = gtkPainter.gtkState(option); if (!(option->state & State_Enabled)) @@ -1867,7 +1865,6 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom else if (state == GTK_STATE_PRELIGHT) state = GTK_STATE_NORMAL; - shadow = GTK_SHADOW_IN; style = gtkPainter.getStyle(gtkSpinButton); diff --git a/src/gui/styles/qplastiquestyle.cpp b/src/gui/styles/qplastiquestyle.cpp index 02ce60e..1d33212 100644 --- a/src/gui/styles/qplastiquestyle.cpp +++ b/src/gui/styles/qplastiquestyle.cpp @@ -2007,14 +2007,10 @@ void QPlastiqueStyle::drawControl(ControlElement element, const QStyleOption *op } else { alphaCornerColor = mergedColors(option->palette.background().color(), borderColor); } - QColor alphaTextColor = mergedColors(option->palette.background().color(), option->palette.text().color()); QColor gradientStartColor = option->palette.button().color().lighter(104); QColor gradientStopColor = option->palette.button().color().darker(105); - QColor shadowGradientStartColor = option->palette.button().color().darker(115); - QColor shadowGradientStopColor = option->palette.button().color().darker(120); - QColor highlightedGradientStartColor = option->palette.button().color().lighter(101); QColor highlightedGradientStopColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 85); @@ -2025,8 +2021,6 @@ void QPlastiqueStyle::drawControl(ControlElement element, const QStyleOption *op QColor highlightedLightInnerBorderColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 58); QColor alphaInnerColor = mergedColors(highlightedDarkInnerBorderColor, option->palette.base().color()); - QColor lightShadow = lightShadowGradientStartColor; - QColor shadow = shadowGradientStartColor; switch (element) { #ifndef QT_NO_TABBAR @@ -3786,10 +3780,6 @@ void QPlastiqueStyle::drawComplexControl(ComplexControl control, const QStyleOpt } QColor gradientStartColor = option->palette.button().color().lighter(104); QColor gradientStopColor = option->palette.button().color().darker(105); - QColor highlightedGradientStartColor = option->palette.button().color().lighter(101); - QColor highlightedGradientStopColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 85); - QColor highlightedDarkInnerBorderColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 35); - QColor highlightedLightInnerBorderColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 58); switch (control) { #ifndef QT_NO_SLIDER @@ -3797,7 +3787,6 @@ void QPlastiqueStyle::drawComplexControl(ComplexControl control, const QStyleOpt if (const QStyleOptionSlider *slider = qstyleoption_cast(option)) { QRect grooveRegion = proxy()->subControlRect(CC_Slider, option, SC_SliderGroove, widget); QRect handle = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle, widget); - QRect ticks = proxy()->subControlRect(CC_Slider, option, SC_SliderTickmarks, widget); bool horizontal = slider->orientation == Qt::Horizontal; bool ticksAbove = slider->tickPosition & QSlider::TicksAbove; bool ticksBelow = slider->tickPosition & QSlider::TicksBelow; diff --git a/src/gui/styles/qwindowsstyle.cpp b/src/gui/styles/qwindowsstyle.cpp index 44f3f92..f61fe67 100644 --- a/src/gui/styles/qwindowsstyle.cpp +++ b/src/gui/styles/qwindowsstyle.cpp @@ -2028,10 +2028,8 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai && tabBarAlignment == Qt::AlignLeft); QColor light = tab->palette.light().color(); - QColor midlight = tab->palette.midlight().color(); QColor dark = tab->palette.dark().color(); QColor shadow = tab->palette.shadow().color(); - QColor background = tab->palette.background().color(); int borderThinkness = proxy()->pixelMetric(PM_TabBarBaseOverlap, tab, widget); if (selected) borderThinkness /= 2; diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp index 223421d..28c0388 100644 --- a/src/gui/widgets/qdockarealayout.cpp +++ b/src/gui/widgets/qdockarealayout.cpp @@ -2100,7 +2100,6 @@ bool QDockAreaLayoutInfo::updateTabBar() const bool gap = false; int tab_idx = 0; - bool changed = false; for (int i = 0; i < item_list.count(); ++i) { const QDockAreaLayoutItem &item = item_list.at(i); if (item.skip()) @@ -2121,7 +2120,6 @@ bool QDockAreaLayoutInfo::updateTabBar() const tabBar->setTabToolTip(tab_idx, title); #endif tabBar->setTabData(tab_idx, id); - changed = true; } else if (qvariant_cast(tabBar->tabData(tab_idx)) != id) { if (tab_idx + 1 < tabBar->count() && qvariant_cast(tabBar->tabData(tab_idx + 1)) == id) @@ -2133,7 +2131,6 @@ bool QDockAreaLayoutInfo::updateTabBar() const #endif tabBar->setTabData(tab_idx, id); } - changed = true; } if (title != tabBar->tabText(tab_idx)) { @@ -2141,7 +2138,6 @@ bool QDockAreaLayoutInfo::updateTabBar() const #ifndef QT_NO_TOOLTIP tabBar->setTabToolTip(tab_idx, title); #endif - changed = true; } ++tab_idx; @@ -2149,7 +2145,6 @@ bool QDockAreaLayoutInfo::updateTabBar() const while (tab_idx < tabBar->count()) { tabBar->removeTab(tab_idx); - changed = true; } tabBar->blockSignals(blocked); diff --git a/src/gui/widgets/qdockwidget.cpp b/src/gui/widgets/qdockwidget.cpp index 9d1a737..16b60c8 100644 --- a/src/gui/widgets/qdockwidget.cpp +++ b/src/gui/widgets/qdockwidget.cpp @@ -161,7 +161,6 @@ void QDockWidgetTitleButton::paintEvent(QPaintEvent *) { QPainter p(this); - QRect r = rect(); QStyleOptionToolButton opt; opt.init(this); opt.state |= QStyle::State_AutoRaise; diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp index 7435691..9871ed3 100644 --- a/src/gui/widgets/qplaintextedit.cpp +++ b/src/gui/widgets/qplaintextedit.cpp @@ -483,6 +483,7 @@ int QPlainTextEditPrivate::verticalOffset(int topBlock, int topLine) const QPlainTextDocumentLayout *documentLayout = qobject_cast(doc->documentLayout()); Q_ASSERT(documentLayout); QRectF r = documentLayout->blockBoundingRect(currentBlock); + Q_UNUSED(r); QTextLayout *layout = currentBlock.layout(); if (layout && topLine <= layout->lineCount()) { QTextLine line = layout->lineAt(topLine - 1); diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp index ff924bf..8df436f 100644 --- a/src/gui/widgets/qtextedit.cpp +++ b/src/gui/widgets/qtextedit.cpp @@ -2614,7 +2614,6 @@ Qt::TextFormat QTextEdit::textFormat() const void QTextEdit::append(const QString &text) { Q_D(QTextEdit); - QTextBlock lastBlock = d->control->document()->lastBlock(); const bool atBottom = isReadOnly() ? d->verticalOffset() >= d->vbar->maximum() : d->control->textCursor().atEnd(); d->control->append(text); diff --git a/src/gui/widgets/qworkspace.cpp b/src/gui/widgets/qworkspace.cpp index bf50d07..13ef13b 100644 --- a/src/gui/widgets/qworkspace.cpp +++ b/src/gui/widgets/qworkspace.cpp @@ -1239,7 +1239,6 @@ QWidget * QWorkspace::addWindow(QWidget *w, Qt::WindowFlags flags) int x = w->x(); int y = w->y(); bool hasPos = w->testAttribute(Qt::WA_Moved); - QSize s = w->size().expandedTo(qSmartMinSize(w)); if (!hasSize && w->sizeHint().isValid()) w->adjustSize(); -- cgit v0.12 From 28061caa38d94de85db9aec743d1efba33c1e46f Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 27 Apr 2011 18:37:28 +0200 Subject: Fixes warnings about unused variables Reviewed-by: Samuel --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 4 ++-- src/gui/graphicsview/qgraphicswidget_p.cpp | 4 ---- src/gui/itemviews/qtableview.cpp | 1 - src/gui/kernel/qgesturemanager.cpp | 1 - src/gui/kernel/qwidget_x11.cpp | 4 +--- src/gui/text/qtextdocumentlayout.cpp | 1 + src/gui/text/qtextlayout.cpp | 2 -- src/gui/util/qflickgesture.cpp | 4 ++-- src/gui/util/qscroller.cpp | 3 --- 9 files changed, 6 insertions(+), 18 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 48cbec3..78918cc 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -451,8 +451,8 @@ static QPair getFactor(qreal valu static qreal interpolate(const QPair &factor, qreal min, qreal minPref, qreal pref, qreal maxPref, qreal max) { - qreal lower; - qreal upper; + qreal lower = 0; + qreal upper = 0; switch (factor.first) { case QGraphicsAnchorLayoutPrivate::MinimumToMinPreferred: diff --git a/src/gui/graphicsview/qgraphicswidget_p.cpp b/src/gui/graphicsview/qgraphicswidget_p.cpp index 4580055..63d7298 100644 --- a/src/gui/graphicsview/qgraphicswidget_p.cpp +++ b/src/gui/graphicsview/qgraphicswidget_p.cpp @@ -857,8 +857,6 @@ void QGraphicsWidgetPrivate::setWidth(qreal w) if (q->geometry().width() == w) return; - QRectF oldGeom = q->geometry(); - q->setGeometry(QRectF(q->x(), q->y(), w, height())); } @@ -882,8 +880,6 @@ void QGraphicsWidgetPrivate::setHeight(qreal h) if (q->geometry().height() == h) return; - QRectF oldGeom = q->geometry(); - q->setGeometry(QRectF(q->x(), q->y(), width(), h)); } diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp index e494ee5..a5eed1d 100644 --- a/src/gui/itemviews/qtableview.cpp +++ b/src/gui/itemviews/qtableview.cpp @@ -1285,7 +1285,6 @@ void QTableView::paintEvent(QPaintEvent *event) const QPen gridPen = QPen(gridColor, 0, d->gridStyle); const QHeaderView *verticalHeader = d->verticalHeader; const QHeaderView *horizontalHeader = d->horizontalHeader; - const QStyle::State state = option.state; const bool alternate = d->alternatingColors; const bool rightToLeft = isRightToLeft(); diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp index 5359fb3..7aa7dffd 100644 --- a/src/gui/kernel/qgesturemanager.cpp +++ b/src/gui/kernel/qgesturemanager.cpp @@ -566,7 +566,6 @@ void QGestureManager::getGestureTargets(const QSet &gestures, = w->d_func()->gestureContext.find(type); if (it != w->d_func()->gestureContext.end()) { // i.e. 'w' listens to gesture 'type' - Qt::GestureFlags flags = it.value(); if (!(it.value() & Qt::DontStartGestureOnChildren) && w != widget) { // conflicting gesture! (*conflicts)[widget].append(gestures[widget]); diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp index 5ece7d6..241a13f 100644 --- a/src/gui/kernel/qwidget_x11.cpp +++ b/src/gui/kernel/qwidget_x11.cpp @@ -486,8 +486,6 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO bool topLevel = (flags & Qt::Window); bool popup = (type == Qt::Popup); - bool dialog = (type == Qt::Dialog - || type == Qt::Sheet); bool desktop = (type == Qt::Desktop); bool tool = (type == Qt::Tool || type == Qt::SplashScreen || type == Qt::ToolTip || type == Qt::Drawer); @@ -553,7 +551,7 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO int sh = DisplayHeight(dpy,scr); if (desktop) { // desktop widget - dialog = popup = false; // force these flags off + popup = false; // force these flags off data.crect.setRect(0, 0, sw, sh); } else if (topLevel && !q->testAttribute(Qt::WA_Resized)) { QDesktopWidget *desktopWidget = qApp->desktop(); diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index ce157be..69ea948 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -3081,6 +3081,7 @@ void QTextDocumentLayoutPrivate::ensureLayouted(QFixed y) const if (currentLazyLayoutPosition == -1) return; const QSizeF oldSize = q->dynamicDocumentSize(); + Q_UNUSED(oldSize); if (checkPoints.isEmpty()) layoutStep(); diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 93f71d3..df4ce97 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -1378,8 +1378,6 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition d->itemize(); QPointF position = pos + d->position; - QFixed pos_x = QFixed::fromReal(position.x()); - QFixed pos_y = QFixed::fromReal(position.y()); cursorPosition = qBound(0, cursorPosition, d->layoutData->string.length()); int line = 0; diff --git a/src/gui/util/qflickgesture.cpp b/src/gui/util/qflickgesture.cpp index fdd2a95..f87c84c 100644 --- a/src/gui/util/qflickgesture.cpp +++ b/src/gui/util/qflickgesture.cpp @@ -218,10 +218,10 @@ public: mouseTarget = 0; } else if (mouseTarget) { // we did send a press, so we need to fake a release now - Qt::MouseButtons mouseButtons = QApplication::mouseButtons(); // release all pressed mouse buttons - /*for (int i = 0; i < 32; ++i) { + /* Qt::MouseButtons mouseButtons = QApplication::mouseButtons(); + for (int i = 0; i < 32; ++i) { if (mouseButtons & (1 << i)) { Qt::MouseButton b = static_cast(1 << i); mouseButtons &= ~b; diff --git a/src/gui/util/qscroller.cpp b/src/gui/util/qscroller.cpp index db128c1..870d56f 100644 --- a/src/gui/util/qscroller.cpp +++ b/src/gui/util/qscroller.cpp @@ -1777,10 +1777,7 @@ void QScrollerPrivate::setState(QScroller::State newstate) */ void QScrollerPrivate::setContentPositionHelperDragging(const QPointF &deltaPos) { - Q_Q(QScroller); - QPointF ppm = q->pixelPerMeter(); const QScrollerPropertiesPrivate *sp = properties.d.data(); - QPointF v = q->velocity(); if (sp->overshootDragResistanceFactor) overshootPosition /= sp->overshootDragResistanceFactor; -- cgit v0.12 From ffe0a2ec7c1f4412792a977401bdc4dbf6c76acd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= Date: Thu, 28 Apr 2011 11:10:24 +0200 Subject: Revert "Added QStringRef::toLatin1 and QStringRef::toUtf8" This reverts commit feabda665de62a0f6a82d831b45926697f30b45b. They were already added by Denis Dzyubenko in commit 2916b074. --- src/corelib/tools/qstring.cpp | 41 ----------------------------------------- src/corelib/tools/qstring.h | 2 -- 2 files changed, 43 deletions(-) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 7569555..5493ba9 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -8014,47 +8014,6 @@ QString QStringRef::toString() const { return QString(m_string->unicode() + m_position, m_size); } -/*! - Returns a Latin-1 representation of the string reference as a QByteArray. - - The returned byte array is undefined if the string reference contains - non-Latin1 characters. Those characters may be suppressed or replaced with a - question mark. - - \sa QString::toLatin1(), toUtf8() - \since 4.8 -*/ -QByteArray QStringRef::toLatin1() const -{ - if (!m_string) - return QByteArray(); - return toLatin1_helper(m_string->unicode() + m_position, m_size); -} - -/*! - Returns a UTF-8 representation of the string reference as a QByteArray. - - UTF-8 is a Unicode codec and can represent all characters in a Unicode - string like QString. - - However, in the Unicode range, there are certain codepoints that are not - considered characters. The Unicode standard reserves the last two - codepoints in each Unicode Plane (U+FFFE, U+FFFF, U+1FFFE, U+1FFFF, - U+2FFFE, etc.), as well as 16 codepoints in the range U+FDD0..U+FDDF, - inclusive, as non-characters. If any of those appear in the string, they - may be discarded and will not appear in the UTF-8 representation, or they - may be replaced by one or more replacement characters. - - \sa QString::toUtf8(), toLatin1(), QTextCodec - \since 4.8 -*/ -QByteArray QStringRef::toUtf8() const -{ - if (isNull()) - return QByteArray(); - return QUtf8::convertFromUnicode(m_string->unicode() + m_position, m_size, 0); -} - /*! \relates QStringRef diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 2b3026c..66cfa74 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -1167,8 +1167,6 @@ public: inline void clear() { m_string = 0; m_position = m_size = 0; } QString toString() const; - QByteArray toLatin1() const; - QByteArray toUtf8() const; inline bool isEmpty() const { return m_size == 0; } inline bool isNull() const { return m_string == 0 || m_string->isNull(); } -- cgit v0.12 From ee9455ed2a83084692d969c398ecb91bcd4fc33a Mon Sep 17 00:00:00 2001 From: Dmitry Zelenkovsky Date: Thu, 28 Apr 2011 11:49:13 +0200 Subject: Support more items for QTextCharFormat::VerticalAlignment enum for custom text objects. * QTextCharFormat::AlignNormal - support text format descent, place text object bottom on (baseline - descent). * QTextCharFormat::AlignBottom - place text object bottom on baseline. * QTextCharFormat::AlignTop - Still not supported. * Any other vertical alignment is mapped QTextCharFormat::AlignBottom. Add new enum AlignBaseline for custom inline objects to take into account font baseline. Merge-request: 2578 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qtextdocumentlayout.cpp | 13 +++++++++++-- src/gui/text/qtextformat.h | 3 ++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index ce157be..130f012 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -2996,10 +2996,19 @@ void QTextDocumentLayout::resizeInlineObject(QTextInlineObject item, int posInDo QSizeF inlineSize = (pos == QTextFrameFormat::InFlow ? intrinsic : QSizeF(0, 0)); item.setWidth(inlineSize.width()); - if (f.verticalAlignment() == QTextCharFormat::AlignMiddle) { + + QFontMetrics m(f.font()); + switch (f.verticalAlignment()) + { + case QTextCharFormat::AlignMiddle: item.setDescent(inlineSize.height() / 2); item.setAscent(inlineSize.height() / 2 - 1); - } else { + break; + case QTextCharFormat::AlignBaseline: + item.setDescent(m.descent()); + item.setAscent(inlineSize.height() - m.descent() - 1); + break; + default: item.setDescent(0); item.setAscent(inlineSize.height() - 1); } diff --git a/src/gui/text/qtextformat.h b/src/gui/text/qtextformat.h index ff28eaa..4f4752a 100644 --- a/src/gui/text/qtextformat.h +++ b/src/gui/text/qtextformat.h @@ -378,7 +378,8 @@ public: AlignSubScript, AlignMiddle, AlignTop, - AlignBottom + AlignBottom, + AlignBaseline }; enum UnderlineStyle { // keep in sync with Qt::PenStyle! NoUnderline, -- cgit v0.12 From 8d4cd52b6981a4e6deea7fdb77f56e40c4f3e6ba Mon Sep 17 00:00:00 2001 From: Martin Petersson Date: Thu, 28 Apr 2011 12:07:07 +0200 Subject: QAbstractSocket: Fix waitForReadyRead infinite loop. Make sure that waitForReadyRead times out if the read buffer is full. Task-number: QTBUG-16123 Reviewed-by: Peter Hartmann --- src/network/socket/qabstractsocket.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index 7af71cc..cfb1413 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -1877,7 +1877,7 @@ bool QAbstractSocket::waitForReadyRead(int msecs) } Q_ASSERT(d->socketEngine); - forever { + do { bool readyToRead = false; bool readyToWrite = false; if (!d->socketEngine->waitForReadOrWrite(&readyToRead, &readyToWrite, true, !d->writeBuffer.isEmpty(), @@ -1904,7 +1904,7 @@ bool QAbstractSocket::waitForReadyRead(int msecs) if (state() != ConnectedState) return false; - } + } while (qt_timeout_value(msecs, stopWatch.elapsed()) > 0); return false; } -- cgit v0.12 From 2fe1f118a791383de68d33a76f72d260f8bda2eb Mon Sep 17 00:00:00 2001 From: Zeno Albisser Date: Thu, 28 Apr 2011 12:50:47 +0200 Subject: fix tst_qscriptengine after merging MR-1149 Reviewed-by: Olivier Goffart --- tests/auto/qscriptengine/tst_qscriptengine.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/qscriptengine/tst_qscriptengine.cpp b/tests/auto/qscriptengine/tst_qscriptengine.cpp index bc4091d..7ba2be2 100644 --- a/tests/auto/qscriptengine/tst_qscriptengine.cpp +++ b/tests/auto/qscriptengine/tst_qscriptengine.cpp @@ -5815,6 +5815,7 @@ void tst_QScriptEngine::dateConversionJSQt() QString qtUTCDateStr = qtDate.toUTC().toString(Qt::ISODate); QString jsUTCDateStr = jsDate.property("toISOString").call(jsDate).toString(); jsUTCDateStr.chop(5); // get rid of milliseconds (".000Z") + jsUTCDateStr.append("Z"); // append the timezone specifier again if (qtUTCDateStr != jsUTCDateStr) QFAIL(qPrintable(jsDate.toString())); secs += 2*60*60; @@ -5829,6 +5830,7 @@ void tst_QScriptEngine::dateConversionQtJS() QScriptValue jsDate = eng.newDate(qtDate); QString jsUTCDateStr = jsDate.property("toISOString").call(jsDate).toString(); jsUTCDateStr.chop(5); // get rid of milliseconds (".000Z") + jsUTCDateStr.append("Z"); // append the timezone specifier again QString qtUTCDateStr = qtDate.toUTC().toString(Qt::ISODate); if (jsUTCDateStr != qtUTCDateStr) QFAIL(qPrintable(qtDate.toString())); -- cgit v0.12 From af9d20680c91f587f4791aa68f3a8b03d3a42be0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Thu, 28 Apr 2011 12:56:35 +0200 Subject: Fixed off-by-one in radial gradient color table index computation. Clamp to GRADIENT_COLOR_TABLE-1, not GRADIENT_COLOR_TABLE-2. Fixes visible error in gradients.qps Reviewed-by: Kim Motoyoshi Kalland --- src/gui/painting/qdrawhelper_p.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index e93d736..fa6ad0b 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -507,11 +507,9 @@ public: const typename Simd::Float32x4 v_dr = Simd::v_dup(op->radial.dr); const typename Simd::Float32x4 v_min = Simd::v_dup(0.0f); - const typename Simd::Float32x4 v_max = Simd::v_dup(GRADIENT_STOPTABLE_SIZE-1.5f); + const typename Simd::Float32x4 v_max = Simd::v_dup(float(GRADIENT_STOPTABLE_SIZE-1)); const typename Simd::Float32x4 v_half = Simd::v_dup(0.5f); - const typename Simd::Float32x4 v_table_size_minus_one = Simd::v_dup(float(GRADIENT_STOPTABLE_SIZE-1)); - const typename Simd::Int32x4 v_repeat_mask = Simd::v_dup(~(uint(0xffffff) << GRADIENT_STOPTABLE_SIZE_SHIFT)); const typename Simd::Int32x4 v_reflect_mask = Simd::v_dup(~(uint(0xffffff) << (GRADIENT_STOPTABLE_SIZE_SHIFT+1))); @@ -524,7 +522,7 @@ public: typename Simd::Vect_buffer_i v_buffer_mask; \ v_buffer_mask.v = Simd::v_greaterOrEqual(det_vec.v, v_min); \ const typename Simd::Float32x4 v_index_local = Simd::v_sub(Simd::v_sqrt(Simd::v_max(v_min, det_vec.v)), b_vec.v); \ - const typename Simd::Float32x4 v_index = Simd::v_add(Simd::v_mul(v_index_local, v_table_size_minus_one), v_half); \ + const typename Simd::Float32x4 v_index = Simd::v_add(Simd::v_mul(v_index_local, v_max), v_half); \ v_buffer_mask.v = Simd::v_and(v_buffer_mask.v, Simd::v_greaterOrEqual(Simd::v_add(v_r0, Simd::v_mul(v_dr, v_index_local)), v_min)); \ typename Simd::Vect_buffer_i index_vec; #define FETCH_RADIAL_LOOP_CLAMP_REPEAT \ -- cgit v0.12 From d5ee1bc752dc8aed717776a80e9e15972dd98065 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Thu, 28 Apr 2011 13:23:42 +0200 Subject: Add missing license headers --- tests/manual/qgraphicslayout/flicker/main.cpp | 41 +++++++++++++++++++++++++ tests/manual/qgraphicslayout/flicker/window.cpp | 41 +++++++++++++++++++++++++ tests/manual/qgraphicslayout/flicker/window.h | 41 +++++++++++++++++++++++++ 3 files changed, 123 insertions(+) diff --git a/tests/manual/qgraphicslayout/flicker/main.cpp b/tests/manual/qgraphicslayout/flicker/main.cpp index 838d45f..7e75c2b 100644 --- a/tests/manual/qgraphicslayout/flicker/main.cpp +++ b/tests/manual/qgraphicslayout/flicker/main.cpp @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + #include #include #include "window.h" diff --git a/tests/manual/qgraphicslayout/flicker/window.cpp b/tests/manual/qgraphicslayout/flicker/window.cpp index d193ad1..ee4db3f 100644 --- a/tests/manual/qgraphicslayout/flicker/window.cpp +++ b/tests/manual/qgraphicslayout/flicker/window.cpp @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + #include "window.h" void SlowWidget::setGeometry(const QRectF &rect) diff --git a/tests/manual/qgraphicslayout/flicker/window.h b/tests/manual/qgraphicslayout/flicker/window.h index df1fc82..b4c42c0 100644 --- a/tests/manual/qgraphicslayout/flicker/window.h +++ b/tests/manual/qgraphicslayout/flicker/window.h @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + #ifndef WINDOW_H #define WINDOW_H -- cgit v0.12 From a690e560b38385ebb9cd83288e8660d2a4ca2fde Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 28 Apr 2011 14:07:47 +0200 Subject: Made the autotest for drawing pixmaps with painter open more fail safe. The autotest relies on QPixmap::grabWindow() which causes random CI failures because it may capture bogus content if some other window comes to foreground, focus is changed, etc. To overcome these false positives the pixmap content comparison is now only done when the captured content is one of the three possible images. If it is anything else, we cannot verify so the case is skipped. Task-number: QT-4002 Reviewed-by: TRUSTME --- tests/auto/qpixmap/tst_qpixmap.cpp | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/tests/auto/qpixmap/tst_qpixmap.cpp b/tests/auto/qpixmap/tst_qpixmap.cpp index d103cb7..0b2f527 100644 --- a/tests/auto/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/qpixmap/tst_qpixmap.cpp @@ -1904,27 +1904,42 @@ private: void tst_QPixmap::drawPixmapWhilePainterOpen() { - int size = 100; + const int delay = 1000; + const int size = 100; + const QColor colors[] = { Qt::red, Qt::blue, Qt::green }; + QPixmap pix(size, size); - pix.fill(Qt::red); + pix.fill(colors[0]); PixmapWidget w(pix); w.show(); QTest::qWaitForWindowShown(&w); - QTest::qWait(1000); + QTest::qWait(delay); QPainter p(&pix); - p.fillRect(0, 0, size, size, Qt::blue); + p.fillRect(0, 0, size, size, colors[1]); w.update(); - QTest::qWait(1000); + QTest::qWait(delay); - p.fillRect(0, 0, size, size, Qt::green); + p.fillRect(0, 0, size, size, colors[2]); w.update(); - QTest::qWait(1000); + QTest::qWait(delay); QPixmap actual = QPixmap::grabWindow(w.effectiveWinId(), 0, 0, size, size); - QVERIFY(lenientCompare(actual, pix)); + // If we captured some bogus content with grabWindow(), the comparison makes no sense + // because it cannot prove the feature is broken. + QPixmap guard(size, size); + bool matchesColors = false; + for (size_t i = 0; i < sizeof(colors) / sizeof(const QColor); ++i) { + guard.fill(colors[i]); + matchesColors |= lenientCompare(actual, guard); + } + if (!matchesColors) { + QSKIP("Skipping verification due to grabWindow() issue", SkipSingle); + } else { + QVERIFY(lenientCompare(actual, pix)); + } } QTEST_MAIN(tst_QPixmap) -- cgit v0.12 From fee052e3e37b3335fe563cb8a1881bf59f9e25d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Thu, 28 Apr 2011 13:58:12 +0200 Subject: Revert "Fix double painting when adding an item into a linear layout" (It did not really fix the issue.) This reverts commit 33f525e636ef8fa64a15d3e66c56adaea0075bda. Conflicts: src/gui/graphicsview/qgraphicslinearlayout.cpp tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp --- src/gui/graphicsview/qgraphicslinearlayout.cpp | 5 +-- tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp | 41 ---------------------- 2 files changed, 1 insertion(+), 45 deletions(-) diff --git a/src/gui/graphicsview/qgraphicslinearlayout.cpp b/src/gui/graphicsview/qgraphicslinearlayout.cpp index 1229379..40f9b1d 100644 --- a/src/gui/graphicsview/qgraphicslinearlayout.cpp +++ b/src/gui/graphicsview/qgraphicslinearlayout.cpp @@ -275,15 +275,12 @@ void QGraphicsLinearLayout::insertItem(int index, QGraphicsLayoutItem *item) qWarning("QGraphicsLinearLayout::insertItem: cannot insert itself"); return; } - d->addChildLayoutItem(item); + Q_ASSERT(item); d->fixIndex(&index); d->engine.insertRow(index, d->orientation); new QGridLayoutItem(&d->engine, item, d->gridRow(index), d->gridColumn(index), 1, 1, 0, index); - //the order of the following instructions is very important because - //invalidating the layout before adding the child item will make the layout happen - //before we try to paint the item invalidate(); } diff --git a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp index e8e2e23..887026c 100644 --- a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp @@ -186,7 +186,6 @@ private slots: void task250119_shortcutContext(); void QT_BUG_6544_tabFocusFirstUnsetWhenRemovingItems(); void QT_BUG_12056_tabFocusFirstUnsetWhenRemovingItems(); - void QT_BUG_13865_doublePaintWhenAddingASubItem(); }; @@ -3367,46 +3366,6 @@ void tst_QGraphicsWidget::QT_BUG_12056_tabFocusFirstUnsetWhenRemovingItems() //This should not crash } - -struct GreenWidget : public QGraphicsWidget -{ - GreenWidget() : count(0) - { - } - - void paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * ) - { - count++; - painter->setPen(Qt::green); - painter->drawRect(option->rect.adjusted(0,0,-1,-1)); - } - - int count; -}; - -void tst_QGraphicsWidget::QT_BUG_13865_doublePaintWhenAddingASubItem() -{ - QGraphicsScene scene; - QGraphicsView view(&scene); - QGraphicsWidget *widget = new QGraphicsWidget; - widget->resize(100, 100); - scene.addItem(widget); - QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(widget); - - view.show(); - QTest::qWaitForWindowShown(&view); - QApplication::processEvents(); - - - GreenWidget *sub = new GreenWidget; - layout->addItem(sub); - - QTest::qWait(100); - QCOMPARE(sub->count, 1); //it should only be painted once - -} - - QTEST_MAIN(tst_QGraphicsWidget) #include "tst_qgraphicswidget.moc" -- cgit v0.12 From c9c54682bcd23598ac7a8db3b10e9f18c978e268 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 28 Apr 2011 15:05:08 +0200 Subject: Fix crash in raster on X11 when text contains unsupported characters We would assume the font engine was a FT engine and do a static cast here, which would cause a crash if the box engine was in use instead. Task-number: QTBUG-17443 Reviewed-by: Samuel --- src/gui/painting/qtextureglyphcache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp index 2420f31..3918ffc 100644 --- a/src/gui/painting/qtextureglyphcache.cpp +++ b/src/gui/painting/qtextureglyphcache.cpp @@ -178,7 +178,7 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g) const { #if defined(Q_WS_X11) - if (m_transform.type() > QTransform::TxTranslate) { + if (m_transform.type() > QTransform::TxTranslate && m_current_fontengine->type() == QFontEngine::Freetype) { QFontEngineFT::GlyphFormat format = QFontEngineFT::Format_None; QImage::Format imageFormat = QImage::Format_Invalid; switch (m_type) { -- cgit v0.12 From 3a10cfc583f30be4dd98e1fcc3463c3d8bc14f31 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 28 Apr 2011 15:32:46 +0200 Subject: Changelog: Qt Designer 4.8 --- dist/changes-4.8.0 | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/dist/changes-4.8.0 b/dist/changes-4.8.0 index fa50f24..b8cc626 100644 --- a/dist/changes-4.8.0 +++ b/dist/changes-4.8.0 @@ -97,9 +97,17 @@ Qt for Windows CE - Assistant - - Designer - + * [QTBUG-18631] Enabled the use of promoted QWidgets in the buddy editor. + * [QTBUG-18120] Fixed saving of the Z-order. + * [QTBUG-13683] Fixed saving of QGridLayout and QFormLayout + by QFormBuilder. + * [QTBUG-10890] Added a filter to the rich text editor dialog. + that simplifies the HTML markup generated. + * [QTBUG-7777] Added support for QIcon::fromTheme. + * [QTBUG-7169] Fixed QtUiTools to be built with the correct + lib-infix. + * [QTBUG-3120] Added support for alignment of box layout items. - Linguist - Linguist GUI -- cgit v0.12 From 7a5e3b9e336efabcf0af1fba1feecf49d000331f Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Thu, 28 Apr 2011 16:06:17 +0200 Subject: Fix tst_Q3ProgressBar::setProgress() Reviewed-by: Jan-Arve --- tests/auto/q3progressbar/tst_q3progressbar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/q3progressbar/tst_q3progressbar.cpp b/tests/auto/q3progressbar/tst_q3progressbar.cpp index 745e2d5..23f3405 100644 --- a/tests/auto/q3progressbar/tst_q3progressbar.cpp +++ b/tests/auto/q3progressbar/tst_q3progressbar.cpp @@ -106,7 +106,7 @@ void tst_Q3ProgressBar::setProgress() { MyCustomProgressBar * m_progressBar = new MyCustomProgressBar(); m_progressBar->show(); - QApplication::processEvents(); + QTest::qWaitForWindowShown(m_progressBar); //case with total steps = 0 m_progressBar->setTotalSteps(0); -- cgit v0.12 From b198fa1cd226df11fbcae28021922e15e745ed1e Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Thu, 28 Apr 2011 16:39:08 +0200 Subject: Disable tst_Q3ComboBox::task231724_clear on Mac Wrong auto-test for this platform. Reviewed-by: Jan-Arve --- tests/auto/q3combobox/tst_q3combobox.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/auto/q3combobox/tst_q3combobox.cpp b/tests/auto/q3combobox/tst_q3combobox.cpp index 17bd861..825acb2 100644 --- a/tests/auto/q3combobox/tst_q3combobox.cpp +++ b/tests/auto/q3combobox/tst_q3combobox.cpp @@ -1004,6 +1004,10 @@ void tst_Q3ComboBox::wheelEvent() void tst_Q3ComboBox::task231724_clear() { +#ifdef Q_WS_MACX + return; // On Mac, we don't use a ListBox for the popup +#endif + Q3ComboBox box; for ( int i = 0; i <50; i++ ) { -- cgit v0.12 From c2adf9395214d711a3a40516c6c2afa64b3b4ca3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 21 Apr 2011 21:14:43 -0400 Subject: wayland: Track wayland changes Pass version number when creating proxies, use wl_ prefix when looking up interfaces and drop wl_egl_display. --- .../wayland_egl/qwaylandeglintegration.cpp | 8 +------- .../wayland_egl/qwaylandeglintegration.h | 3 --- .../gl_integration/wayland_egl/qwaylandeglwindow.cpp | 2 +- src/plugins/platforms/wayland/qwaylanddisplay.cpp | 18 +++++++++--------- src/plugins/platforms/wayland/qwaylandinputdevice.cpp | 2 +- 5 files changed, 12 insertions(+), 21 deletions(-) diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp index 39e7be5..ddd1763 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp @@ -49,7 +49,6 @@ QWaylandEglIntegration::QWaylandEglIntegration(struct wl_display *waylandDisplay) : mWaylandDisplay(waylandDisplay) - , mNativeEglDisplay(wl_egl_display_create(mWaylandDisplay)) { qDebug() << "Using Wayland-EGL"; } @@ -63,7 +62,7 @@ QWaylandEglIntegration::~QWaylandEglIntegration() void QWaylandEglIntegration::initialize() { EGLint major,minor; - mEglDisplay = eglGetDisplay((EGLNativeDisplayType)mNativeEglDisplay); + mEglDisplay = eglGetDisplay(mWaylandDisplay); if (mEglDisplay == NULL) { qWarning("EGL not available"); } else { @@ -84,11 +83,6 @@ EGLDisplay QWaylandEglIntegration::eglDisplay() const return mEglDisplay; } -wl_egl_display * QWaylandEglIntegration::nativeDisplay() const -{ - return mNativeEglDisplay; -} - QWaylandGLIntegration *QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay) { return new QWaylandEglIntegration(waylandDisplay->wl_display()); diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h index bf4c3fe..3a26f97 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h @@ -65,9 +65,6 @@ private: struct wl_display *mWaylandDisplay; EGLDisplay mEglDisplay; - struct wl_egl_display *mNativeEglDisplay; - - }; #endif // QWAYLANDEGLINTEGRATION_H diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp index d7cf0a5..cf52f39 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp @@ -103,7 +103,7 @@ void QWaylandEglWindow::newSurfaceCreated() if (!size.isValid()) size = QSize(0,0); - mWaylandEglWindow = wl_egl_window_create(mEglIntegration->nativeDisplay(),mSurface,size.width(),size.height(),visual); + mWaylandEglWindow = wl_egl_window_create(mSurface,size.width(),size.height(),visual); if (mGLContext) { EGLNativeWindowType window(reinterpret_cast(mWaylandEglWindow)); EGLSurface surface = eglCreateWindowSurface(mEglIntegration->eglDisplay(),mGLContext->eglConfig(),window,NULL); diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp index 1c56561..bd50e64 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp +++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp @@ -252,17 +252,17 @@ void QWaylandDisplay::displayHandleGlobal(uint32_t id, { Q_UNUSED(version); - if (interface == "output") { - struct wl_output *output = wl_output_create(mDisplay, id); + if (interface == "wl_output") { + struct wl_output *output = wl_output_create(mDisplay, id, 1); wl_output_add_listener(output, &outputListener, this); - } else if (interface == "compositor") { - mCompositor = wl_compositor_create(mDisplay, id); - } else if (interface == "shm") { - mShm = wl_shm_create(mDisplay, id); - } else if (interface == "shell"){ - mShell = wl_shell_create(mDisplay, id); + } else if (interface == "wl_compositor") { + mCompositor = wl_compositor_create(mDisplay, id, 1); + } else if (interface == "wl_shm") { + mShm = wl_shm_create(mDisplay, id, 1); + } else if (interface == "wl_shell"){ + mShell = wl_shell_create(mDisplay, id, 1); wl_shell_add_listener(mShell, &shellListener, this); - } else if (interface == "input_device") { + } else if (interface == "wl_input_device") { QWaylandInputDevice *inputDevice = new QWaylandInputDevice(mDisplay, id); mInputDevices.append(inputDevice); diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp index 2d7df1d..f9e7c95 100644 --- a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp +++ b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp @@ -61,7 +61,7 @@ QWaylandInputDevice::QWaylandInputDevice(struct wl_display *display, uint32_t id) : mDisplay(display) - , mInputDevice(wl_input_device_create(display, id)) + , mInputDevice(wl_input_device_create(display, id, 1)) , mPointerFocus(NULL) , mKeyboardFocus(NULL) , mButtons(0) -- cgit v0.12 From 1de8a46d1e11a5fe0eec80ada7592b0f16c17d06 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 29 Apr 2011 07:47:36 +0200 Subject: Fix missing glyphs for large fonts with QStaticText/GL/Freetype MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When rendering fonts that are so large the Freetype engine will fall back to outline rendering, we would sometimes lose glyphs that were at the edge of the texture, because the width of the image returned by QFontEngine::alphaMapForGlyph() includes a margin (which the other font engines do not) and thus it would sometimes be wider than the available area in the cache's texture. This would in turn cause the GL call to copy the glyph into the cache to fail. The correct fix would probably be to make the algorithm used to calculate the width in QFontEngine::alphaMapForGlyph() the same as the algorithm used by the glyph cache (which would mean to remove the margin there), but to minimize the impact in a patch release, we fix the symptom and move the correct fix to next minor release instead. Task-number: QT-4876 Reviewed-by: Jørgen --- src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp index 312d66f..0ffc7af 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp @@ -306,7 +306,7 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph) // time. for (int i = 0; i < maskHeight; ++i) - glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, maskWidth, 1, GL_ALPHA, GL_UNSIGNED_BYTE, mask.scanLine(i)); + glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, qMin(c.w, maskWidth), 1, GL_ALPHA, GL_UNSIGNED_BYTE, mask.scanLine(i)); } } -- cgit v0.12 From 18fcbf7ae41504324cd453ba9b9655f3e94f6495 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Fri, 29 Apr 2011 09:58:30 +0200 Subject: Fix glyph position issue with fallback fonts Task-number: QTBUG-18933 Reviewed-by: Eskil --- src/gui/text/qtextlayout.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 122382f..cb5ba0e 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -2149,6 +2149,9 @@ QList QTextLine::glyphs(int from, int length) const QGlyphLayout subLayout = glyphLayout.mid(start, end - start); glyphLayoutHash.insertMulti(multiFontEngine->engine(which), GlyphInfo(subLayout, pos, flags)); + for (int i = 0; i < subLayout.numGlyphs; i++) + pos += QPointF(subLayout.advances_x[i].toReal(), + subLayout.advances_y[i].toReal()); start = end; which = e; -- cgit v0.12 From cb5e526c6023237c36aac3446a0a18288f39f3a9 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 29 Apr 2011 10:07:12 +0200 Subject: Make sure QFont's resolve mask is copied on compilers with C++0x support The QFont consists of a d pointer and a resolve mask, and they should both be copied in the assignment operator. Task-number: QTBUG-18921 Done-by: Friedemann Kleint --- src/gui/text/qfont.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/text/qfont.h b/src/gui/text/qfont.h index 8dbc746..0c7b6f8 100644 --- a/src/gui/text/qfont.h +++ b/src/gui/text/qfont.h @@ -239,7 +239,7 @@ public: bool isCopyOf(const QFont &) const; #ifdef Q_COMPILER_RVALUE_REFS inline QFont &operator=(QFont &&other) - { qSwap(d, other.d); return *this; } + { qSwap(d, other.d); qSwap(resolve_mask, other.resolve_mask); return *this; } #endif #ifdef Q_WS_WIN -- cgit v0.12 From c85c1ea36cd9ebe6a9ff970d7ba0ce8d08d5b27b Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Wed, 27 Apr 2011 11:48:53 +0200 Subject: QNetworkCookie: allow spaces in unquoted values We should follow http://tools.ietf.org/html/draft-ietf-httpstate-cookie-23 , which says parse the value until reaching the next ';' or the end of the line. Other cookie implementations allow spaces in unquoted values as well. Reviewed-by: Martin Petersson Task-number: QTBUG-18876 --- src/network/access/qnetworkcookie.cpp | 9 +++++---- tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp | 8 ++++++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index 52eb345..eec8507 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -395,8 +395,8 @@ static QPair nextField(const QByteArray &text, int &posi // qdtext = > // quoted-pair = "\" CHAR - // If its NAME=VALUE, retain the value as is - // refer to ttp://bugreports.qt.nokia.com/browse/QTBUG-17746 + // If it is NAME=VALUE, retain the value as is + // refer to http://bugreports.qt.nokia.com/browse/QTBUG-17746 if (isNameValue) second += '"'; ++i; @@ -432,7 +432,9 @@ static QPair nextField(const QByteArray &text, int &posi position = i; for ( ; i < length; ++i) { register char c = text.at(i); - if (c == ',' || c == ';' || isLWS(c)) + // for name value pairs, we want to parse until reaching the next ';' + // and not break when reaching a space char + if (c == ',' || c == ';' || ((isNameValue && (c == '\n' || c == '\r')) || (!isNameValue && isLWS(c)))) break; } @@ -487,7 +489,6 @@ QByteArray QNetworkCookie::toRawForm(RawForm form) const result += '='; if ((d->value.contains(';') || d->value.contains(',') || - d->value.contains(' ') || d->value.contains('"')) && (!d->value.startsWith('"') && !d->value.endsWith('"'))) { diff --git a/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp b/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp index e0c477b..9a58482 100644 --- a/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp +++ b/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp @@ -182,6 +182,14 @@ void tst_QNetworkCookie::parseSingleCookie_data() cookie.setValue("\"\\\"a, b; c\\\"\""); QTest::newRow("with-value-with-special5") << "a = \"\\\"a, b; c\\\"\"" << cookie; + cookie.setValue("b c"); + QTest::newRow("with-value-with-whitespace") << "a = b c" << cookie; + + cookie.setValue("\"b\""); + QTest::newRow("quoted-value") << "a = \"b\"" << cookie; + cookie.setValue("\"b c\""); + QTest::newRow("quoted-value-with-whitespace") << "a = \"b c\"" << cookie; + cookie.setValue("b"); cookie.setSecure(true); QTest::newRow("secure") << "a=b;secure" << cookie; -- cgit v0.12 From 849ebd5eceed33b6abc72aef3085afefc8d927ba Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 29 Apr 2011 10:41:00 +0200 Subject: Fix tst_Q3ProgressBar::setProgress, again Reviewed-by: Jan-Arve --- tests/auto/q3progressbar/tst_q3progressbar.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/auto/q3progressbar/tst_q3progressbar.cpp b/tests/auto/q3progressbar/tst_q3progressbar.cpp index 23f3405..3a0c3e2 100644 --- a/tests/auto/q3progressbar/tst_q3progressbar.cpp +++ b/tests/auto/q3progressbar/tst_q3progressbar.cpp @@ -45,6 +45,7 @@ #include #include #include +#include "../../shared/util.h" //TESTED_CLASS= //TESTED_FILES= @@ -114,10 +115,9 @@ void tst_Q3ProgressBar::setProgress() m_progressBar->paintNumber = 0; m_progressBar->setProgress(m_progressBar->progress() + 1); QCOMPARE(oldValue + 1,m_progressBar->progress()); - QApplication::processEvents(); // It might be > 1 because it is animated. - QVERIFY(m_progressBar->paintNumber >= 1); + QTRY_VERIFY(m_progressBar->paintNumber >= 1); qDebug() << "Animation test: paintNumber =" << m_progressBar->paintNumber; //standard case @@ -125,10 +125,9 @@ void tst_Q3ProgressBar::setProgress() m_progressBar->setProgress(0); m_progressBar->paintNumber = 0; m_progressBar->setProgress(m_progressBar->progress() + 1); - QApplication::processEvents(); // It might be > 1 because other events might cause painting. - QVERIFY(m_progressBar->paintNumber >= 1); + QTRY_VERIFY(m_progressBar->paintNumber >= 1); qDebug() << "Standard test: paintNumber =" << m_progressBar->paintNumber; } -- cgit v0.12 From 31ef8fa6abc2ea23c6f0a996b36494d88aafb0b5 Mon Sep 17 00:00:00 2001 From: mae Date: Fri, 29 Apr 2011 11:44:43 +0200 Subject: Reduce open and stat system calls for QSettings The patch moves the global static QSettings object from QLibrary to QCoreApplication and reduces a few stat and open calls. Without the patch, a large Trolltech.conf was pushed out of the unused settings cache during startup, meaning Trolltech.conf was parsed more than once. Reviewed-by: Liang Qi --- src/corelib/io/qsettings.cpp | 29 +++++------------------------ src/corelib/kernel/qcoreapplication.cpp | 12 ++++++++++++ src/corelib/kernel/qcoreapplication_p.h | 2 ++ src/corelib/plugin/qlibrary.cpp | 13 ++----------- src/gui/kernel/qcursor_x11.cpp | 3 +++ 5 files changed, 24 insertions(+), 35 deletions(-) diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index b084ca5..f43fb31 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -981,23 +981,6 @@ QStringList QSettingsPrivate::splitArgs(const QString &s, int idx) // ************************************************************************ // QConfFileSettingsPrivate -/* - If we don't have the permission to read the file, returns false. - If the file doesn't exist, returns true. -*/ -static bool checkAccess(const QString &name) -{ - QFileInfo fileInfo(name); - - if (fileInfo.exists()) { - QFile file(name); - // if the file exists but we can't open it, report an error - return file.open(QFile::ReadOnly); - } else { - return true; - } -} - void QConfFileSettingsPrivate::initFormat() { extension = (format == QSettings::NativeFormat) ? QLatin1String(".conf") : QLatin1String(".ini"); @@ -1026,18 +1009,13 @@ void QConfFileSettingsPrivate::initFormat() void QConfFileSettingsPrivate::initAccess() { - bool readAccess = false; if (confFiles[spec]) { - readAccess = checkAccess(confFiles[spec]->name); if (format > QSettings::IniFormat) { if (!readFunc) - readAccess = false; + setStatus(QSettings::AccessError); } } - if (!readAccess) - setStatus(QSettings::AccessError); - sync(); // loads the files the first time } @@ -1432,7 +1410,7 @@ void QConfFileSettingsPrivate::syncConfFile(int confFileNo) We can often optimize the read-only case, if the file on disk hasn't changed. */ - if (readOnly) { + if (readOnly && confFile->size > 0) { QFileInfo fileInfo(confFile->name); if (confFile->size == fileInfo.size() && confFile->timeStamp == fileInfo.lastModified()) return; @@ -1455,6 +1433,9 @@ void QConfFileSettingsPrivate::syncConfFile(int confFileNo) if (!file.isOpen()) file.open(QFile::ReadOnly); + if (!createFile && !file.isOpen()) + setStatus(QSettings::AccessError); + #ifdef Q_OS_WIN HANDLE readSemaphore = 0; HANDLE writeSemaphore = 0; diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index be86c58..df8bc59 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -270,6 +270,8 @@ bool QCoreApplicationPrivate::is_app_closing = false; Q_CORE_EXPORT bool qt_locale_initialized = false; +QSettings *QCoreApplicationPrivate::trolltechConf = 0; + Q_CORE_EXPORT uint qGlobalPostedEventsCount() { QThreadData *currentThreadData = QThreadData::current(); @@ -371,6 +373,9 @@ QCoreApplicationPrivate::~QCoreApplicationPrivate() threadData->postEventList.recursion = 0; threadData->quitNow = false; } + + delete trolltechConf; + trolltechConf = 0; } void QCoreApplicationPrivate::createEventDispatcher() @@ -688,6 +693,13 @@ void QCoreApplication::init() } #endif + + /* + Create an instance of Trolltech.conf. This ensures that the settings will not + be thrown out of QSetting's cache for unused settings. + */ + d->trolltechConf = new QSettings(QSettings::UserScope, QLatin1String("Trolltech")); + qt_startup_hook(); } diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h index add2a35..0557f83 100644 --- a/src/corelib/kernel/qcoreapplication_p.h +++ b/src/corelib/kernel/qcoreapplication_p.h @@ -55,6 +55,7 @@ #include "QtCore/qcoreapplication.h" #include "QtCore/qtranslator.h" +#include "QtCore/qsettings.h" #include "private/qobject_p.h" #ifdef Q_OS_SYMBIAN @@ -139,6 +140,7 @@ public: #if defined(QT3_SUPPORT) static bool useQt3Support; #endif + static QSettings *trolltechConf; }; QT_END_NAMESPACE diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp index 80e927b..6f3ee1c 100644 --- a/src/corelib/plugin/qlibrary.cpp +++ b/src/corelib/plugin/qlibrary.cpp @@ -52,6 +52,7 @@ #include #include #include +#include #ifdef Q_OS_MAC # include #endif @@ -408,12 +409,6 @@ static bool qt_unix_query(const QString &library, uint *version, bool *debug, QB typedef QMap LibraryMap; struct LibraryData { - LibraryData() : settings(0) { } - ~LibraryData() { - delete settings; - } - - QSettings *settings; LibraryMap libraryMap; QSet loadedLibs; }; @@ -711,11 +706,7 @@ bool QLibraryPrivate::isPlugin(QSettings *settings) QStringList reg; #ifndef QT_NO_SETTINGS if (!settings) { - settings = libraryData()->settings; - if (!settings) { - settings = new QSettings(QSettings::UserScope, QLatin1String("Trolltech")); - libraryData()->settings = settings; - } + settings = QCoreApplicationPrivate::trolltechConf; } reg = settings->value(regkey).toStringList(); #endif diff --git a/src/gui/kernel/qcursor_x11.cpp b/src/gui/kernel/qcursor_x11.cpp index d0ed98e..0bc7250 100644 --- a/src/gui/kernel/qcursor_x11.cpp +++ b/src/gui/kernel/qcursor_x11.cpp @@ -55,6 +55,9 @@ #endif // QT_NO_XCURSOR #ifndef QT_NO_XFIXES +#ifndef Status +#define Status int +#endif # include #endif // QT_NO_XFIXES -- cgit v0.12 From 244fedd484b022881b906b1bc794d5af19d02843 Mon Sep 17 00:00:00 2001 From: Fabien Freling Date: Fri, 29 Apr 2011 12:26:08 +0200 Subject: Change the repaint() to an update(). Forcing to repaint might cause a recursive repaint. Since there is no apparent reason to directly repaint, we just call update(). Reviewed-by: Richard Moe Gustavsen --- src/gui/kernel/qwidget_mac.mm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 354f05b..8dc9d2e 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -2733,7 +2733,7 @@ QWidget::macCGHandle() const return handle(); } -void qt_mac_repaintParentUnderAlienWidget(QWidget *alienWidget) +void qt_mac_updateParentUnderAlienWidget(QWidget *alienWidget) { QWidget *nativeParent = alienWidget->nativeParentWidget(); if (!nativeParent) @@ -2741,7 +2741,7 @@ void qt_mac_repaintParentUnderAlienWidget(QWidget *alienWidget) QPoint globalPos = alienWidget->mapToGlobal(QPoint(0, 0)); QRect dirtyRect = QRect(nativeParent->mapFromGlobal(globalPos), alienWidget->size()); - nativeParent->repaint(dirtyRect); + nativeParent->update(dirtyRect); } void QWidget::destroy(bool destroyWindow, bool destroySubWindows) @@ -2752,7 +2752,7 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows) if (!isWindow() && parentWidget()) parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry())); if (!internalWinId()) - qt_mac_repaintParentUnderAlienWidget(this); + qt_mac_updateParentUnderAlienWidget(this); d->deactivateWidgetCleanup(); qt_mac_event_release(this); if(testAttribute(Qt::WA_WState_Created)) { @@ -3683,7 +3683,7 @@ void QWidgetPrivate::hide_sys() [view setHidden:YES]; } else { // INVARIANT: q is alien. Repaint where q is placed instead: - qt_mac_repaintParentUnderAlienWidget(q); + qt_mac_updateParentUnderAlienWidget(q); } #endif } -- cgit v0.12 From 10fd0d3e5c88c7b0265db3acdd75cb3d6f35ee63 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 21 Apr 2011 17:22:13 +0200 Subject: use the Hash typedef Reviewed-by: thiago Reviewed-by: dt --- src/corelib/io/qprocess.cpp | 12 ++++++------ src/corelib/io/qprocess_unix.cpp | 6 +++--- src/corelib/io/qprocess_win.cpp | 8 ++++---- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index a45225f..d18571c 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -190,8 +190,8 @@ template<> void QSharedDataPointer::detach() QStringList QProcessEnvironmentPrivate::toList() const { QStringList result; - QHash::ConstIterator it = hash.constBegin(), - end = hash.constEnd(); + Hash::ConstIterator it = hash.constBegin(), + end = hash.constEnd(); for ( ; it != end; ++it) { QString data = nameToString(it.key()); QString value = valueToString(it.value()); @@ -224,8 +224,8 @@ QProcessEnvironment QProcessEnvironmentPrivate::fromList(const QStringList &list QStringList QProcessEnvironmentPrivate::keys() const { QStringList result; - QHash::ConstIterator it = hash.constBegin(), - end = hash.constEnd(); + Hash::ConstIterator it = hash.constBegin(), + end = hash.constEnd(); for ( ; it != end; ++it) result << nameToString(it.key()); return result; @@ -233,8 +233,8 @@ QStringList QProcessEnvironmentPrivate::keys() const void QProcessEnvironmentPrivate::insert(const Hash &h) { - QHash::ConstIterator it = h.constBegin(), - end = h.constEnd(); + Hash::ConstIterator it = h.constBegin(), + end = h.constEnd(); for ( ; it != end; ++it) hash.insert(it.key(), it.value()); } diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 3af9b46..47b4963 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -453,7 +453,7 @@ bool QProcessPrivate::createChannel(Channel &channel) } } -static char **_q_dupEnvironment(const QHash &environment, int *envc) +static char **_q_dupEnvironment(const QProcessEnvironmentPrivate::Hash &environment, int *envc) { *envc = 0; if (environment.isEmpty()) @@ -475,8 +475,8 @@ static char **_q_dupEnvironment(const QHash &environment envp[environment.count()] = 0; envp[environment.count() + 1] = 0; - QHash::ConstIterator it = environment.constBegin(); - const QHash::ConstIterator end = environment.constEnd(); + QProcessEnvironmentPrivate::Hash::ConstIterator it = environment.constBegin(); + const QProcessEnvironmentPrivate::Hash::ConstIterator end = environment.constEnd(); for ( ; it != end; ++it) { QByteArray key = it.key(); QByteArray value = it.value(); diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index 625ed98..74d8926 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -278,11 +278,11 @@ static QString qt_create_commandline(const QString &program, const QStringList & return args; } -static QByteArray qt_create_environment(const QHash &environment) +static QByteArray qt_create_environment(const QProcessEnvironmentPrivate::Hash &environment) { QByteArray envlist; if (!environment.isEmpty()) { - QHash copy = environment; + QProcessEnvironmentPrivate::Hash copy = environment; // add PATH if necessary (for DLL loading) if (!copy.contains(QLatin1String("PATH"))) { @@ -299,8 +299,8 @@ static QByteArray qt_create_environment(const QHash &environme } int pos = 0; - QHash::ConstIterator it = copy.constBegin(), - end = copy.constEnd(); + QProcessEnvironmentPrivate::Hash::ConstIterator it = copy.constBegin(), + end = copy.constEnd(); static const wchar_t equal = L'='; static const wchar_t nul = L'\0'; -- cgit v0.12 From 6a53f17c7039f1a5405912a4a645572e215410bb Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 21 Apr 2011 17:31:06 +0200 Subject: minor optimization: use QList::reserve() Reviewed-by: thiago Reviewed-by: dt --- src/corelib/io/qprocess.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index d18571c..868c86d 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -190,6 +190,7 @@ template<> void QSharedDataPointer::detach() QStringList QProcessEnvironmentPrivate::toList() const { QStringList result; + result.reserve(hash.size()); Hash::ConstIterator it = hash.constBegin(), end = hash.constEnd(); for ( ; it != end; ++it) { @@ -224,6 +225,7 @@ QProcessEnvironment QProcessEnvironmentPrivate::fromList(const QStringList &list QStringList QProcessEnvironmentPrivate::keys() const { QStringList result; + result.reserve(hash.size()); Hash::ConstIterator it = hash.constBegin(), end = hash.constEnd(); for ( ; it != end; ++it) -- cgit v0.12 From e989a4d375b279b3ea61139cb07596e0e4b79e28 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 21 Apr 2011 17:30:13 +0200 Subject: remove unused functions Reviewed-by: thiago Reviewed-by: dt --- src/corelib/io/qprocess.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 868c86d..f82a872 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -146,33 +146,21 @@ QT_BEGIN_NAMESPACE #ifdef Q_OS_WIN static inline QProcessEnvironmentPrivate::Unit prepareName(const QString &name) { return name.toUpper(); } -static inline QProcessEnvironmentPrivate::Unit prepareName(const QByteArray &name) -{ return QString::fromLocal8Bit(name).toUpper(); } static inline QString nameToString(const QProcessEnvironmentPrivate::Unit &name) { return name; } static inline QProcessEnvironmentPrivate::Unit prepareValue(const QString &value) { return value; } -static inline QProcessEnvironmentPrivate::Unit prepareValue(const QByteArray &value) -{ return QString::fromLocal8Bit(value); } static inline QString valueToString(const QProcessEnvironmentPrivate::Unit &value) { return value; } -static inline QByteArray valueToByteArray(const QProcessEnvironmentPrivate::Unit &value) -{ return value.toLocal8Bit(); } #else -static inline QProcessEnvironmentPrivate::Unit prepareName(const QByteArray &name) -{ return name; } static inline QProcessEnvironmentPrivate::Unit prepareName(const QString &name) { return name.toLocal8Bit(); } static inline QString nameToString(const QProcessEnvironmentPrivate::Unit &name) { return QString::fromLocal8Bit(name); } -static inline QProcessEnvironmentPrivate::Unit prepareValue(const QByteArray &value) -{ return value; } static inline QProcessEnvironmentPrivate::Unit prepareValue(const QString &value) { return value.toLocal8Bit(); } static inline QString valueToString(const QProcessEnvironmentPrivate::Unit &value) { return QString::fromLocal8Bit(value); } -static inline QByteArray valueToByteArray(const QProcessEnvironmentPrivate::Unit &value) -{ return value; } #endif template<> void QSharedDataPointer::detach() -- cgit v0.12 From 11a79c65ea992be0e2ede7dc8f60660c9190291f Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 21 Apr 2011 17:50:40 +0200 Subject: split QProcessEnvironmentPrivate::Unit into Key and Value Reviewed-by: thiago Reviewed-by: dt --- src/corelib/io/qprocess.cpp | 16 ++++++++-------- src/corelib/io/qprocess_p.h | 9 ++++++--- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index f82a872..ecad92c 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -144,22 +144,22 @@ QT_BEGIN_NAMESPACE \sa QProcess, QProcess::systemEnvironment(), QProcess::setProcessEnvironment() */ #ifdef Q_OS_WIN -static inline QProcessEnvironmentPrivate::Unit prepareName(const QString &name) +static inline QProcessEnvironmentPrivate::Key prepareName(const QString &name) { return name.toUpper(); } -static inline QString nameToString(const QProcessEnvironmentPrivate::Unit &name) +static inline QString nameToString(const QProcessEnvironmentPrivate::Key &name) { return name; } -static inline QProcessEnvironmentPrivate::Unit prepareValue(const QString &value) +static inline QProcessEnvironmentPrivate::Value prepareValue(const QString &value) { return value; } -static inline QString valueToString(const QProcessEnvironmentPrivate::Unit &value) +static inline QString valueToString(const QProcessEnvironmentPrivate::Value &value) { return value; } #else -static inline QProcessEnvironmentPrivate::Unit prepareName(const QString &name) +static inline QProcessEnvironmentPrivate::Key prepareName(const QString &name) { return name.toLocal8Bit(); } -static inline QString nameToString(const QProcessEnvironmentPrivate::Unit &name) +static inline QString nameToString(const QProcessEnvironmentPrivate::Key &name) { return QString::fromLocal8Bit(name); } -static inline QProcessEnvironmentPrivate::Unit prepareValue(const QString &value) +static inline QProcessEnvironmentPrivate::Value prepareValue(const QString &value) { return value.toLocal8Bit(); } -static inline QString valueToString(const QProcessEnvironmentPrivate::Unit &value) +static inline QString valueToString(const QProcessEnvironmentPrivate::Value &value) { return QString::fromLocal8Bit(value); } #endif diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h index 7bfcb31..b2a69ef 100644 --- a/src/corelib/io/qprocess_p.h +++ b/src/corelib/io/qprocess_p.h @@ -85,11 +85,14 @@ class QProcessEnvironmentPrivate: public QSharedData { public: #ifdef Q_OS_WIN - typedef QString Unit; + typedef QString Key; + typedef QString Value; #else - typedef QByteArray Unit; + typedef QByteArray Key; + typedef QByteArray Value; #endif - typedef QHash Hash; + + typedef QHash Hash; Hash hash; static QProcessEnvironment fromList(const QStringList &list); -- cgit v0.12 From f3db5603871928ebed43a085a496397e65952b39 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 21 Apr 2011 18:32:36 +0200 Subject: make QProcessEnvironment on Windows preserve variable name case MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit while windows itself does not care which case the variable names are in, they may be passed to unix tools which *do* care. note that this uses true case folding for string comparisons while windows uses uppercasing. this means that "ess" and "eß" will be considered the same by us, while not by windows. this is not expected to have real-world impact, particularly because non-ascii variable names are not used much. Task-number: QTCREATORBUG-3110 Reviewed-by: thiago Reviewed-by: dt --- src/corelib/io/qprocess.cpp | 2 +- src/corelib/io/qprocess_p.h | 14 +++++++++++++- src/corelib/io/qprocess_win.cpp | 12 +++++++----- tests/auto/qprocessenvironment/tst_qprocessenvironment.cpp | 13 +++++++------ 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index ecad92c..20efeae 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -145,7 +145,7 @@ QT_BEGIN_NAMESPACE */ #ifdef Q_OS_WIN static inline QProcessEnvironmentPrivate::Key prepareName(const QString &name) -{ return name.toUpper(); } +{ return QProcessEnvironmentPrivate::Key(name); } static inline QString nameToString(const QProcessEnvironmentPrivate::Key &name) { return name; } static inline QProcessEnvironmentPrivate::Value prepareValue(const QString &value) diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h index b2a69ef..2d4c556 100644 --- a/src/corelib/io/qprocess_p.h +++ b/src/corelib/io/qprocess_p.h @@ -85,7 +85,15 @@ class QProcessEnvironmentPrivate: public QSharedData { public: #ifdef Q_OS_WIN - typedef QString Key; + class Key : public QString + { + public: + Key() {} + explicit Key(const QString &other) : QString(other) {} + Key(const Key &other) : QString(other) {} + bool operator==(const Key &other) const { return !compare(other, Qt::CaseInsensitive); } + }; + typedef QString Value; #else typedef QByteArray Key; @@ -100,6 +108,10 @@ public: QStringList keys() const; void insert(const Hash &hash); }; +#ifdef Q_OS_WIN +Q_DECLARE_TYPEINFO(QProcessEnvironmentPrivate::Key, Q_MOVABLE_TYPE); +inline uint qHash(const QProcessEnvironmentPrivate::Key &key) { return qHash(key.toCaseFolded()); } +#endif class QProcessPrivate : public QIODevicePrivate { diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index 74d8926..82043a5 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -285,17 +285,19 @@ static QByteArray qt_create_environment(const QProcessEnvironmentPrivate::Hash & QProcessEnvironmentPrivate::Hash copy = environment; // add PATH if necessary (for DLL loading) - if (!copy.contains(QLatin1String("PATH"))) { + QProcessEnvironmentPrivate::Key pathKey(QLatin1String("PATH")); + if (!copy.contains(pathKey)) { QByteArray path = qgetenv("PATH"); if (!path.isEmpty()) - copy.insert(QLatin1String("PATH"), QString::fromLocal8Bit(path)); + copy.insert(pathKey, QString::fromLocal8Bit(path)); } // add systemroot if needed - if (!copy.contains(QLatin1String("SYSTEMROOT"))) { - QByteArray systemRoot = qgetenv("SYSTEMROOT"); + QProcessEnvironmentPrivate::Key rootKey(QLatin1String("SystemRoot")); + if (!copy.contains(rootKey)) { + QByteArray systemRoot = qgetenv("SystemRoot"); if (!systemRoot.isEmpty()) - copy.insert(QLatin1String("SYSTEMROOT"), QString::fromLocal8Bit(systemRoot)); + copy.insert(rootKey, QString::fromLocal8Bit(systemRoot)); } int pos = 0; diff --git a/tests/auto/qprocessenvironment/tst_qprocessenvironment.cpp b/tests/auto/qprocessenvironment/tst_qprocessenvironment.cpp index 1c26343..98d4890 100644 --- a/tests/auto/qprocessenvironment/tst_qprocessenvironment.cpp +++ b/tests/auto/qprocessenvironment/tst_qprocessenvironment.cpp @@ -43,10 +43,6 @@ #include #include -// Note: -// in cross-platform tests, ALWAYS use UPPERCASE variable names -// That's because on Windows, the variables are uppercased - class tst_QProcessEnvironment: public QObject { Q_OBJECT @@ -214,7 +210,7 @@ void tst_QProcessEnvironment::caseSensitivity() e.insert("foo", "bar"); #ifdef Q_OS_WIN - // on Windows, it's uppercased + // Windows is case-insensitive, but case-preserving QVERIFY(e.contains("foo")); QVERIFY(e.contains("FOO")); QVERIFY(e.contains("FoO")); @@ -223,8 +219,12 @@ void tst_QProcessEnvironment::caseSensitivity() QCOMPARE(e.value("FOO"), QString("bar")); QCOMPARE(e.value("FoO"), QString("bar")); + // Per Windows, this overwrites the value, but keeps the name's original capitalization + e.insert("Foo", "Bar"); + QStringList list = e.toStringList(); - QCOMPARE(list.at(0), QString("FOO=bar")); + QCOMPARE(list.length(), 1); + QCOMPARE(list.at(0), QString("foo=Bar")); #else // otherwise, it's case sensitive QVERIFY(e.contains("foo")); @@ -236,6 +236,7 @@ void tst_QProcessEnvironment::caseSensitivity() QCOMPARE(e.value("foo"), QString("bar")); QStringList list = e.toStringList(); + QCOMPARE(list.length(), 2); QVERIFY(list.contains("foo=bar")); QVERIFY(list.contains("FOO=baz")); #endif -- cgit v0.12 From a2d70d71c8c7652ded41d5d603672c3927df44e6 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 21 Apr 2011 19:04:02 +0200 Subject: move key/value converters to the private class this will enable them to access other members later Reviewed-by: thiago Reviewed-by: dt --- src/corelib/io/qprocess.cpp | 29 +++++------------------------ src/corelib/io/qprocess_p.h | 10 ++++++++++ 2 files changed, 15 insertions(+), 24 deletions(-) diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 20efeae..ffd5ff0 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -143,25 +143,6 @@ QT_BEGIN_NAMESPACE \sa QProcess, QProcess::systemEnvironment(), QProcess::setProcessEnvironment() */ -#ifdef Q_OS_WIN -static inline QProcessEnvironmentPrivate::Key prepareName(const QString &name) -{ return QProcessEnvironmentPrivate::Key(name); } -static inline QString nameToString(const QProcessEnvironmentPrivate::Key &name) -{ return name; } -static inline QProcessEnvironmentPrivate::Value prepareValue(const QString &value) -{ return value; } -static inline QString valueToString(const QProcessEnvironmentPrivate::Value &value) -{ return value; } -#else -static inline QProcessEnvironmentPrivate::Key prepareName(const QString &name) -{ return name.toLocal8Bit(); } -static inline QString nameToString(const QProcessEnvironmentPrivate::Key &name) -{ return QString::fromLocal8Bit(name); } -static inline QProcessEnvironmentPrivate::Value prepareValue(const QString &value) -{ return value.toLocal8Bit(); } -static inline QString valueToString(const QProcessEnvironmentPrivate::Value &value) -{ return QString::fromLocal8Bit(value); } -#endif template<> void QSharedDataPointer::detach() { @@ -321,7 +302,7 @@ void QProcessEnvironment::clear() */ bool QProcessEnvironment::contains(const QString &name) const { - return d ? d->hash.contains(prepareName(name)) : false; + return d ? d->hash.contains(d->prepareName(name)) : false; } /*! @@ -343,7 +324,7 @@ bool QProcessEnvironment::contains(const QString &name) const void QProcessEnvironment::insert(const QString &name, const QString &value) { // d detaches from null - d->hash.insert(prepareName(name), prepareValue(value)); + d->hash.insert(d->prepareName(name), d->prepareValue(value)); } /*! @@ -360,7 +341,7 @@ void QProcessEnvironment::insert(const QString &name, const QString &value) void QProcessEnvironment::remove(const QString &name) { if (d) - d->hash.remove(prepareName(name)); + d->hash.remove(d->prepareName(name)); } /*! @@ -379,11 +360,11 @@ QString QProcessEnvironment::value(const QString &name, const QString &defaultVa if (!d) return defaultValue; - QProcessEnvironmentPrivate::Hash::ConstIterator it = d->hash.constFind(prepareName(name)); + QProcessEnvironmentPrivate::Hash::ConstIterator it = d->hash.constFind(d->prepareName(name)); if (it == d->hash.constEnd()) return defaultValue; - return valueToString(it.value()); + return d->valueToString(it.value()); } /*! diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h index 2d4c556..14fc9f3 100644 --- a/src/corelib/io/qprocess_p.h +++ b/src/corelib/io/qprocess_p.h @@ -95,9 +95,19 @@ public: }; typedef QString Value; + + inline Key prepareName(const QString &name) const { return Key(name); } + inline QString nameToString(const Key &name) const { return name; } + inline Value prepareValue(const QString &value) const { return value; } + inline QString valueToString(const Value &value) const { return value; } #else typedef QByteArray Key; typedef QByteArray Value; + + inline Key prepareName(const QString &name) const { return name.toLocal8Bit(); } + inline QString nameToString(const Key &name) const { return QString::fromLocal8Bit(name); } + inline Value prepareValue(const QString &value) const { return value.toLocal8Bit(); } + inline QString valueToString(const Value &value) const { return QString::fromLocal8Bit(value); } #endif typedef QHash Hash; -- cgit v0.12 From 18f1613aa8ece72d24ac10e28f06e3db1d8ce400 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 28 Apr 2011 10:53:14 +0200 Subject: make QProcessEnvironment on Unix cache converted variable names the converted keys also cache their hash, as they are used only for the purpose of looking up in a qhash. Reviewed-by: thiago Reviewed-by: dt --- src/corelib/io/qprocess.cpp | 17 +++++++++++++---- src/corelib/io/qprocess_p.h | 40 +++++++++++++++++++++++++++++++++++----- src/corelib/io/qprocess_unix.cpp | 4 ++-- 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index ffd5ff0..80e0b0f 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -202,12 +202,19 @@ QStringList QProcessEnvironmentPrivate::keys() const return result; } -void QProcessEnvironmentPrivate::insert(const Hash &h) +void QProcessEnvironmentPrivate::insert(const QProcessEnvironmentPrivate &other) { - Hash::ConstIterator it = h.constBegin(), - end = h.constEnd(); + Hash::ConstIterator it = other.hash.constBegin(), + end = other.hash.constEnd(); for ( ; it != end; ++it) hash.insert(it.key(), it.value()); + +#ifdef Q_OS_UNIX + QHash::ConstIterator nit = other.nameMap.constBegin(), + nend = other.nameMap.constEnd(); + for ( ; nit != nend; ++nit) + nameMap.insert(nit.key(), nit.value()); +#endif } /*! @@ -288,6 +295,8 @@ void QProcessEnvironment::clear() { if (d) d->hash.clear(); + // Unix: Don't clear d->nameMap, as the environment is likely to be + // re-populated with the same keys again. } /*! @@ -409,7 +418,7 @@ void QProcessEnvironment::insert(const QProcessEnvironment &e) return; // d detaches from null - d->insert(e.d->hash); + d->insert(*e.d); } void QProcessPrivate::Channel::clear() diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h index 14fc9f3..9a9981e 100644 --- a/src/corelib/io/qprocess_p.h +++ b/src/corelib/io/qprocess_p.h @@ -101,11 +101,33 @@ public: inline Value prepareValue(const QString &value) const { return value; } inline QString valueToString(const Value &value) const { return value; } #else - typedef QByteArray Key; + class Key + { + public: + Key() : hash(0) {} + explicit Key(const QByteArray &other) : key(other), hash(qHash(key)) {} + Key(const Key &other) { *this = other; } + bool operator==(const Key &other) const { return key == other.key; } + + QByteArray key; + uint hash; + }; + typedef QByteArray Value; - inline Key prepareName(const QString &name) const { return name.toLocal8Bit(); } - inline QString nameToString(const Key &name) const { return QString::fromLocal8Bit(name); } + inline Key prepareName(const QString &name) const + { + Key &ent = nameMap[name]; + if (ent.key.isEmpty()) + ent = Key(name.toLocal8Bit()); + return ent; + } + inline QString nameToString(const Key &name) const + { + const QString sname = QString::fromLocal8Bit(name.key); + nameMap[sname] = name; + return sname; + } inline Value prepareValue(const QString &value) const { return value.toLocal8Bit(); } inline QString valueToString(const Value &value) const { return QString::fromLocal8Bit(value); } #endif @@ -113,14 +135,22 @@ public: typedef QHash Hash; Hash hash; +#ifdef Q_OS_UNIX + typedef QHash NameHash; + mutable NameHash nameMap; +#endif + static QProcessEnvironment fromList(const QStringList &list); QStringList toList() const; QStringList keys() const; - void insert(const Hash &hash); + void insert(const QProcessEnvironmentPrivate &other); }; -#ifdef Q_OS_WIN Q_DECLARE_TYPEINFO(QProcessEnvironmentPrivate::Key, Q_MOVABLE_TYPE); + +#ifdef Q_OS_WIN inline uint qHash(const QProcessEnvironmentPrivate::Key &key) { return qHash(key.toCaseFolded()); } +#else +inline uint qHash(const QProcessEnvironmentPrivate::Key &key) { return key.hash; } #endif class QProcessPrivate : public QIODevicePrivate diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 47b4963..b79054a 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -469,7 +469,7 @@ static char **_q_dupEnvironment(const QProcessEnvironmentPrivate::Hash &environm #endif const QByteArray envLibraryPath = qgetenv(libraryPath); bool needToAddLibraryPath = !envLibraryPath.isEmpty() && - !environment.contains(libraryPath); + !environment.contains(QProcessEnvironmentPrivate::Key(QByteArray(libraryPath))); char **envp = new char *[environment.count() + 2]; envp[environment.count()] = 0; @@ -478,7 +478,7 @@ static char **_q_dupEnvironment(const QProcessEnvironmentPrivate::Hash &environm QProcessEnvironmentPrivate::Hash::ConstIterator it = environment.constBegin(); const QProcessEnvironmentPrivate::Hash::ConstIterator end = environment.constEnd(); for ( ; it != end; ++it) { - QByteArray key = it.key(); + QByteArray key = it.key().key; QByteArray value = it.value(); key.reserve(key.length() + 1 + value.length()); key.append('='); -- cgit v0.12 From 60194ad0ea68d7c82b4729119d122dcfeb909842 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 21 Apr 2011 21:30:34 +0200 Subject: make QProcessEnvironment::systemEnvironment() encoding-safe on unix, don't do the roundtrip over unicode. on windows, use the WinAPI unicode environment instead of the 8-bit CRT environment. Reviewed-by: thiago Reviewed-by: dt --- src/corelib/io/qprocess.cpp | 17 ++--------------- src/corelib/io/qprocess_unix.cpp | 17 +++++++++++++++++ src/corelib/io/qprocess_win.cpp | 20 ++++++++++++++++++++ 3 files changed, 39 insertions(+), 15 deletions(-) diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 80e0b0f..9ce9fd8 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -2301,6 +2301,8 @@ QStringList QProcess::systemEnvironment() } /*! + \fn QProcessEnvironment QProcessEnvironment::systemEnvironment() + \since 4.6 \brief The systemEnvironment function returns the environment of @@ -2316,21 +2318,6 @@ QStringList QProcess::systemEnvironment() \sa QProcess::systemEnvironment() */ -QProcessEnvironment QProcessEnvironment::systemEnvironment() -{ - QProcessEnvironment env; - const char *entry; - for (int count = 0; (entry = environ[count]); ++count) { - const char *equal = strchr(entry, '='); - if (!equal) - continue; - - QByteArray name(entry, equal - entry); - QByteArray value(equal + 1); - env.insert(QString::fromLocal8Bit(name), QString::fromLocal8Bit(value)); - } - return env; -} /*! \typedef Q_PID diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index b79054a..451bf61 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -453,6 +453,23 @@ bool QProcessPrivate::createChannel(Channel &channel) } } +QProcessEnvironment QProcessEnvironment::systemEnvironment() +{ + QProcessEnvironment env; + const char *entry; + for (int count = 0; (entry = environ[count]); ++count) { + const char *equal = strchr(entry, '='); + if (!equal) + continue; + + QByteArray name(entry, equal - entry); + QByteArray value(equal + 1); + env.d->hash.insert(QProcessEnvironmentPrivate::Key(name), + QProcessEnvironmentPrivate::Value(value)); + } + return env; +} + static char **_q_dupEnvironment(const QProcessEnvironmentPrivate::Hash &environment, int *envc) { *envc = 0; diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index 82043a5..7739bbd 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -278,6 +278,26 @@ static QString qt_create_commandline(const QString &program, const QStringList & return args; } +QProcessEnvironment QProcessEnvironment::systemEnvironment() +{ + QProcessEnvironment env; + // Calls to setenv() affect the low-level environment as well. + // This is not the case the other way round. + wchar_t *envStrings = GetEnvironmentStringsW(); + for (const wchar_t *entry = envStrings; *entry; ) { + int entryLen = wcslen(entry); + if (const wchar_t *equal = wcschr(entry, L'=')) { + int nameLen = equal - entry; + QString name = QString::fromWCharArray(entry, nameLen); + QString value = QString::fromWCharArray(equal + 1, entryLen - nameLen - 1); + env.d->hash.insert(QProcessEnvironmentPrivate::Key(name), value); + } + entry += entryLen + 1; + } + FreeEnvironmentStrings(envStrings); + return env; +} + static QByteArray qt_create_environment(const QProcessEnvironmentPrivate::Hash &environment) { QByteArray envlist; -- cgit v0.12 From 7aa4ecdedba60ac4cbc07a774ae9d834677002e9 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 21 Apr 2011 21:34:59 +0200 Subject: make QProcessEnvironment on Unix cache converted values values are converted between byte arrays and qstrings on demand. this makes it feasible to use the class as a generic environment container with fast reading and writing access. Reviewed-by: thiago Reviewed-by: dt --- src/corelib/io/qprocess_p.h | 37 ++++++++++++++++++++++++++++++++++--- src/corelib/io/qprocess_unix.cpp | 2 +- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h index 9a9981e..251f8bc 100644 --- a/src/corelib/io/qprocess_p.h +++ b/src/corelib/io/qprocess_p.h @@ -113,7 +113,35 @@ public: uint hash; }; - typedef QByteArray Value; + class Value + { + public: + Value() {} + Value(const Value &other) { *this = other; } + explicit Value(const QString &value) : stringValue(value) {} + explicit Value(const QByteArray &value) : byteValue(value) {} + bool operator==(const Value &other) const + { + return byteValue.isEmpty() && other.byteValue.isEmpty() + ? stringValue == other.stringValue + : bytes() == other.bytes(); + } + QByteArray bytes() const + { + if (byteValue.isEmpty() && !stringValue.isEmpty()) + byteValue = stringValue.toLocal8Bit(); + return byteValue; + } + QString string() const + { + if (stringValue.isEmpty() && !byteValue.isEmpty()) + stringValue = QString::fromLocal8Bit(byteValue); + return stringValue; + } + + mutable QByteArray byteValue; + mutable QString stringValue; + }; inline Key prepareName(const QString &name) const { @@ -128,8 +156,8 @@ public: nameMap[sname] = name; return sname; } - inline Value prepareValue(const QString &value) const { return value.toLocal8Bit(); } - inline QString valueToString(const Value &value) const { return QString::fromLocal8Bit(value); } + inline Value prepareValue(const QString &value) const { return Value(value); } + inline QString valueToString(const Value &value) const { return value.string(); } #endif typedef QHash Hash; @@ -146,6 +174,9 @@ public: void insert(const QProcessEnvironmentPrivate &other); }; Q_DECLARE_TYPEINFO(QProcessEnvironmentPrivate::Key, Q_MOVABLE_TYPE); +#ifdef Q_OS_UNIX +Q_DECLARE_TYPEINFO(QProcessEnvironmentPrivate::Value, Q_MOVABLE_TYPE); +#endif #ifdef Q_OS_WIN inline uint qHash(const QProcessEnvironmentPrivate::Key &key) { return qHash(key.toCaseFolded()); } diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 451bf61..47f3e69 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -496,7 +496,7 @@ static char **_q_dupEnvironment(const QProcessEnvironmentPrivate::Hash &environm const QProcessEnvironmentPrivate::Hash::ConstIterator end = environment.constEnd(); for ( ; it != end; ++it) { QByteArray key = it.key().key; - QByteArray value = it.value(); + QByteArray value = it.value().bytes(); key.reserve(key.length() + 1 + value.length()); key.append('='); key.append(value); -- cgit v0.12 From 0670770e98e3f914bd221205e1f4ec144b0757fb Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 29 Apr 2011 13:48:34 +0200 Subject: Fix another case where QVariant::Invalid should be QVariant::UserType Due to the QMetaType change before 4.7.0, if the typename of the variant is QVariant then the type itself is of UserType and not Invalid as it was previously. Reviewed-by: Martin Petersson --- src/activeqt/shared/qaxtypes.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/activeqt/shared/qaxtypes.cpp b/src/activeqt/shared/qaxtypes.cpp index f0a8ad8..b741620 100644 --- a/src/activeqt/shared/qaxtypes.cpp +++ b/src/activeqt/shared/qaxtypes.cpp @@ -265,7 +265,7 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type return QVariantToVARIANT(var, *arg.pvarVal, typeName, false); } - if (out && proptype == QVariant::Invalid && typeName == "QVariant") { + if (out && proptype == QVariant::UserType && typeName == "QVariant") { VARIANT *pVariant = new VARIANT; QVariantToVARIANT(var, *pVariant, QByteArray(), false); arg.vt = VT_VARIANT|VT_BYREF; -- cgit v0.12 From 2af5f51c1a7e4b9b5af4eafff8f64f2f8978c3a2 Mon Sep 17 00:00:00 2001 From: Morten Engvoldsen Date: Fri, 29 Apr 2011 14:24:54 +0200 Subject: Fixing potential js hole in the js function for the feedback channel. --- doc/src/template/scripts/functions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/template/scripts/functions.js b/doc/src/template/scripts/functions.js index 62bc535..3ab4a08 100755 --- a/doc/src/template/scripts/functions.js +++ b/doc/src/template/scripts/functions.js @@ -184,7 +184,7 @@ var blankRE=/^\s*$/; function CheckEmptyAndLoadList() { /* Start Extracting information for feedback and adding this to the feedback form */ - var pageUrl = window.location.href; + var pageUrl = window.location.pathname; var pageVal = $('title').html(); $('#pageType').removeClass('red'); $('#feedUrl').remove(); -- cgit v0.12 From 78821cd51c69757a7b4e711c495e702adf97d682 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Fri, 29 Apr 2011 16:46:33 +0200 Subject: Revert symbol addition in b033bb9 Because it breaks forward compatibility. We will use the original fix in 4.8. In 4.7 we just make sure it doesn't crash in QTextBlock::next(). Reviewed-by: Thiago Macieira --- src/gui/text/qtextobject.cpp | 7 +------ src/gui/text/qtextobject.h | 2 +- src/s60installs/eabi/QtGuiu.def | 1 - tests/auto/qtextblock/tst_qtextblock.cpp | 12 ------------ 4 files changed, 2 insertions(+), 20 deletions(-) diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp index a403cc5..2a93f67 100644 --- a/src/gui/text/qtextobject.cpp +++ b/src/gui/text/qtextobject.cpp @@ -891,11 +891,6 @@ QTextBlockUserData::~QTextBlockUserData() Returns true if this text block is valid; otherwise returns false. */ -bool QTextBlock::isValid() const -{ - return p != 0 && p->blockMap().isValid(n); -} - /*! \fn QTextBlock &QTextBlock::operator=(const QTextBlock &other) @@ -1493,7 +1488,7 @@ QTextBlock::iterator QTextBlock::end() const */ QTextBlock QTextBlock::next() const { - if (!isValid()) + if (!isValid() || !p->blockMap().isValid(n)) return QTextBlock(); return QTextBlock(p, p->blockMap().next(n)); diff --git a/src/gui/text/qtextobject.h b/src/gui/text/qtextobject.h index 73aed79..d5c1e8d 100644 --- a/src/gui/text/qtextobject.h +++ b/src/gui/text/qtextobject.h @@ -204,7 +204,7 @@ public: inline QTextBlock(const QTextBlock &o) : p(o.p), n(o.n) {} inline QTextBlock &operator=(const QTextBlock &o) { p = o.p; n = o.n; return *this; } - bool isValid() const; + inline bool isValid() const { return p != 0 && n != 0; } inline bool operator==(const QTextBlock &o) const { return p == o.p && n == o.n; } inline bool operator!=(const QTextBlock &o) const { return p != o.p || n != o.n; } diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def index 799ac43..fafa07b 100644 --- a/src/s60installs/eabi/QtGuiu.def +++ b/src/s60installs/eabi/QtGuiu.def @@ -12183,5 +12183,4 @@ EXPORTS _ZN15QGraphicsSystem22releaseCachedResourcesEv @ 12182 NONAME _Z32qt_s60_setPartialScreenInputModeb @ 12183 NONAME _Z29qt_draw_decoration_for_glyphsP8QPainterPKjPK11QFixedPointiP11QFontEngineRK5QFontRK15QTextCharFormat @ 12184 NONAME - _ZNK10QTextBlock7isValidEv @ 12185 NONAME diff --git a/tests/auto/qtextblock/tst_qtextblock.cpp b/tests/auto/qtextblock/tst_qtextblock.cpp index 748d921..cec3a6a 100644 --- a/tests/auto/qtextblock/tst_qtextblock.cpp +++ b/tests/auto/qtextblock/tst_qtextblock.cpp @@ -76,7 +76,6 @@ private slots: void excludeParagraphSeparatorFragment(); void backwardsBlockIterator(); void previousBlock_qtbug18026(); - void removedBlock_qtbug18500(); private: QTextDocument *doc; @@ -182,16 +181,5 @@ void tst_QTextBlock::previousBlock_qtbug18026() QVERIFY(last.isValid()); } -void tst_QTextBlock::removedBlock_qtbug18500() -{ - cursor.insertText("line 1\nline 2\nline 3 \nline 4\n"); - cursor.setPosition(7); - QTextBlock block = cursor.block(); - cursor.setPosition(21, QTextCursor::KeepAnchor); - - cursor.removeSelectedText(); - QVERIFY(!block.isValid()); -} - QTEST_MAIN(tst_QTextBlock) #include "tst_qtextblock.moc" -- cgit v0.12 From 49d2906a9566c8b44df48f51ca137b9ba2feb671 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Fri, 8 Apr 2011 17:34:51 +0200 Subject: Make sure removed QTextBlock is invalid If the block is removed from document block map, we will mark the right node to the current head->freelist index, but it shouldn't be accessed directly, otherwise it can cause crash because of uninitialized node. Hence we need to check if a node index is equal to current freelist index. If so, it cannot be a valid block. Task-number: QTBUG-18500 Reviewed-by: Eskil --- src/gui/text/qfragmentmap_p.h | 5 +++++ src/gui/text/qtextobject.cpp | 5 +++++ src/gui/text/qtextobject.h | 2 +- tests/auto/qtextblock/tst_qtextblock.cpp | 12 ++++++++++++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/gui/text/qfragmentmap_p.h b/src/gui/text/qfragmentmap_p.h index 501bfff..4057142 100644 --- a/src/gui/text/qfragmentmap_p.h +++ b/src/gui/text/qfragmentmap_p.h @@ -195,6 +195,10 @@ public: head->root = new_root; } + inline bool isValid(uint n) const { + return n > 0 && n != head->freelist; + } + union { Header *head; Fragment *fragments; @@ -854,6 +858,7 @@ public: return data.fragment(index); } inline uint position(uint node, uint field = 0) const { return data.position(node, field); } + inline bool isValid(uint n) const { return data.isValid(n); } inline uint next(uint n) const { return data.next(n); } inline uint previous(uint n) const { return data.previous(n); } inline uint size(uint node, uint field = 0) const { return data.size(node, field); } diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp index 0a9dff8..5c1c8b9 100644 --- a/src/gui/text/qtextobject.cpp +++ b/src/gui/text/qtextobject.cpp @@ -891,6 +891,11 @@ QTextBlockUserData::~QTextBlockUserData() Returns true if this text block is valid; otherwise returns false. */ +bool QTextBlock::isValid() const +{ + return p != 0 && p->blockMap().isValid(n); +} + /*! \fn QTextBlock &QTextBlock::operator=(const QTextBlock &other) diff --git a/src/gui/text/qtextobject.h b/src/gui/text/qtextobject.h index 2e588c2..ad8e657 100644 --- a/src/gui/text/qtextobject.h +++ b/src/gui/text/qtextobject.h @@ -205,7 +205,7 @@ public: inline QTextBlock(const QTextBlock &o) : p(o.p), n(o.n) {} inline QTextBlock &operator=(const QTextBlock &o) { p = o.p; n = o.n; return *this; } - inline bool isValid() const { return p != 0 && n != 0; } + bool isValid() const; inline bool operator==(const QTextBlock &o) const { return p == o.p && n == o.n; } inline bool operator!=(const QTextBlock &o) const { return p != o.p || n != o.n; } diff --git a/tests/auto/qtextblock/tst_qtextblock.cpp b/tests/auto/qtextblock/tst_qtextblock.cpp index cec3a6a..748d921 100644 --- a/tests/auto/qtextblock/tst_qtextblock.cpp +++ b/tests/auto/qtextblock/tst_qtextblock.cpp @@ -76,6 +76,7 @@ private slots: void excludeParagraphSeparatorFragment(); void backwardsBlockIterator(); void previousBlock_qtbug18026(); + void removedBlock_qtbug18500(); private: QTextDocument *doc; @@ -181,5 +182,16 @@ void tst_QTextBlock::previousBlock_qtbug18026() QVERIFY(last.isValid()); } +void tst_QTextBlock::removedBlock_qtbug18500() +{ + cursor.insertText("line 1\nline 2\nline 3 \nline 4\n"); + cursor.setPosition(7); + QTextBlock block = cursor.block(); + cursor.setPosition(21, QTextCursor::KeepAnchor); + + cursor.removeSelectedText(); + QVERIFY(!block.isValid()); +} + QTEST_MAIN(tst_QTextBlock) #include "tst_qtextblock.moc" -- cgit v0.12 From aae6ef391d2ee2fa5b91c834ea65f14fd61e5af6 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 2 May 2011 09:38:40 +0200 Subject: fix build on mac environ needs to be declared properly --- src/corelib/io/qprocess_unix.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 47f3e69..a3c589f 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -453,6 +453,18 @@ bool QProcessPrivate::createChannel(Channel &channel) } } +QT_BEGIN_INCLUDE_NAMESPACE +#if defined(Q_OS_MAC) && !defined(QT_NO_CORESERVICES) +# include +# define environ (*_NSGetEnviron()) +#elif defined(Q_OS_SYMBIAN) || (defined(Q_OS_MAC) && defined(QT_NO_CORESERVICES)) + static char *qt_empty_environ[] = { 0 }; +#define environ qt_empty_environ +#else + extern char **environ; +#endif +QT_END_INCLUDE_NAMESPACE + QProcessEnvironment QProcessEnvironment::systemEnvironment() { QProcessEnvironment env; -- cgit v0.12 From ac9e63b58533a3215106ed9da82cff3a3e3dda3a Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 2 May 2011 10:06:44 +0200 Subject: Make pixel size a qreal in QRawFont The pixel size in the font engines is already a floating point value. For maximum flexibility, we should expose this in the public API. Task-number: QTBUG-18817 Reviewed-by: Jiang Jiang --- src/gui/text/qrawfont.cpp | 6 +++--- src/gui/text/qrawfont.h | 4 ++-- tests/auto/qrawfont/tst_qrawfont.cpp | 32 ++++++++++++++++---------------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp index 6ac2677..1bce909 100644 --- a/src/gui/text/qrawfont.cpp +++ b/src/gui/text/qrawfont.cpp @@ -308,10 +308,10 @@ qreal QRawFont::descent() const \sa setPixelSize() */ -int QRawFont::pixelSize() const +qreal QRawFont::pixelSize() const { if (!isValid()) - return -1; + return 0.0; return d->fontEngine->fontDef.pixelSize; } @@ -577,7 +577,7 @@ QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writ /*! Sets the pixel size with which this font should be rendered to \a pixelSize. */ -void QRawFont::setPixelSize(int pixelSize) +void QRawFont::setPixelSize(qreal pixelSize) { if (d->fontEngine == 0) return; diff --git a/src/gui/text/qrawfont.h b/src/gui/text/qrawfont.h index 96dc838..56aeefc 100644 --- a/src/gui/text/qrawfont.h +++ b/src/gui/text/qrawfont.h @@ -96,8 +96,8 @@ public: const QTransform &transform = QTransform()) const; QPainterPath pathForGlyph(quint32 glyphIndex) const; - void setPixelSize(int pixelSize); - int pixelSize() const; + void setPixelSize(qreal pixelSize); + qreal pixelSize() const; QFont::HintingPreference hintingPreference() const; diff --git a/tests/auto/qrawfont/tst_qrawfont.cpp b/tests/auto/qrawfont/tst_qrawfont.cpp index 3aa4006..4b42c74 100644 --- a/tests/auto/qrawfont/tst_qrawfont.cpp +++ b/tests/auto/qrawfont/tst_qrawfont.cpp @@ -104,7 +104,7 @@ void tst_QRawFont::invalidRawFont() { QRawFont font; QVERIFY(!font.isValid()); - QCOMPARE(font.pixelSize(), -1); + QCOMPARE(font.pixelSize(), 0.0); QVERIFY(font.familyName().isEmpty()); QCOMPARE(font.style(), QFont::StyleNormal); QCOMPARE(font.weight(), -1); @@ -165,7 +165,7 @@ void tst_QRawFont::correctFontData_data() QTest::addColumn("weight"); QTest::addColumn("hintingPreference"); QTest::addColumn("unitsPerEm"); - QTest::addColumn("pixelSize"); + QTest::addColumn("pixelSize"); int hintingPreferences[] = { int(QFont::PreferDefaultHinting), @@ -189,7 +189,7 @@ void tst_QRawFont::correctFontData_data() << QFont::Normal << QFont::HintingPreference(*hintingPreference) << 1000.0 - << 10; + << 10.0; fileName = QLatin1String(SRCDIR "testfont_bold_italic.ttf"); title = fileName @@ -203,7 +203,7 @@ void tst_QRawFont::correctFontData_data() << QFont::Bold << QFont::HintingPreference(*hintingPreference) << 1000.0 - << 10; + << 10.0; ++hintingPreference; } @@ -217,7 +217,7 @@ void tst_QRawFont::correctFontData() QFETCH(QFont::Weight, weight); QFETCH(QFont::HintingPreference, hintingPreference); QFETCH(qreal, unitsPerEm); - QFETCH(int, pixelSize); + QFETCH(qreal, pixelSize); QRawFont font(fileName, 10, hintingPreference); QVERIFY(font.isValid()); @@ -284,7 +284,7 @@ void tst_QRawFont::textLayout() QString familyName = QString::fromLatin1("QtBidiTestFont"); QFont font(familyName); - font.setPixelSize(18); + font.setPixelSize(18.0); QCOMPARE(QFontInfo(font).family(), familyName); QTextLayout layout(QLatin1String("Foobar")); @@ -301,7 +301,7 @@ void tst_QRawFont::textLayout() QRawFont rawFont = glyphs.font(); QVERIFY(rawFont.isValid()); QCOMPARE(rawFont.familyName(), familyName); - QCOMPARE(rawFont.pixelSize(), 18); + QCOMPARE(rawFont.pixelSize(), 18.0); QVector expectedGlyphIndices; expectedGlyphIndices << 44 << 83 << 83 << 70 << 69 << 86; @@ -597,12 +597,12 @@ void tst_QRawFont::fromFont() QFont font(familyName); font.setHintingPreference(hintingPreference); - font.setPixelSize(26); + font.setPixelSize(26.0); QRawFont rawFont = QRawFont::fromFont(font, writingSystem); QVERIFY(rawFont.isValid()); QCOMPARE(rawFont.familyName(), familyName); - QCOMPARE(rawFont.pixelSize(), 26); + QCOMPARE(rawFont.pixelSize(), 26.0); QVERIFY(fontDatabase.removeApplicationFont(id)); } @@ -623,7 +623,7 @@ void tst_QRawFont::copyConstructor() { QString rawFontFamilyName; - int rawFontPixelSize; + qreal rawFontPixelSize; qreal rawFontAscent; qreal rawFontDescent; int rawFontTableSize; @@ -691,7 +691,7 @@ void tst_QRawFont::detach() { QString rawFontFamilyName; - int rawFontPixelSize; + qreal rawFontPixelSize; qreal rawFontAscent; qreal rawFontDescent; int rawFontTableSize; @@ -773,15 +773,15 @@ void tst_QRawFont::unsupportedWritingSystem() QFont font("QtBidiTestFont"); font.setHintingPreference(hintingPreference); - font.setPixelSize(12); + font.setPixelSize(12.0); QRawFont rawFont = QRawFont::fromFont(font, QFontDatabase::Any); QCOMPARE(rawFont.familyName(), QString::fromLatin1("QtBidiTestFont")); - QCOMPARE(rawFont.pixelSize(), 12); + QCOMPARE(rawFont.pixelSize(), 12.0); rawFont = QRawFont::fromFont(font, QFontDatabase::Hebrew); QCOMPARE(rawFont.familyName(), QString::fromLatin1("QtBidiTestFont")); - QCOMPARE(rawFont.pixelSize(), 12); + QCOMPARE(rawFont.pixelSize(), 12.0); QString arabicText = QFontDatabase::writingSystemSample(QFontDatabase::Arabic); @@ -798,11 +798,11 @@ void tst_QRawFont::unsupportedWritingSystem() QGlyphs glyphs = glyphss.at(0); QRawFont layoutFont = glyphs.font(); QVERIFY(layoutFont.familyName() != QString::fromLatin1("QtBidiTestFont")); - QCOMPARE(layoutFont.pixelSize(), 12); + QCOMPARE(layoutFont.pixelSize(), 12.0); rawFont = QRawFont::fromFont(font, QFontDatabase::Arabic); QCOMPARE(rawFont.familyName(), layoutFont.familyName()); - QCOMPARE(rawFont.pixelSize(), 12); + QCOMPARE(rawFont.pixelSize(), 12.0); fontDatabase.removeApplicationFont(id); } -- cgit v0.12 From 75d2387fbf005b022437855ab6433790372639f8 Mon Sep 17 00:00:00 2001 From: Fabien Freling Date: Mon, 2 May 2011 10:52:25 +0200 Subject: Fix the update() autotest for raster. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the CoreGraphics engine, we expect the test to fail with update(), but with the raster engine the behavior is the same across platforms. Hence we don't need a special case for Mac OS X with the raster engine. Reviewed-by: Samuel Rødal --- tests/auto/qwidget/tst_qwidget.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index 35014c9..9c2f6ea 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -4738,7 +4738,8 @@ void tst_QWidget::update() QCOMPARE(w.visibleRegion(), expectedVisible); QCOMPARE(w.paintedRegion, expectedVisible); #ifdef QT_MAC_USE_COCOA - QEXPECT_FAIL(0, "Cocoa compositor says to paint this.", Continue); + if (QApplicationPrivate::graphics_system_name != QLatin1String("raster")) + QEXPECT_FAIL(0, "Cocoa compositor says to paint this.", Continue); #endif QCOMPARE(child.numPaintEvents, 0); -- cgit v0.12 From c08151e01cdf466ac659c469c7ebceb46c10c2b2 Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Mon, 2 May 2011 11:03:07 +0200 Subject: skip widget when its focusPolicy is Qt::ClickFocus in TabOrderEditor TabOrderEditor should allow user to set tab order for widget that focusPolicy contains Qt::TabFocus. Reviewed-by: Friedemann Kleint --- tools/designer/src/components/tabordereditor/tabordereditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/designer/src/components/tabordereditor/tabordereditor.cpp b/tools/designer/src/components/tabordereditor/tabordereditor.cpp index e372bdc..2932adc 100644 --- a/tools/designer/src/components/tabordereditor/tabordereditor.cpp +++ b/tools/designer/src/components/tabordereditor/tabordereditor.cpp @@ -208,7 +208,7 @@ bool TabOrderEditor::skipWidget(QWidget *w) const if (index != -1) { bool ok = false; Qt::FocusPolicy q = (Qt::FocusPolicy) Utils::valueOf(sheet->property(index), &ok); - return !ok || q == Qt::NoFocus; + return !ok || !(q & Qt::TabFocus); } } -- cgit v0.12 From 167044693cc1d16684a5732b05e3926d0af61960 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 2 May 2011 11:06:27 +0200 Subject: fix build on symbian Error: #793: explicit specialization of class "QTypeInfo" must precede its first use just un-nest QProcessEnvironmentPrivate::{Key,Value} Reviewed-by: thiago --- src/corelib/io/qprocess_p.h | 122 ++++++++++++++++++++++---------------------- 1 file changed, 60 insertions(+), 62 deletions(-) diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h index 251f8bc..f70579b 100644 --- a/src/corelib/io/qprocess_p.h +++ b/src/corelib/io/qprocess_p.h @@ -81,68 +81,76 @@ class QTimer; class RProcess; #endif -class QProcessEnvironmentPrivate: public QSharedData +#ifdef Q_OS_WIN +class QProcEnvKey : public QString { public: -#ifdef Q_OS_WIN - class Key : public QString + QProcEnvKey() {} + explicit QProcEnvKey(const QString &other) : QString(other) {} + QProcEnvKey(const QProcEnvKey &other) : QString(other) {} + bool operator==(const QProcEnvKey &other) const { return !compare(other, Qt::CaseInsensitive); } +}; +inline uint qHash(const QProcEnvKey &key) { return qHash(key.toCaseFolded()); } + +typedef QString QProcEnvValue; +#else +class QProcEnvKey +{ +public: + QProcEnvKey() : hash(0) {} + explicit QProcEnvKey(const QByteArray &other) : key(other), hash(qHash(key)) {} + QProcEnvKey(const QProcEnvKey &other) { *this = other; } + bool operator==(const QProcEnvKey &other) const { return key == other.key; } + + QByteArray key; + uint hash; +}; +inline uint qHash(const QProcEnvKey &key) { return key.hash; } + +class QProcEnvValue +{ +public: + QProcEnvValue() {} + QProcEnvValue(const QProcEnvValue &other) { *this = other; } + explicit QProcEnvValue(const QString &value) : stringValue(value) {} + explicit QProcEnvValue(const QByteArray &value) : byteValue(value) {} + bool operator==(const QProcEnvValue &other) const { - public: - Key() {} - explicit Key(const QString &other) : QString(other) {} - Key(const Key &other) : QString(other) {} - bool operator==(const Key &other) const { return !compare(other, Qt::CaseInsensitive); } - }; + return byteValue.isEmpty() && other.byteValue.isEmpty() + ? stringValue == other.stringValue + : bytes() == other.bytes(); + } + QByteArray bytes() const + { + if (byteValue.isEmpty() && !stringValue.isEmpty()) + byteValue = stringValue.toLocal8Bit(); + return byteValue; + } + QString string() const + { + if (stringValue.isEmpty() && !byteValue.isEmpty()) + stringValue = QString::fromLocal8Bit(byteValue); + return stringValue; + } - typedef QString Value; + mutable QByteArray byteValue; + mutable QString stringValue; +}; +Q_DECLARE_TYPEINFO(QProcEnvValue, Q_MOVABLE_TYPE); +#endif +Q_DECLARE_TYPEINFO(QProcEnvKey, Q_MOVABLE_TYPE); +class QProcessEnvironmentPrivate: public QSharedData +{ +public: + typedef QProcEnvKey Key; + typedef QProcEnvValue Value; +#ifdef Q_OS_WIN inline Key prepareName(const QString &name) const { return Key(name); } inline QString nameToString(const Key &name) const { return name; } inline Value prepareValue(const QString &value) const { return value; } inline QString valueToString(const Value &value) const { return value; } #else - class Key - { - public: - Key() : hash(0) {} - explicit Key(const QByteArray &other) : key(other), hash(qHash(key)) {} - Key(const Key &other) { *this = other; } - bool operator==(const Key &other) const { return key == other.key; } - - QByteArray key; - uint hash; - }; - - class Value - { - public: - Value() {} - Value(const Value &other) { *this = other; } - explicit Value(const QString &value) : stringValue(value) {} - explicit Value(const QByteArray &value) : byteValue(value) {} - bool operator==(const Value &other) const - { - return byteValue.isEmpty() && other.byteValue.isEmpty() - ? stringValue == other.stringValue - : bytes() == other.bytes(); - } - QByteArray bytes() const - { - if (byteValue.isEmpty() && !stringValue.isEmpty()) - byteValue = stringValue.toLocal8Bit(); - return byteValue; - } - QString string() const - { - if (stringValue.isEmpty() && !byteValue.isEmpty()) - stringValue = QString::fromLocal8Bit(byteValue); - return stringValue; - } - - mutable QByteArray byteValue; - mutable QString stringValue; - }; - inline Key prepareName(const QString &name) const { Key &ent = nameMap[name]; @@ -173,16 +181,6 @@ public: QStringList keys() const; void insert(const QProcessEnvironmentPrivate &other); }; -Q_DECLARE_TYPEINFO(QProcessEnvironmentPrivate::Key, Q_MOVABLE_TYPE); -#ifdef Q_OS_UNIX -Q_DECLARE_TYPEINFO(QProcessEnvironmentPrivate::Value, Q_MOVABLE_TYPE); -#endif - -#ifdef Q_OS_WIN -inline uint qHash(const QProcessEnvironmentPrivate::Key &key) { return qHash(key.toCaseFolded()); } -#else -inline uint qHash(const QProcessEnvironmentPrivate::Key &key) { return key.hash; } -#endif class QProcessPrivate : public QIODevicePrivate { -- cgit v0.12 From eb61f612fea1b76fe01ee237e5bd160f66aeca3d Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Mon, 2 May 2011 11:23:47 +0200 Subject: Fix compilation with QT_NO_* Merge-request: 1206 Reviewed-by: Oswald Buddenhagen --- src/declarative/debugger/qdeclarativedebugserver.cpp | 2 ++ src/network/access/qhttpthreaddelegate.cpp | 3 +++ src/network/access/qhttpthreaddelegate_p.h | 4 ++++ 3 files changed, 9 insertions(+) diff --git a/src/declarative/debugger/qdeclarativedebugserver.cpp b/src/declarative/debugger/qdeclarativedebugserver.cpp index c7bdcb6..5112af0 100644 --- a/src/declarative/debugger/qdeclarativedebugserver.cpp +++ b/src/declarative/debugger/qdeclarativedebugserver.cpp @@ -116,6 +116,7 @@ void QDeclarativeDebugServerPrivate::advertisePlugins() QDeclarativeDebugServerConnection *QDeclarativeDebugServerPrivate::loadConnectionPlugin( const QString &pluginName) { +#ifndef QT_NO_LIBRARY QStringList pluginCandidates; const QStringList paths = QCoreApplication::libraryPaths(); foreach (const QString &libPath, paths) { @@ -142,6 +143,7 @@ QDeclarativeDebugServerConnection *QDeclarativeDebugServerPrivate::loadConnectio return connection; loader.unload(); } +#endif return 0; } diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp index 99f9376..0364dac 100644 --- a/src/network/access/qhttpthreaddelegate.cpp +++ b/src/network/access/qhttpthreaddelegate.cpp @@ -51,6 +51,7 @@ #include "private/qnetworkaccesscache_p.h" #include "private/qnoncontiguousbytedevice_p.h" +#ifndef QT_NO_HTTP QT_BEGIN_NAMESPACE @@ -576,4 +577,6 @@ void QHttpThreadDelegate::synchronousProxyAuthenticationRequiredSlot(const QNet #endif +#endif // QT_NO_HTTP + QT_END_NAMESPACE diff --git a/src/network/access/qhttpthreaddelegate_p.h b/src/network/access/qhttpthreaddelegate_p.h index 752bc09..c0f2077 100644 --- a/src/network/access/qhttpthreaddelegate_p.h +++ b/src/network/access/qhttpthreaddelegate_p.h @@ -68,6 +68,8 @@ #include "private/qnoncontiguousbytedevice_p.h" #include "qnetworkaccessauthenticationmanager_p.h" +#ifndef QT_NO_HTTP + QT_BEGIN_NAMESPACE class QAuthenticator; @@ -285,4 +287,6 @@ signals: QT_END_NAMESPACE +#endif // QT_NO_HTTP + #endif // QHTTPTHREADDELEGATE_H -- cgit v0.12 From 6a92de7c89764848f7a85b1aa412a07bedc72b1a Mon Sep 17 00:00:00 2001 From: Jani Hautakangas Date: Mon, 2 May 2011 12:22:24 +0300 Subject: Fix for native child widget performance issue. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flushing native child widgets in VG and GL window surfaces caused performance downgrade because unnecessary swapBuffers calls. On Symbian we must not support flushing native child widgets in VG and GL window surfaces because it causes GPU memory overhead and performance issues. Symbian graphics architecture allows us to render native child widgets to TLW EGL surface correctly in most of the cases. Task-number: QTMOBILITY-1570 Reviewed-by: Samuel Rødal --- src/opengl/qwindowsurface_gl.cpp | 11 +++++++++++ src/openvg/qwindowsurface_vg.cpp | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index b056caa..c6cb214 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -604,6 +604,17 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & if (!hasPartialUpdateSupport() && !d_ptr->did_paint) return; +#ifdef Q_OS_SYMBIAN + if (window() != widget) { + // For performance reasons we don't support + // flushing native child widgets on Symbian. + // It breaks overlapping native child widget + // rendering in some cases but we prefer performance. + return; + } +#endif + + QWidget *parent = widget->internalWinId() ? widget : widget->nativeParentWidget(); Q_ASSERT(parent); diff --git a/src/openvg/qwindowsurface_vg.cpp b/src/openvg/qwindowsurface_vg.cpp index 9ce7f9a..01a6ce9 100644 --- a/src/openvg/qwindowsurface_vg.cpp +++ b/src/openvg/qwindowsurface_vg.cpp @@ -79,6 +79,17 @@ QPaintDevice *QVGWindowSurface::paintDevice() void QVGWindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &offset) { Q_UNUSED(offset); + +#ifdef Q_OS_SYMBIAN + if (window() != widget) { + // For performance reasons we don't support + // flushing native child widgets on Symbian. + // It breaks overlapping native child widget + // rendering in some cases but we prefer performance. + return; + } +#endif + QWidget *parent = widget->internalWinId() ? widget : widget->nativeParentWidget(); d_ptr->endPaint(parent, region); } -- cgit v0.12 From d4fd21f746b536eaddbdd7a07f1d717ef18278e7 Mon Sep 17 00:00:00 2001 From: Jani Hautakangas Date: Mon, 2 May 2011 12:47:34 +0300 Subject: Fix trailing whitespaces Reviewed-by: TRUSTME --- src/opengl/qwindowsurface_gl.cpp | 2 +- src/openvg/qwindowsurface_vg.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index c6cb214..7c41bb9 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -608,7 +608,7 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & if (window() != widget) { // For performance reasons we don't support // flushing native child widgets on Symbian. - // It breaks overlapping native child widget + // It breaks overlapping native child widget // rendering in some cases but we prefer performance. return; } diff --git a/src/openvg/qwindowsurface_vg.cpp b/src/openvg/qwindowsurface_vg.cpp index 01a6ce9..5fb28ac 100644 --- a/src/openvg/qwindowsurface_vg.cpp +++ b/src/openvg/qwindowsurface_vg.cpp @@ -84,7 +84,7 @@ void QVGWindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoin if (window() != widget) { // For performance reasons we don't support // flushing native child widgets on Symbian. - // It breaks overlapping native child widget + // It breaks overlapping native child widget // rendering in some cases but we prefer performance. return; } -- cgit v0.12 From 988871dabf3c949ffc71d126131281a3ae641ebf Mon Sep 17 00:00:00 2001 From: mae Date: Mon, 2 May 2011 11:56:03 +0200 Subject: Fix regression with QSettings patch The plugin loader is used without QCoreApplication. This fixes 31ef8fa6abc2ea23c6f0a996b36494d88aafb0b5 --- src/corelib/kernel/qcoreapplication.cpp | 21 ++++++++++----------- src/corelib/kernel/qcoreapplication_p.h | 2 +- src/corelib/plugin/qlibrary.cpp | 2 +- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index df8bc59..e569894 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -270,7 +270,16 @@ bool QCoreApplicationPrivate::is_app_closing = false; Q_CORE_EXPORT bool qt_locale_initialized = false; -QSettings *QCoreApplicationPrivate::trolltechConf = 0; +/* + Create an instance of Trolltech.conf. This ensures that the settings will not + be thrown out of QSetting's cache for unused settings. + */ +Q_GLOBAL_STATIC_WITH_ARGS(QSettings, trolltechConf, (QSettings::UserScope, QLatin1String("Trolltech"))) + +QSettings *QCoreApplicationPrivate::trolltechConf() +{ + return ::trolltechConf(); +} Q_CORE_EXPORT uint qGlobalPostedEventsCount() { @@ -373,9 +382,6 @@ QCoreApplicationPrivate::~QCoreApplicationPrivate() threadData->postEventList.recursion = 0; threadData->quitNow = false; } - - delete trolltechConf; - trolltechConf = 0; } void QCoreApplicationPrivate::createEventDispatcher() @@ -693,13 +699,6 @@ void QCoreApplication::init() } #endif - - /* - Create an instance of Trolltech.conf. This ensures that the settings will not - be thrown out of QSetting's cache for unused settings. - */ - d->trolltechConf = new QSettings(QSettings::UserScope, QLatin1String("Trolltech")); - qt_startup_hook(); } diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h index 0557f83..eb46ae5 100644 --- a/src/corelib/kernel/qcoreapplication_p.h +++ b/src/corelib/kernel/qcoreapplication_p.h @@ -140,7 +140,7 @@ public: #if defined(QT3_SUPPORT) static bool useQt3Support; #endif - static QSettings *trolltechConf; + static QSettings *trolltechConf(); }; QT_END_NAMESPACE diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp index 6f3ee1c..d9aac00 100644 --- a/src/corelib/plugin/qlibrary.cpp +++ b/src/corelib/plugin/qlibrary.cpp @@ -706,7 +706,7 @@ bool QLibraryPrivate::isPlugin(QSettings *settings) QStringList reg; #ifndef QT_NO_SETTINGS if (!settings) { - settings = QCoreApplicationPrivate::trolltechConf; + settings = QCoreApplicationPrivate::trolltechConf(); } reg = settings->value(regkey).toStringList(); #endif -- cgit v0.12 From 18122b473ecbd85ba953f70743b1756358bf7c0c Mon Sep 17 00:00:00 2001 From: Matthew Cattell Date: Mon, 2 May 2011 11:26:05 +0200 Subject: Fixed bug in QPdfEngine::addImage causing mono images to be made 32 bit Regression from 4.5 causing performance and size degradation. Task-number: QTBUG-18997 Reviewed-by: Samuel --- src/gui/painting/qprintengine_pdf.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/painting/qprintengine_pdf.cpp b/src/gui/painting/qprintengine_pdf.cpp index b7f5160..353869f 100644 --- a/src/gui/painting/qprintengine_pdf.cpp +++ b/src/gui/painting/qprintengine_pdf.cpp @@ -534,7 +534,10 @@ int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_n QImage image = img; QImage::Format format = image.format(); - if (image.depth() == 1 && *bitmap && img.colorTable().size() == 0) { + if (image.depth() == 1 && *bitmap && img.colorTable().size() == 2 + && img.colorTable().at(0) == QColor(Qt::black).rgba() + && img.colorTable().at(1) == QColor(Qt::white).rgba()) + { if (format == QImage::Format_MonoLSB) image = image.convertToFormat(QImage::Format_Mono); format = QImage::Format_Mono; -- cgit v0.12 From c99be6bf73dce10fc706764b72a8dacc1c6589a0 Mon Sep 17 00:00:00 2001 From: mae Date: Mon, 2 May 2011 12:45:43 +0200 Subject: Fix namespace issue with the global static --- src/corelib/kernel/qcoreapplication.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index e569894..c0b1748 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -274,11 +274,11 @@ Q_CORE_EXPORT bool qt_locale_initialized = false; Create an instance of Trolltech.conf. This ensures that the settings will not be thrown out of QSetting's cache for unused settings. */ -Q_GLOBAL_STATIC_WITH_ARGS(QSettings, trolltechConf, (QSettings::UserScope, QLatin1String("Trolltech"))) +Q_GLOBAL_STATIC_WITH_ARGS(QSettings, staticTrolltechConf, (QSettings::UserScope, QLatin1String("Trolltech"))) QSettings *QCoreApplicationPrivate::trolltechConf() { - return ::trolltechConf(); + return staticTrolltechConf(); } Q_CORE_EXPORT uint qGlobalPostedEventsCount() -- cgit v0.12 From 6db0153cd7e35e4a919a76ae2aadbf2d2510bfb7 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: 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 --- 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 ac35d42..fcb098f 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -292,6 +292,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) @@ -2563,6 +2564,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(); @@ -10041,6 +10058,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(); @@ -10195,6 +10213,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 377e3a7..c9dba29 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -759,6 +759,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 bb8b8b4..a851d03 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(); @@ -8522,6 +8523,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: -- cgit v0.12 From f33b31dcc1b8fd35501ab5b441a4529e2f8570f3 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 2 May 2011 14:03:35 +0200 Subject: QmlViewer: Translate UI Install translators for the Qt & QmlViewer translations. also add QT_NO_CAST_FROM_ASCII, QT_NO_CAST_TO_ASCII to check for untranslated strings. Reviewed-by: Oswald Buddenhagen Task-number: QTBUG-14848 --- tools/qml/loggerwidget.cpp | 14 ++--- tools/qml/main.cpp | 91 +++++++++++++++++-------------- tools/qml/proxysettings.cpp | 36 ++++++------- tools/qml/proxysettings_maemo5.ui | 6 +-- tools/qml/qdeclarativetester.cpp | 10 ++-- tools/qml/qml.pro | 2 + tools/qml/qmlruntime.cpp | 109 +++++++++++++++++++------------------- translations/translations.pro | 1 + 8 files changed, 143 insertions(+), 126 deletions(-) diff --git a/tools/qml/loggerwidget.cpp b/tools/qml/loggerwidget.cpp index 3f2337a..9a07402 100644 --- a/tools/qml/loggerwidget.cpp +++ b/tools/qml/loggerwidget.cpp @@ -139,10 +139,10 @@ QAction *LoggerWidget::showAction() void LoggerWidget::readSettings() { QSettings settings; - QString warningsPreferences = settings.value("warnings", "hide").toString(); - if (warningsPreferences == "show") { + QString warningsPreferences = settings.value(QLatin1String("warnings"), QLatin1String("hide")).toString(); + if (warningsPreferences == QLatin1String("show")) { m_visibility = ShowWarnings; - } else if (warningsPreferences == "hide") { + } else if (warningsPreferences == QLatin1String("hide")) { m_visibility = HideWarnings; } else { m_visibility = AutoShowWarnings; @@ -154,15 +154,15 @@ void LoggerWidget::saveSettings() if (m_visibilityOrigin != SettingsOrigin) return; - QString value = "autoShow"; + QString value = QLatin1String("autoShow"); if (defaultVisibility() == ShowWarnings) { - value = "show"; + value = QLatin1String("show"); } else if (defaultVisibility() == HideWarnings) { - value = "hide"; + value = QLatin1String("hide"); } QSettings settings; - settings.setValue("warnings", value); + settings.setValue(QLatin1String("warnings"), value); } void LoggerWidget::warningsPreferenceChanged(QAction *action) diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp index edd6b04..24a4940 100644 --- a/tools/qml/main.cpp +++ b/tools/qml/main.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #include "qdeclarativetester.h" #include @@ -67,7 +68,7 @@ void exitApp(int i) // Debugging output is not visible by default on Windows - // therefore show modal dialog with errors instead. if (!warnings.isEmpty()) { - QMessageBox::warning(0, QApplication::tr("Qt QML Viewer"), warnings); + QMessageBox::warning(0, QApplication::translate("QDeclarativeViewer", "Qt QML Viewer"), warnings); } #endif exit(i); @@ -123,7 +124,7 @@ void myMessageOutput(QtMsgType type, const char *msg) static QDeclarativeViewer* globalViewer = 0; // The qml file that is shown if the user didn't specify a QML file -QString initialFile = "qrc:/startup/startup.qml"; +QString initialFile = QLatin1String("qrc:/startup/startup.qml"); void usage() { @@ -199,7 +200,7 @@ struct ViewerOptions fps(0.0), autorecord_from(0), autorecord_to(0), - dither("none"), + dither(QLatin1String("none")), runScript(false), devkeys(false), cache(0), @@ -336,54 +337,54 @@ static void parseCommandLineOptions(const QStringList &arguments) for (int i = 1; i < arguments.count(); ++i) { bool lastArg = (i == arguments.count() - 1); QString arg = arguments.at(i); - if (arg == "-frameless") { + if (arg == QLatin1String("-frameless")) { opts.frameless = true; - } else if (arg == "-maximized") { + } else if (arg == QLatin1String("-maximized")) { opts.maximized = true; - } else if (arg == "-fullscreen") { + } else if (arg == QLatin1String("-fullscreen")) { opts.fullScreen = true; - } else if (arg == "-stayontop") { + } else if (arg == QLatin1String("-stayontop")) { opts.stayOnTop = true; - } else if (arg == "-netcache") { + } else if (arg == QLatin1String("-netcache")) { if (lastArg) usage(); opts.cache = arguments.at(++i).toInt(); - } else if (arg == "-recordrate") { + } else if (arg == QLatin1String("-recordrate")) { if (lastArg) usage(); opts.fps = arguments.at(++i).toDouble(); - } else if (arg == "-recordfile") { + } else if (arg == QLatin1String("-recordfile")) { if (lastArg) usage(); opts.recordfile = arguments.at(++i); - } else if (arg == "-record") { + } else if (arg == QLatin1String("-record")) { if (lastArg) usage(); opts.recordargs << arguments.at(++i); - } else if (arg == "-recorddither") { + } else if (arg == QLatin1String("-recorddither")) { if (lastArg) usage(); opts.dither = arguments.at(++i); - } else if (arg == "-autorecord") { + } else if (arg == QLatin1String("-autorecord")) { if (lastArg) usage(); QString range = arguments.at(++i); - int dash = range.indexOf('-'); + int dash = range.indexOf(QLatin1Char('-')); if (dash > 0) opts.autorecord_from = range.left(dash).toInt(); opts.autorecord_to = range.mid(dash+1).toInt(); - } else if (arg == "-devicekeys") { + } else if (arg == QLatin1String("-devicekeys")) { opts.devkeys = true; - } else if (arg == "-dragthreshold") { + } else if (arg == QLatin1String("-dragthreshold")) { if (lastArg) usage(); qApp->setStartDragDistance(arguments.at(++i).toInt()); } else if (arg == QLatin1String("-v") || arg == QLatin1String("-version")) { qWarning("Qt QML Viewer version %s", QT_VERSION_STR); exitApp(0); - } else if (arg == "-translation") { + } else if (arg == QLatin1String("-translation")) { if (lastArg) usage(); opts.translationFile = arguments.at(++i); - } else if (arg == "-no-opengl") { + } else if (arg == QLatin1String("-no-opengl")) { opts.useGL = false; - } else if (arg == "-opengl") { + } else if (arg == QLatin1String("-opengl")) { opts.useGL = true; - } else if (arg == "-qmlbrowser") { + } else if (arg == QLatin1String("-qmlbrowser")) { opts.useNativeFileBrowser = false; - } else if (arg == "-warnings") { + } else if (arg == QLatin1String("-warnings")) { if (lastArg) usage(); QString warningsStr = arguments.at(++i); if (warningsStr == QLatin1String("show")) { @@ -393,8 +394,8 @@ static void parseCommandLineOptions(const QStringList &arguments) } else { usage(); } - } else if (arg == "-I" || arg == "-L") { - if (arg == "-L") + } else if (arg == QLatin1String("-I") || arg == QLatin1String("-L")) { + if (arg == QLatin1String("-L")) qWarning("-L option provided for compatibility only, use -I instead"); if (lastArg) { QDeclarativeEngine tmpEngine; @@ -403,32 +404,32 @@ static void parseCommandLineOptions(const QStringList &arguments) exitApp(0); } opts.imports << arguments.at(++i); - } else if (arg == "-P") { + } else if (arg == QLatin1String("-P")) { if (lastArg) usage(); opts.plugins << arguments.at(++i); - } else if (arg == "-script") { + } else if (arg == QLatin1String("-script")) { if (lastArg) usage(); opts.script = arguments.at(++i); - } else if (arg == "-scriptopts") { + } else if (arg == QLatin1String("-scriptopts")) { if (lastArg) usage(); opts.scriptopts = arguments.at(++i); - } else if (arg == "-savescript") { + } else if (arg == QLatin1String("-savescript")) { if (lastArg) usage(); opts.script = arguments.at(++i); opts.runScript = false; - } else if (arg == "-playscript") { + } else if (arg == QLatin1String("-playscript")) { if (lastArg) usage(); opts.script = arguments.at(++i); opts.runScript = true; - } else if (arg == "-sizeviewtorootobject") { + } else if (arg == QLatin1String("-sizeviewtorootobject")) { opts.sizeToView = false; - } else if (arg == "-sizerootobjecttoview") { + } else if (arg == QLatin1String("-sizerootobjecttoview")) { opts.sizeToView = true; - } else if (arg == "-experimentalgestures") { + } else if (arg == QLatin1String("-experimentalgestures")) { opts.experimentalGestures = true; - } else if (!arg.startsWith('-')) { + } else if (!arg.startsWith(QLatin1Char('-'))) { fileNames.append(arg); - } else if (true || arg == "-help") { + } else if (true || arg == QLatin1String("-help")) { usage(); } } @@ -527,29 +528,41 @@ int main(int argc, char ** argv) //### default to using raster graphics backend for now bool gsSpecified = false; for (int i = 0; i < argc; ++i) { - QString arg = argv[i]; - if (arg == "-graphicssystem") { + QString arg = QString::fromAscii(argv[i]); + if (arg == QLatin1String("-graphicssystem")) { gsSpecified = true; break; } } if (!gsSpecified) - QApplication::setGraphicsSystem("raster"); + QApplication::setGraphicsSystem(QLatin1String("raster")); #endif QDeclarativeDebugHelper::enableDebugging(); Application app(argc, argv); - app.setApplicationName("QtQmlViewer"); - app.setOrganizationName("Nokia"); - app.setOrganizationDomain("nokia.com"); + app.setApplicationName(QLatin1String("QtQmlViewer")); + app.setOrganizationName(QLatin1String("Nokia")); + app.setOrganizationDomain(QLatin1String("nokia.com")); QDeclarativeViewer::registerTypes(); QDeclarativeTester::registerTypes(); parseCommandLineOptions(app.arguments()); + QTranslator translator; + QTranslator qtTranslator; + QString sysLocale = QLocale::system().name(); + if (translator.load(QLatin1String("qmlviewer_") + sysLocale, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) { + app.installTranslator(&translator); + if (qtTranslator.load(QLatin1String("qt_") + sysLocale, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) { + app.installTranslator(&qtTranslator); + } else { + app.removeTranslator(&translator); + } + } + QTranslator qmlTranslator; if (!opts.translationFile.isEmpty()) { if (qmlTranslator.load(opts.translationFile)) { diff --git a/tools/qml/proxysettings.cpp b/tools/qml/proxysettings.cpp index c4dc087..78963da 100644 --- a/tools/qml/proxysettings.cpp +++ b/tools/qml/proxysettings.cpp @@ -54,17 +54,17 @@ ProxySettings::ProxySettings (QWidget * parent) #if !defined Q_WS_MAEMO_5 // the onscreen keyboard can't cope with masks - proxyServerEdit->setInputMask ("000.000.000.000;_"); + proxyServerEdit->setInputMask(QLatin1String("000.000.000.000;_")); #endif QIntValidator *validator = new QIntValidator (0, 9999, this); - proxyPortEdit->setValidator (validator); + proxyPortEdit->setValidator(validator); QSettings settings; - proxyCheckBox->setChecked (settings.value ("http_proxy/use", 0).toBool ()); - proxyServerEdit->insert (settings.value ("http_proxy/hostname", "").toString ()); - proxyPortEdit->insert (settings.value ("http_proxy/port", "80").toString ()); - usernameEdit->insert (settings.value ("http_proxy/username", "").toString ()); - passwordEdit->insert (settings.value ("http_proxy/password", "").toString ()); + proxyCheckBox->setChecked(settings.value(QLatin1String("http_proxy/use"), 0).toBool()); + proxyServerEdit->insert(settings.value(QLatin1String("http_proxy/hostname")).toString()); + proxyPortEdit->insert(settings.value(QLatin1String("http_proxy/port"), QLatin1String("80")).toString ()); + usernameEdit->insert(settings.value(QLatin1String("http_proxy/username")).toString ()); + passwordEdit->insert(settings.value(QLatin1String("http_proxy/password")).toString ()); } ProxySettings::~ProxySettings() @@ -75,11 +75,11 @@ void ProxySettings::accept () { QSettings settings; - settings.setValue ("http_proxy/use", proxyCheckBox->isChecked ()); - settings.setValue ("http_proxy/hostname", proxyServerEdit->text ()); - settings.setValue ("http_proxy/port", proxyPortEdit->text ()); - settings.setValue ("http_proxy/username", usernameEdit->text ()); - settings.setValue ("http_proxy/password", passwordEdit->text ()); + settings.setValue(QLatin1String("http_proxy/use"), proxyCheckBox->isChecked()); + settings.setValue(QLatin1String("http_proxy/hostname"), proxyServerEdit->text()); + settings.setValue(QLatin1String("http_proxy/port"), proxyPortEdit->text()); + settings.setValue(QLatin1String("http_proxy/username"), usernameEdit->text()); + settings.setValue(QLatin1String("http_proxy/password"), passwordEdit->text()); QDialog::accept (); } @@ -89,13 +89,13 @@ QNetworkProxy ProxySettings::httpProxy () QSettings settings; QNetworkProxy proxy; - bool proxyInUse = settings.value ("http_proxy/use", 0).toBool (); + bool proxyInUse = settings.value(QLatin1String("http_proxy/use"), 0).toBool(); if (proxyInUse) { proxy.setType (QNetworkProxy::HttpProxy); - proxy.setHostName (settings.value ("http_proxy/hostname", "").toString ());// "192.168.220.5" - proxy.setPort (settings.value ("http_proxy/port", 80).toInt ()); // 8080 - proxy.setUser (settings.value ("http_proxy/username", "").toString ()); - proxy.setPassword (settings.value ("http_proxy/password", "").toString ()); + proxy.setHostName (settings.value(QLatin1String("http_proxy/hostname")).toString());// "192.168.220.5" + proxy.setPort (settings.value(QLatin1String("http_proxy/port"), 80).toInt()); // 8080 + proxy.setUser (settings.value(QLatin1String("http_proxy/username")).toString()); + proxy.setPassword (settings.value(QLatin1String("http_proxy/password")).toString()); //QNetworkProxy::setApplicationProxy (proxy); } else { @@ -107,7 +107,7 @@ QNetworkProxy ProxySettings::httpProxy () bool ProxySettings::httpProxyInUse() { QSettings settings; - return settings.value ("http_proxy/use", 0).toBool (); + return settings.value(QLatin1String("http_proxy/use"), 0).toBool(); } QT_END_NAMESPACE diff --git a/tools/qml/proxysettings_maemo5.ui b/tools/qml/proxysettings_maemo5.ui index 83f0c2a..75875d8 100644 --- a/tools/qml/proxysettings_maemo5.ui +++ b/tools/qml/proxysettings_maemo5.ui @@ -6,8 +6,8 @@ 0 0 - 449 - 164 + 447 + 162 @@ -88,7 +88,7 @@ - 8080 + 8080 diff --git a/tools/qml/qdeclarativetester.cpp b/tools/qml/qdeclarativetester.cpp index 11f81fc..fa8af8f 100644 --- a/tools/qml/qdeclarativetester.cpp +++ b/tools/qml/qdeclarativetester.cpp @@ -205,7 +205,7 @@ void QDeclarativeTester::save() QString filename = m_script + QLatin1String(".qml"); QFileInfo filenameInfo(filename); QDir saveDir = filenameInfo.absoluteDir(); - saveDir.mkpath("."); + saveDir.mkpath(QLatin1String(".")); QFile file(filename); file.open(QIODevice::WriteOnly); @@ -224,8 +224,8 @@ void QDeclarativeTester::save() if (!fe.hash.isEmpty()) { ts << " hash: \"" << fe.hash.toHex() << "\"\n"; } else if (!fe.image.isNull()) { - QString filename = filenameInfo.baseName() + "." + QString::number(imgCount) + ".png"; - fe.image.save(m_script + "." + QString::number(imgCount) + ".png"); + QString filename = filenameInfo.baseName() + QLatin1String(".") + QString::number(imgCount) + QLatin1String(".png"); + fe.image.save(m_script + QLatin1String(".") + QString::number(imgCount) + QLatin1String(".png")); imgCount++; ts << " image: \"" << filename << "\"\n"; } @@ -375,7 +375,7 @@ void QDeclarativeTester::updateCurrentTime(int msec) imagefailure(); } if (goodImage != img) { - QString reject(frame->image().toLocalFile() + ".reject.png"); + QString reject(frame->image().toLocalFile() + QLatin1String(".reject.png")); qWarning() << "QDeclarativeTester(" << m_script << "): Image mismatch. Reject saved to:" << reject; img.save(reject); @@ -393,7 +393,7 @@ void QDeclarativeTester::updateCurrentTime(int msec) } } } - QString diff(frame->image().toLocalFile() + ".diff.png"); + QString diff(frame->image().toLocalFile() + QLatin1String(".diff.png")); diffimg.save(diff); qWarning().nospace() << " Diff (" << diffCount << " pixels differed) saved to: " << diff; } diff --git a/tools/qml/qml.pro b/tools/qml/qml.pro index b1d56ea..9467b70 100644 --- a/tools/qml/qml.pro +++ b/tools/qml/qml.pro @@ -10,6 +10,8 @@ INCLUDEPATH += ../../include/QtDeclarative INCLUDEPATH += ../../src/declarative/util INCLUDEPATH += ../../src/declarative/graphicsitems +DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII + target.path = $$[QT_INSTALL_BINS] INSTALLS += target diff --git a/tools/qml/qmlruntime.cpp b/tools/qml/qmlruntime.cpp index 36915d1..7422032 100644 --- a/tools/qml/qmlruntime.cpp +++ b/tools/qml/qmlruntime.cpp @@ -265,7 +265,7 @@ public: hz->setValidator(new QDoubleValidator(hz)); #endif for (int i=0; ffmpegprofiles[i].name; ++i) { - profile->addItem(ffmpegprofiles[i].name); + profile->addItem(QString::fromAscii(ffmpegprofiles[i].name)); } } @@ -273,9 +273,9 @@ public: { int i; for (i=0; ffmpegprofiles[i].args[0]; ++i) { - if (ffmpegprofiles[i].args == a) { + if (QString::fromAscii(ffmpegprofiles[i].args) == a) { profile->setCurrentIndex(i); - args->setText(QLatin1String(ffmpegprofiles[i].args)); + args->setText(QString::fromAscii(ffmpegprofiles[i].args)); return; } } @@ -465,14 +465,14 @@ private: } } QSettings settings; - settings.setValue("Cookies",data); + settings.setValue(QLatin1String("Cookies"), data); } void load() { QMutexLocker lock(&mutex); QSettings settings; - QByteArray data = settings.value("Cookies").toByteArray(); + QByteArray data = settings.value(QLatin1String("Cookies")).toByteArray(); setAllCookies(QNetworkCookie::parseCookies(data)); } @@ -490,7 +490,7 @@ public: if (proxyDirty) setupProxy(); QString protocolTag = query.protocolTag(); - if (httpProxyInUse && (protocolTag == "http" || protocolTag == "https")) { + if (httpProxyInUse && (protocolTag == QLatin1String("http") || protocolTag == QLatin1String("https"))) { QList ret; ret << httpProxy; return ret; @@ -597,7 +597,7 @@ QString QDeclarativeViewer::getVideoFileName() if (convertAvailable) types += tr("GIF Animation")+QLatin1String(" (*.gif)"); types += tr("Individual PNG frames")+QLatin1String(" (*.png)"); if (ffmpegAvailable) types += tr("All ffmpeg formats (*.*)"); - return QFileDialog::getSaveFileName(this, title, "", types.join(";; ")); + return QFileDialog::getSaveFileName(this, title, QString(), types.join(QLatin1String(";; "))); } QDeclarativeViewer::QDeclarativeViewer(QWidget *parent, Qt::WindowFlags flags) @@ -725,18 +725,18 @@ void QDeclarativeViewer::createMenu() connect(reloadAction, SIGNAL(triggered()), this, SLOT(reload())); QAction *snapshotAction = new QAction(tr("&Take Snapshot"), this); - snapshotAction->setShortcut(QKeySequence("F3")); + snapshotAction->setShortcut(QKeySequence(tr("F3"))); connect(snapshotAction, SIGNAL(triggered()), this, SLOT(takeSnapShot())); recordAction = new QAction(tr("Start Recording &Video"), this); - recordAction->setShortcut(QKeySequence("F9")); + recordAction->setShortcut(QKeySequence(tr("F9"))); connect(recordAction, SIGNAL(triggered()), this, SLOT(toggleRecordingWithSelection())); QAction *recordOptions = new QAction(tr("Video &Options..."), this); connect(recordOptions, SIGNAL(triggered()), this, SLOT(chooseRecordingOptions())); QAction *slowAction = new QAction(tr("&Slow Down Animations"), this); - slowAction->setShortcut(QKeySequence("Ctrl+.")); + slowAction->setShortcut(QKeySequence(tr("Ctrl+."))); slowAction->setCheckable(true); connect(slowAction, SIGNAL(triggered(bool)), this, SLOT(setSlowMode(bool))); @@ -755,7 +755,7 @@ void QDeclarativeViewer::createMenu() connect(fullscreenAction, SIGNAL(triggered()), this, SLOT(toggleFullScreen())); rotateAction = new QAction(tr("Rotate orientation"), this); - rotateAction->setShortcut(QKeySequence("Ctrl+T")); + rotateAction->setShortcut(QKeySequence(tr("Ctrl+T"))); connect(rotateAction, SIGNAL(triggered()), this, SLOT(rotateOrientation())); orientation = new QActionGroup(this); @@ -963,7 +963,7 @@ void QDeclarativeViewer::chooseRecordingOptions() // Profile - recdlg->setArguments(record_args.join(" ")); + recdlg->setArguments(record_args.join(QLatin1String(" "))); if (recdlg->exec()) { // File record_file = recdlg->file->text(); @@ -972,7 +972,7 @@ void QDeclarativeViewer::chooseRecordingOptions() // Rate record_rate = recdlg->videoRate(); // Profile - record_args = recdlg->arguments().split(" ",QString::SkipEmptyParts); + record_args = recdlg->arguments().split(QLatin1Char(' '),QString::SkipEmptyParts); } } @@ -983,8 +983,8 @@ void QDeclarativeViewer::toggleRecordingWithSelection() QString fileName = getVideoFileName(); if (fileName.isEmpty()) return; - if (!fileName.contains(QRegExp(".[^\\/]*$"))) - fileName += ".avi"; + if (!fileName.contains(QRegExp(QLatin1String(".[^\\/]*$")))) + fileName += QLatin1String(".avi"); setRecordFile(fileName); } } @@ -1026,7 +1026,7 @@ void QDeclarativeViewer::openFile() { QString cur = canvas->source().toLocalFile(); if (useQmlFileBrowser) { - open("qrc:/browser/Browser.qml"); + open(QLatin1String("qrc:/browser/Browser.qml")); } else { QString fileName = QFileDialog::getOpenFileName(this, tr("Open QML file"), cur, tr("QML Files (*.qml)")); if (!fileName.isEmpty()) { @@ -1072,7 +1072,7 @@ void QDeclarativeViewer::loadTranslationFile(const QString& directory) void QDeclarativeViewer::loadDummyDataFiles(const QString& directory) { - QDir dir(directory+"/dummydata", "*.qml"); + QDir dir(directory + QLatin1String("/dummydata"), QLatin1String("*.qml")); QStringList list = dir.entryList(); for (int i = 0; i < list.size(); ++i) { QString qml = list.at(i); @@ -1114,14 +1114,14 @@ bool QDeclarativeViewer::open(const QString& file_or_url) delete canvas->rootObject(); canvas->engine()->clearComponentCache(); QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("qmlViewer", this); + ctxt->setContextProperty(QLatin1String("qmlViewer"), this); #ifdef Q_OS_SYMBIAN - ctxt->setContextProperty("qmlViewerFolder", "E:\\"); // Documents on your S60 phone + ctxt->setContextProperty(QLatin1String("qmlViewerFolder"), QLatin1String("E:\\")); // Documents on your S60 phone #else - ctxt->setContextProperty("qmlViewerFolder", QDir::currentPath()); + ctxt->setContextProperty(QLatin1String("qmlViewerFolder"), QDir::currentPath()); #endif - ctxt->setContextProperty("runtime", Runtime::instance()); + ctxt->setContextProperty(QLatin1String("runtime"), Runtime::instance()); QString fileName = url.toLocalFile(); if (!fileName.isEmpty()) { @@ -1224,26 +1224,26 @@ bool QDeclarativeViewer::event(QEvent *event) void QDeclarativeViewer::senseImageMagick() { QProcess proc; - proc.start("convert", QStringList() << "-h"); + proc.start(QLatin1String("convert"), QStringList() << QLatin1String("-h")); proc.waitForFinished(2000); - QString help = proc.readAllStandardOutput(); - convertAvailable = help.contains("ImageMagick"); + QString help = QString::fromAscii(proc.readAllStandardOutput()); + convertAvailable = help.contains(QLatin1String("ImageMagick")); } void QDeclarativeViewer::senseFfmpeg() { QProcess proc; - proc.start("ffmpeg", QStringList() << "-h"); + proc.start(QLatin1String("ffmpeg"), QStringList() << QLatin1String("-h")); proc.waitForFinished(2000); - QString ffmpegHelp = proc.readAllStandardOutput(); - ffmpegAvailable = ffmpegHelp.contains("-s "); - ffmpegHelp = tr("Video recording uses ffmpeg:")+"\n\n"+ffmpegHelp; + QString ffmpegHelp = QString::fromAscii(proc.readAllStandardOutput()); + ffmpegAvailable = ffmpegHelp.contains(QLatin1String("-s ")); + ffmpegHelp = tr("Video recording uses ffmpeg:") + QLatin1String("\n\n") + ffmpegHelp; QDialog *d = new QDialog(recdlg); QVBoxLayout *l = new QVBoxLayout(d); QTextBrowser *b = new QTextBrowser(d); QFont f = b->font(); - f.setFamily("courier"); + f.setFamily(QLatin1String("courier")); b->setFont(f); b->setText(ffmpegHelp); l->addWidget(b); @@ -1266,7 +1266,7 @@ void QDeclarativeViewer::setRecording(bool on) recordTimer.start(); frame_fmt = record_file.right(4).toLower(); frame = QImage(canvas->width(),canvas->height(),QImage::Format_RGB32); - if (frame_fmt != ".png" && (!convertAvailable || frame_fmt != ".gif")) { + if (frame_fmt != QLatin1String(".png") && (!convertAvailable || frame_fmt != QLatin1String(".gif"))) { // Stream video to ffmpeg QProcess *proc = new QProcess(this); @@ -1274,19 +1274,19 @@ void QDeclarativeViewer::setRecording(bool on) frame_stream = proc; QStringList args; - args << "-y"; - args << "-r" << QString::number(record_rate); - args << "-f" << "rawvideo"; - args << "-pix_fmt" << (frame_fmt == ".gif" ? "rgb24" : "rgb32"); - args << "-s" << QString("%1x%2").arg(canvas->width()).arg(canvas->height()); - args << "-i" << "-"; + args << QLatin1String("-y"); + args << QLatin1String("-r") << QString::number(record_rate); + args << QLatin1String("-f") << QLatin1String("rawvideo"); + args << QLatin1String("-pix_fmt") << (frame_fmt == QLatin1String(".gif") ? QLatin1String("rgb24") : QLatin1String("rgb32")); + args << QLatin1String("-s") << QString::fromAscii("%1x%2").arg(canvas->width()).arg(canvas->height()); + args << QLatin1String("-i") << QLatin1String("-"); if (record_outsize.isValid()) { - args << "-s" << QString("%1x%2").arg(record_outsize.width()).arg(record_outsize.height()); - args << "-aspect" << QString::number(double(canvas->width())/canvas->height()); + args << QLatin1String("-s") << QString::fromAscii("%1x%2").arg(record_outsize.width()).arg(record_outsize.height()); + args << QLatin1String("-aspect") << QString::number(double(canvas->width())/canvas->height()); } args += record_args; args << record_file; - proc->start("ffmpeg",args); + proc->start(QLatin1String("ffmpeg"), args); } else { // Store frames, save to GIF/PNG @@ -1309,14 +1309,14 @@ void QDeclarativeViewer::setRecording(bool on) QString framename; bool png_output = false; - if (record_file.right(4).toLower()==".png") { - if (record_file.contains('%')) + if (record_file.right(4).toLower() == QLatin1String(".png")) { + if (record_file.contains(QLatin1Char('%'))) framename = record_file; else - framename = record_file.left(record_file.length()-4)+"%04d"+record_file.right(4); + framename = record_file.left(record_file.length()-4) + QLatin1String("%04d") + record_file.right(4); png_output = true; } else { - framename = "tmp-frame%04d.png"; + framename = QLatin1String("tmp-frame%04d.png"); png_output = false; } foreach (QImage* img, frames) { @@ -1327,11 +1327,11 @@ void QDeclarativeViewer::setRecording(bool on) name.sprintf(framename.toLocal8Bit(),frame++); if (record_outsize.isValid()) *img = img->scaled(record_outsize,Qt::IgnoreAspectRatio,Qt::SmoothTransformation); - if (record_dither=="ordered") + if (record_dither==QLatin1String("ordered")) img->convertToFormat(QImage::Format_Indexed8,Qt::PreferDither|Qt::OrderedDither).save(name); - else if (record_dither=="threshold") + else if (record_dither==QLatin1String("threshold")) img->convertToFormat(QImage::Format_Indexed8,Qt::PreferDither|Qt::ThresholdDither).save(name); - else if (record_dither=="floyd") + else if (record_dither==QLatin1String("floyd")) img->convertToFormat(QImage::Format_Indexed8,Qt::PreferDither).save(name); else img->save(name); @@ -1341,25 +1341,26 @@ void QDeclarativeViewer::setRecording(bool on) if (!progress.wasCanceled()) { if (png_output) { - framename.replace(QRegExp("%\\d*."),"*"); + framename.replace(QRegExp(QLatin1String("%\\d*.")), QLatin1String("*")); qDebug() << "Wrote frames" << framename; inputs.clear(); // don't remove them } else { // ImageMagick and gifsicle for GIF encoding progress.setLabelText(tr("Converting frames to GIF file...")); QStringList args; - args << "-delay" << QString::number(period/10); + args << QLatin1String("-delay") << QString::number(period/10); args << inputs; args << record_file; qDebug() << "Converting..." << record_file << "(this may take a while)"; - if (0!=QProcess::execute("convert", args)) { + if (0!=QProcess::execute(QLatin1String("convert"), args)) { qWarning() << "Cannot run ImageMagick 'convert' - recorded frames not converted"; inputs.clear(); // don't remove them qDebug() << "Wrote frames tmp-frame*.png"; } else { - if (record_file.right(4).toLower() == ".gif") { + if (record_file.right(4).toLower() == QLatin1String(".gif")) { qDebug() << "Compressing..." << record_file; - if (0!=QProcess::execute("gifsicle", QStringList() << "-O2" << "-o" << record_file << record_file)) + if (0!=QProcess::execute(QLatin1String("gifsicle"), QStringList() << QLatin1String("-O2") + << QLatin1String("-o") << record_file << record_file)) qWarning() << "Cannot run 'gifsicle' - not compressed"; } qDebug() << "Wrote" << record_file; @@ -1410,7 +1411,7 @@ void QDeclarativeViewer::recordFrame() { canvas->QWidget::render(&frame); if (frame_stream) { - if (frame_fmt == ".gif") { + if (frame_fmt == QLatin1String(".gif")) { // ffmpeg can't do 32bpp with gif QImage rgb24 = frame.convertToFormat(QImage::Format_RGB888); frame_stream->write((char*)rgb24.bits(),rgb24.numBytes()); @@ -1541,8 +1542,8 @@ void QDeclarativeViewer::registerTypes() if (!registered) { // registering only for exposing the DeviceOrientation::Orientation enum - qmlRegisterUncreatableType("Qt",4,7,"Orientation",""); - qmlRegisterUncreatableType("QtQuick",1,0,"Orientation",""); + qmlRegisterUncreatableType("Qt", 4, 7, "Orientation", QString()); + qmlRegisterUncreatableType("QtQuick", 1, 0, "Orientation", QString()); registered = true; } } diff --git a/translations/translations.pro b/translations/translations.pro index 311b032..dc99beb 100644 --- a/translations/translations.pro +++ b/translations/translations.pro @@ -55,6 +55,7 @@ addTsTargets(assistant, ../tools/assistant/tools/tools.pro) addTsTargets(qt_help, ../tools/assistant/lib/lib.pro) addTsTargets(qtconfig, ../tools/qtconfig/qtconfig.pro) addTsTargets(qvfb, ../tools/qvfb/qvfb.pro) +addTsTargets(qmlviewer, ../tools/qml/qml.pro) check-ts.commands = (cd $$PWD && perl check-ts.pl) check-ts.depends = ts-all -- cgit v0.12 From 0b877b48dc990ca6bb806be668d60f6ced470de2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= Date: Wed, 6 Apr 2011 14:45:11 +0200 Subject: Removed some superfluous semicolons Reviewed-by: Kai Koehne --- src/script/api/qscriptengineagent_p.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/script/api/qscriptengineagent_p.h b/src/script/api/qscriptengineagent_p.h index abe4e9e..b96d19d 100644 --- a/src/script/api/qscriptengineagent_p.h +++ b/src/script/api/qscriptengineagent_p.h @@ -57,22 +57,22 @@ public: static QScriptEngineAgentPrivate* get(QScriptEngineAgent* p) {return p->d_func();} QScriptEngineAgentPrivate(){} - virtual ~QScriptEngineAgentPrivate(){}; + virtual ~QScriptEngineAgentPrivate(){} void attach(); void detach(); //scripts - virtual void sourceParsed(JSC::ExecState*, const JSC::SourceCode&, int /*errorLine*/, const JSC::UString& /*errorMsg*/) {}; + virtual void sourceParsed(JSC::ExecState*, const JSC::SourceCode&, int /*errorLine*/, const JSC::UString& /*errorMsg*/) {} virtual void scriptUnload(qint64 id) { q_ptr->scriptUnload(id); - }; + } virtual void scriptLoad(qint64 id, const JSC::UString &program, const JSC::UString &fileName, int baseLineNumber) { q_ptr->scriptLoad(id,program, fileName, baseLineNumber); - }; + } //exceptions virtual void exception(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno, bool hasHandler) @@ -81,7 +81,7 @@ public: Q_UNUSED(sourceID); Q_UNUSED(lineno); Q_UNUSED(hasHandler); - }; + } virtual void exceptionThrow(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, bool hasHandler); virtual void exceptionCatch(const JSC::DebuggerCallFrame& frame, intptr_t sourceID); @@ -92,20 +92,20 @@ public: Q_UNUSED(lineno); q_ptr->contextPush(); q_ptr->functionEntry(sourceID); - }; + } virtual void returnEvent(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno); virtual void willExecuteProgram(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno) { Q_UNUSED(frame); Q_UNUSED(sourceID); Q_UNUSED(lineno); - }; + } virtual void didExecuteProgram(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno) { Q_UNUSED(frame); - Q_UNUSED(sourceID); + Q_UNUSED(sourceID); Q_UNUSED(lineno); - }; + } virtual void functionExit(const JSC::JSValue& returnValue, intptr_t sourceID); //others virtual void didReachBreakpoint(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno/*, int column*/); -- cgit v0.12 From 0ba0c374fe055623381e3795daa6743c5c995bbc Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Tue, 19 Apr 2011 07:47:33 +0200 Subject: Rewrite the interfaces of QtConcurrent. At least make RVCT 2.2 work. Task-number: QTBUG-5182 Task-number: QTBUG-9070 Reviewed-by: Olivier Goffart Reviewed-by: joao --- src/corelib/concurrent/qtconcurrentfilter.h | 554 ++---------------- .../concurrent/qtconcurrentfunctionwrappers.h | 137 +++++ src/corelib/concurrent/qtconcurrentmap.h | 636 +++------------------ 3 files changed, 270 insertions(+), 1057 deletions(-) diff --git a/src/corelib/concurrent/qtconcurrentfilter.h b/src/corelib/concurrent/qtconcurrentfilter.h index e392212..63dcc4b 100644 --- a/src/corelib/concurrent/qtconcurrentfilter.h +++ b/src/corelib/concurrent/qtconcurrentfilter.h @@ -115,19 +115,7 @@ ThreadEngineStarter filterInternal(Sequence &sequence, KeepFunctor keep, T template QFuture filter(Sequence &sequence, KeepFunctor keep) { - return filterInternal(sequence, keep, &Sequence::push_back); -} - -template -QFuture filter(Sequence &sequence, bool (keep)(T)) -{ - return filterInternal(sequence, FunctionWrapper1(keep), &Sequence::push_back); -} - -template -QFuture filter(Sequence &sequence, bool (C::*keep)() const) -{ - return filterInternal(sequence, ConstMemberFunctionWrapper(keep), &Sequence::push_back); + return filterInternal(sequence, QtPrivate::createFunctionWrapper(keep), &Sequence::push_back); } // filteredReduced() on sequences @@ -137,103 +125,20 @@ QFuture filteredReduced(const Sequence &sequence, ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startFilteredReduced(sequence, keep, reduce, options); - } - -template -QFuture filteredReduced(const Sequence &sequence, - bool (filter)(T), - ReduceFunctor reduce, - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return filteredReduced(sequence, - FunctionWrapper1(filter), - reduce, - options); + return startFilteredReduced(sequence, QtPrivate::createFunctionWrapper(keep), QtPrivate::createFunctionWrapper(reduce), options); } -template -QFuture filteredReduced(const Sequence &sequence, - bool (C::*filter)() const, +template +QFuture::ResultType> filteredReduced(const Sequence &sequence, + KeepFunctor keep, ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return filteredReduced(sequence, - ConstMemberFunctionWrapper(filter), - reduce, - options); -} - -template -QFuture filteredReduced(const Sequence &sequence, - KeepFunctor keep, - T (reduce)(U &, V), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return filteredReduced(sequence, - keep, - FunctionWrapper2(reduce), - options); -} - -template -QFuture filteredReduced(const Sequence &sequence, - KeepFunctor keep, - T (C::*reduce)(U), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return filteredReduced(sequence, - keep, - MemberFunctionWrapper1(reduce), - options); -} - -template -QFuture filteredReduced(const Sequence &sequence, - bool (keep)(T), - U (reduce)(V &, W), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return filteredReduced(sequence, - FunctionWrapper1(keep), - FunctionWrapper2(reduce), - options); -} - -template -QFuture filteredReduced(const Sequence &sequence, - bool (C::*keep)() const, - T (reduce)(U &, V), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return filteredReduced(sequence, - ConstMemberFunctionWrapper(keep), - FunctionWrapper2(reduce), - options); -} - -template -QFuture filteredReduced(const Sequence &sequence, - bool (keep)(T), - U (C::*reduce)(V), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return filteredReduced(sequence, - FunctionWrapper1(keep), - MemberFunctionWrapper1(reduce), - options); -} - -template -QFuture filteredReduced(const Sequence &sequence, - bool (C::*keep)() const, - T (D::*reduce)(U), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return filteredReduced(sequence, - ConstMemberFunctionWrapper(keep), - MemberFunctionWrapper1(reduce), - options); + return startFilteredReduced::ResultType> + (sequence, + QtPrivate::createFunctionWrapper(keep), + QtPrivate::createFunctionWrapper(reduce), + options); } // filteredReduced() on iterators @@ -244,184 +149,42 @@ QFuture filteredReduced(Iterator begin, ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startFilteredReduced(begin, end, keep, reduce, options); -} - -template -QFuture filteredReduced(Iterator begin, - Iterator end, - bool (filter)(T), - ReduceFunctor reduce, - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return filteredReduced(begin, - end, - FunctionWrapper1(filter), - reduce, - options); + return startFilteredReduced(begin, end, QtPrivate::createFunctionWrapper(keep), QtPrivate::createFunctionWrapper(reduce), options); } -template -QFuture filteredReduced(Iterator begin, +template +QFuture::ResultType> filteredReduced(Iterator begin, Iterator end, - bool (C::*filter)() const, + KeepFunctor keep, ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return filteredReduced(begin, - end, - ConstMemberFunctionWrapper(filter), - reduce, - options); -} - -template -QFuture filteredReduced(Iterator begin, - Iterator end, - KeepFunctor keep, - T (reduce)(U &, V), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return filteredReduced(begin, - end, - keep, - FunctionWrapper2(reduce), - options); -} - -template -QFuture filteredReduced(Iterator begin, - Iterator end, - KeepFunctor keep, - T (C::*reduce)(U), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return filteredReduced(begin, - end, - keep, - MemberFunctionWrapper1(reduce), - options); -} - -template -QFuture filteredReduced(Iterator begin, - Iterator end, - bool (keep)(T), - U (reduce)(V &, W), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return filteredReduced(begin, - end, - FunctionWrapper1(keep), - FunctionWrapper2(reduce), - options); -} - -template -QFuture filteredReduced(Iterator begin, - Iterator end, - bool (C::*keep)() const, - T (reduce)(U &, V), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return filteredReduced(begin, - end, - ConstMemberFunctionWrapper(keep), - FunctionWrapper2(reduce), - options); -} - -template -QFuture filteredReduced(Iterator begin, - Iterator end, - bool (keep)(T), - U (C::*reduce)(V), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return filteredReduced(begin, - end, - FunctionWrapper1(keep), - MemberFunctionWrapper1(reduce), - options); + return startFilteredReduced::ResultType> + (begin, end, + QtPrivate::createFunctionWrapper(keep), + QtPrivate::createFunctionWrapper(reduce), + options); } -template -QFuture filteredReduced(Iterator begin, - Iterator end, - bool (C::*keep)() const, - T (D::*reduce)(U), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return filteredReduced(begin, - end, - ConstMemberFunctionWrapper(keep), - MemberFunctionWrapper1(reduce), - options); -} - - // filtered() on sequences template QFuture filtered(const Sequence &sequence, KeepFunctor keep) { - return startFiltered(sequence, keep); -} - -template -QFuture filtered(const Sequence &sequence, bool (keep)(T)) -{ - return startFiltered(sequence, FunctionWrapper1(keep)); -} - -template -QFuture filtered(const Sequence &sequence, bool (C::*keep)() const) -{ - return startFiltered(sequence, ConstMemberFunctionWrapper(keep)); + return startFiltered(sequence, QtPrivate::createFunctionWrapper(keep)); } // filtered() on iterators template QFuture::value_type> filtered(Iterator begin, Iterator end, KeepFunctor keep) { - return startFiltered(begin, end, keep); + return startFiltered(begin, end, QtPrivate::createFunctionWrapper(keep)); } -template -QFuture::value_type> filtered(Iterator begin, Iterator end, bool (keep)(T)) -{ - return startFiltered(begin, end, FunctionWrapper1(keep)); -} - -template -QFuture::value_type> filtered(Iterator begin, - Iterator end, - bool (C::*keep)() const) -{ - return startFiltered(begin, end, ConstMemberFunctionWrapper(keep)); -} - - // blocking filter() on sequences template void blockingFilter(Sequence &sequence, KeepFunctor keep) { - filterInternal(sequence, keep, &Sequence::push_back).startBlocking(); -} - -template -void blockingFilter(Sequence &sequence, bool (keep)(T)) -{ - filterInternal(sequence, FunctionWrapper1(keep), &Sequence::push_back) - .startBlocking(); -} - -template -void blockingFilter(Sequence &sequence, bool (C::*keep)() const) -{ - filterInternal(sequence, - ConstMemberFunctionWrapper(keep), - &Sequence::push_back) - .startBlocking(); + filterInternal(sequence, QtPrivate::createFunctionWrapper(keep), &Sequence::push_back).startBlocking(); } // blocking filteredReduced() on sequences @@ -431,111 +194,20 @@ ResultType blockingFilteredReduced(const Sequence &sequence, ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startFilteredReduced(sequence, keep, reduce, options) + return startFilteredReduced(sequence, QtPrivate::createFunctionWrapper(keep), QtPrivate::createFunctionWrapper(reduce), options) .startBlocking(); } -template -ResultType blockingFilteredReduced(const Sequence &sequence, - bool (filter)(T), - ReduceFunctor reduce, - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return blockingFilteredReduced - (sequence, - FunctionWrapper1(filter), - reduce, - options); -} - -template -ResultType blockingFilteredReduced(const Sequence &sequence, - bool (C::*filter)() const, +template +typename QtPrivate::ReduceResultType::ResultType blockingFilteredReduced(const Sequence &sequence, + KeepFunctor keep, ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return blockingFilteredReduced - (sequence, - ConstMemberFunctionWrapper(filter), - reduce, - options); -} - -template -U blockingFilteredReduced(const Sequence &sequence, - KeepFunctor keep, - T (reduce)(U &, V), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return blockingFilteredReduced - (sequence, - keep, - FunctionWrapper2(reduce), - options); -} - -template -C blockingFilteredReduced(const Sequence &sequence, - KeepFunctor keep, - T (C::*reduce)(U), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return blockingFilteredReduced + return blockingFilteredReduced::ResultType> (sequence, - keep, - MemberFunctionWrapper1(reduce), - options); -} - -template -V blockingFilteredReduced(const Sequence &sequence, - bool (keep)(T), - U (reduce)(V &, W), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return blockingFilteredReduced - (sequence, - FunctionWrapper1(keep), - FunctionWrapper2(reduce), - options); -} - -template -U blockingFilteredReduced(const Sequence &sequence, - bool (C::*keep)() const, - T (reduce)(U &, V), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return blockingFilteredReduced - (sequence, - ConstMemberFunctionWrapper(keep), - FunctionWrapper2(reduce), - options); -} - -template -C blockingFilteredReduced(const Sequence &sequence, - bool (keep)(T), - U (C::*reduce)(V), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return blockingFilteredReduced - (sequence, - FunctionWrapper1(keep), - MemberFunctionWrapper1(reduce), - options); -} - -template -D blockingFilteredReduced(const Sequence &sequence, - bool (C::*keep)() const, - T (D::*reduce)(U), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return blockingFilteredReduced - (sequence, - ConstMemberFunctionWrapper(keep), - MemberFunctionWrapper1(reduce), + QtPrivate::createFunctionWrapper(keep), + QtPrivate::createFunctionWrapper(reduce), options); } @@ -547,150 +219,34 @@ ResultType blockingFilteredReduced(Iterator begin, ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startFilteredReduced(begin, end, keep, reduce, options) + return startFilteredReduced + (begin, end, + QtPrivate::createFunctionWrapper(keep), + QtPrivate::createFunctionWrapper(reduce), + options) .startBlocking(); } -template -ResultType blockingFilteredReduced(Iterator begin, - Iterator end, - bool (filter)(T), - ReduceFunctor reduce, - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return blockingFilteredReduced - (begin, - end, - FunctionWrapper1(filter), - reduce, - options); -} - -template -ResultType blockingFilteredReduced(Iterator begin, +template +typename QtPrivate::ReduceResultType::ResultType blockingFilteredReduced(Iterator begin, Iterator end, - bool (C::*filter)() const, + KeepFunctor keep, ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return blockingFilteredReduced - (begin, - end, - ConstMemberFunctionWrapper(filter), - reduce, - options); -} - -template -U blockingFilteredReduced(Iterator begin, - Iterator end, - KeepFunctor keep, - T (reduce)(U &, V), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return blockingFilteredReduced - (begin, - end, - keep, - FunctionWrapper2(reduce), - options); -} - -template -C blockingFilteredReduced(Iterator begin, - Iterator end, - KeepFunctor keep, - T (C::*reduce)(U), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return blockingFilteredReduced - (begin, - end, - keep, - MemberFunctionWrapper1(reduce), - options); -} - -template -V blockingFilteredReduced(Iterator begin, - Iterator end, - bool (keep)(T), - U (reduce)(V &, W), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return blockingFilteredReduced - (begin, - end, - FunctionWrapper1(keep), - FunctionWrapper2(reduce), - options); -} - -template -U blockingFilteredReduced(Iterator begin, - Iterator end, - bool (C::*keep)() const, - T (reduce)(U &, V), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return blockingFilteredReduced - (begin, - end, - ConstMemberFunctionWrapper(keep), - FunctionWrapper2(reduce), - options); -} - -template -C blockingFilteredReduced(Iterator begin, - Iterator end, - bool (keep)(T), - U (C::*reduce)(V), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return blockingFilteredReduced - (begin, - end, - FunctionWrapper1(keep), - MemberFunctionWrapper1(reduce), - options); -} - -template -D blockingFilteredReduced(Iterator begin, - Iterator end, - bool (C::*keep)() const, - T (D::*reduce)(U), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return blockingFilteredReduced - (begin, - end, - ConstMemberFunctionWrapper(keep), - MemberFunctionWrapper1(reduce), - options); + return startFilteredReduced::ResultType> + (begin, end, + QtPrivate::createFunctionWrapper(keep), + QtPrivate::createFunctionWrapper(reduce), + options) + .startBlocking(); } // blocking filtered() on sequences template Sequence blockingFiltered(const Sequence &sequence, KeepFunctor keep) { - return blockingFilteredReduced(sequence, keep, &Sequence::push_back, OrderedReduce); -} - -template -Sequence blockingFiltered(const Sequence &sequence, bool (keep)(T)) -{ - return blockingFilteredReduced(sequence, keep, &Sequence::push_back, OrderedReduce); -} - -template -Sequence blockingFiltered(const Sequence &sequence, bool (C::*filter)() const) -{ - return blockingFilteredReduced(sequence, - filter, - &Sequence::push_back, - OrderedReduce); + return blockingFilteredReduced(sequence, QtPrivate::createFunctionWrapper(keep), &Sequence::push_back, OrderedReduce); } // blocking filtered() on iterators @@ -699,27 +255,7 @@ OutputSequence blockingFiltered(Iterator begin, Iterator end, KeepFunctor keep) { return blockingFilteredReduced(begin, end, - keep, - &OutputSequence::push_back, - OrderedReduce); -} - -template -OutputSequence blockingFiltered(Iterator begin, Iterator end, bool (keep)(T)) -{ - return blockingFilteredReduced(begin, - end, - keep, - &OutputSequence::push_back, - OrderedReduce); -} - -template -OutputSequence blockingFiltered(Iterator begin, Iterator end, bool (C::*filter)() const) -{ - return blockingFilteredReduced(begin, - end, - filter, + QtPrivate::createFunctionWrapper(keep), &OutputSequence::push_back, OrderedReduce); } diff --git a/src/corelib/concurrent/qtconcurrentfunctionwrappers.h b/src/corelib/concurrent/qtconcurrentfunctionwrappers.h index f31f7d2..1c19164 100644 --- a/src/corelib/concurrent/qtconcurrentfunctionwrappers.h +++ b/src/corelib/concurrent/qtconcurrentfunctionwrappers.h @@ -163,6 +163,143 @@ private: } // namespace QtConcurrent. +namespace QtPrivate { + +template +const T& createFunctionWrapper(const T& t) +{ + return t; +} + +template +QtConcurrent::FunctionWrapper1 createFunctionWrapper(T (*func)(U)) +{ + return QtConcurrent::FunctionWrapper1(func); +} + +template +QtConcurrent::MemberFunctionWrapper createFunctionWrapper(T (C::*func)()) +{ + return QtConcurrent::MemberFunctionWrapper(func); +} + +template +QtConcurrent::MemberFunctionWrapper1 createFunctionWrapper(T (C::*func)(U)) +{ + return QtConcurrent::MemberFunctionWrapper1(func); +} + +template +QtConcurrent::ConstMemberFunctionWrapper createFunctionWrapper(T (C::*func)() const) +{ + return QtConcurrent::ConstMemberFunctionWrapper(func); +} + +template +struct ReduceResultType; + +template +struct ReduceResultType +{ + typedef U ResultType; +}; + +template +struct ReduceResultType +{ + typedef C ResultType; +}; + +template +struct MapResultType +{ + typedef typename MapFunctor::result_type ResultType; +}; + +template +struct MapResultType +{ + typedef U ResultType; +}; + +template +struct MapResultType +{ + typedef T ResultType; +}; + +#ifndef QT_NO_TEMPLATE_TEMPLATE_PARAMETERS + +template