diff options
author | Bill King <bill.king@nokia.com> | 2010-01-04 23:51:54 (GMT) |
---|---|---|
committer | Bill King <bill.king@nokia.com> | 2010-01-04 23:51:54 (GMT) |
commit | b72d504e686f0c51c3afef2cc34baa1436cb90e1 (patch) | |
tree | 5e239e2660b8bc13ea509d3fc154b9930b82b059 | |
parent | cc39141c7526f95147b4a4983e30adecd8a84e28 (diff) | |
parent | 619392c059326c11c24c1092ab62dd091114a0ab (diff) | |
download | Qt-b72d504e686f0c51c3afef2cc34baa1436cb90e1.zip Qt-b72d504e686f0c51c3afef2cc34baa1436cb90e1.tar.gz Qt-b72d504e686f0c51c3afef2cc34baa1436cb90e1.tar.bz2 |
Merge branch '4.6' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into 4.6
85 files changed, 1772 insertions, 824 deletions
@@ -5107,7 +5107,7 @@ if [ "$PLATFORM_X11" = "yes" ]; then if [ $? != "0" ]; then echo "The OpenGL ES 1.x Common Lite Profile functionality test failed!" echo " You might need to modify the include and library search paths by editing" - echo " QMAKE_INCDIR_OPENGL, QMAKE_LIBDIR_OPENGL and QMAKE_LIBS_OPENGL in" + echo " QMAKE_INCDIR_OPENGL_ES1CL, QMAKE_LIBDIR_OPENGL_ES1CL and QMAKE_LIBS_OPENGL_ES1CL in" echo " ${XQMAKESPEC}." exit 1 fi @@ -5117,7 +5117,7 @@ if [ "$PLATFORM_X11" = "yes" ]; then if [ $? != "0" ]; then echo "The OpenGL ES 1.x functionality test failed!" echo " You might need to modify the include and library search paths by editing" - echo " QMAKE_INCDIR_OPENGL, QMAKE_LIBDIR_OPENGL and QMAKE_LIBS_OPENGL in" + echo " QMAKE_INCDIR_OPENGL_ES1, QMAKE_LIBDIR_OPENGL_ES1 and QMAKE_LIBS_OPENGL_ES1 in" echo " ${XQMAKESPEC}." exit 1 fi @@ -5127,7 +5127,7 @@ if [ "$PLATFORM_X11" = "yes" ]; then if [ $? != "0" ]; then echo "The OpenGL ES 2.0 functionality test failed!" echo " You might need to modify the include and library search paths by editing" - echo " QMAKE_INCDIR_OPENGL, QMAKE_LIBDIR_OPENGL and QMAKE_LIBS_OPENGL in" + echo " QMAKE_INCDIR_OPENGL_ES2, QMAKE_LIBDIR_OPENGL_ES2 and QMAKE_LIBS_OPENGL_ES2 in" echo " ${XQMAKESPEC}." exit 1 fi diff --git a/demos/embedded/anomaly/src/flickcharm.cpp b/demos/embedded/anomaly/src/flickcharm.cpp index 0b9e68e..b7e2151 100644 --- a/demos/embedded/anomaly/src/flickcharm.cpp +++ b/demos/embedded/anomaly/src/flickcharm.cpp @@ -49,20 +49,112 @@ #include <QList> #include <QMouseEvent> #include <QScrollBar> +#include <QTime> #include <QWebFrame> #include <QWebView> #include <QDebug> +const int fingerAccuracyThreshold = 3; + struct FlickData { - typedef enum { Steady, Pressed, ManualScroll, AutoScroll, Stop } State; + typedef enum { + Steady, // Interaction without scrolling + ManualScroll, // Scrolling manually with the finger on the screen + AutoScroll, // Scrolling automatically + AutoScrollAcceleration // Scrolling automatically but a finger is on the screen + } State; State state; QWidget *widget; QPoint pressPos; - QPoint offset; - QPoint dragPos; + QPoint lastPos; QPoint speed; + QTime speedTimer; QList<QEvent*> ignored; + QTime accelerationTimer; + bool lastPosValid:1; + bool waitingAcceleration:1; + + FlickData() + : lastPosValid(false) + , waitingAcceleration(false) + {} + + void resetSpeed() + { + speed = QPoint(); + lastPosValid = false; + } + void updateSpeed(const QPoint &newPosition) + { + if (lastPosValid) { + const int timeElapsed = speedTimer.elapsed(); + if (timeElapsed) { + const QPoint newPixelDiff = (newPosition - lastPos); + const QPoint pixelsPerSecond = newPixelDiff * (1000 / timeElapsed); + // fingers are inacurates, we ignore small changes to avoid stopping the autoscroll because + // of a small horizontal offset when scrolling vertically + const int newSpeedY = (qAbs(pixelsPerSecond.y()) > fingerAccuracyThreshold) ? pixelsPerSecond.y() : 0; + const int newSpeedX = (qAbs(pixelsPerSecond.x()) > fingerAccuracyThreshold) ? pixelsPerSecond.x() : 0; + if (state == AutoScrollAcceleration) { + const int max = 4000; // px by seconds + const int oldSpeedY = speed.y(); + const int oldSpeedX = speed.x(); + if ((oldSpeedY <= 0 && newSpeedY <= 0) || (oldSpeedY >= 0 && newSpeedY >= 0) + && (oldSpeedX <= 0 && newSpeedX <= 0) || (oldSpeedX >= 0 && newSpeedX >= 0)) { + speed.setY(qBound(-max, (oldSpeedY + (newSpeedY / 4)), max)); + speed.setX(qBound(-max, (oldSpeedX + (newSpeedX / 4)), max)); + } else { + speed = QPoint(); + } + } else { + const int max = 2500; // px by seconds + // we average the speed to avoid strange effects with the last delta + if (!speed.isNull()) { + speed.setX(qBound(-max, (speed.x() / 4) + (newSpeedX * 3 / 4), max)); + speed.setY(qBound(-max, (speed.y() / 4) + (newSpeedY * 3 / 4), max)); + } else { + speed = QPoint(newSpeedX, newSpeedY); + } + } + } + } else { + lastPosValid = true; + } + speedTimer.start(); + lastPos = newPosition; + } + + // scroll by dx, dy + // return true if the widget was scrolled + bool scrollWidget(const int dx, const int dy) + { + QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea*>(widget); + if (scrollArea) { + const int x = scrollArea->horizontalScrollBar()->value(); + const int y = scrollArea->verticalScrollBar()->value(); + scrollArea->horizontalScrollBar()->setValue(x - dx); + scrollArea->verticalScrollBar()->setValue(y - dy); + return (scrollArea->horizontalScrollBar()->value() != x + || scrollArea->verticalScrollBar()->value() != y); + } + + QWebView *webView = qobject_cast<QWebView*>(widget); + if (webView) { + QWebFrame *frame = webView->page()->mainFrame(); + const QPoint position = frame->scrollPosition(); + frame->setScrollPosition(position - QPoint(dx, dy)); + return frame->scrollPosition() != position; + } + return false; + } + + bool scrollTo(const QPoint &newPosition) + { + const QPoint delta = newPosition - lastPos; + updateSpeed(newPosition); + return scrollWidget(delta.x(), delta.y()); + } }; class FlickCharmPrivate @@ -70,6 +162,13 @@ class FlickCharmPrivate public: QHash<QWidget*, FlickData*> flickData; QBasicTimer ticker; + QTime timeCounter; + void startTicker(QObject *object) + { + if (!ticker.isActive()) + ticker.start(15, object); + timeCounter.start(); + } }; FlickCharm::FlickCharm(QObject *parent): QObject(parent) @@ -148,46 +247,14 @@ void FlickCharm::deactivateFrom(QWidget *widget) } } -static QPoint scrollOffset(QWidget *widget) +static QPoint deaccelerate(const QPoint &speed, const int deltatime) { - int x = 0, y = 0; - - QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea*>(widget); - if (scrollArea) { - x = scrollArea->horizontalScrollBar()->value(); - y = scrollArea->verticalScrollBar()->value(); - } - - QWebView *webView = qobject_cast<QWebView*>(widget); - if (webView) { - QWebFrame *frame = webView->page()->mainFrame(); - x = frame->evaluateJavaScript("window.scrollX").toInt(); - y = frame->evaluateJavaScript("window.scrollY").toInt(); - } - - return QPoint(x, y); -} - -static void setScrollOffset(QWidget *widget, const QPoint &p) -{ - QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea*>(widget); - if (scrollArea) { - scrollArea->horizontalScrollBar()->setValue(p.x()); - scrollArea->verticalScrollBar()->setValue(p.y()); - } + const int deltaSpeed = deltatime; - QWebView *webView = qobject_cast<QWebView*>(widget); - QWebFrame *frame = webView ? webView->page()->mainFrame() : 0; - if (frame) - frame->evaluateJavaScript(QString("window.scrollTo(%1,%2);").arg(p.x()).arg(p.y())); -} - -static QPoint deaccelerate(const QPoint &speed, int a = 1, int max = 64) -{ - int x = qBound(-max, speed.x(), max); - int y = qBound(-max, speed.y(), max); - x = (x == 0) ? x : (x > 0) ? qMax(0, x - a) : qMin(0, x + a); - y = (y == 0) ? y : (y > 0) ? qMax(0, y - a) : qMin(0, y + a); + int x = speed.x(); + int y = speed.y(); + x = (x == 0) ? x : (x > 0) ? qMax(0, x - deltaSpeed) : qMin(0, x + deltaSpeed); + y = (y == 0) ? y : (y > 0) ? qMax(0, y - deltaSpeed) : qMin(0, y + deltaSpeed); return QPoint(x, y); } @@ -196,22 +263,24 @@ bool FlickCharm::eventFilter(QObject *object, QEvent *event) if (!object->isWidgetType()) return false; - QEvent::Type type = event->type(); - if (type != QEvent::MouseButtonPress && - type != QEvent::MouseButtonRelease && - type != QEvent::MouseMove) - return false; + const QEvent::Type type = event->type(); - QMouseEvent *mouseEvent = 0; - switch (event->type()) { - case QEvent::MouseButtonPress: - case QEvent::MouseButtonRelease: - case QEvent::MouseMove: - mouseEvent = static_cast<QMouseEvent*>(event); - break; + switch (type) { + case QEvent::MouseButtonPress: + case QEvent::MouseMove: + case QEvent::MouseButtonRelease: + break; + case QEvent::MouseButtonDblClick: // skip double click + return true; + default: + return false; } - if (!mouseEvent || mouseEvent->modifiers() != Qt::NoModifier) + QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event); + if (type == QEvent::MouseMove && mouseEvent->buttons() != Qt::LeftButton) + return false; + + if (mouseEvent->modifiers() != Qt::NoModifier) return false; QWidget *viewport = qobject_cast<QWidget*>(object); @@ -219,89 +288,83 @@ bool FlickCharm::eventFilter(QObject *object, QEvent *event) if (!viewport || !data || data->ignored.removeAll(event)) return false; + const QPoint mousePos = mouseEvent->pos(); bool consumed = false; switch (data->state) { case FlickData::Steady: - if (mouseEvent->type() == QEvent::MouseButtonPress) - if (mouseEvent->buttons() == Qt::LeftButton) { - consumed = true; - data->state = FlickData::Pressed; - data->pressPos = mouseEvent->pos(); - data->offset = scrollOffset(data->widget); - } - break; - - case FlickData::Pressed: - if (mouseEvent->type() == QEvent::MouseButtonRelease) { + if (type == QEvent::MouseButtonPress) { + consumed = true; + data->pressPos = mousePos; + } else if (type == QEvent::MouseButtonRelease) { consumed = true; - data->state = FlickData::Steady; - QMouseEvent *event1 = new QMouseEvent(QEvent::MouseButtonPress, data->pressPos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); - QMouseEvent *event2 = new QMouseEvent(*mouseEvent); + QMouseEvent *event2 = new QMouseEvent(QEvent::MouseButtonRelease, + data->pressPos, Qt::LeftButton, + Qt::LeftButton, Qt::NoModifier); data->ignored << event1; data->ignored << event2; QApplication::postEvent(object, event1); QApplication::postEvent(object, event2); - } - if (mouseEvent->type() == QEvent::MouseMove) { + } else if (type == QEvent::MouseMove) { consumed = true; - data->state = FlickData::ManualScroll; - data->dragPos = QCursor::pos(); - if (!d->ticker.isActive()) - d->ticker.start(20, this); + data->scrollTo(mousePos); + + const QPoint delta = mousePos - data->pressPos; + if (delta.x() > fingerAccuracyThreshold || delta.y() > fingerAccuracyThreshold) + data->state = FlickData::ManualScroll; } break; case FlickData::ManualScroll: - if (mouseEvent->type() == QEvent::MouseMove) { + if (type == QEvent::MouseMove) { consumed = true; - QPoint delta = mouseEvent->pos() - data->pressPos; - setScrollOffset(data->widget, data->offset - delta); - } - if (mouseEvent->type() == QEvent::MouseButtonRelease) { + data->scrollTo(mousePos); + } else if (type == QEvent::MouseButtonRelease) { consumed = true; data->state = FlickData::AutoScroll; + data->lastPosValid = false; + d->startTicker(this); } break; case FlickData::AutoScroll: - if (mouseEvent->type() == QEvent::MouseButtonPress) { + if (type == QEvent::MouseButtonPress) { consumed = true; - data->state = FlickData::Stop; - data->speed = QPoint(0, 0); - data->pressPos = mouseEvent->pos(); - data->offset = scrollOffset(data->widget); - } - if (mouseEvent->type() == QEvent::MouseButtonRelease) { + data->state = FlickData::AutoScrollAcceleration; + data->waitingAcceleration = true; + data->accelerationTimer.start(); + data->updateSpeed(mousePos); + data->pressPos = mousePos; + } else if (type == QEvent::MouseButtonRelease) { consumed = true; data->state = FlickData::Steady; - data->speed = QPoint(0, 0); + data->resetSpeed(); } break; - case FlickData::Stop: - if (mouseEvent->type() == QEvent::MouseButtonRelease) { + case FlickData::AutoScrollAcceleration: + if (type == QEvent::MouseMove) { consumed = true; - data->state = FlickData::Steady; - } - if (mouseEvent->type() == QEvent::MouseMove) { + data->updateSpeed(mousePos); + data->accelerationTimer.start(); + if (data->speed.isNull()) + data->state = FlickData::ManualScroll; + } else if (type == QEvent::MouseButtonRelease) { consumed = true; - data->state = FlickData::ManualScroll; - data->dragPos = QCursor::pos(); - if (!d->ticker.isActive()) - d->ticker.start(20, this); + data->state = FlickData::AutoScroll; + data->waitingAcceleration = false; + data->lastPosValid = false; } break; - default: break; } - - return consumed; + data->lastPos = mousePos; + return true; } void FlickCharm::timerEvent(QTimerEvent *event) @@ -311,25 +374,29 @@ void FlickCharm::timerEvent(QTimerEvent *event) while (item.hasNext()) { item.next(); FlickData *data = item.value(); - - if (data->state == FlickData::ManualScroll) { - count++; - data->speed = QCursor::pos() - data->dragPos; - data->dragPos = QCursor::pos(); + if (data->state == FlickData::AutoScrollAcceleration + && data->waitingAcceleration + && data->accelerationTimer.elapsed() > 40) { + data->state = FlickData::ManualScroll; + data->resetSpeed(); } + if (data->state == FlickData::AutoScroll || data->state == FlickData::AutoScrollAcceleration) { + const int timeElapsed = d->timeCounter.elapsed(); + const QPoint delta = (data->speed) * timeElapsed / 1000; + bool hasScrolled = data->scrollWidget(delta.x(), delta.y()); - if (data->state == FlickData::AutoScroll) { - count++; - data->speed = deaccelerate(data->speed); - QPoint p = scrollOffset(data->widget); - setScrollOffset(data->widget, p - data->speed); - if (data->speed == QPoint(0, 0)) + if (data->speed.isNull() || !hasScrolled) data->state = FlickData::Steady; + else + count++; + data->speed = deaccelerate(data->speed, timeElapsed); } } if (!count) d->ticker.stop(); + else + d->timeCounter.start(); QObject::timerEvent(event); } diff --git a/demos/embedded/fluidlauncher/fluidlauncher.pro b/demos/embedded/fluidlauncher/fluidlauncher.pro index b47f6a0..bb8835b 100644 --- a/demos/embedded/fluidlauncher/fluidlauncher.pro +++ b/demos/embedded/fluidlauncher/fluidlauncher.pro @@ -163,6 +163,11 @@ symbian { resource.sources += $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/anomaly.rsc mifs.sources += \ $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/anomaly.mif + + # Since Fluidlauncher itself doesn't link webkit, we won't get dependency automatically + executables.pkg_prerules += \ + "; Dependency to Qt Webkit" \ + "(0x200267C2), $${QT_MAJOR_VERSION}, $${QT_MINOR_VERSION}, $${QT_PATCH_VERSION}, {\"QtWebKit\"}" } contains(QT_CONFIG, phonon) { diff --git a/mkspecs/features/symbian/platform_paths.prf b/mkspecs/features/symbian/platform_paths.prf index bec9811..f5caae0 100644 --- a/mkspecs/features/symbian/platform_paths.prf +++ b/mkspecs/features/symbian/platform_paths.prf @@ -216,10 +216,11 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { OS_LAYER_SSL_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/openssl) # stlportv5 is preferred over stlport as it has the throwing version of operator new - exists($${EPOCROOT}epoc32/include/stdapis/stlportv5) { - OS_LAYER_STDCPP_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/stlportv5) - } else { + exists($${EPOCROOT}epoc32/include/stdapis/stlport) \ + :!exists($${EPOCROOT}epoc32/include/stdapis/stlportv5) { OS_LAYER_STDCPP_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/stlport) + } else { + OS_LAYER_STDCPP_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/stlportv5) } OS_LAYER_BOOST_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/boost) @@ -427,12 +428,15 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { /epoc32/include/stdapis/openssl # stlportv5 is preferred over stlport as it has the throwing version of operator new - exists($${EPOCROOT}epoc32/include/osextensions/stdapis/stlportv5)|exists($${EPOCROOT}epoc32/include/stdapis/stlportv5) { - OS_LAYER_STDCPP_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/stlportv5) \ - /epoc32/include/stdapis/stlportv5 - } else { - OS_LAYER_STDCPP_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/stlport) \ - /epoc32/include/stdapis/stlport + OS_LAYER_STDCPP_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/stlportv5) \ + /epoc32/include/stdapis/stlportv5 + exists($${EPOCROOT}epoc32/include/osextensions/stdapis/stlport) \ + |exists($${EPOCROOT}epoc32/include/stdapis/stlport) { + !exists($${EPOCROOT}epoc32/include/osextensions/stdapis/stlportv5) \ + :!exists($${EPOCROOT}epoc32/include/stdapis/stlportv5) { + OS_LAYER_STDCPP_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/stlport) \ + /epoc32/include/stdapis/stlport + } } OS_LAYER_BOOST_SYSTEMINCLUDE = $$OS_LAYER_PUBLIC_EXPORT_PATH(stdapis/boost) \ diff --git a/mkspecs/features/symbian/qt.prf b/mkspecs/features/symbian/qt.prf index 0f5b08b..99f5ece 100644 --- a/mkspecs/features/symbian/qt.prf +++ b/mkspecs/features/symbian/qt.prf @@ -28,6 +28,13 @@ contains(CONFIG, qt):!contains(TARGET.UID3, 0x2001E61C):!contains(TARGET.UID3, 0 default_deployment.pkg_prerules += \ "; Default dependency to Qt libraries" \ "(0x2001E61C), $${QT_MAJOR_VERSION}, $${QT_MINOR_VERSION}, $${QT_PATCH_VERSION}, {\"Qt\"}" + + # Projects linking to webkit need dependency to webkit + contains(QT, webkit): { + default_deployment.pkg_prerules += \ + "; Dependency to Qt Webkit" \ + "(0x200267C2), $${QT_MAJOR_VERSION}, $${QT_MINOR_VERSION}, $${QT_PATCH_VERSION}, {\"QtWebKit\"}" + } } isEmpty(TARGET.EPOCSTACKSIZE):TARGET.EPOCSTACKSIZE = 0x14000 diff --git a/mkspecs/linux-g++-maemo/qmake.conf b/mkspecs/linux-g++-maemo/qmake.conf index c39ba2c..b0f3ca3 100644 --- a/mkspecs/linux-g++-maemo/qmake.conf +++ b/mkspecs/linux-g++-maemo/qmake.conf @@ -5,6 +5,7 @@ MAKEFILE_GENERATOR = UNIX TEMPLATE = app CONFIG += qt warn_on release incremental link_prl +CONFIG += nostrip QT += core gui QMAKE_INCREMENTAL_STYLE = sublib diff --git a/mkspecs/linux-g++/qplatformdefs.h b/mkspecs/linux-g++/qplatformdefs.h index ecfbc73..00f1b51 100644 --- a/mkspecs/linux-g++/qplatformdefs.h +++ b/mkspecs/linux-g++/qplatformdefs.h @@ -67,7 +67,6 @@ #include <grp.h> #include <pwd.h> #include <signal.h> -#include <dlfcn.h> #include <sys/types.h> #include <sys/ioctl.h> diff --git a/mkspecs/solaris-cc-64-stlport/qmake.conf b/mkspecs/solaris-cc-64-stlport/qmake.conf new file mode 100644 index 0000000..3437b8f --- /dev/null +++ b/mkspecs/solaris-cc-64-stlport/qmake.conf @@ -0,0 +1,8 @@ +# +# qmake configuration for solaris-cc-64-stlport +# + +include(../solaris-cc-64/qmake.conf) + +QMAKE_CXXFLAGS += -library=stlport4 +QMAKE_LFLAGS += -library=stlport4 diff --git a/mkspecs/solaris-cc-64-stlport/qplatformdefs.h b/mkspecs/solaris-cc-64-stlport/qplatformdefs.h new file mode 100644 index 0000000..7c88722 --- /dev/null +++ b/mkspecs/solaris-cc-64-stlport/qplatformdefs.h @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake spec 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 "../solaris-cc-64/qplatformdefs.h" diff --git a/mkspecs/solaris-cc-stlport/qmake.conf b/mkspecs/solaris-cc-stlport/qmake.conf new file mode 100644 index 0000000..b0df45e --- /dev/null +++ b/mkspecs/solaris-cc-stlport/qmake.conf @@ -0,0 +1,8 @@ +# +# qmake configuration for solaris-cc-stlport +# + +include(../solaris-cc/qmake.conf) + +QMAKE_CXXFLAGS += -library=stlport4 +QMAKE_LFLAGS += -library=stlport4 diff --git a/mkspecs/solaris-cc-stlport/qplatformdefs.h b/mkspecs/solaris-cc-stlport/qplatformdefs.h new file mode 100644 index 0000000..bb75c1f --- /dev/null +++ b/mkspecs/solaris-cc-stlport/qplatformdefs.h @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake spec 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 "../solaris-cc/qplatformdefs.h" diff --git a/qmake/generators/symbian/symmake.cpp b/qmake/generators/symbian/symmake.cpp index 14177b5..ddda848 100644 --- a/qmake/generators/symbian/symmake.cpp +++ b/qmake/generators/symbian/symmake.cpp @@ -1764,7 +1764,9 @@ void SymbianMakefileGenerator::writeSisTargets(QTextStream &t) { t << SIS_TARGET ": " RESTORE_BUILD_TARGET << endl; QString siscommand = QString("\t$(if $(wildcard %1_template.%2),$(if $(wildcard %3)," \ - "$(MAKE) -s -f $(MAKEFILE) %4,$(MAKE) -s -f $(MAKEFILE) %5)," \ + "$(MAKE) -s -f $(MAKEFILE) %4," \ + "$(if $(QT_SIS_TARGET),$(MAKE) -s -f $(MAKEFILE) %4," \ + "$(MAKE) -s -f $(MAKEFILE) %5))," \ "$(MAKE) -s -f $(MAKEFILE) %6)") .arg(fixedTarget) .arg("pkg") @@ -1789,7 +1791,7 @@ void SymbianMakefileGenerator::writeSisTargets(QTextStream &t) t << endl; t << FAIL_SIS_NOCACHE_TARGET ":" << endl; - t << "\t$(error Project has to be build before calling 'SIS' target)" << endl; + t << "\t$(error Project has to be built or QT_SIS_TARGET environment variable has to be set before calling 'SIS' target)" << endl; t << endl; diff --git a/src/3rdparty/webkit/JavaScriptCore/ChangeLog b/src/3rdparty/webkit/JavaScriptCore/ChangeLog index d7d2d57..50cff63 100644 --- a/src/3rdparty/webkit/JavaScriptCore/ChangeLog +++ b/src/3rdparty/webkit/JavaScriptCore/ChangeLog @@ -1,3 +1,15 @@ +2009-12-18 Yongjun Zhang <yongjun.zhang@nokia.com> + + Reviewed by Simon Hausmann. + + https://bugs.webkit.org/show_bug.cgi?id=32713 + [Qt] make wtf/Assertions.h compile in winscw compiler. + + Add string arg before ellipsis to help winscw compiler resolve variadic + macro definitions in wtf/Assertions.h. + + * wtf/Assertions.h: + 2009-11-30 Jan-Arve Sæther <jan-arve.saether@nokia.com> Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/Assertions.h b/src/3rdparty/webkit/JavaScriptCore/wtf/Assertions.h index f529a62..aa72e5a 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/Assertions.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/Assertions.h @@ -158,8 +158,8 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann #define ASSERT(assertion) ((void)0) #if COMPILER(MSVC7) #define ASSERT_WITH_MESSAGE(assertion) ((void)0) -#elif PLATFORM(SYMBIAN) -#define ASSERT_WITH_MESSAGE(assertion...) ((void)0) +#elif COMPILER(WINSCW) +#define ASSERT_WITH_MESSAGE(assertion, arg...) ((void)0) #else #define ASSERT_WITH_MESSAGE(assertion, ...) ((void)0) #endif /* COMPILER(MSVC7) */ @@ -176,8 +176,8 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann while (0) #if COMPILER(MSVC7) #define ASSERT_WITH_MESSAGE(assertion) ((void)0) -#elif PLATFORM(SYMBIAN) -#define ASSERT_WITH_MESSAGE(assertion...) ((void)0) +#elif COMPILER(WINSCW) +#define ASSERT_WITH_MESSAGE(assertion, arg...) ((void)0) #else #define ASSERT_WITH_MESSAGE(assertion, ...) do \ if (!(assertion)) { \ @@ -219,11 +219,11 @@ while (0) /* FATAL */ -#if FATAL_DISABLED && !COMPILER(MSVC7) && !PLATFORM(SYMBIAN) +#if FATAL_DISABLED && !COMPILER(MSVC7) && !COMPILER(WINSCW) #define FATAL(...) ((void)0) #elif COMPILER(MSVC7) #define FATAL() ((void)0) -#elif PLATFORM(SYMBIAN) +#elif COMPILER(WINSCW) #define FATAL(args...) ((void)0) #else #define FATAL(...) do { \ @@ -234,24 +234,24 @@ while (0) /* LOG_ERROR */ -#if ERROR_DISABLED && !COMPILER(MSVC7) && !PLATFORM(SYMBIAN) +#if ERROR_DISABLED && !COMPILER(MSVC7) && !COMPILER(WINSCW) #define LOG_ERROR(...) ((void)0) #elif COMPILER(MSVC7) #define LOG_ERROR() ((void)0) -#elif PLATFORM(SYMBIAN) -#define LOG_ERROR(args...) ((void)0) +#elif COMPILER(WINSCW) +#define LOG_ERROR(arg...) ((void)0) #else #define LOG_ERROR(...) WTFReportError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__) #endif /* LOG */ -#if LOG_DISABLED && !COMPILER(MSVC7) && !PLATFORM(SYMBIAN) +#if LOG_DISABLED && !COMPILER(MSVC7) && !COMPILER(WINSCW) #define LOG(channel, ...) ((void)0) #elif COMPILER(MSVC7) #define LOG() ((void)0) -#elif PLATFORM(SYMBIAN) -#define LOG(channel, args...) ((void)0) +#elif COMPILER(WINSCW) +#define LOG(arg...) ((void)0) #else #define LOG(channel, ...) WTFLog(&JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__) #define JOIN_LOG_CHANNEL_WITH_PREFIX(prefix, channel) JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel) @@ -260,12 +260,12 @@ while (0) /* LOG_VERBOSE */ -#if LOG_DISABLED && !COMPILER(MSVC7) && !PLATFORM(SYMBIAN) +#if LOG_DISABLED && !COMPILER(MSVC7) && !COMPILER(WINSCW) #define LOG_VERBOSE(channel, ...) ((void)0) #elif COMPILER(MSVC7) #define LOG_VERBOSE(channel) ((void)0) -#elif PLATFORM(SYMBIAN) -#define LOG_VERBOSE(channel, args...) ((void)0) +#elif COMPILER(WINSCW) +#define LOG_VERBOSE(channel, arg...) ((void)0) #else #define LOG_VERBOSE(channel, ...) WTFLogVerbose(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, &JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__) #endif diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index e6813a1..daa3be7 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -8,4 +8,4 @@ The commit imported was from the and has the sha1 checksum - de77f8ee69c434bde9306c8f407ee2e443a00188 + 70b5989bdeea2f73bd950099fc0f0e954550ef54 diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index c60a5d4..03bb1fb 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,76 @@ +2009-12-30 Janne Koskinen <janne.p.koskinen@digia.com> + + Reviewed by Simon Hausmann. + + [Qt] Add support for Symbian def files + + * WebCore.pro: + +2009-12-30 Simon Hausmann <simon.hausmann@nokia.com> + + Unreviewed Qt/Symbian build fix. + + Don't build network state notifier support when building inside of Qt. + Otherwise the Qt build depends on an external module that itself depends + on Qt again. + + * WebCore.pro: + +2009-12-30 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Simon Hausmann. + + Turn off DataGrid support by default. + + No new tests, as there is no new functionality. + + * WebCore.pro: + +2009-12-17 Yael Aharon <yael.aharon@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] support navigator.onLine and ononline/onoffline events. + https://bugs.webkit.org/show_bug.cgi?id=32555 + + Hooked up Bearer Management to NetworkStateNotifier. This solution is available + only if QtMobility's Bearer Management is installed. + + * WebCore.pro: + * platform/network/NetworkStateNotifier.h: + * platform/network/qt/NetworkStateNotifierPrivate.h: Added. + * platform/network/qt/NetworkStateNotifierQt.cpp: Added. + (WebCore::NetworkStateNotifierPrivate::NetworkStateNotifierPrivate): + (WebCore::NetworkStateNotifierPrivate::onlineStateChanged): + (WebCore::NetworkStateNotifierPrivate::~NetworkStateNotifierPrivate): + (WebCore::NetworkStateNotifier::updateState): + (WebCore::NetworkStateNotifier::NetworkStateNotifier): + +2009-12-17 Simon Hausmann <simon.hausmann@nokia.com> + + Reviewed by Tor Arne Vestbø. + + [Qt] Symbian build fix: Don't include QtXml/qxmlstream.h but omit the prefix, to + make sure we pick up the header file from QtCore. That is where the implementation + is compiled. + + * dom/XMLTokenizer.h: + +2009-12-14 Holger Hans Peter Freyther <zecke@selfish.org> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Add manual test for JavaScript prompt corner case + https://bugs.webkit.org/show_bug.cgi?id=30914 + + The patch is based on the work done by Gupta Manish. + + Verify behavior of the JavaScript prompt function. Currently + Qt is not behaving like other WebKit ports and Firefox in + regards to accepting the prompt but not entering a text. + + * manual-tests/qt/java-script-prompt.html: Added. + 2009-12-21 Andreas Kling <andreas.kling@nokia.com> Reviewed by Darin Adler. diff --git a/src/3rdparty/webkit/WebCore/WebCore.pro b/src/3rdparty/webkit/WebCore/WebCore.pro index 9239089..be64e3b 100644 --- a/src/3rdparty/webkit/WebCore/WebCore.pro +++ b/src/3rdparty/webkit/WebCore/WebCore.pro @@ -136,7 +136,7 @@ contains(DEFINES, ENABLE_SINGLE_THREADED=1) { !contains(DEFINES, ENABLE_SHARED_WORKERS=.): DEFINES += ENABLE_SHARED_WORKERS=1 !contains(DEFINES, ENABLE_WORKERS=.): DEFINES += ENABLE_WORKERS=1 !contains(DEFINES, ENABLE_XHTMLMP=.): DEFINES += ENABLE_XHTMLMP=0 -!contains(DEFINES, ENABLE_DATAGRID=.): DEFINES += ENABLE_DATAGRID=1 +!contains(DEFINES, ENABLE_DATAGRID=.): DEFINES += ENABLE_DATAGRID=0 # SVG support !contains(DEFINES, ENABLE_SVG=0) { @@ -180,6 +180,15 @@ contains(DEFINES, ENABLE_SINGLE_THREADED=1) { else:DEFINES += ENABLE_XSLT=0 } +!CONFIG(QTDIR_build):!contains(DEFINES, ENABLE_QT_BEARER=.) { + symbian: { + exists($${EPOCROOT}epoc32/release/winscw/udeb/QtBearer.lib)| \ + exists($${EPOCROOT}epoc32/release/armv5/lib/QtBearer.lib) { + DEFINES += ENABLE_QT_BEARER=1 + } + } +} + DEFINES += WTF_USE_JAVASCRIPTCORE_BINDINGS=1 WTF_CHANGES=1 # Used to compute defaults for the build-webkit script @@ -2860,6 +2869,17 @@ contains(DEFINES, ENABLE_XHTMLMP=1) { FEATURE_DEFINES_JAVASCRIPT += ENABLE_XHTMLMP=1 } +contains(DEFINES, ENABLE_QT_BEARER=1) { + HEADERS += \ + platform/network/qt/NetworkStateNotifierPrivate.h + + SOURCES += \ + platform/network/qt/NetworkStateNotifierQt.cpp + + LIBS += -lQtBearer + +} + contains(DEFINES, ENABLE_SVG=1) { FEATURE_DEFINES_JAVASCRIPT += ENABLE_SVG=1 @@ -3382,16 +3402,15 @@ CONFIG(QTDIR_build):isEqual(QT_MAJOR_VERSION, 4):greaterThan(QT_MINOR_VERSION, 4 } } -# Temporary workaround to pick up the DEF file from the same place as all the others symbian { shared { contains(MMP_RULES, defBlock) { MMP_RULES -= defBlock MMP_RULES += "$${LITERAL_HASH}ifdef WINSCW" \ - "DEFFILE ../../../s60installs/bwins/$${TARGET}.def" \ + "DEFFILE ../WebKit/qt/symbian/bwins/$${TARGET}.def" \ "$${LITERAL_HASH}elif defined EABI" \ - "DEFFILE ../../../s60installs/eabi/$${TARGET}.def" \ + "DEFFILE ../WebKit/qt/symbian/eabi/$${TARGET}.def" \ "$${LITERAL_HASH}endif" } } diff --git a/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.h b/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.h index e1ee09f..a83e73a 100644 --- a/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.h +++ b/src/3rdparty/webkit/WebCore/dom/XMLTokenizer.h @@ -34,7 +34,7 @@ #include <wtf/OwnPtr.h> #if USE(QXMLSTREAM) -#include <QtXml/qxmlstream.h> +#include <qxmlstream.h> #else #include <libxml/tree.h> #include <libxml/xmlstring.h> diff --git a/src/3rdparty/webkit/WebCore/platform/network/NetworkStateNotifier.h b/src/3rdparty/webkit/WebCore/platform/network/NetworkStateNotifier.h index 0189f5f..f8c5654 100644 --- a/src/3rdparty/webkit/WebCore/platform/network/NetworkStateNotifier.h +++ b/src/3rdparty/webkit/WebCore/platform/network/NetworkStateNotifier.h @@ -46,6 +46,10 @@ typedef const struct __SCDynamicStore * SCDynamicStoreRef; namespace WebCore { +#if (PLATFORM(QT) && ENABLE(QT_BEARER)) +class NetworkStateNotifierPrivate; +#endif + class NetworkStateNotifier { public: NetworkStateNotifier(); @@ -78,10 +82,14 @@ private: #elif PLATFORM(CHROMIUM) NetworkStateNotifierPrivate p; + +#elif PLATFORM(QT) && ENABLE(QT_BEARER) + friend class NetworkStateNotifierPrivate; + NetworkStateNotifierPrivate* p; #endif }; -#if !PLATFORM(MAC) && !PLATFORM(WIN) && !PLATFORM(CHROMIUM) +#if !PLATFORM(MAC) && !PLATFORM(WIN) && !PLATFORM(CHROMIUM) && !(PLATFORM(QT) && ENABLE(QT_BEARER)) inline NetworkStateNotifier::NetworkStateNotifier() : m_isOnLine(true) diff --git a/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierPrivate.h b/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierPrivate.h new file mode 100644 index 0000000..7af6392 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierPrivate.h @@ -0,0 +1,49 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef NetworkStateNotifierPrivate_h +#define NetworkStateNotifierPrivate_h + +#include <QObject> + +namespace QtMobility { +class QNetworkConfigurationManager; +} + +namespace WebCore { + +class NetworkStateNotifier; + +class NetworkStateNotifierPrivate : public QObject { + Q_OBJECT +public: + NetworkStateNotifierPrivate(NetworkStateNotifier* notifier); + ~NetworkStateNotifierPrivate(); +public slots: + void onlineStateChanged(bool); + +public: + QtMobility::QNetworkConfigurationManager* m_configurationManager; + bool m_online; + NetworkStateNotifier* m_notifier; +}; + +} // namespace WebCore + +#endif diff --git a/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp b/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp new file mode 100644 index 0000000..f74398b --- /dev/null +++ b/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp @@ -0,0 +1,73 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "NetworkStateNotifier.h" + +#include "NetworkStateNotifierPrivate.h" +#include "qnetworkconfigmanager.h" + +using namespace QtMobility; + +namespace WebCore { + +NetworkStateNotifierPrivate::NetworkStateNotifierPrivate(NetworkStateNotifier* notifier) + : m_configurationManager(new QNetworkConfigurationManager()) + , m_online(m_configurationManager->isOnline()) + , m_notifier(notifier) +{ + Q_ASSERT(notifier); + connect(m_configurationManager, SIGNAL(onlineStateChanged(bool)), this, SLOT(onlineStateChanged(bool))); +} + +void NetworkStateNotifierPrivate::onlineStateChanged(bool isOnline) +{ + if (m_online == isOnline) + return; + + m_online = isOnline; + m_notifier->updateState(); +} + +NetworkStateNotifierPrivate::~NetworkStateNotifierPrivate() +{ + delete m_configurationManager; +} + +void NetworkStateNotifier::updateState() +{ + if (m_isOnLine == p->m_online) + return; + + m_isOnLine = p->m_online; + if (m_networkStateChangedFunction) + m_networkStateChangedFunction(); +} + +NetworkStateNotifier::NetworkStateNotifier() + : m_isOnLine(true) + , m_networkStateChangedFunction(0) +{ + p = new NetworkStateNotifierPrivate(this); + m_isOnLine = p->m_online; +} + +} // namespace WebCore + +#include "moc_NetworkStateNotifierPrivate.cpp" diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp index 35f6e0c..6d08c32 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp @@ -1849,7 +1849,8 @@ bool QWebPage::javaScriptConfirm(QWebFrame *frame, const QString& msg) The program may provide an optional message, \a msg, as well as a default value for the input in \a defaultValue. If the prompt was cancelled by the user the implementation should return false; otherwise the - result should be written to \a result and true should be returned. + result should be written to \a result and true should be returned. If the prompt was not cancelled by the + user, the implementation should return true and the result string must not be null. The default implementation uses QInputDialog::getText. */ diff --git a/src/3rdparty/webkit/WebKit/qt/ChangeLog b/src/3rdparty/webkit/WebKit/qt/ChangeLog index 37d527fa..4ab5bfb 100644 --- a/src/3rdparty/webkit/WebKit/qt/ChangeLog +++ b/src/3rdparty/webkit/WebKit/qt/ChangeLog @@ -1,3 +1,39 @@ +2009-12-30 Janne Koskinen <janne.p.koskinen@digia.com> + + Reviewed by Simon Hausmann. + + Upstream Symbian def files from Qt 4.6. + + These files define the ABI of QtWebKit on Symbian. + + * symbian/bwins/QtWebKitu.def: Added. + * symbian/eabi/QtWebKitu.def: Added. + +2009-12-14 Holger Hans Peter Freyther <zecke@selfish.org> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Fix JavaScript prompt behavior for empty/null strings. + https://bugs.webkit.org/show_bug.cgi?id=30914 + + The patch is based on the work done by Gupta Manish. + + In the default implementation of the JavaScript prompt + we are using a QInputDialog to get the text and this has + one quirk with regard to not entering any text. + + In other WebKit ports and in Firefox an empty string is + returned but in the Qt case it is a null string. + + Change the API documentation in QWebPage to mention we want to + have a non null string but do the fixup in the ChromeClientQt + to support existing code. + + * Api/qwebpage.cpp: + (QWebPage::javaScriptPrompt): Change API documentation + * WebCoreSupport/ChromeClientQt.cpp: + (WebCore::ChromeClientQt::runJavaScriptPrompt): Fixup null QString + 2009-12-21 David Boddie <dboddie@trolltech.com> Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp index 26cf6f6..c5d2792 100644 --- a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp +++ b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp @@ -278,7 +278,14 @@ bool ChromeClientQt::runJavaScriptPrompt(Frame* f, const String& message, const QString x = result; FrameLoaderClientQt *fl = static_cast<FrameLoaderClientQt*>(f->loader()->client()); bool rc = m_webPage->javaScriptPrompt(fl->webFrame(), (QString)message, (QString)defaultValue, &x); - result = x; + + // Fix up a quirk in the QInputDialog class. If no input happened the string should be empty + // but it is null. See https://bugs.webkit.org/show_bug.cgi?id=30914. + if (rc && result.isNull()) + result = String(""); + else + result = x; + return rc; } diff --git a/src/s60installs/bwins/QtWebKitu.def b/src/3rdparty/webkit/WebKit/qt/symbian/bwins/QtWebKitu.def index e5631f8..e5631f8 100644 --- a/src/s60installs/bwins/QtWebKitu.def +++ b/src/3rdparty/webkit/WebKit/qt/symbian/bwins/QtWebKitu.def diff --git a/src/s60installs/eabi/QtWebKitu.def b/src/3rdparty/webkit/WebKit/qt/symbian/eabi/QtWebKitu.def index 4aad884..4aad884 100644 --- a/src/s60installs/eabi/QtWebKitu.def +++ b/src/3rdparty/webkit/WebKit/qt/symbian/eabi/QtWebKitu.def diff --git a/src/corelib/concurrent/qtconcurrentiteratekernel.cpp b/src/corelib/concurrent/qtconcurrentiteratekernel.cpp index 15b8ecd..e93394f 100644 --- a/src/corelib/concurrent/qtconcurrentiteratekernel.cpp +++ b/src/corelib/concurrent/qtconcurrentiteratekernel.cpp @@ -46,6 +46,9 @@ #include <mach/mach_time.h> #include <unistd.h> #elif defined(Q_OS_UNIX) +#if defined(Q_OS_HURD) +#include <sys/time.h> +#endif #include <time.h> #include <unistd.h> #elif defined(Q_OS_WIN) diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro index 7f33791..9a15bf1 100644 --- a/src/corelib/corelib.pro +++ b/src/corelib/corelib.pro @@ -35,6 +35,4 @@ symbian: { # Workaroud for problems with paging this dll MMP_RULES -= PAGED MMP_RULES *= UNPAGED - # Timezone server - LIBS += -ltzclient } diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h index ff8c6c8..c1c7812 100644 --- a/src/corelib/io/qdebug.h +++ b/src/corelib/io/qdebug.h @@ -93,7 +93,7 @@ public: inline QDebug &maybeSpace() { if (stream->space) stream->ts << ' '; return *this; } inline QDebug &operator<<(QChar t) { stream->ts << '\'' << t << '\''; return maybeSpace(); } - inline QDebug &operator<<(QBool t) { stream->ts << (bool(t) ? "true" : "false"); return maybeSpace(); } + inline QDebug &operator<<(QBool t) { stream->ts << (bool(t != 0) ? "true" : "false"); return maybeSpace(); } inline QDebug &operator<<(bool t) { stream->ts << (t ? "true" : "false"); return maybeSpace(); } inline QDebug &operator<<(char t) { stream->ts << t; return maybeSpace(); } inline QDebug &operator<<(signed short t) { stream->ts << t; return maybeSpace(); } diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index fd51bcf..6ac6468 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -3864,14 +3864,18 @@ QByteArray QUrlPrivate::toEncoded(QUrl::FormattingOptions options) const url += "//"; if ((options & QUrl::RemoveUserInfo) != QUrl::RemoveUserInfo) { + bool hasUserOrPass = false; if (!userName.isEmpty()) { url += encodedUserName; - if (!(options & QUrl::RemovePassword) && !password.isEmpty()) { - url += ':'; - url += encodedPassword; - } - url += '@'; + hasUserOrPass = true; } + if (!(options & QUrl::RemovePassword) && !password.isEmpty()) { + url += ':'; + url += encodedPassword; + hasUserOrPass = true; + } + if (hasUserOrPass) + url += '@'; } if (host.startsWith(QLatin1Char('['))) { diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 240f0cf..db6435e 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -75,7 +75,6 @@ #if defined(Q_OS_SYMBIAN) #include <e32std.h> -#include <tz.h> #endif QT_BEGIN_NAMESPACE @@ -3722,32 +3721,23 @@ static QDateTimePrivate::Spec utcToLocal(QDate &date, QTime &time) #elif defined(Q_OS_SYMBIAN) // months and days are zero index based _LIT(KUnixEpoch, "19700000:000000.000000"); + TTimeIntervalSeconds utcOffset = User::UTCOffset(); TTimeIntervalSeconds tTimeIntervalSecsSince1Jan1970UTC(secsSince1Jan1970UTC); TTime epochTTime; TInt err = epochTTime.Set(KUnixEpoch); tm res; if(err == KErrNone) { TTime utcTTime = epochTTime + tTimeIntervalSecsSince1Jan1970UTC; - TRAP(err, - RTz tz; - User::LeaveIfError(tz.Connect()); - CleanupClosePushL(tz); - res.tm_isdst = tz.IsDaylightSavingOnL(*tz.GetTimeZoneIdL(),utcTTime); - User::LeaveIfError(tz.ConvertToLocalTime(utcTTime)); - CleanupStack::PopAndDestroy(&tz)); - if (KErrNone == err) { - TDateTime localDateTime = utcTTime.DateTime(); - res.tm_sec = localDateTime.Second(); - res.tm_min = localDateTime.Minute(); - res.tm_hour = localDateTime.Hour(); - res.tm_mday = localDateTime.Day() + 1; // non-zero based index for tm struct - res.tm_mon = localDateTime.Month(); - res.tm_year = localDateTime.Year() - 1900; - // Symbian's timezone server doesn't know how to handle DST before year 1997 - if (res.tm_year < 97) - res.tm_isdst = -1; - brokenDown = &res; - } + utcTTime = utcTTime + utcOffset; + TDateTime utcDateTime = utcTTime.DateTime(); + res.tm_sec = utcDateTime.Second(); + res.tm_min = utcDateTime.Minute(); + res.tm_hour = utcDateTime.Hour(); + res.tm_mday = utcDateTime.Day() + 1; // non-zero based index for tm struct + res.tm_mon = utcDateTime.Month(); + res.tm_year = utcDateTime.Year() - 1900; + res.tm_isdst = 0; + brokenDown = &res; } #elif !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) // use the reentrant version of localtime() where available @@ -3822,27 +3812,23 @@ static void localToUtc(QDate &date, QTime &time, int isdst) #elif defined(Q_OS_SYMBIAN) // months and days are zero index based _LIT(KUnixEpoch, "19700000:000000.000000"); + TTimeIntervalSeconds utcOffset = TTimeIntervalSeconds(0 - User::UTCOffset().Int()); TTimeIntervalSeconds tTimeIntervalSecsSince1Jan1970UTC(secsSince1Jan1970UTC); TTime epochTTime; TInt err = epochTTime.Set(KUnixEpoch); tm res; if(err == KErrNone) { - TTime localTTime = epochTTime + tTimeIntervalSecsSince1Jan1970UTC; - RTz tz; - if (KErrNone == tz.Connect()) { - if (KErrNone == tz.ConvertToUniversalTime(localTTime)) { - TDateTime utcDateTime = localTTime.DateTime(); - res.tm_sec = utcDateTime.Second(); - res.tm_min = utcDateTime.Minute(); - res.tm_hour = utcDateTime.Hour(); - res.tm_mday = utcDateTime.Day() + 1; // non-zero based index for tm struct - res.tm_mon = utcDateTime.Month(); - res.tm_year = utcDateTime.Year() - 1900; - res.tm_isdst = (int)isdst; - brokenDown = &res; - } - tz.Close(); - } + TTime utcTTime = epochTTime + tTimeIntervalSecsSince1Jan1970UTC; + utcTTime = utcTTime + utcOffset; + TDateTime utcDateTime = utcTTime.DateTime(); + res.tm_sec = utcDateTime.Second(); + res.tm_min = utcDateTime.Minute(); + res.tm_hour = utcDateTime.Hour(); + res.tm_mday = utcDateTime.Day() + 1; // non-zero based index for tm struct + res.tm_mon = utcDateTime.Month(); + res.tm_year = utcDateTime.Year() - 1900; + res.tm_isdst = (int)isdst; + brokenDown = &res; } #elif !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) // use the reentrant version of gmtime() where available diff --git a/src/dbus/qdbusabstractinterface.cpp b/src/dbus/qdbusabstractinterface.cpp index 994da10..ff0a93e 100644 --- a/src/dbus/qdbusabstractinterface.cpp +++ b/src/dbus/qdbusabstractinterface.cpp @@ -561,13 +561,7 @@ void QDBusAbstractInterface::connectNotify(const char *signal) QDBusConnectionPrivate *conn = d->connectionPrivate(); if (conn) { - // do we know what our owner is? - QString owner; - if (!d->service.isEmpty() && d->currentOwner.isNull()) - owner = QLatin1String(""); - else - owner = d->currentOwner; - conn->connectRelay(d->service, owner, d->path, d->interface, + conn->connectRelay(d->service, d->path, d->interface, this, signal); } } @@ -585,7 +579,7 @@ void QDBusAbstractInterface::disconnectNotify(const char *signal) QDBusConnectionPrivate *conn = d->connectionPrivate(); if (conn) - conn->disconnectRelay(d->service, d->currentOwner, d->path, d->interface, + conn->disconnectRelay(d->service, d->path, d->interface, this, signal); } diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp index d7088ff..47893cc 100644 --- a/src/dbus/qdbusconnection.cpp +++ b/src/dbus/qdbusconnection.cpp @@ -619,10 +619,8 @@ bool QDBusConnection::connect(const QString &service, const QString &path, const if (interface.isEmpty() && name.isEmpty()) return false; - QString owner = d->getNameOwner(service); // we don't care if the owner is empty - // it might get started later QDBusWriteLocker locker(ConnectAction, d); - return d->connectSignal(service, owner, path, interface, name, argumentMatch, signature, receiver, slot); + return d->connectSignal(service, path, interface, name, argumentMatch, signature, receiver, slot); } /*! diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index d6f7598..32e057c 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -119,7 +119,7 @@ public: struct SignalHook { inline SignalHook() : obj(0), midx(-1) { } - QString owner, service, path, signature; + QString service, path, signature; QObject* obj; int midx; QList<int> params; @@ -155,7 +155,13 @@ public: typedef QMultiHash<QString, SignalHook> SignalHookHash; typedef QHash<QString, QDBusMetaObject* > MetaObjectHash; typedef QHash<QByteArray, int> MatchRefCountHash; - typedef QHash<QString, int> WatchedServicesHash; + + struct WatchedServiceData { + WatchedServiceData() : refcount(0) {} + QString owner; + int refcount; + }; + typedef QHash<QString, WatchedServiceData> WatchedServicesHash; public: // public methods are entry points from other objects @@ -177,7 +183,7 @@ public: QDBusPendingCallPrivate *sendWithReplyAsync(const QDBusMessage &message, int timeout = -1); int sendWithReplyAsync(const QDBusMessage &message, QObject *receiver, const char *returnMethod, const char *errorMethod, int timeout = -1); - bool connectSignal(const QString &service, const QString &owner, const QString &path, const QString& interface, + bool connectSignal(const QString &service, const QString &path, const QString& interface, const QString &name, const QStringList &argumentMatch, const QString &signature, QObject *receiver, const char *slot); void connectSignal(const QString &key, const SignalHook &hook); @@ -186,10 +192,10 @@ public: const QString &name, const QStringList &argumentMatch, const QString &signature, QObject *receiver, const char *slot); void registerObject(const ObjectTreeNode *node); - void connectRelay(const QString &service, const QString ¤tOwner, + void connectRelay(const QString &service, const QString &path, const QString &interface, QDBusAbstractInterface *receiver, const char *signal); - void disconnectRelay(const QString &service, const QString ¤tOwner, + void disconnectRelay(const QString &service, const QString &path, const QString &interface, QDBusAbstractInterface *receiver, const char *signal); @@ -223,6 +229,8 @@ private: bool isServiceRegisteredByThread(const QString &serviceName) const; + QString getNameOwnerNoCache(const QString &service); + protected: void customEvent(QEvent *e); void timerEvent(QTimerEvent *e); @@ -271,7 +279,7 @@ public: QDBusError lastError; QStringList serviceNames; - WatchedServicesHash watchedServiceNames; + WatchedServicesHash watchedServices; SignalHookHash signalHooks; MatchRefCountHash matchRefCounts; ObjectTreeNode rootNode; @@ -284,7 +292,7 @@ public: // static methods static int findSlot(QObject *obj, const QByteArray &normalizedName, QList<int>& params); static bool prepareHook(QDBusConnectionPrivate::SignalHook &hook, QString &key, - const QString &service, const QString &owner, + const QString &service, const QString &path, const QString &interface, const QString &name, const QStringList &argMatch, QObject *receiver, const char *signal, int minMIdx, diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 40febc4..ea02005 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -390,7 +390,7 @@ static void qDBusNewConnection(DBusServer *server, DBusConnection *connection, v } // extern "C" -static QByteArray buildMatchRule(const QString &service, const QString & /*owner*/, +static QByteArray buildMatchRule(const QString &service, const QString &objectPath, const QString &interface, const QString &member, const QStringList &argMatch, const QString & /*signature*/) { @@ -523,7 +523,7 @@ qDBusSignalFilter(DBusConnection *connection, DBusMessage *message, void *data) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; QDBusMessage amsg = QDBusMessagePrivate::fromDBusMessage(message); - qDBusDebug() << QThread::currentThread() << "got message:" << amsg; + qDBusDebug() << d << "got message:" << amsg; return d->handleMessage(amsg) ? DBUS_HANDLER_RESULT_HANDLED : @@ -913,7 +913,7 @@ void QDBusConnectionPrivate::deliverCall(QObject *object, int /*flags*/, const Q if (msg.isReplyRequired() && !msg.isDelayedReply()) { if (!fail) { // normal reply - qDBusDebug() << QThread::currentThread() << "Automatically sending reply:" << outputArgs; + qDBusDebug() << this << "Automatically sending reply:" << outputArgs; send(msg.createReply(outputArgs)); } else { // generate internal error @@ -947,7 +947,6 @@ QDBusConnectionPrivate::QDBusConnectionPrivate(QObject *p) QDBusMetaTypeId::init(); rootNode.flags = 0; - watchedServiceNames[QLatin1String(DBUS_SERVICE_DBUS)] = 1; } QDBusConnectionPrivate::~QDBusConnectionPrivate() @@ -1179,11 +1178,15 @@ void QDBusConnectionPrivate::_q_serviceOwnerChanged(const QString &name, { Q_UNUSED(oldOwner); QDBusWriteLocker locker(UpdateSignalHookOwnerAction, this); - QMutableHashIterator<QString, SignalHook> it(signalHooks); - it.toFront(); - while (it.hasNext()) - if (it.next().value().service == name) - it.value().owner = newOwner; + WatchedServicesHash::Iterator it = watchedServices.find(name); + if (it == watchedServices.end()) + return; + if (oldOwner != it->owner) + qWarning("QDBusConnection: name '%s' had owner '%s' but we thought it was '%s'", + qPrintable(name), qPrintable(oldOwner), qPrintable(it->owner)); + + qDBusDebug() << this << "Updating name" << name << "from" << oldOwner << "to" << newOwner; + it->owner = newOwner; } int QDBusConnectionPrivate::findSlot(QObject* obj, const QByteArray &normalizedName, @@ -1201,7 +1204,7 @@ int QDBusConnectionPrivate::findSlot(QObject* obj, const QByteArray &normalizedN } bool QDBusConnectionPrivate::prepareHook(QDBusConnectionPrivate::SignalHook &hook, QString &key, - const QString &service, const QString &owner, + const QString &service, const QString &path, const QString &interface, const QString &name, const QStringList &argMatch, QObject *receiver, const char *signal, int minMIdx, @@ -1220,7 +1223,6 @@ bool QDBusConnectionPrivate::prepareHook(QDBusConnectionPrivate::SignalHook &hoo } hook.service = service; - hook.owner = owner; // we don't care if the service has an owner yet hook.path = path; hook.obj = receiver; hook.argumentMatch = argMatch; @@ -1245,7 +1247,7 @@ bool QDBusConnectionPrivate::prepareHook(QDBusConnectionPrivate::SignalHook &hoo hook.signature += QLatin1String( QDBusMetaType::typeToSignature( hook.params.at(i) ) ); } - hook.matchRule = buildMatchRule(service, owner, path, interface, mname, argMatch, hook.signature); + hook.matchRule = buildMatchRule(service, path, interface, mname, argMatch, hook.signature); return true; // connect to this signal } @@ -1488,8 +1490,14 @@ void QDBusConnectionPrivate::handleSignal(const QString &key, const QDBusMessage //qDBusDebug() << signalHooks.keys(); for ( ; it != end && it.key() == key; ++it) { const SignalHook &hook = it.value(); - if (!hook.owner.isNull() && hook.owner != msg.service()) - continue; + if (!hook.service.isEmpty()) { + const QString owner = + shouldWatchService(hook.service) ? + watchedServices.value(hook.service).owner : + hook.service; + if (owner != msg.service()) + continue; + } if (!hook.path.isEmpty() && hook.path != msg.path()) continue; if (!hook.signature.isEmpty() && hook.signature != msg.signature()) @@ -1652,15 +1660,18 @@ void QDBusConnectionPrivate::setConnection(DBusConnection *dbc, const QDBusError } QString busService = QLatin1String(DBUS_SERVICE_DBUS); - connectSignal(busService, QString(), QString(), QString(), QLatin1String("NameAcquired"), QStringList(), QString(), + WatchedServicesHash::mapped_type &bus = watchedServices[busService]; + bus.refcount = 1; + bus.owner = getNameOwnerNoCache(busService); + connectSignal(busService, QString(), QString(), QLatin1String("NameAcquired"), QStringList(), QString(), this, SLOT(registerService(QString))); - connectSignal(busService, QString(), QString(), QString(), QLatin1String("NameLost"), QStringList(), QString(), + connectSignal(busService, QString(), QString(), QLatin1String("NameLost"), QStringList(), QString(), this, SLOT(unregisterService(QString))); q_dbus_connection_add_filter(connection, qDBusSignalFilter, this, 0); - //qDebug("base service: %s", service); + qDBusDebug() << this << ": connected successfully"; // schedule a dispatch: QMetaObject::invokeMethod(this, "doDispatch", Qt::QueuedConnection); @@ -1695,7 +1706,7 @@ void QDBusConnectionPrivate::processFinishedCall(QDBusPendingCallPrivate *call) msg = QDBusMessagePrivate::fromDBusMessage(reply); q_dbus_message_unref(reply); } - qDBusDebug() << QThread::currentThread() << "got message reply (async):" << msg; + qDBusDebug() << connection << "got message reply (async):" << msg; // Check if the reply has the expected signature call->checkReceivedSignature(); @@ -1763,7 +1774,7 @@ int QDBusConnectionPrivate::send(const QDBusMessage& message) q_dbus_message_set_no_reply(msg, true); // the reply would not be delivered to anything - qDBusDebug() << QThread::currentThread() << "sending message (no reply):" << message; + qDBusDebug() << this << "sending message (no reply):" << message; checkThread(); bool isOk = q_dbus_connection_send(connection, msg, 0); int serial = 0; @@ -1795,7 +1806,7 @@ QDBusMessage QDBusConnectionPrivate::sendWithReply(const QDBusMessage &message, return QDBusMessage::createError(err); } - qDBusDebug() << QThread::currentThread() << "sending message (blocking):" << message; + qDBusDebug() << this << "sending message (blocking):" << message; QDBusErrorInternal error; DBusMessage *reply = q_dbus_connection_send_with_reply_and_block(connection, msg, timeout, error); @@ -1808,7 +1819,7 @@ QDBusMessage QDBusConnectionPrivate::sendWithReply(const QDBusMessage &message, QDBusMessage amsg = QDBusMessagePrivate::fromDBusMessage(reply); q_dbus_message_unref(reply); - qDBusDebug() << QThread::currentThread() << "got message reply (blocking):" << amsg; + qDBusDebug() << this << "got message reply (blocking):" << amsg; return amsg; } else { // use the event loop @@ -1835,7 +1846,7 @@ QDBusMessage QDBusConnectionPrivate::sendWithReply(const QDBusMessage &message, QDBusMessage QDBusConnectionPrivate::sendWithReplyLocal(const QDBusMessage &message) { - qDBusDebug() << QThread::currentThread() << "sending message via local-loop:" << message; + qDBusDebug() << this << "sending message via local-loop:" << message; QDBusMessage localCallMsg = QDBusMessagePrivate::makeLocal(*this, message); bool handled = handleMessage(localCallMsg); @@ -1862,7 +1873,7 @@ QDBusMessage QDBusConnectionPrivate::sendWithReplyLocal(const QDBusMessage &mess } // there is a reply - qDBusDebug() << QThread::currentThread() << "got message via local-loop:" << localReplyMsg; + qDBusDebug() << this << "got message via local-loop:" << localReplyMsg; return localReplyMsg; } @@ -1896,7 +1907,7 @@ QDBusPendingCallPrivate *QDBusConnectionPrivate::sendWithReplyAsync(const QDBusM return pcall; } - qDBusDebug() << QThread::currentThread() << "sending message (async):" << message; + qDBusDebug() << this << "sending message (async):" << message; DBusPendingCall *pending = 0; QDBusDispatchLocker locker(SendWithReplyAsyncAction, this); @@ -1968,7 +1979,7 @@ int QDBusConnectionPrivate::sendWithReplyAsync(const QDBusMessage &message, QObj return 1; } -bool QDBusConnectionPrivate::connectSignal(const QString &service, const QString &owner, +bool QDBusConnectionPrivate::connectSignal(const QString &service, const QString &path, const QString &interface, const QString &name, const QStringList &argumentMatch, const QString &signature, QObject *receiver, const char *slot) @@ -1981,7 +1992,7 @@ bool QDBusConnectionPrivate::connectSignal(const QString &service, const QString name2.detach(); hook.signature = signature; - if (!prepareHook(hook, key, service, owner, path, interface, name, argumentMatch, receiver, slot, 0, false)) + if (!prepareHook(hook, key, service, path, interface, name, argumentMatch, receiver, slot, 0, false)) return false; // don't connect // avoid duplicating: @@ -1990,7 +2001,6 @@ bool QDBusConnectionPrivate::connectSignal(const QString &service, const QString for ( ; it != end && it.key() == key; ++it) { const QDBusConnectionPrivate::SignalHook &entry = it.value(); if (entry.service == hook.service && - entry.owner == hook.owner && entry.path == hook.path && entry.signature == hook.signature && entry.obj == hook.obj && @@ -2035,16 +2045,19 @@ void QDBusConnectionPrivate::connectSignal(const QString &key, const SignalHook // Successfully connected the signal // Do we need to watch for this name? if (shouldWatchService(hook.service)) { - WatchedServicesHash::Iterator it = watchedServiceNames.find(hook.service); - if (it != watchedServiceNames.end()) { + WatchedServicesHash::mapped_type &data = watchedServices[hook.service]; + if (data.refcount) { // already watching - ++it.value(); + ++data.refcount; } else { // we need to watch for this service changing QString dbusServerService = QLatin1String(DBUS_SERVICE_DBUS); - connectSignal(dbusServerService, dbusServerService, QString(), QLatin1String(DBUS_INTERFACE_DBUS), + connectSignal(dbusServerService, QString(), QLatin1String(DBUS_INTERFACE_DBUS), QLatin1String("NameOwnerChanged"), QStringList() << hook.service, QString(), this, SLOT(_q_serviceOwnerChanged(QString,QString,QString))); + data.owner = getNameOwnerNoCache(hook.service); + qDBusDebug() << this << "Watching service" << hook.service << "for owner changes (current owner:" + << data.owner << ")"; } } } @@ -2064,7 +2077,7 @@ bool QDBusConnectionPrivate::disconnectSignal(const QString &service, name2.detach(); hook.signature = signature; - if (!prepareHook(hook, key, service, QString(), path, interface, name, argumentMatch, receiver, slot, 0, false)) + if (!prepareHook(hook, key, service, path, interface, name, argumentMatch, receiver, slot, 0, false)) return false; // don't disconnect // avoid duplicating: @@ -2073,7 +2086,6 @@ bool QDBusConnectionPrivate::disconnectSignal(const QString &service, for ( ; it != end && it.key() == key; ++it) { const QDBusConnectionPrivate::SignalHook &entry = it.value(); if (entry.service == hook.service && - //entry.owner == hook.owner && entry.path == hook.path && entry.signature == hook.signature && entry.obj == hook.obj && @@ -2093,16 +2105,16 @@ QDBusConnectionPrivate::disconnectSignal(SignalHookHash::Iterator &it) { const SignalHook &hook = it.value(); - WatchedServicesHash::Iterator sit = watchedServiceNames.find(hook.service); - if (sit != watchedServiceNames.end()) { - if (sit.value() == 1) { - watchedServiceNames.erase(sit); + WatchedServicesHash::Iterator sit = watchedServices.find(hook.service); + if (sit != watchedServices.end()) { + if (sit.value().refcount == 1) { + watchedServices.erase(sit); QString dbusServerService = QLatin1String(DBUS_SERVICE_DBUS); disconnectSignal(dbusServerService, QString(), QLatin1String(DBUS_INTERFACE_DBUS), QLatin1String("NameOwnerChanged"), QStringList() << hook.service, QString(), this, SLOT(_q_serviceOwnerChanged(QString,QString,QString))); } else { - --sit.value(); + --sit.value().refcount; } } @@ -2154,7 +2166,7 @@ void QDBusConnectionPrivate::registerObject(const ObjectTreeNode *node) } } -void QDBusConnectionPrivate::connectRelay(const QString &service, const QString &owner, +void QDBusConnectionPrivate::connectRelay(const QString &service, const QString &path, const QString &interface, QDBusAbstractInterface *receiver, const char *signal) @@ -2164,7 +2176,7 @@ void QDBusConnectionPrivate::connectRelay(const QString &service, const QString SignalHook hook; QString key; - if (!prepareHook(hook, key, service, owner, path, interface, QString(), QStringList(), receiver, signal, + if (!prepareHook(hook, key, service, path, interface, QString(), QStringList(), receiver, signal, QDBusAbstractInterface::staticMetaObject.methodCount(), true)) return; // don't connect @@ -2175,7 +2187,6 @@ void QDBusConnectionPrivate::connectRelay(const QString &service, const QString for ( ; it != end && it.key() == key; ++it) { const SignalHook &entry = it.value(); if (entry.service == hook.service && - entry.owner == hook.owner && entry.path == hook.path && entry.signature == hook.signature && entry.obj == hook.obj && @@ -2186,7 +2197,7 @@ void QDBusConnectionPrivate::connectRelay(const QString &service, const QString connectSignal(key, hook); } -void QDBusConnectionPrivate::disconnectRelay(const QString &service, const QString &owner, +void QDBusConnectionPrivate::disconnectRelay(const QString &service, const QString &path, const QString &interface, QDBusAbstractInterface *receiver, const char *signal) @@ -2196,7 +2207,7 @@ void QDBusConnectionPrivate::disconnectRelay(const QString &service, const QStri SignalHook hook; QString key; - if (!prepareHook(hook, key, service, owner, path, interface, QString(), QStringList(), receiver, signal, + if (!prepareHook(hook, key, service, path, interface, QString(), QStringList(), receiver, signal, QDBusAbstractInterface::staticMetaObject.methodCount(), true)) return; // don't connect @@ -2207,7 +2218,6 @@ void QDBusConnectionPrivate::disconnectRelay(const QString &service, const QStri for ( ; it != end && it.key() == key; ++it) { const SignalHook &entry = it.value(); if (entry.service == hook.service && - entry.owner == hook.owner && entry.path == hook.path && entry.signature == hook.signature && entry.obj == hook.obj && @@ -2225,9 +2235,23 @@ QString QDBusConnectionPrivate::getNameOwner(const QString& serviceName) { if (QDBusUtil::isValidUniqueConnectionName(serviceName)) return serviceName; - if (!connection || !QDBusUtil::isValidBusName(serviceName)) + if (!connection) return QString(); + { + // acquire a read lock for the cache + QReadLocker locker(&lock); + WatchedServicesHash::ConstIterator it = watchedServices.constFind(serviceName); + if (it != watchedServices.constEnd()) + return it->owner; + } + + // not cached + return getNameOwnerNoCache(serviceName); +} + +QString QDBusConnectionPrivate::getNameOwnerNoCache(const QString &serviceName) +{ QDBusMessage msg = QDBusMessage::createMethodCall(QLatin1String(DBUS_SERVICE_DBUS), QLatin1String(DBUS_PATH_DBUS), QLatin1String(DBUS_INTERFACE_DBUS), QLatin1String("GetNameOwner")); diff --git a/src/dbus/qdbusmarshaller.cpp b/src/dbus/qdbusmarshaller.cpp index d732ad0..28cec7d 100644 --- a/src/dbus/qdbusmarshaller.cpp +++ b/src/dbus/qdbusmarshaller.cpp @@ -387,7 +387,6 @@ bool QDBusMarshaller::appendVariantInternal(const QVariant &arg) switch (*signature) { #ifdef __OPTIMIZE__ case DBUS_TYPE_BYTE: - case DBUS_TYPE_BOOLEAN: case DBUS_TYPE_INT16: case DBUS_TYPE_UINT16: case DBUS_TYPE_INT32: @@ -397,6 +396,9 @@ bool QDBusMarshaller::appendVariantInternal(const QVariant &arg) case DBUS_TYPE_DOUBLE: qIterAppend(&iterator, ba, *signature, arg.constData()); return true; + case DBUS_TYPE_BOOLEAN: + append( arg.toBool() ); + return true; #else case DBUS_TYPE_BYTE: append( qvariant_cast<uchar>(arg) ); diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp index 45a410f..d952c34 100644 --- a/src/gui/dialogs/qfiledialog.cpp +++ b/src/gui/dialogs/qfiledialog.cpp @@ -669,6 +669,9 @@ void QFileDialog::setOptions(Options options) } if (changed & HideNameFilterDetails) setNameFilters(d->nameFilters); + + if (changed & ShowDirsOnly) + setFilter((options & ShowDirsOnly) ? filter() & ~QDir::Files : filter() | QDir::Files); } QFileDialog::Options QFileDialog::options() const diff --git a/src/gui/embedded/directfb.pri b/src/gui/embedded/directfb.pri index 84253b5..bd1d947 100644 --- a/src/gui/embedded/directfb.pri +++ b/src/gui/embedded/directfb.pri @@ -14,6 +14,7 @@ #DEFINES += QT_NO_DIRECTFB_KEYBOARD #DEFINES += QT_DIRECTFB_TIMING #DEFINES += QT_NO_DIRECTFB_OPAQUE_DETECTION +#DEFINES += QT_NO_DIRECTFB_STRETCHBLIT #DIRECTFB_DRAWINGOPERATIONS=DRAW_RECTS|DRAW_LINES|DRAW_IMAGE|DRAW_PIXMAP|DRAW_TILED_PIXMAP|STROKE_PATH|DRAW_PATH|DRAW_POINTS|DRAW_ELLIPSE|DRAW_POLYGON|DRAW_TEXT|FILL_PATH|FILL_RECT|DRAW_COLORSPANS|DRAW_ROUNDED_RECT #DEFINES += \"QT_DIRECTFB_WARN_ON_RASTERFALLBACKS=$$DIRECTFB_DRAWINGOPERATIONS\" #DEFINES += \"QT_DIRECTFB_DISABLE_RASTERFALLBACKS=$$DIRECTFB_DRAWINGOPERATIONS\" diff --git a/src/gui/embedded/qscreen_qws.cpp b/src/gui/embedded/qscreen_qws.cpp index ae5570f..07bb258 100644 --- a/src/gui/embedded/qscreen_qws.cpp +++ b/src/gui/embedded/qscreen_qws.cpp @@ -3150,6 +3150,7 @@ int QScreen::subScreenIndexAt(const QPoint &p) const #if 0 #ifdef QT_LOADABLE_MODULES +#include <dlfcn.h> // ### needs update after driver init changes diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 3bb40fb..1569078 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -3365,7 +3365,8 @@ void QGraphicsView::paintEvent(QPaintEvent *event) #define X11 qt_x11Data #endif backgroundPainter.setCompositionMode(QPainter::CompositionMode_Source); - drawBackground(&backgroundPainter, exposedSceneRect); + QRectF backgroundExposedSceneRect = mapToScene(d->backgroundPixmapExposed.boundingRect()).boundingRect(); + drawBackground(&backgroundPainter, backgroundExposedSceneRect); d->backgroundPixmapExposed = QRegion(); } diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp index 1b01e6f..3c1d7e9 100644 --- a/src/gui/image/qpixmap_raster.cpp +++ b/src/gui/image/qpixmap_raster.cpp @@ -375,7 +375,7 @@ int QRasterPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const case QPaintDevice::PdmWidthMM: return qRound(d->width * 25.4 / qt_defaultDpiX()); case QPaintDevice::PdmHeightMM: - return qRound(d->width * 25.4 / qt_defaultDpiY()); + return qRound(d->height * 25.4 / qt_defaultDpiY()); case QPaintDevice::PdmNumColors: return d->colortable.size(); case QPaintDevice::PdmDepth: diff --git a/src/gui/image/qpixmap_x11.cpp b/src/gui/image/qpixmap_x11.cpp index 7008fbd..f3947ff 100644 --- a/src/gui/image/qpixmap_x11.cpp +++ b/src/gui/image/qpixmap_x11.cpp @@ -1932,6 +1932,8 @@ QPixmap QX11PixmapData::transformed(const QTransform &transform, x11Data->hd = (Qt::HANDLE)XCreatePixmap(X11->display, RootWindow(X11->display, xinfo.screen()), w, h, d); + x11Data->setSerialNumber(++qt_pixmap_serial); + #ifndef QT_NO_XRENDER if (X11->use_xrender) { XRenderPictFormat *format = x11Data->d == 32 diff --git a/src/gui/image/qppmhandler.cpp b/src/gui/image/qppmhandler.cpp index 8ec9efb..f2d51f7 100644 --- a/src/gui/image/qppmhandler.cpp +++ b/src/gui/image/qppmhandler.cpp @@ -264,7 +264,7 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QBy bool gray = format == "pgm"; if (format == "pbm") { - image = image.convertToFormat(QImage::Format_MonoLSB); + image = image.convertToFormat(QImage::Format_Mono); } else if (image.depth() == 1) { image = image.convertToFormat(QImage::Format_Indexed8); } else { diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index e551a1d..81f38ec 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -9774,13 +9774,12 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f) } #endif - if (newParent) { - if (QWidgetBackingStore *oldBs = oldtlw->d_func()->maybeBackingStore()) { + if (QWidgetBackingStore *oldBs = oldtlw->d_func()->maybeBackingStore()) { + if (newParent) oldBs->removeDirtyWidget(this); - // Move the widget and all its static children from - // the old backing store to the new one. - oldBs->moveStaticWidgets(this); - } + // Move the widget and all its static children from + // the old backing store to the new one. + oldBs->moveStaticWidgets(this); } if ((QApplicationPrivate::app_compile_version < 0x040200 diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 84cf5cc..9bb4486 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -1364,7 +1364,10 @@ static void QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int le for (int i = 0; i < length; ++i) { PRELOAD_COND2(dest, src) uint s = src[i]; - dest[i] = s + BYTE_MUL(dest[i], qAlpha(~s)); + if (s >= 0xff000000) + dest[i] = s; + else if (s != 0) + dest[i] = s + BYTE_MUL(dest[i], qAlpha(~s)); } } else { for (int i = 0; i < length; ++i) { diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 8ed126f..fd67f96 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -1329,7 +1329,7 @@ void QPainterPrivate::updateState(QPainterState *newState) of composition modes, brushes, clipping, transformation, etc, is close to an impossible task because of the number of permutations. As a compromise we have selected a subset of the - QPainter API and backends, were performance is guaranteed to be as + QPainter API and backends, where performance is guaranteed to be as good as we can sensibly get it for the given combination of hardware and software. diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index ed86f5a..bcc993a 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -310,8 +310,8 @@ QColor QS60StylePrivate::stateColor(const QColor &color, const QStyleOption *opt QColor hsvColor = retColor.toHsv(); int colorSat = hsvColor.saturation(); int colorVal = hsvColor.value(); - colorSat = (colorSat!=0) ? (colorSat>>1) : 128; - colorVal = (colorVal!=0) ? (colorVal>>1) : 128; + colorSat = (colorSat != 0) ? (colorSat >> 1) : 128; + colorVal = (colorVal != 0) ? (colorVal >> 1) : 128; hsvColor.setHsv(hsvColor.hue(), colorSat, colorVal); retColor = hsvColor.toRgb(); } @@ -339,7 +339,7 @@ QColor QS60StylePrivate::lighterColor(const QColor &baseColor) bool QS60StylePrivate::drawsOwnThemeBackground(const QWidget *widget) { - return qobject_cast<const QDialog *> (widget); + return (widget ? (widget->windowType() == Qt::Dialog) : false); } QFont QS60StylePrivate::s60Font( @@ -372,7 +372,6 @@ void QS60StylePrivate::clearCaches(CacheClearReason reason) case CC_LayoutChange: // when layout changes, the colors remain in cache, but graphics and fonts can change m_mappedFontsCache.clear(); - deleteBackground(); QPixmapCache::clear(); break; case CC_ThemeChange: @@ -400,10 +399,10 @@ QColor QS60StylePrivate::colorFromFrameGraphics(SkinFrameElements frame) const if (!cachedColorExists) { const int frameCornerWidth = pixelMetric(PM_Custom_FrameCornerWidth); const int frameCornerHeight = pixelMetric(PM_Custom_FrameCornerHeight); - Q_ASSERT(2*frameCornerWidth<32); - Q_ASSERT(2*frameCornerHeight<32); + Q_ASSERT(2 * frameCornerWidth < 32); + Q_ASSERT(2 * frameCornerHeight < 32); - const QImage frameImage = QS60StylePrivate::frame(frame, QSize(32,32)).toImage(); + const QImage frameImage = QS60StylePrivate::frame(frame, QSize(32, 32)).toImage(); Q_ASSERT(frameImage.bytesPerLine() > 0); if (frameImage.isNull()) return Qt::black; @@ -418,14 +417,14 @@ QColor QS60StylePrivate::colorFromFrameGraphics(SkinFrameElements frame) const int skips = 0; int estimations = 0; - const int topBorderLastPixel = frameCornerHeight*frameImage.width()-1; - const int bottomBorderFirstPixel = frameImage.width()*frameImage.height()-frameCornerHeight*frameImage.width()-1; - const int rightBorderFirstPixel = frameImage.width()-frameCornerWidth; + const int topBorderLastPixel = frameCornerHeight*frameImage.width() - 1; + const int bottomBorderFirstPixel = frameImage.width() * frameImage.height() - frameCornerHeight*frameImage.width() - 1; + const int rightBorderFirstPixel = frameImage.width() - frameCornerWidth; const int leftBorderLastPixel = frameCornerWidth; while ((skips + estimations) < pixels) { - if ((skips+estimations) > topBorderLastPixel && - (skips+estimations) < bottomBorderFirstPixel) { + if ((skips + estimations) > topBorderLastPixel && + (skips + estimations) < bottomBorderFirstPixel) { for (int rowIndex = 0; rowIndex < frameImage.width(); rowIndex++) { if (rowIndex > leftBorderLastPixel && rowIndex < rightBorderFirstPixel) { @@ -530,18 +529,18 @@ void QS60StylePrivate::drawRow(QS60StyleEnums::SkinParts start, endRect = startRect.translated(rect.width() - startRect.width(), 0); middleRect.adjust(startRect.width(), 0, -startRect.width(), 0); if (startRect.bottomRight().x() > endRect.topLeft().x()) { - const int overlap = (startRect.bottomRight().x() - endRect.topLeft().x())>>1; - startRect.setWidth(startRect.width()-overlap); - endRect.adjust(overlap,0,0,0); + const int overlap = (startRect.bottomRight().x() - endRect.topLeft().x()) >> 1; + startRect.setWidth(startRect.width() - overlap); + endRect.adjust(overlap, 0, 0, 0); } } else { startRect.setHeight(qMin((rect.height() >> 1) - 1, startRect.height())); endRect = startRect.translated(0, rect.height() - startRect.height()); middleRect.adjust(0, startRect.height(), 0, -startRect.height()); if (startRect.topRight().y() > endRect.bottomLeft().y()) { - const int overlap = (startRect.topRight().y() - endRect.bottomLeft().y())>>1; - startRect.setHeight(startRect.height()-overlap); - endRect.adjust(0,overlap,0,0); + const int overlap = (startRect.topRight().y() - endRect.bottomLeft().y()) >> 1; + startRect.setHeight(startRect.height() - overlap); + endRect.adjust(0, overlap, 0, 0); } } @@ -809,13 +808,13 @@ QSize QS60StylePrivate::partSize(QS60StyleEnums::SkinParts part, SkinElementFlag case QS60StyleEnums::SP_QgnGrafTabActiveL: //Returned QSize for tabs must not be square, but narrow rectangle with width:height //ratio of 1:2 for horizontal tab bars (and 2:1 for vertical ones). - result.setWidth(result.height()>>1); + result.setWidth(result.height() >> 1); break; case QS60StyleEnums::SP_QgnGrafNsliderEndLeft: case QS60StyleEnums::SP_QgnGrafNsliderEndRight: case QS60StyleEnums::SP_QgnGrafNsliderMiddle: - result.setWidth(result.height()>>1); + result.setWidth(result.height() >> 1); break; case QS60StyleEnums::SP_QgnGrafNsliderMarker: @@ -992,10 +991,11 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom buttonOption.QStyleOption::operator=(*cmb); const int maxHeight = cmbxFrame.height(); const int maxWidth = cmbxFrame.width() - cmbxEditField.width(); - const int topLeftPoint = direction ? cmbxEditField.right()+1 : cmbxEditField.left()+1-maxWidth; + const int topLeftPoint = direction ? + (cmbxEditField.right() + 1) : (cmbxEditField.left() + 1 - maxWidth); const QRect buttonRect(topLeftPoint, cmbxEditField.top(), maxWidth, maxHeight); buttonOption.rect = buttonRect; - buttonOption.state = cmb->state & (State_Enabled | State_MouseOver); + buttonOption.state = cmb->state; drawPrimitive(PE_PanelButtonCommand, &buttonOption, painter, widget); // draw label background - label itself is drawn separately @@ -1381,9 +1381,9 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, const QModelIndex index = vopt->index; //todo: Draw cell background only once - for the first cell. QStyleOptionViewItemV4 voptAdj2 = voptAdj; - const QModelIndex indexFirst = itemView->model()->index(0,0); + const QModelIndex indexFirst = itemView->model()->index(0, 0); const QModelIndex indexLast = itemView->model()->index( - itemView->model()->rowCount()-1,itemView->model()->columnCount()-1); + itemView->model()->rowCount() - 1, itemView->model()->columnCount() -1); if (itemView->viewport()) voptAdj2.rect = QRect( itemView->visualRect(indexFirst).topLeft(), itemView->visualRect(indexLast).bottomRight()).intersect(itemView->viewport()->rect()); @@ -1571,16 +1571,16 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, f.setPointSizeF(f.pointSizeF() * KTabFontMul); painter->setFont(f); - if (option->state & QStyle::State_Selected){ + const bool selected = optionTab.state & State_Selected; + if (selected) optionTab.palette.setColor(QPalette::Active, QPalette::WindowText, QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 3, option)); - } const bool verticalTabs = optionTab.shape == QTabBar::RoundedEast || optionTab.shape == QTabBar::RoundedWest || optionTab.shape == QTabBar::TriangularEast || optionTab.shape == QTabBar::TriangularWest; - const bool selected = optionTab.state & State_Selected; + if (verticalTabs) { painter->save(); int newX, newY, newRotation; @@ -1618,12 +1618,12 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, QPixmap tabIcon = optionTab.icon.pixmap(iconSize, (optionTab.state & State_Enabled) ? QIcon::Normal : QIcon::Disabled); if (tab->text.isEmpty()) - painter->drawPixmap(tr.center().x() - (tabIcon.height() >>1), - tr.center().y() - (tabIcon.height() >>1), + painter->drawPixmap(tr.center().x() - (tabIcon.height() >> 1), + tr.center().y() - (tabIcon.height() >> 1), tabIcon); else painter->drawPixmap(tr.left() + tabOverlap, - tr.center().y() - (tabIcon.height() >>1), + tr.center().y() - (tabIcon.height() >> 1), tabIcon); tr.setLeft(tr.left() + iconSize.width() + 4); } @@ -1652,7 +1652,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, if (optionProgressBar->orientation == Qt::Horizontal) { progressRect.setWidth(int(progressRect.width() * progressFactor)); if(optionProgressBar->direction == Qt::RightToLeft) - progressRect.translate(optionProgressBar->rect.width()-progressRect.width(),0); + progressRect.translate(optionProgressBar->rect.width()-progressRect.width(), 0); progressRect.adjust(1, 0, -1, 0); } else { progressRect.adjust(0, 1, 0, -1); @@ -1718,18 +1718,18 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, optionCheckBox.QStyleOptionMenuItem::operator=(*menuItem); optionCheckBox.rect.setWidth(pixelMetric(PM_IndicatorWidth)); optionCheckBox.rect.setHeight(pixelMetric(PM_IndicatorHeight)); - const int moveByX = optionCheckBox.rect.width()+vSpacing; + const int moveByX = optionCheckBox.rect.width() + vSpacing; if (optionMenuItem.direction == Qt::LeftToRight) { - textRect.translate(moveByX,0); + textRect.translate(moveByX, 0); iconRect.translate(moveByX, 0); - iconRect.setWidth(iconRect.width()+vSpacing); - textRect.setWidth(textRect.width()-moveByX-vSpacing); - optionCheckBox.rect.translate(vSpacing/2, hSpacing/2); + iconRect.setWidth(iconRect.width() + vSpacing); + textRect.setWidth(textRect.width() - moveByX - vSpacing); + optionCheckBox.rect.translate(vSpacing >> 1, hSpacing >> 1); } else { - textRect.setWidth(textRect.width()-moveByX); - iconRect.setWidth(iconRect.width()+vSpacing); - iconRect.translate(-optionCheckBox.rect.width()-vSpacing, 0); - optionCheckBox.rect.translate(textRect.width()+iconRect.width(),0); + textRect.setWidth(textRect.width() - moveByX); + iconRect.setWidth(iconRect.width() + vSpacing); + iconRect.translate(-optionCheckBox.rect.width() - vSpacing, 0); + optionCheckBox.rect.translate(textRect.width() + iconRect.width(), 0); } drawPrimitive(PE_IndicatorMenuCheckMark, &optionCheckBox, painter, widget); } @@ -1740,9 +1740,9 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, if (itemWithIcon) { drawItemPixmap(painter, iconRect, text_flags, pix); if (optionMenuItem.direction == Qt::LeftToRight) - textRect.translate(vSpacing,0); + textRect.translate(vSpacing, 0); else - textRect.translate(-vSpacing,0); + textRect.translate(-vSpacing, 0); textRect.setWidth(textRect.width()-vSpacing); } @@ -1750,7 +1750,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, if (drawSubMenuIndicator) { QStyleOptionMenuItem arrowOptions; arrowOptions.QStyleOption::operator=(*menuItem); - const int indicatorWidth = (pixelMetric(PM_ListViewIconSize, option, widget)>>1) + + const int indicatorWidth = (pixelMetric(PM_ListViewIconSize, option, widget) >> 1) + pixelMetric(QStyle::PM_LayoutVerticalSpacing, option, widget); if (optionMenuItem.direction == Qt::LeftToRight) arrowOptions.rect.setLeft(textRect.right()); @@ -1795,8 +1795,8 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, painter->save(); QPen linePen = QPen(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 1, header)); const int penWidth = (header->orientation == Qt::Horizontal) ? - linePen.width()+QS60StylePrivate::pixelMetric(PM_Custom_BoldLineWidth) - : linePen.width()+QS60StylePrivate::pixelMetric(PM_Custom_ThinLineWidth); + linePen.width() + QS60StylePrivate::pixelMetric(PM_Custom_BoldLineWidth) + : linePen.width() + QS60StylePrivate::pixelMetric(PM_Custom_ThinLineWidth); linePen.setWidth(penWidth); painter->setPen(linePen); if (header->orientation == Qt::Horizontal){ @@ -1815,7 +1815,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, //Make cornerButton slightly smaller so that it is not on top of table border graphic. QStyleOptionHeader subopt = *header; const int borderTweak = - QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth)>>1; + QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth) >> 1; if (subopt.direction == Qt::LeftToRight) subopt.rect.adjust(borderTweak, borderTweak, 0, -borderTweak); else @@ -1908,9 +1908,9 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, } else { const int frameWidth = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth); if (option->direction == Qt::LeftToRight) - headerRect.adjust(-2*frameWidth, 0, 0, 0); + headerRect.adjust(-2 * frameWidth, 0, 0, 0); else - headerRect.adjust(0, 0, 2*frameWidth, 0); + headerRect.adjust(0, 0, 2 * frameWidth, 0); } if (option->palette.brush(QPalette::Button).color() == Qt::transparent) QS60StylePrivate::drawSkinElement( @@ -2033,7 +2033,7 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti QRect tickRect = option->rect; const int frameBorderWidth = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth); // adjust tickmark rect to exclude frame border - tickRect.adjust(0,-frameBorderWidth,0,-frameBorderWidth); + tickRect.adjust(0, -frameBorderWidth, 0, -frameBorderWidth); QS60StyleEnums::SkinParts skinPart = QS60StyleEnums::SP_QgnIndiMarkedAdd; QS60StylePrivate::drawSkinPart(skinPart, painter, tickRect, (flags | QS60StylePrivate::SF_ColorSkinned)); @@ -2045,7 +2045,7 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti case PE_IndicatorRadioButton: { QRect buttonRect = option->rect; //there is empty (a. 33%) space in svg graphics for radiobutton - const qreal reduceWidth = (qreal)buttonRect.width()/3.0; + const qreal reduceWidth = (qreal)buttonRect.width() / 3.0; const qreal rectWidth = (qreal)option->rect.width() != 0 ? option->rect.width() : 1.0; // Try to occupy the full area const qreal scaler = 1 + (reduceWidth/rectWidth); @@ -2108,27 +2108,28 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti case PE_IndicatorSpinDown: case PE_IndicatorSpinUp: if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) { - QStyleOptionSpinBox optionSpinBox = *spinBox; - if (QS60StylePrivate::canDrawThemeBackground(optionSpinBox.palette.base())) { + if (QS60StylePrivate::canDrawThemeBackground(spinBox->palette.base())) { + QStyleOptionSpinBox optionSpinBox = *spinBox; const QS60StyleEnums::SkinParts part = (element == PE_IndicatorSpinUp) ? QS60StyleEnums::SP_QgnGrafScrollArrowUp : QS60StyleEnums::SP_QgnGrafScrollArrowDown; - const int adjustment = qMin(optionSpinBox.rect.width(), optionSpinBox.rect.height())/6; - optionSpinBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? adjustment : -adjustment ); - QS60StylePrivate::drawSkinPart(part, painter, optionSpinBox.rect,flags); + const int iconMargin = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth) >> 1; + optionSpinBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? iconMargin : -iconMargin ); + QS60StylePrivate::drawSkinPart(part, painter, optionSpinBox.rect, flags); } else { commonStyleDraws = true; } } +#endif //QT_NO_SPINBOX #ifndef QT_NO_COMBOBOX - else if (const QStyleOptionFrame *cmb = qstyleoption_cast<const QStyleOptionFrame *>(option)) { + if (const QStyleOptionFrame *cmb = qstyleoption_cast<const QStyleOptionFrame *>(option)) { if (QS60StylePrivate::canDrawThemeBackground( option->palette.base())) { // We want to draw down arrow here for comboboxes as well. + QStyleOptionFrame optionsComboBox = *cmb; const QS60StyleEnums::SkinParts part = QS60StyleEnums::SP_QgnGrafScrollArrowDown; - QStyleOptionFrame comboBox = *cmb; - const int adjustment = qMin(comboBox.rect.width(), comboBox.rect.height())/6; - comboBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? adjustment : -adjustment ); - QS60StylePrivate::drawSkinPart(part, painter, comboBox.rect,flags); + const int iconMargin = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth) >> 1; + optionsComboBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? iconMargin : -iconMargin ); + QS60StylePrivate::drawSkinPart(part, painter, optionsComboBox.rect, flags); } else { commonStyleDraws = true; } @@ -2146,12 +2147,11 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti // We want to draw down arrow here for comboboxes as well. QStyleOptionFrame comboBox = *cmb; const int frameWidth = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth); - comboBox.rect.adjust(0,frameWidth,0,-frameWidth); + comboBox.rect.adjust(0, frameWidth, 0, -frameWidth); QCommonStyle::drawPrimitive(element, &comboBox, painter, widget); } #endif //QT_NO_COMBOBOX break; -#endif //QT_NO_SPINBOX case PE_Widget: if (QS60StylePrivate::drawsOwnThemeBackground(widget) #ifndef QT_NO_COMBOBOX @@ -2161,7 +2161,10 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti || qobject_cast<const QMenu *> (widget) #endif //QT_NO_MENU ) { - if (QS60StylePrivate::canDrawThemeBackground(option->palette.base())) + //Need extra check since dialogs have their own theme background + if (QS60StylePrivate::canDrawThemeBackground(option->palette.base()) && + option->palette.window().texture().cacheKey() == + QS60StylePrivate::m_themePalette->window().texture().cacheKey()) QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_OptionsMenu, painter, option->rect, flags); else commonStyleDraws = true; @@ -2338,22 +2341,22 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt, case CT_ToolButton: sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget); //FIXME properly - style should calculate the location of border frame-part - sz += QSize(2*pixelMetric(PM_ButtonMargin), 2*pixelMetric(PM_ButtonMargin)); + sz += QSize(2 * pixelMetric(PM_ButtonMargin), 2 * pixelMetric(PM_ButtonMargin)); if (const QStyleOptionToolButton *toolBtn = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) if (toolBtn->subControls & SC_ToolButtonMenu) - sz += QSize(pixelMetric(PM_MenuButtonIndicator),0); + sz += QSize(pixelMetric(PM_MenuButtonIndicator), 0); break; case CT_PushButton: sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget); //FIXME properly - style should calculate the location of border frame-part - sz += QSize(2*pixelMetric(PM_ButtonMargin), 2*pixelMetric(PM_ButtonMargin)); + sz += QSize(2 * pixelMetric(PM_ButtonMargin), 2 * pixelMetric(PM_ButtonMargin)); if (const QAbstractButton *buttonWidget = (qobject_cast<const QAbstractButton *>(widget))) if (buttonWidget->isCheckable()) sz += QSize(pixelMetric(PM_IndicatorWidth) + pixelMetric(PM_CheckBoxLabelSpacing), 0); break; case CT_LineEdit: if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt)) - sz += QSize(2*f->lineWidth, 4*f->lineWidth); + sz += QSize(2 * f->lineWidth, 4 * f->lineWidth); break; case CT_TabBarTab: { @@ -2368,7 +2371,7 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt, if (QS60StylePrivate::isTouchSupported()) //Make itemview easier to use in touch devices //QCommonStyle does not adjust height with horizontal margin, it only adjusts width - sz.setHeight(sz.height() + 2*pixelMetric(QStyle::PM_FocusFrameVMargin)); + sz.setHeight(sz.height() + 2 * pixelMetric(QStyle::PM_FocusFrameVMargin)); break; default: sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget); @@ -2384,10 +2387,10 @@ int QS60Style::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w int retValue = -1; switch (sh) { case SH_Table_GridLineColor: - retValue = int(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors,2,0).rgba()); + retValue = int(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 2, 0).rgba()); break; case SH_GroupBox_TextLabelColor: - retValue = int(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors,6,0).rgba()); + retValue = int(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0).rgba()); break; case SH_ScrollBar_ScrollWhenPointerLeavesControl: retValue = true; @@ -2469,7 +2472,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple sliderlen = (qint64(scrollbarOption->pageStep) * maxlen) / (range + scrollbarOption->pageStep); const int slidermin = pixelMetric(PM_ScrollBarSliderMin, scrollbarOption, widget); - if (sliderlen < slidermin || range > (INT_MAX>>1)) + if (sliderlen < slidermin || range > (INT_MAX >> 1)) sliderlen = slidermin; if (sliderlen > maxlen) sliderlen = maxlen; @@ -2520,39 +2523,40 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) { const int frameThickness = spinbox->frame ? pixelMetric(PM_SpinBoxFrameWidth, spinbox, widget) : 0; const int buttonMargin = spinbox->frame ? 2 : 0; - const int buttonWidth = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize) + 2*buttonMargin; + const int buttonWidth = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize) + 2 * buttonMargin; QSize buttonSize; buttonSize.setHeight(qMax(8, spinbox->rect.height() - frameThickness)); - buttonSize.setWidth(buttonWidth); + //width should at least be equal to height + buttonSize.setWidth(qMax(buttonSize.height(), buttonWidth)); buttonSize = buttonSize.expandedTo(QApplication::globalStrut()); const int y = frameThickness + spinbox->rect.y(); - const int x = spinbox->rect.x() + spinbox->rect.width() - frameThickness - 2*buttonSize.width(); + const int x = spinbox->rect.x() + spinbox->rect.width() - frameThickness - 2 * buttonSize.width(); switch (scontrol) { case SC_SpinBoxUp: if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) return QRect(); - ret = QRect(x, y, buttonWidth, buttonSize.height()); + ret = QRect(x, y, buttonSize.width(), buttonSize.height()); break; case SC_SpinBoxDown: if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) return QRect(); - ret = QRect(x+buttonSize.width(), y, buttonWidth, buttonSize.height()); + ret = QRect(x + buttonSize.width(), y, buttonSize.width(), buttonSize.height()); break; case SC_SpinBoxEditField: if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons) ret = QRect( frameThickness, frameThickness, - spinbox->rect.width() - 2*frameThickness, - spinbox->rect.height() - 2*frameThickness); + spinbox->rect.width() - 2 * frameThickness, + spinbox->rect.height() - 2 * frameThickness); else ret = QRect( frameThickness, frameThickness, x - frameThickness, - spinbox->rect.height() - 2*frameThickness); + spinbox->rect.height() - 2 * frameThickness); break; case SC_SpinBoxFrame: ret = spinbox->rect; @@ -2568,29 +2572,29 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple ret = cmb->rect; const int width = cmb->rect.width(); const int height = cmb->rect.height(); + const int buttonIconSize = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize); const int buttonMargin = cmb->frame ? 2 : 0; // lets use spinbox frame here as well, as no combobox specific value available. const int frameThickness = cmb->frame ? pixelMetric(PM_SpinBoxFrameWidth, cmb, widget) : 0; - const int buttonWidth = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize); + const int buttonWidth = qMax(cmb->rect.height(), buttonIconSize); + const int xposMod = (cmb->rect.x()) + width - buttonMargin - buttonWidth; + const int ypos = cmb->rect.y(); QSize buttonSize; - buttonSize.setHeight(qMax(8, (cmb->rect.height()>>1) - frameThickness)); //minimum of 8 pixels - buttonSize.setWidth(buttonWidth+2*buttonMargin); + buttonSize.setWidth(buttonWidth + 2 * buttonMargin); + buttonSize.setHeight(qMax(8, (cmb->rect.height() >> 1) - frameThickness)); //buttons should be squares buttonSize = buttonSize.expandedTo(QApplication::globalStrut()); switch (scontrol) { case SC_ComboBoxArrow: - ret.setRect( - ret.x() + ret.width() - buttonMargin - buttonWidth, - ret.y() + buttonMargin, - buttonWidth, - height - 2*buttonMargin); + ret.setRect(xposMod, ypos + buttonMargin, buttonWidth, height - 2 * buttonMargin); break; case SC_ComboBoxEditField: { - ret.setRect( - ret.x() + frameThickness, - ret.y() + frameThickness, - ret.width() - 2*frameThickness - buttonSize.width(), - ret.height() - 2*frameThickness); + const int withFrameX = cmb->rect.x() + cmb->rect.width() - frameThickness - buttonSize.width(); + ret = QRect( + frameThickness, + frameThickness, + withFrameX - frameThickness, + cmb->rect.height() - 2 * frameThickness); } break; default: @@ -2607,7 +2611,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple //slightly indent text and boxes, so that dialog border does not mess with them. const int horizontalSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing); - ret.adjust(2,horizontalSpacing-3,0,0); + ret.adjust(2, horizontalSpacing - 3, 0, 0); } break; case SC_GroupBoxFrame: { @@ -2615,7 +2619,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple const int tbHeight = textBox.height(); ret.translate(0, -ret.y()); // include title to within the groupBox frame - ret.setHeight(ret.height()+tbHeight); + ret.setHeight(ret.height() + tbHeight); if (widget && ret.bottom() > widget->rect().bottom()) ret.setBottom(widget->rect().bottom()); } @@ -2627,7 +2631,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple break; case CC_ToolButton: if (const QStyleOptionToolButton *toolButton = qstyleoption_cast<const QStyleOptionToolButton *>(option)) { - const int indicatorRect = pixelMetric(PM_MenuButtonIndicator) + 2*pixelMetric(PM_ButtonMargin); + const int indicatorRect = pixelMetric(PM_MenuButtonIndicator) + 2 * pixelMetric(PM_ButtonMargin); const int border = pixelMetric(PM_ButtonMargin) + pixelMetric(PM_DefaultFrameWidth); ret = toolButton->rect; const bool popup = (toolButton->features & @@ -2665,13 +2669,13 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con // in S60 the input text box doesn't start from line Edit's TL, but // a bit indented. QRect lineEditRect = opt->rect; - const int adjustment = opt->rect.height()>>2; - lineEditRect.adjust(adjustment,0,0,0); + const int adjustment = opt->rect.height() >> 2; + lineEditRect.adjust(adjustment, 0, 0, 0); ret = lineEditRect; } break; case SE_TabBarTearIndicator: - ret = QRect(0,0,0,0); + ret = QRect(0, 0, 0, 0); break; case SE_TabWidgetTabBar: if (const QStyleOptionTabWidgetFrame *optionTab = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) { @@ -2693,12 +2697,12 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con // make sure that gain does not set the rect outside of widget boundaries if (twf->direction == Qt::RightToLeft) { if ((ret.left() - gain) < widget->rect().left()) - gain = widget->rect().left()-ret.left(); - ret.adjust(-gain,0,0,0); + gain = widget->rect().left() - ret.left(); + ret.adjust(-gain, 0, 0, 0); } else { if ((ret.right() + gain) > widget->rect().right()) - gain = widget->rect().right()-ret.right(); - ret.adjust(0,0,gain,0); + gain = widget->rect().right() - ret.right(); + ret.adjust(0, 0, gain, 0); } } break; @@ -2706,8 +2710,8 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con default: { if (widget) { if ((ret.bottom() + gain) > widget->rect().bottom()) - gain = widget->rect().bottom()-ret.bottom(); - ret.adjust(0,0,0,gain); + gain = widget->rect().bottom() - ret.bottom(); + ret.adjust(0, 0, 0, gain); } break; } @@ -2733,7 +2737,7 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con QS60StylePrivate::pixelMetric(QStyle::PM_LayoutVerticalSpacing); //const int horizontalSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing); const int checkBoxRectWidth = subElementRect(SE_ItemViewItemCheckIndicator, opt, widget).width(); - ret.adjust(-checkBoxRectWidth-verticalSpacing,0,-checkBoxRectWidth-verticalSpacing,0); + ret.adjust(-checkBoxRectWidth - verticalSpacing, 0, -checkBoxRectWidth - verticalSpacing, 0); } } else if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) { const bool checkable = menuItem->checkType != QStyleOptionMenuItem::NotCheckable; @@ -2758,9 +2762,9 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu){ // submenu indicator is very small, so lets halve the rect if (menuItem->direction == Qt::LeftToRight) - ret.adjust(0,0,-(indicatorWidth >> 1),0); + ret.adjust(0, 0, -(indicatorWidth >> 1), 0); else - ret.adjust((indicatorWidth >> 1),0,0,0); + ret.adjust((indicatorWidth >> 1), 0, 0, 0); } } } @@ -2784,14 +2788,14 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con const int itemHeight = opt->rect.height(); int heightOffset = 0; if (indicatorHeight < itemHeight) - heightOffset = ((itemHeight - indicatorHeight)>>1); + heightOffset = ((itemHeight - indicatorHeight) >> 1); if (checkBoxOnly) { // Move rect and make it slightly smaller, so that // a) highlight border does not cross the rect // b) in s60 list checkbox is smaller than normal checkbox //todo; magic three - ret.setRect(opt->rect.left()+3, opt->rect.top() + heightOffset, - indicatorWidth-3, indicatorHeight-3); + ret.setRect(opt->rect.left() + 3, opt->rect.top() + heightOffset, + indicatorWidth - 3, indicatorHeight - 3); } else { ret.setRect(opt->rect.right() - indicatorWidth - spacing, opt->rect.top() + heightOffset, indicatorWidth, indicatorHeight); @@ -2955,7 +2959,7 @@ QIcon QS60Style::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const { const int iconDimension = QS60StylePrivate::pixelMetric(QStyle::PM_ToolBarIconSize); - const QRect iconSize = (!option) ? QRect(0,0,iconDimension,iconDimension) : option->rect; + const QRect iconSize = (!option) ? QRect(0, 0, iconDimension, iconDimension) : option->rect; QS60StyleEnums::SkinParts part; QS60StylePrivate::SkinElementFlags adjustedFlags; if (option) diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp index 13ac301..fb9665a 100644 --- a/src/gui/styles/qs60style_s60.cpp +++ b/src/gui/styles/qs60style_s60.cpp @@ -1133,9 +1133,21 @@ QPixmap QS60StylePrivate::frame(SkinFrameElements frame, const QSize &size, Skin QPixmap QS60StylePrivate::backgroundTexture() { + bool createNewBackground = false; if (!m_background) { + createNewBackground = true; + } else { + //if background brush does not match screensize, re-create it + if (m_background->width() != S60->screenWidthInPixels || + m_background->height() != S60->screenHeightInPixels) { + delete m_background; + createNewBackground = true; + } + } + + if (createNewBackground) { QPixmap background = part(QS60StyleEnums::SP_QsnBgScreen, - QSize(S60->screenWidthInPixels, S60->screenHeightInPixels), 0, SkinElementFlags()); + QSize(S60->screenWidthInPixels, S60->screenHeightInPixels), 0, SkinElementFlags()); m_background = new QPixmap(background); } return *m_background; @@ -1143,8 +1155,7 @@ QPixmap QS60StylePrivate::backgroundTexture() QSize QS60StylePrivate::screenSize() { - const TSize screenSize = QS60Data::screenDevice()->SizeInPixels(); - return QSize(screenSize.iWidth, screenSize.iHeight); + return QSize(S60->screenWidthInPixels, S60->screenHeightInPixels); } QS60Style::QS60Style() diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp index 8b40931..aff3ac0 100644 --- a/src/gui/styles/qstylesheetstyle.cpp +++ b/src/gui/styles/qstylesheetstyle.cpp @@ -1065,7 +1065,7 @@ QRect QRenderRule::boxRect(const QRect& cr, int flags) const r.adjust(-p[LeftEdge], -p[TopEdge], p[RightEdge], p[BottomEdge]); } } - if (!hasNativeBorder() && (flags & Border)) { + if (hasBorder() && (flags & Border)) { const int *b = border()->borders; r.adjust(-b[LeftEdge], -b[TopEdge], b[RightEdge], b[BottomEdge]); } diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp index 1bd4dd6..5822d92 100644 --- a/src/gui/text/qtextodfwriter.cpp +++ b/src/gui/text/qtextodfwriter.cpp @@ -484,6 +484,10 @@ void QTextOdfWriter::writeBlockFormat(QXmlStreamWriter &writer, QTextBlockFormat if (format.pageBreakPolicy() & QTextFormat::PageBreak_AlwaysAfter) writer.writeAttribute(foNS, QString::fromLatin1("break-after"), QString::fromLatin1("page")); } + if (format.hasProperty(QTextFormat::BackgroundBrush)) { + QBrush brush = format.background(); + writer.writeAttribute(foNS, QString::fromLatin1("background-color"), brush.color().name()); + } if (format.hasProperty(QTextFormat::BlockNonBreakableLines)) writer.writeAttribute(foNS, QString::fromLatin1("keep-together"), format.nonBreakableLines() ? QString::fromLatin1("true") : QString::fromLatin1("false")); @@ -610,9 +614,12 @@ void QTextOdfWriter::writeCharacterFormat(QXmlStreamWriter &writer, QTextCharFor } if (format.hasProperty(QTextFormat::ForegroundBrush)) { QBrush brush = format.foreground(); - // TODO writer.writeAttribute(foNS, QString::fromLatin1("color"), brush.color().name()); } + if (format.hasProperty(QTextFormat::BackgroundBrush)) { + QBrush brush = format.background(); + writer.writeAttribute(foNS, QString::fromLatin1("background-color"), brush.color().name()); + } writer.writeEndElement(); // style } diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index 9d545b9..326ea1f 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -218,6 +218,23 @@ QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context) } +QGLEngineSharedShaders::~QGLEngineSharedShaders() +{ + QList<QGLEngineShaderProg*>::iterator itr; + for (itr = cachedPrograms.begin(); itr != cachedPrograms.end(); ++itr) + delete *itr; + + if (blitShaderProg) { + delete blitShaderProg; + blitShaderProg = 0; + } + + if (simpleShaderProg) { + delete simpleShaderProg; + simpleShaderProg = 0; + } +} + #if defined (QT_DEBUG) QByteArray QGLEngineSharedShaders::snippetNameStr(SnippetName name) { @@ -393,7 +410,7 @@ QGLEngineShaderManager::~QGLEngineShaderManager() removeCustomStage(); } -uint QGLEngineShaderManager::getUniformLocation(Uniform id) +GLuint QGLEngineShaderManager::getUniformLocation(Uniform id) { if (!currentShaderProg) return 0; @@ -428,9 +445,9 @@ uint QGLEngineShaderManager::getUniformLocation(Uniform id) } -void QGLEngineShaderManager::optimiseForBrushTransform(const QTransform &transform) +void QGLEngineShaderManager::optimiseForBrushTransform(QTransform::TransformationType transformType) { - Q_UNUSED(transform); // Currently ignored + Q_UNUSED(transformType); // Currently ignored } void QGLEngineShaderManager::setDirty() @@ -505,7 +522,27 @@ QGLShaderProgram* QGLEngineShaderManager::currentProgram() if (currentShaderProg) return currentShaderProg->program; else - return simpleProgram(); + return sharedShaders->simpleProgram(); +} + +void QGLEngineShaderManager::useSimpleProgram() +{ + sharedShaders->simpleProgram()->bind(); + QGLContextPrivate* ctx_d = ctx->d_func(); + ctx_d->setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, true); + ctx_d->setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, false); + ctx_d->setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false); + shaderProgNeedsChanging = true; +} + +void QGLEngineShaderManager::useBlitProgram() +{ + sharedShaders->blitProgram()->bind(); + QGLContextPrivate* ctx_d = ctx->d_func(); + ctx_d->setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, true); + ctx_d->setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, true); + ctx_d->setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false); + shaderProgNeedsChanging = true; } QGLShaderProgram* QGLEngineShaderManager::simpleProgram() @@ -716,6 +753,13 @@ bool QGLEngineShaderManager::useCorrectShaderProg() customSrcStage->setUniforms(currentShaderProg->program); } + // Make sure all the vertex attribute arrays the program uses are enabled (and the ones it + // doesn't use are disabled) + QGLContextPrivate* ctx_d = ctx->d_func(); + ctx_d->setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, true); + ctx_d->setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, currentShaderProg->useTextureCoords); + ctx_d->setVertexAttribArrayEnabled(QT_OPACITY_ATTR, currentShaderProg->useOpacityAttribute); + shaderProgNeedsChanging = false; return true; } diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h index 50c1432..a3464d4 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h @@ -344,6 +344,7 @@ public: */ QGLEngineSharedShaders(const QGLContext *context); + ~QGLEngineSharedShaders(); QGLShaderProgram *simpleProgram() { return simpleShaderProg; } QGLShaderProgram *blitProgram() { return blitShaderProg; } @@ -454,7 +455,7 @@ public: // There are optimisations we can do, depending on the brush transform: // 1) May not have to apply perspective-correction // 2) Can use lower precision for matrix - void optimiseForBrushTransform(const QTransform &transform); + void optimiseForBrushTransform(QTransform::TransformationType transformType); void setSrcPixelType(Qt::BrushStyle); void setSrcPixelType(PixelSrcType); // For non-brush sources, like pixmaps & images void setOpacityMode(OpacityMode); @@ -463,11 +464,14 @@ public: void setCustomStage(QGLCustomShaderStage* stage); void removeCustomStage(); - uint getUniformLocation(Uniform id); + GLuint getUniformLocation(Uniform id); void setDirty(); // someone has manually changed the current shader program bool useCorrectShaderProg(); // returns true if the shader program needed to be changed + void useSimpleProgram(); + void useBlitProgram(); + QGLShaderProgram* currentProgram(); // Returns pointer to the shader the manager has chosen QGLShaderProgram* simpleProgram(); // Used to draw into e.g. stencil buffers QGLShaderProgram* blitProgram(); // Used to blit a texture into the framebuffer diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 32fa3dc..7655971 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -124,17 +124,20 @@ public: public Q_SLOTS: void contextDestroyed(const QGLContext *context) { if (context == ctx) { - QList<const QGLContext *> shares = qgl_share_reg()->shares(ctx); - if (shares.isEmpty()) { - glDeleteFramebuffers(1, &m_fbo); - if (m_width || m_height) - glDeleteTextures(1, &m_texture); + const QGLContext *nextCtx = qt_gl_transfer_context(ctx); + if (!nextCtx) { + // the context may not be current, so we cannot directly + // destroy the fbo and texture here, but since the context + // is about to be destroyed, the GL server will do the + // clean up for us anyway + m_fbo = 0; + m_texture = 0; ctx = 0; } else { // since the context holding the texture is shared, and // about to be destroyed, we have to transfer ownership // of the texture to one of the share contexts - ctx = const_cast<QGLContext *>((ctx == shares.at(0)) ? shares.at(1) : shares.at(0)); + ctx = const_cast<QGLContext *>(nextCtx); } } } @@ -227,11 +230,6 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height) pex->transferMode(BrushDrawingMode); -#ifndef QT_OPENGL_ES_2 - if (pex->inRenderText) - glPushAttrib(GL_ENABLE_BIT | GL_VIEWPORT_BIT | GL_SCISSOR_BIT); -#endif - glDisable(GL_STENCIL_TEST); glDisable(GL_DEPTH_TEST); glDisable(GL_SCISSOR_TEST); @@ -242,21 +240,14 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height) float vertexCoordinateArray[] = { -1, -1, 1, -1, 1, 1, -1, 1 }; float textureCoordinateArray[] = { 0, 0, 1, 0, 1, 1, 0, 1 }; - glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR); - glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); - glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinateArray); glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinateArray); - pex->shaderManager->blitProgram()->bind(); + pex->shaderManager->useBlitProgram(); pex->shaderManager->blitProgram()->setUniformValue("imageTexture", QT_IMAGE_TEXTURE_UNIT); - pex->shaderManager->setDirty(); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR); - glDisableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); - glBindTexture(GL_TEXTURE_2D, m_texture); #ifdef QT_OPENGL_ES_2 @@ -283,11 +274,6 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height) glViewport(0, 0, pex->width, pex->height); pex->updateClipScissorTest(); - -#ifndef QT_OPENGL_ES_2 - if (pex->inRenderText) - glPopAttrib(); -#endif } void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph) @@ -358,10 +344,10 @@ QGL2PaintEngineExPrivate::~QGL2PaintEngineExPrivate() void QGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform, GLuint id) { // glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); //### Is it always this texture unit? - if (id != GLuint(-1) && id == lastTexture) + if (id != GLuint(-1) && id == lastTextureUsed) return; - lastTexture = id; + lastTextureUsed = id; if (smoothPixmapTransform) { glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -407,14 +393,13 @@ void QGL2PaintEngineExPrivate::setBrush(const QBrush& brush) } else { shaderManager->setSrcPixelType(newStyle); } - shaderManager->optimiseForBrushTransform(currentBrush.transform()); + shaderManager->optimiseForBrushTransform(currentBrush.transform().type()); } void QGL2PaintEngineExPrivate::useSimpleShader() { - shaderManager->simpleProgram()->bind(); - shaderManager->setDirty(); + shaderManager->useSimpleProgram(); if (matrixDirty) updateMatrix(); @@ -607,13 +592,28 @@ void QGL2PaintEngineExPrivate::updateMatrix() const GLfloat wfactor = 2.0f / width; const GLfloat hfactor = -2.0f / height; + GLfloat dx = transform.dx(); + GLfloat dy = transform.dy(); + + // Non-integer translates can have strange effects for some rendering operations such as + // anti-aliased text rendering. In such cases, we snap the translate to the pixel grid. + if (snapToPixelGrid && transform.type() == QTransform::TxTranslate) { + // 0.50 needs to rounded down to 0.0 for consistency with raster engine: + dx = ceilf(dx - 0.5f); + dy = ceilf(dy - 0.5f); + } + + if (addOffset) { + dx += 0.49f; + dy += 0.49f; + } pmvMatrix[0][0] = (wfactor * transform.m11()) - transform.m13(); pmvMatrix[1][0] = (wfactor * transform.m21()) - transform.m23(); - pmvMatrix[2][0] = (wfactor * transform.dx() ) - transform.m33(); + pmvMatrix[2][0] = (wfactor * dx) - transform.m33(); pmvMatrix[0][1] = (hfactor * transform.m12()) + transform.m13(); pmvMatrix[1][1] = (hfactor * transform.m22()) + transform.m23(); - pmvMatrix[2][1] = (hfactor * transform.dy() ) + transform.m33(); + pmvMatrix[2][1] = (hfactor * dy) + transform.m33(); pmvMatrix[0][2] = transform.m13(); pmvMatrix[1][2] = transform.m23(); pmvMatrix[2][2] = transform.m33(); @@ -705,6 +705,17 @@ void QGL2PaintEngineExPrivate::drawTexture(const QGLRect& dest, const QGLRect& s // Setup for texture drawing currentBrush = noBrush; shaderManager->setSrcPixelType(pattern ? QGLEngineShaderManager::PatternSrc : QGLEngineShaderManager::ImageSrc); + + if (addOffset) { + addOffset = false; + matrixDirty = true; + } + + if (snapToPixelGrid) { + snapToPixelGrid = false; + matrixDirty = true; + } + if (prepareForDraw(opaque)) shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::ImageTexture), QT_IMAGE_TEXTURE_UNIT); @@ -733,6 +744,10 @@ void QGL2PaintEngineEx::beginNativePainting() QGLContext *ctx = d->ctx; glUseProgram(0); + // Disable all the vertex attribute arrays: + for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) + glDisableVertexAttribArray(i); + #ifndef QT_OPENGL_ES_2 // be nice to people who mix OpenGL 1.x code with QPainter commands // by setting modelview and projection matrices to mirror the GL 1 @@ -759,7 +774,7 @@ void QGL2PaintEngineEx::beginNativePainting() Q_UNUSED(ctx); #endif - d->lastTexture = GLuint(-1); + d->lastTextureUsed = GLuint(-1); d->dirtyStencilRegion = QRect(0, 0, d->width, d->height); d->resetGLState(); @@ -786,46 +801,26 @@ void QGL2PaintEngineEx::endNativePainting() d->needsSync = true; } -const QGLContext *QGL2PaintEngineEx::context() -{ - Q_D(QGL2PaintEngineEx); - return d->ctx; -} - void QGL2PaintEngineExPrivate::transferMode(EngineMode newMode) { if (newMode == mode) return; if (mode == TextDrawingMode || mode == ImageDrawingMode || mode == ImageArrayDrawingMode) { - glDisableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); - glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR); - glDisableVertexAttribArray(QT_OPACITY_ATTR); - - lastTexture = GLuint(-1); + lastTextureUsed = GLuint(-1); } if (newMode == TextDrawingMode) { - glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR); - glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); - glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinateArray.data()); glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinateArray.data()); } if (newMode == ImageDrawingMode) { - glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR); - glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); - glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, staticVertexCoordinateArray); glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, staticTextureCoordinateArray); } if (newMode == ImageArrayDrawingMode) { - glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR); - glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); - glEnableVertexAttribArray(QT_OPACITY_ATTR); - glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinateArray.data()); glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinateArray.data()); glVertexAttribPointer(QT_OPACITY_ATTR, 1, GL_FLOAT, GL_FALSE, 0, opacityArray.data()); @@ -850,13 +845,14 @@ struct QGL2PEVectorPathCache qreal iscale; }; -void qopengl2paintengine_cleanup_vectorpath(QPaintEngineEx *engine, void *data) +void QGL2PaintEngineExPrivate::cleanupVectorPath(QPaintEngineEx *engine, void *data) { QGL2PEVectorPathCache *c = (QGL2PEVectorPathCache *) data; #ifdef QT_OPENGL_CACHE_AS_VBOS - QGL2PaintEngineExPrivate *d = QGL2PaintEngineExPrivate::getData((QGL2PaintEngineEx *) engine); - d->unusedVBOSToClean << c->vbo; + Q_ASSERT(engine->type() == QPaintEngine::OpenGL2); + static_cast<QGL2PaintEngineEx *>(engine)->d_func()->unusedVBOSToClean << c->vbo; #else + Q_UNUSED(engine); qFree(c->vertices); #endif delete c; @@ -867,6 +863,21 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) { transferMode(BrushDrawingMode); + const QOpenGL2PaintEngineState *s = q->state(); + const bool newAddOffset = !(s->renderHints & QPainter::Antialiasing) && + (qbrush_style(currentBrush) == Qt::SolidPattern) && + !multisamplingAlwaysEnabled; + + if (addOffset != newAddOffset) { + addOffset = newAddOffset; + matrixDirty = true; + } + + if (snapToPixelGrid) { + snapToPixelGrid = false; + matrixDirty = true; + } + // Might need to call updateMatrix to re-calculate inverseScale if (matrixDirty) updateMatrix(); @@ -902,7 +913,7 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) } else { cache = new QGL2PEVectorPathCache; cache->vertexCount = 0; - data = const_cast<QVectorPath &>(path).addCacheData(q, cache, qopengl2paintengine_cleanup_vectorpath); + data = const_cast<QVectorPath &>(path).addCacheData(q, cache, cleanupVectorPath); } // Flatten the path at the current scale factor and fill it into the cache struct. @@ -925,7 +936,6 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) } prepareForDraw(currentBrush.isOpaque()); - glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR); #ifdef QT_OPENGL_CACHE_AS_VBOS glBindBuffer(GL_ARRAY_BUFFER, cache->vbo); glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, false, 0, 0); @@ -967,20 +977,11 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) // Pass when high bit is set, replace stencil value with 0 glStencilFunc(GL_NOTEQUAL, 0, GL_STENCIL_HIGH_BIT); } - prepareForDraw(currentBrush.isOpaque()); - if (inRenderText) - prepareDepthRangeForRenderText(); - // Stencil the brush onto the dest buffer composite(vertexCoordinateArray.boundingRect()); - - if (inRenderText) - restoreDepthRangeForRenderText(); - glStencilMask(0); - updateClipScissorTest(); } } @@ -1019,13 +1020,6 @@ void QGL2PaintEngineExPrivate::fillStencilWithVertexArray(const float *data, useSimpleShader(); glEnable(GL_STENCIL_TEST); // For some reason, this has to happen _after_ the simple shader is use()'d -#ifndef QT_OPENGL_ES_2 - if (inRenderText) { - glPushAttrib(GL_ENABLE_BIT); - glDisable(GL_DEPTH_TEST); - } -#endif - if (mode == WindingFillMode) { Q_ASSERT(stops && !count); if (q->state()->clipTestEnabled) { @@ -1066,10 +1060,8 @@ void QGL2PaintEngineExPrivate::fillStencilWithVertexArray(const float *data, glStencilMask(GL_STENCIL_HIGH_BIT); #if 0 glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); // Simply invert the stencil bit - glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR); glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, data); glDrawArrays(GL_TRIANGLE_STRIP, 0, count); - glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR); #else glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); @@ -1079,21 +1071,13 @@ void QGL2PaintEngineExPrivate::fillStencilWithVertexArray(const float *data, } else { glStencilFunc(GL_ALWAYS, GL_STENCIL_HIGH_BIT, 0xff); } - glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR); glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, data); glDrawArrays(GL_TRIANGLE_STRIP, 0, count); - glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR); #endif } // Enable color writes & disable stencil writes glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - -#ifndef QT_OPENGL_ES_2 - if (inRenderText) - glPopAttrib(); -#endif - } /* @@ -1209,12 +1193,8 @@ void QGL2PaintEngineExPrivate::composite(const QGLRect& boundingRect) boundingRect.right, boundingRect.top }; - glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR); glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, rectVerts); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR); } // Draws the vertex array as a set of <vertexArrayStops.size()> triangle fans. @@ -1222,7 +1202,6 @@ void QGL2PaintEngineExPrivate::drawVertexArrays(const float *data, int *stops, i GLenum primitive) { // Now setup the pointer to the vertex array: - glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR); glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, data); int previousStop = 0; @@ -1236,31 +1215,6 @@ void QGL2PaintEngineExPrivate::drawVertexArrays(const float *data, int *stops, i glDrawArrays(primitive, previousStop, stop - previousStop); previousStop = stop; } - glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR); -} - -void QGL2PaintEngineExPrivate::prepareDepthRangeForRenderText() -{ -#ifndef QT_OPENGL_ES_2 - // Get the z translation value from the model view matrix and - // transform it using the ortogonal projection with z-near = 0, - // and z-far = 1, which is used in QGLWidget::renderText() - GLdouble model[4][4]; - glGetDoublev(GL_MODELVIEW_MATRIX, &model[0][0]); - float deviceZ = -2 * model[3][2] - 1; - - glGetFloatv(GL_DEPTH_RANGE, depthRange); - float windowZ = depthRange[0] + (deviceZ + 1) * 0.5 * (depthRange[1] - depthRange[0]); - - glDepthRange(windowZ, windowZ); -#endif -} - -void QGL2PaintEngineExPrivate::restoreDepthRangeForRenderText() -{ -#ifndef QT_OPENGL_ES_2 - glDepthRange(depthRange[0], depthRange[1]); -#endif } /////////////////////////////////// Public Methods ////////////////////////////////////////// @@ -1278,31 +1232,11 @@ void QGL2PaintEngineEx::fill(const QVectorPath &path, const QBrush &brush) { Q_D(QGL2PaintEngineEx); - Qt::BrushStyle style = qbrush_style(brush); - if (style == Qt::NoBrush) + if (qbrush_style(brush) == Qt::NoBrush) return; - if (!d->inRenderText) - ensureActive(); - - QOpenGL2PaintEngineState *s = state(); - bool doOffset = !(s->renderHints & QPainter::Antialiasing) && - (style == Qt::SolidPattern) && - !d->multisamplingAlwaysEnabled; - - if (doOffset) { - d->temporaryTransform = s->matrix; - QTransform tx = QTransform::fromTranslate(.49, .49); - s->matrix = s->matrix * tx; - d->matrixDirty = true; - } - + ensureActive(); d->setBrush(brush); d->fill(path); - - if (doOffset) { - s->matrix = d->temporaryTransform; - d->matrixDirty = true; - } } extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp @@ -1312,9 +1246,8 @@ void QGL2PaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) { Q_D(QGL2PaintEngineEx); - Qt::PenStyle penStyle = qpen_style(pen); const QBrush &penBrush = qpen_brush(pen); - if (penStyle == Qt::NoPen || qbrush_style(penBrush) == Qt::NoBrush) + if (qpen_style(pen) == Qt::NoPen || qbrush_style(penBrush) == Qt::NoBrush) return; QOpenGL2PaintEngineState *s = state(); @@ -1325,53 +1258,57 @@ void QGL2PaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) } ensureActive(); + d->setBrush(penBrush); + d->stroke(path, pen); +} - bool doOffset = !(s->renderHints & QPainter::Antialiasing) && !d->multisamplingAlwaysEnabled; - if (doOffset) { - d->temporaryTransform = s->matrix; - QTransform tx = QTransform::fromTranslate(0.49, .49); - s->matrix = s->matrix * tx; - d->matrixDirty = true; +void QGL2PaintEngineExPrivate::stroke(const QVectorPath &path, const QPen &pen) +{ + const QOpenGL2PaintEngineState *s = q->state(); + const bool newAddOffset = !(s->renderHints & QPainter::Antialiasing) && !multisamplingAlwaysEnabled; + if (addOffset != newAddOffset) { + addOffset = newAddOffset; + matrixDirty = true; } - bool opaque = penBrush.isOpaque() && s->opacity > 0.99; - d->setBrush(penBrush); - d->transferMode(BrushDrawingMode); + if (snapToPixelGrid) { + snapToPixelGrid = false; + matrixDirty = true; + } + + const Qt::PenStyle penStyle = qpen_style(pen); + const QBrush &penBrush = qpen_brush(pen); + const bool opaque = penBrush.isOpaque() && s->opacity > 0.99; + + transferMode(BrushDrawingMode); // updateMatrix() is responsible for setting the inverse scale on // the strokers, so we need to call it here and not wait for // prepareForDraw() down below. - d->updateMatrix(); + updateMatrix(); if (penStyle == Qt::SolidLine) { - d->stroker.process(path, pen); + stroker.process(path, pen); } else { // Some sort of dash - d->dasher.process(path, pen); + dasher.process(path, pen); - QVectorPath dashStroke(d->dasher.points(), - d->dasher.elementCount(), - d->dasher.elementTypes()); - d->stroker.process(dashStroke, pen); + QVectorPath dashStroke(dasher.points(), + dasher.elementCount(), + dasher.elementTypes()); + stroker.process(dashStroke, pen); } - - QGLContext *ctx = d->ctx; - Q_UNUSED(ctx); - if (opaque) { - d->prepareForDraw(opaque); - glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR); - glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, false, 0, d->stroker.vertices()); - glDrawArrays(GL_TRIANGLE_STRIP, 0, d->stroker.vertexCount() / 2); + prepareForDraw(opaque); + glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, false, 0, stroker.vertices()); + glDrawArrays(GL_TRIANGLE_STRIP, 0, stroker.vertexCount() / 2); // QBrush b(Qt::green); // d->setBrush(&b); // d->prepareForDraw(true); // glDrawArrays(GL_LINE_STRIP, 0, d->stroker.vertexCount() / 2); - glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR); - } else { qreal width = qpen_widthf(pen) / 2; if (width == 0) @@ -1381,30 +1318,25 @@ void QGL2PaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) : width; if (pen.isCosmetic()) - extra = extra * d->inverseScale; + extra = extra * inverseScale; QRectF bounds = path.controlPointRect().adjusted(-extra, -extra, extra, extra); - d->fillStencilWithVertexArray(d->stroker.vertices(), d->stroker.vertexCount() / 2, + fillStencilWithVertexArray(stroker.vertices(), stroker.vertexCount() / 2, 0, 0, bounds, QGL2PaintEngineExPrivate::TriStripStrokeFillMode); glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); // Pass when any bit is set, replace stencil value with 0 glStencilFunc(GL_NOTEQUAL, 0, GL_STENCIL_HIGH_BIT); - d->prepareForDraw(false); + prepareForDraw(false); // Stencil the brush onto the dest buffer - d->composite(bounds); + composite(bounds); glStencilMask(0); - d->updateClipScissorTest(); - } - - if (doOffset) { - s->matrix = d->temporaryTransform; - d->matrixDirty = true; + updateClipScissorTest(); } } @@ -1444,7 +1376,7 @@ void QGL2PaintEngineEx::renderHintsChanged() #endif Q_D(QGL2PaintEngineEx); - d->lastTexture = GLuint(-1); + d->lastTextureUsed = GLuint(-1); d->brushTextureDirty = true; // qDebug("QGL2PaintEngineEx::renderHintsChanged() not implemented!"); } @@ -1522,8 +1454,7 @@ void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem { Q_D(QGL2PaintEngineEx); - if (!d->inRenderText) - ensureActive(); + ensureActive(); QOpenGL2PaintEngineState *s = state(); const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem); @@ -1542,7 +1473,7 @@ void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem ? QFontEngineGlyphCache::Type(ti.fontEngine->glyphFormat) : d->glyphCacheType; - if (d->inRenderText || txtype > QTransform::TxTranslate) + if (txtype > QTransform::TxTranslate) glyphType = QFontEngineGlyphCache::Raster_A8; if (glyphType == QFontEngineGlyphCache::Raster_RGBMask @@ -1584,8 +1515,6 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, QFontEngineGly if (cache->width() == 0 || cache->height() == 0) return; - if (inRenderText) - transferMode(BrushDrawingMode); transferMode(TextDrawingMode); int margin = cache->glyphMargin(); @@ -1613,12 +1542,18 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, QFontEngineGly if (textureCoordinateArray.data() != oldTextureCoordinateDataPtr) glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinateArray.data()); + if (addOffset) { + addOffset = false; + matrixDirty = true; + } + if (!snapToPixelGrid) { + snapToPixelGrid = true; + matrixDirty = true; + } + QBrush pensBrush = q->state()->pen.brush(); setBrush(pensBrush); - if (inRenderText) - prepareDepthRangeForRenderText(); - if (glyphType == QFontEngineGlyphCache::Raster_RGBMask) { // Subpixel antialiasing without gamma correction @@ -1703,27 +1638,40 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, QFontEngineGly shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::MaskTexture), QT_MASK_TEXTURE_UNIT); glDrawArrays(GL_TRIANGLES, 0, 6 * glyphs.size()); - - if (inRenderText) - restoreDepthRangeForRenderText(); } void QGL2PaintEngineEx::drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints hints) { + Q_D(QGL2PaintEngineEx); // Use fallback for extended composition modes. if (state()->composition_mode > QPainter::CompositionMode_Plus) { QPaintEngineEx::drawPixmaps(drawingData, dataCount, pixmap, hints); return; } - Q_D(QGL2PaintEngineEx); + ensureActive(); + d->drawPixmaps(drawingData, dataCount, pixmap, hints); +} + +void QGL2PaintEngineExPrivate::drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints hints) +{ GLfloat dx = 1.0f / pixmap.size().width(); GLfloat dy = 1.0f / pixmap.size().height(); - d->vertexCoordinateArray.clear(); - d->textureCoordinateArray.clear(); - d->opacityArray.reset(); + vertexCoordinateArray.clear(); + textureCoordinateArray.clear(); + opacityArray.reset(); + + if (addOffset) { + addOffset = false; + matrixDirty = true; + } + + if (snapToPixelGrid) { + snapToPixelGrid = false; + matrixDirty = true; + } bool allOpaque = true; @@ -1740,31 +1688,28 @@ void QGL2PaintEngineEx::drawPixmaps(const QDrawPixmaps::Data *drawingData, int d QGLPoint bottomRight(right * c - bottom * s, right * s + bottom * c); QGLPoint bottomLeft(-right * c - bottom * s, -right * s + bottom * c); - d->vertexCoordinateArray.lineToArray(bottomRight.x + drawingData[i].point.x(), bottomRight.y + drawingData[i].point.y()); - d->vertexCoordinateArray.lineToArray(-bottomLeft.x + drawingData[i].point.x(), -bottomLeft.y + drawingData[i].point.y()); - d->vertexCoordinateArray.lineToArray(-bottomRight.x + drawingData[i].point.x(), -bottomRight.y + drawingData[i].point.y()); - d->vertexCoordinateArray.lineToArray(-bottomRight.x + drawingData[i].point.x(), -bottomRight.y + drawingData[i].point.y()); - d->vertexCoordinateArray.lineToArray(bottomLeft.x + drawingData[i].point.x(), bottomLeft.y + drawingData[i].point.y()); - d->vertexCoordinateArray.lineToArray(bottomRight.x + drawingData[i].point.x(), bottomRight.y + drawingData[i].point.y()); + vertexCoordinateArray.lineToArray(bottomRight.x + drawingData[i].point.x(), bottomRight.y + drawingData[i].point.y()); + vertexCoordinateArray.lineToArray(-bottomLeft.x + drawingData[i].point.x(), -bottomLeft.y + drawingData[i].point.y()); + vertexCoordinateArray.lineToArray(-bottomRight.x + drawingData[i].point.x(), -bottomRight.y + drawingData[i].point.y()); + vertexCoordinateArray.lineToArray(-bottomRight.x + drawingData[i].point.x(), -bottomRight.y + drawingData[i].point.y()); + vertexCoordinateArray.lineToArray(bottomLeft.x + drawingData[i].point.x(), bottomLeft.y + drawingData[i].point.y()); + vertexCoordinateArray.lineToArray(bottomRight.x + drawingData[i].point.x(), bottomRight.y + drawingData[i].point.y()); QGLRect src(drawingData[i].source.left() * dx, drawingData[i].source.top() * dy, drawingData[i].source.right() * dx, drawingData[i].source.bottom() * dy); - d->textureCoordinateArray.lineToArray(src.right, src.bottom); - d->textureCoordinateArray.lineToArray(src.right, src.top); - d->textureCoordinateArray.lineToArray(src.left, src.top); - d->textureCoordinateArray.lineToArray(src.left, src.top); - d->textureCoordinateArray.lineToArray(src.left, src.bottom); - d->textureCoordinateArray.lineToArray(src.right, src.bottom); + textureCoordinateArray.lineToArray(src.right, src.bottom); + textureCoordinateArray.lineToArray(src.right, src.top); + textureCoordinateArray.lineToArray(src.left, src.top); + textureCoordinateArray.lineToArray(src.left, src.top); + textureCoordinateArray.lineToArray(src.left, src.bottom); + textureCoordinateArray.lineToArray(src.right, src.bottom); - qreal opacity = drawingData[i].opacity * state()->opacity; - d->opacityArray << opacity << opacity << opacity << opacity << opacity << opacity; + qreal opacity = drawingData[i].opacity * q->state()->opacity; + opacityArray << opacity << opacity << opacity << opacity << opacity << opacity; allOpaque &= (opacity >= 0.99f); } - ensureActive(); - - QGLContext *ctx = d->ctx; glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); QGLTexture *texture = ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, QGLContext::InternalBindOption @@ -1772,28 +1717,28 @@ void QGL2PaintEngineEx::drawPixmaps(const QDrawPixmaps::Data *drawingData, int d if (texture->options & QGLContext::InvertedYBindOption) { // Flip texture y-coordinate. - QGLPoint *data = d->textureCoordinateArray.data(); + QGLPoint *data = textureCoordinateArray.data(); for (int i = 0; i < 6 * dataCount; ++i) data[i].y = 1 - data[i].y; } - d->transferMode(ImageArrayDrawingMode); + transferMode(ImageArrayDrawingMode); bool isBitmap = pixmap.isQBitmap(); bool isOpaque = !isBitmap && (!pixmap.hasAlphaChannel() || (hints & QDrawPixmaps::OpaqueHint)) && allOpaque; - d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, - state()->renderHints & QPainter::SmoothPixmapTransform, texture->id); + updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, + q->state()->renderHints & QPainter::SmoothPixmapTransform, texture->id); // Setup for texture drawing - d->currentBrush = d->noBrush; - d->shaderManager->setSrcPixelType(isBitmap ? QGLEngineShaderManager::PatternSrc : QGLEngineShaderManager::ImageSrc); - if (d->prepareForDraw(isOpaque)) - d->shaderManager->currentProgram()->setUniformValue(d->location(QGLEngineShaderManager::ImageTexture), QT_IMAGE_TEXTURE_UNIT); + currentBrush = noBrush; + shaderManager->setSrcPixelType(isBitmap ? QGLEngineShaderManager::PatternSrc : QGLEngineShaderManager::ImageSrc); + if (prepareForDraw(isOpaque)) + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::ImageTexture), QT_IMAGE_TEXTURE_UNIT); if (isBitmap) { - QColor col = qt_premultiplyColor(state()->pen.color(), (GLfloat)state()->opacity); - d->shaderManager->currentProgram()->setUniformValue(d->location(QGLEngineShaderManager::PatternColor), col); + QColor col = qt_premultiplyColor(q->state()->pen.color(), (GLfloat)q->state()->opacity); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::PatternColor), col); } glDrawArrays(GL_TRIANGLES, 0, 6 * dataCount); @@ -1825,7 +1770,7 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) d->compositionModeDirty = true; d->opacityUniformDirty = true; d->needsSync = true; - d->use_system_clip = !systemClip().isEmpty(); + d->useSystemClip = !systemClip().isEmpty(); d->currentBrush = QBrush(); d->dirtyStencilRegion = QRect(0, 0, d->width, d->height); @@ -1845,11 +1790,9 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) d->shaderManager = new QGLEngineShaderManager(d->ctx); - if (!d->inRenderText) { - glDisable(GL_STENCIL_TEST); - glDisable(GL_DEPTH_TEST); - glDisable(GL_SCISSOR_TEST); - } + glDisable(GL_STENCIL_TEST); + glDisable(GL_DEPTH_TEST); + glDisable(GL_SCISSOR_TEST); #if !defined(QT_OPENGL_ES_2) glDisable(GL_MULTISAMPLE); @@ -1926,6 +1869,7 @@ void QGL2PaintEngineEx::ensureActive() glViewport(0, 0, d->width, d->height); d->needsSync = false; d->shaderManager->setDirty(); + d->ctx->d_func()->syncGlState(); setState(state()); } } @@ -1946,12 +1890,12 @@ void QGL2PaintEngineExPrivate::updateClipScissorTest() #else QRect bounds = q->state()->rectangleClip; if (!q->state()->clipEnabled) { - if (use_system_clip) + if (useSystemClip) bounds = systemClip.boundingRect(); else bounds = QRect(0, 0, width, height); } else { - if (use_system_clip) + if (useSystemClip) bounds = bounds.intersected(systemClip.boundingRect()); else bounds = bounds.intersected(QRect(0, 0, width, height)); @@ -2006,6 +1950,15 @@ void QGL2PaintEngineExPrivate::writeClip(const QVectorPath &path, uint value) { transferMode(BrushDrawingMode); + if (addOffset) { + addOffset = false; + matrixDirty = true; + } + if (snapToPixelGrid) { + snapToPixelGrid = false; + matrixDirty = true; + } + if (matrixDirty) updateMatrix(); @@ -2105,7 +2058,7 @@ void QGL2PaintEngineEx::clip(const QVectorPath &path, Qt::ClipOperation op) switch (op) { case Qt::NoClip: - if (d->use_system_clip) { + if (d->useSystemClip) { state()->clipTestEnabled = true; state()->currentClip = 1; } else { @@ -2177,13 +2130,13 @@ void QGL2PaintEngineExPrivate::systemStateChanged() q->state()->clipChanged = true; if (systemClip.isEmpty()) { - use_system_clip = false; + useSystemClip = false; } else { if (q->paintDevice()->devType() == QInternal::Widget && currentClipWidget) { QWidgetPrivate *widgetPrivate = qt_widget_private(currentClipWidget->window()); - use_system_clip = widgetPrivate->extra && widgetPrivate->extra->inRenderWithPainter; + useSystemClip = widgetPrivate->extra && widgetPrivate->extra->inRenderWithPainter; } else { - use_system_clip = true; + useSystemClip = true; } } @@ -2193,19 +2146,19 @@ void QGL2PaintEngineExPrivate::systemStateChanged() q->state()->currentClip = 1; maxClip = 1; - q->state()->rectangleClip = use_system_clip ? systemClip.boundingRect() : QRect(0, 0, width, height); + q->state()->rectangleClip = useSystemClip ? systemClip.boundingRect() : QRect(0, 0, width, height); updateClipScissorTest(); if (systemClip.rectCount() == 1) { if (systemClip.boundingRect() == QRect(0, 0, width, height)) - use_system_clip = false; + useSystemClip = false; #ifndef QT_GL_NO_SCISSOR_TEST // scissoring takes care of the system clip return; #endif } - if (use_system_clip) { + if (useSystemClip) { clearClip(0); QPainterPath path; @@ -2284,12 +2237,6 @@ QPainterState *QGL2PaintEngineEx::createState(QPainterState *orig) const return s; } -void QGL2PaintEngineEx::setRenderTextActive(bool active) -{ - Q_D(QGL2PaintEngineEx); - d->inRenderText = active; -} - QOpenGL2PaintEngineState::QOpenGL2PaintEngineState(QOpenGL2PaintEngineState &other) : QPainterState(other) { diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index 8de4a82..7d5cb52 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -105,13 +105,8 @@ public: ~QGL2PaintEngineEx(); bool begin(QPaintDevice *device); - bool end(); - void ensureActive(); - - virtual void fill(const QVectorPath &path, const QBrush &brush); - virtual void stroke(const QVectorPath &path, const QPen &pen); - virtual void clip(const QVectorPath &path, Qt::ClipOperation op); + bool end(); virtual void clipEnabledChanged(); virtual void penChanged(); @@ -122,20 +117,21 @@ public: virtual void renderHintsChanged(); virtual void transformChanged(); - + virtual void drawTexture(const QRectF &r, GLuint textureId, const QSize &size, const QRectF &sr); virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr); + virtual void drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints hints); virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, Qt::ImageConversionFlags flags = Qt::AutoColor); - virtual void drawTexture(const QRectF &r, GLuint textureId, const QSize &size, const QRectF &sr); - virtual void drawTextItem(const QPointF &p, const QTextItem &textItem); + virtual void fill(const QVectorPath &path, const QBrush &brush); + virtual void stroke(const QVectorPath &path, const QPen &pen); + virtual void clip(const QVectorPath &path, Qt::ClipOperation op); - virtual void drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints hints); Type type() const { return OpenGL2; } - void setState(QPainterState *s); - QPainterState *createState(QPainterState *orig) const; + virtual void setState(QPainterState *s); + virtual QPainterState *createState(QPainterState *orig) const; inline QOpenGL2PaintEngineState *state() { return static_cast<QOpenGL2PaintEngineState *>(QPaintEngineEx::state()); } @@ -146,8 +142,6 @@ public: void beginNativePainting(); void endNativePainting(); - const QGLContext* context(); - QPixmapFilter *pixmapFilter(int type, const QPixmapFilter *prototype); void setRenderTextActive(bool); @@ -169,11 +163,13 @@ public: QGL2PaintEngineExPrivate(QGL2PaintEngineEx *q_ptr) : q(q_ptr), + shaderManager(0), width(0), height(0), ctx(0), - inverseScale(1), - shaderManager(0), - inRenderText(false) + useSystemClip(true), + snapToPixelGrid(false), + addOffset(false), + inverseScale(1) { } ~QGL2PaintEngineExPrivate(); @@ -184,45 +180,57 @@ public: void updateCompositionMode(); void updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform, GLuint id = -1); - void setBrush(const QBrush& brush); - - void transferMode(EngineMode newMode); void resetGLState(); - // fill, drawOutline, drawTexture & drawCachedGlyphs are the rendering entry points: + // fill, stroke, drawTexture, drawPixmaps & drawCachedGlyphs are the main rendering entry-points, + // however writeClip can also be thought of as en entry point as it does similar things. void fill(const QVectorPath &path); + void stroke(const QVectorPath &path, const QPen &pen); void drawTexture(const QGLRect& dest, const QGLRect& src, const QSize &textureSize, bool opaque, bool pattern = false); + void drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints hints); void drawCachedGlyphs(const QPointF &p, QFontEngineGlyphCache::Type glyphType, const QTextItemInt &ti); + // draws whatever is in the vertex array: void drawVertexArrays(const float *data, int *stops, int stopCount, GLenum primitive); void drawVertexArrays(QGL2PEXVertexArray &vertexArray, GLenum primitive) { drawVertexArrays((const float *) vertexArray.data(), vertexArray.stops(), vertexArray.stopCount(), primitive); } - // ^ draws whatever is in the vertex array + // Composites the bounding rect onto dest buffer: void composite(const QGLRect& boundingRect); - // ^ Composites the bounding rect onto dest buffer + // Calls drawVertexArrays to render into stencil buffer: void fillStencilWithVertexArray(const float *data, int count, int *stops, int stopCount, const QGLRect &bounds, StencilFillMode mode); void fillStencilWithVertexArray(QGL2PEXVertexArray& vertexArray, bool useWindingFill) { fillStencilWithVertexArray((const float *) vertexArray.data(), 0, vertexArray.stops(), vertexArray.stopCount(), vertexArray.boundingRect(), useWindingFill ? WindingFillMode : OddEvenFillMode); } - // ^ Calls drawVertexArrays to render into stencil buffer - - bool prepareForDraw(bool srcPixelsAreOpaque); - // ^ returns whether the current program changed or not + void setBrush(const QBrush& brush); + void transferMode(EngineMode newMode); + bool prepareForDraw(bool srcPixelsAreOpaque); // returns true if the program has changed inline void useSimpleShader(); + inline GLuint location(const QGLEngineShaderManager::Uniform uniform) { + return shaderManager->getUniformLocation(uniform); + } - void prepareDepthRangeForRenderText(); - void restoreDepthRangeForRenderText(); + void clearClip(uint value); + void writeClip(const QVectorPath &path, uint value); + void resetClipIfNeeded(); + + void updateClipScissorTest(); + void setScissor(const QRect &rect); + void regenerateClip(); + void systemStateChanged(); static QGLEngineShaderManager* shaderManagerForEngine(QGL2PaintEngineEx *engine) { return engine->d_func()->shaderManager; } static QGL2PaintEngineExPrivate *getData(QGL2PaintEngineEx *engine) { return engine->d_func(); } + static void cleanupVectorPath(QPaintEngineEx *engine, void *data); + QGL2PaintEngineEx* q; + QGLEngineShaderManager* shaderManager; QGLPaintDevice* device; int width, height; QGLContext *ctx; @@ -239,6 +247,7 @@ public: bool opacityUniformDirty; bool stencilClean; // Has the stencil not been used for clipping so far? + bool useSystemClip; QRegion dirtyStencilRegion; QRect currentScissorBounds; uint maxClip; @@ -246,38 +255,20 @@ public: QBrush currentBrush; // May not be the state's brush! const QBrush noBrush; - GLfloat inverseScale; - QGL2PEXVertexArray vertexCoordinateArray; QGL2PEXVertexArray textureCoordinateArray; QDataBuffer<GLfloat> opacityArray; - GLfloat staticVertexCoordinateArray[8]; GLfloat staticTextureCoordinateArray[8]; + bool snapToPixelGrid; + bool addOffset; // When enabled, adds a 0.49,0.49 offset to matrix in updateMatrix GLfloat pmvMatrix[3][3]; + GLfloat inverseScale; - QGLEngineShaderManager* shaderManager; - - void clearClip(uint value); - void writeClip(const QVectorPath &path, uint value); - void resetClipIfNeeded(); - - void updateClipScissorTest(); - void setScissor(const QRect &rect); - void regenerateClip(); - void systemStateChanged(); - uint use_system_clip : 1; - - uint location(QGLEngineShaderManager::Uniform uniform) - { - return shaderManager->getUniformLocation(uniform); - } - - GLuint lastTexture; + GLuint lastTextureUsed; bool needsSync; - bool inRenderText; bool multisamplingAlwaysEnabled; GLfloat depthRange[2]; @@ -286,7 +277,6 @@ public: QTriangulatingStroker stroker; QDashedStrokeProcessor dasher; - QTransform temporaryTransform; QScopedPointer<QPixmapFilter> convolutionFilter; QScopedPointer<QPixmapFilter> colorizeFilter; diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 466e851..c3e4a2e 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1436,6 +1436,18 @@ void QGLContextGroup::removeGuard(QGLSharedResourceGuard *guard) m_guards = guard->m_next; } +const QGLContext *qt_gl_transfer_context(const QGLContext *ctx) +{ + if (!ctx) + return 0; + QList<const QGLContext *> shares + (QGLContextPrivate::contextGroup(ctx)->shares()); + if (shares.size() >= 2) + return (ctx == shares.at(0)) ? shares.at(1) : shares.at(0); + else + return 0; +} + QGLContextPrivate::~QGLContextPrivate() { if (!group->m_refs.deref()) { @@ -1484,6 +1496,8 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format) current_fbo = 0; default_fbo = 0; active_engine = 0; + for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) + vertexAttributeArraysEnabledState[i] = false; } QGLContext* QGLContext::currentCtx = 0; @@ -1729,12 +1743,6 @@ struct DDSFormat { #define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 #endif -Q_GLOBAL_STATIC(QGLShareRegister, _qgl_share_reg) -Q_OPENGL_EXPORT QGLShareRegister* qgl_share_reg() -{ - return _qgl_share_reg(); -} - /*! \class QGLContext \brief The QGLContext class encapsulates an OpenGL rendering context. @@ -1874,6 +1882,35 @@ void QGLContextPrivate::cleanup() { } +#define ctx q_ptr +void QGLContextPrivate::setVertexAttribArrayEnabled(int arrayIndex, bool enabled) +{ + Q_ASSERT(arrayIndex < QT_GL_VERTEX_ARRAY_TRACKED_COUNT); + Q_ASSERT(glEnableVertexAttribArray); + + if (vertexAttributeArraysEnabledState[arrayIndex] && !enabled) + glDisableVertexAttribArray(arrayIndex); + + if (!vertexAttributeArraysEnabledState[arrayIndex] && enabled) + glEnableVertexAttribArray(arrayIndex); + + vertexAttributeArraysEnabledState[arrayIndex] = enabled; +} + +void QGLContextPrivate::syncGlState() +{ + Q_ASSERT(glEnableVertexAttribArray); + for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) { + if (vertexAttributeArraysEnabledState[i]) + glEnableVertexAttribArray(i); + else + glDisableVertexAttribArray(i); + } + +} +#undef ctx + + /*! \overload @@ -2954,7 +2991,7 @@ bool QGLContext::create(const QGLContext* shareContext) wd->usesDoubleBufferedGLContext = d->glFormat.doubleBuffer(); } if (d->sharing) // ok, we managed to share - qgl_share_reg()->addShare(this, shareContext); + QGLContextGroup::addShare(this, shareContext); return d->valid; } @@ -4378,9 +4415,9 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font, int height = d->glcx->device()->height(); bool auto_swap = autoBufferSwap(); + QPaintEngine::Type oldEngineType = qgl_engine_selector()->preferredPaintEngine(); + qgl_engine_selector()->setPreferredPaintEngine(QPaintEngine::OpenGL); QPaintEngine *engine = paintEngine(); - if (engine->type() == QPaintEngine::OpenGL2) - static_cast<QGL2PaintEngineEx *>(engine)->setRenderTextActive(true); QPainter *p; bool reuse_painter = false; if (engine->isActive()) { @@ -4400,11 +4437,6 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font, setAutoBufferSwap(false); // disable glClear() as a result of QPainter::begin() d->disable_clear_on_painter_begin = true; - if (engine->type() == QPaintEngine::OpenGL2) { - qt_save_gl_state(); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - } p = new QPainter(this); } @@ -4428,11 +4460,8 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font, delete p; setAutoBufferSwap(auto_swap); d->disable_clear_on_painter_begin = false; - if (engine->type() == QPaintEngine::OpenGL2) - qt_restore_gl_state(); } - if (engine->type() == QPaintEngine::OpenGL2) - static_cast<QGL2PaintEngineEx *>(engine)->setRenderTextActive(false); + qgl_engine_selector()->setPreferredPaintEngine(oldEngineType); #else // QT_OPENGL_ES Q_UNUSED(x); Q_UNUSED(y); @@ -4480,9 +4509,9 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con &win_x, &win_y, &win_z); win_y = height - win_y; // y is inverted + QPaintEngine::Type oldEngineType = qgl_engine_selector()->preferredPaintEngine(); + qgl_engine_selector()->setPreferredPaintEngine(QPaintEngine::OpenGL); QPaintEngine *engine = paintEngine(); - if (engine->type() == QPaintEngine::OpenGL2) - static_cast<QGL2PaintEngineEx *>(engine)->setRenderTextActive(true); QPainter *p; bool reuse_painter = false; bool use_depth_testing = glIsEnabled(GL_DEPTH_TEST); @@ -4496,8 +4525,6 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con setAutoBufferSwap(false); // disable glClear() as a result of QPainter::begin() d->disable_clear_on_painter_begin = true; - if (engine->type() == QPaintEngine::OpenGL2) - qt_save_gl_state(); p = new QPainter(this); } @@ -4526,13 +4553,10 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con } else { p->end(); delete p; - if (engine->type() == QPaintEngine::OpenGL2) - qt_restore_gl_state(); setAutoBufferSwap(auto_swap); d->disable_clear_on_painter_begin = false; } - if (engine->type() == QPaintEngine::OpenGL2) - static_cast<QGL2PaintEngineEx *>(engine)->setRenderTextActive(false); + qgl_engine_selector()->setPreferredPaintEngine(oldEngineType); #else // QT_OPENGL_ES Q_UNUSED(x); Q_UNUSED(y); @@ -4953,7 +4977,7 @@ Q_OPENGL_EXPORT const QString qt_gl_library_name() } #endif -void QGLShareRegister::addShare(const QGLContext *context, const QGLContext *share) { +void QGLContextGroup::addShare(const QGLContext *context, const QGLContext *share) { Q_ASSERT(context && share); if (context->d_ptr->group == share->d_ptr->group) return; @@ -4974,11 +4998,7 @@ void QGLShareRegister::addShare(const QGLContext *context, const QGLContext *sha group->m_shares.append(context); } -QList<const QGLContext *> QGLShareRegister::shares(const QGLContext *context) { - return context->d_ptr->group->m_shares; -} - -void QGLShareRegister::removeShare(const QGLContext *context) { +void QGLContextGroup::removeShare(const QGLContext *context) { // Remove the context from the group. QGLContextGroup *group = context->d_ptr->group; if (group->m_shares.isEmpty()) diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h index 2076c46..932ea7e 100644 --- a/src/opengl/qgl.h +++ b/src/opengl/qgl.h @@ -393,11 +393,12 @@ private: friend class QOpenGLPaintEnginePrivate; friend class QGL2PaintEngineEx; friend class QGL2PaintEngineExPrivate; + friend class QGLEngineShaderManager; friend class QGLWindowSurface; friend class QGLPixmapData; friend class QGLPixmapFilterBase; friend class QGLTextureGlyphCache; - friend class QGLShareRegister; + friend class QGLContextGroup; friend class QGLSharedResourceGuard; friend class QGLPixmapBlurFilter; friend QGLFormat::OpenGLVersionFlags QGLFormat::openGLVersionFlags(); diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp index 839e8eb..084db32 100644 --- a/src/opengl/qgl_egl.cpp +++ b/src/opengl/qgl_egl.cpp @@ -152,7 +152,7 @@ void QGLContext::reset() d->valid = false; d->transpColor = QColor(); d->initDone = false; - qgl_share_reg()->removeShare(this); + QGLContextGroup::removeShare(this); } void QGLContext::makeCurrent() diff --git a/src/opengl/qgl_mac.mm b/src/opengl/qgl_mac.mm index 4dd822d..8ecc48b 100644 --- a/src/opengl/qgl_mac.mm +++ b/src/opengl/qgl_mac.mm @@ -476,7 +476,7 @@ void QGLContext::reset() d->valid = false; d->transpColor = QColor(); d->initDone = false; - qgl_share_reg()->removeShare(this); + QGLContextGroup::removeShare(this); } void QGLContext::makeCurrent() diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 99c0f33..fcfe791 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -222,9 +222,8 @@ class QGLSharedResourceGuard; typedef QHash<QString, GLuint> QGLDDSCache; // QGLContextPrivate has the responsibility of creating context groups. -// QGLContextPrivate and QGLShareRegister will both maintain the reference counter and destroy +// QGLContextPrivate maintains the reference counter and destroys // context groups when needed. -// QGLShareRegister has the responsibility of keeping the context pointer up to date. class QGLContextGroup { public: @@ -233,9 +232,13 @@ public: QGLExtensionFuncs &extensionFuncs() {return m_extensionFuncs;} const QGLContext *context() const {return m_context;} bool isSharing() const { return m_shares.size() >= 2; } + QList<const QGLContext *> shares() const { return m_shares; } void addGuard(QGLSharedResourceGuard *guard); void removeGuard(QGLSharedResourceGuard *guard); + + static void addShare(const QGLContext *context, const QGLContext *share); + static void removeShare(const QGLContext *context); private: QGLContextGroup(const QGLContext *context) : m_context(context), m_guards(0), m_refs(1) { } @@ -249,14 +252,21 @@ private: void cleanupResources(const QGLContext *ctx); - friend class QGLShareRegister; friend class QGLContext; friend class QGLContextPrivate; friend class QGLContextResource; }; +// Get the context that resources for "ctx" will transfer to once +// "ctx" is destroyed. Returns null if nothing is sharing with ctx. +Q_OPENGL_EXPORT const QGLContext *qt_gl_transfer_context(const QGLContext *); + class QGLTexture; +// This probably needs to grow to GL_MAX_VERTEX_ATTRIBS, but 3 is ok for now as that's +// all the GL2 engine uses: +#define QT_GL_VERTEX_ARRAY_TRACKED_COUNT 3 + class QGLContextPrivate { Q_DECLARE_PUBLIC(QGLContext) @@ -276,6 +286,9 @@ public: void cleanup(); + void setVertexAttribArrayEnabled(int arrayIndex, bool enabled = true); + void syncGlState(); // Makes sure the GL context's state is what we think it is + #if defined(Q_WS_WIN) HGLRC rc; HDC dc; @@ -332,6 +345,8 @@ public: GLuint default_fbo; QPaintEngine *active_engine; + bool vertexAttributeArraysEnabledState[QT_GL_VERTEX_ARRAY_TRACKED_COUNT]; + static inline QGLContextGroup *contextGroup(const QGLContext *ctx) { return ctx->d_ptr->group; } #ifdef Q_WS_WIN @@ -395,19 +410,6 @@ public: Q_DECLARE_OPERATORS_FOR_FLAGS(QGLExtensions::Extensions) -class Q_OPENGL_EXPORT QGLShareRegister -{ -public: - QGLShareRegister() {} - ~QGLShareRegister() {} - - void addShare(const QGLContext *context, const QGLContext *share); - QList<const QGLContext *> shares(const QGLContext *context); - void removeShare(const QGLContext *context); -}; - -extern Q_OPENGL_EXPORT QGLShareRegister* qgl_share_reg(); - // Temporarily make a context current if not already current or // shared with the current contex. The previous context is made // current when the object goes out of scope. diff --git a/src/opengl/qgl_win.cpp b/src/opengl/qgl_win.cpp index 5b5820a..f80025d 100644 --- a/src/opengl/qgl_win.cpp +++ b/src/opengl/qgl_win.cpp @@ -1145,7 +1145,7 @@ void QGLContext::reset() delete d->cmap; d->cmap = 0; d->initDone = false; - qgl_share_reg()->removeShare(this); + QGLContextGroup::removeShare(this); } // diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp index 9c3fc79..8173bec 100644 --- a/src/opengl/qgl_x11.cpp +++ b/src/opengl/qgl_x11.cpp @@ -825,7 +825,7 @@ void QGLContext::reset() d->valid = false; d->transpColor = QColor(); d->initDone = false; - qgl_share_reg()->removeShare(this); + QGLContextGroup::removeShare(this); } diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp index 7c97ebb..fab6efc 100644 --- a/src/opengl/qglpixelbuffer.cpp +++ b/src/opengl/qglpixelbuffer.cpp @@ -127,7 +127,7 @@ void QGLPixelBufferPrivate::common_init(const QSize &size, const QGLFormat &form qctx = new QGLContext(format); qctx->d_func()->sharing = (shareWidget != 0); if (shareWidget != 0 && shareWidget->d_func()->glcx) { - qgl_share_reg()->addShare(qctx, shareWidget->d_func()->glcx); + QGLContextGroup::addShare(qctx, shareWidget->d_func()->glcx); shareWidget->d_func()->glcx->d_func()->sharing = true; } diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp index ed7fdff..8dae02a 100644 --- a/src/opengl/qpaintengine_opengl.cpp +++ b/src/opengl/qpaintengine_opengl.cpp @@ -4522,6 +4522,12 @@ typedef QHash<QFontEngine*, QGLGlyphHash*> QGLFontGlyphHash; typedef QHash<quint64, QGLFontTexture*> QGLFontTexHash; typedef QHash<const QGLContext*, QGLFontGlyphHash*> QGLContextHash; +static inline void qt_delete_glyph_hash(QGLGlyphHash *hash) +{ + qDeleteAll(*hash); + delete hash; +} + class QGLGlyphCache : public QObject { Q_OBJECT @@ -4562,7 +4568,7 @@ void QGLGlyphCache::fontEngineDestroyed(QObject *o) if (font_cache->find(fe) != font_cache->end()) { ctx = keys.at(i); QGLGlyphHash *cache = font_cache->take(fe); - delete cache; + qt_delete_glyph_hash(cache); break; } } @@ -4599,7 +4605,7 @@ void QGLGlyphCache::cleanupContext(const QGLContext *ctx) QList<QFontEngine *> keys = font_cache->keys(); for (int i=0; i < keys.size(); ++i) { QFontEngine *fe = keys.at(i); - delete font_cache->take(fe); + qt_delete_glyph_hash(font_cache->take(fe)); quint64 font_key = (reinterpret_cast<quint64>(ctx) << 32) | reinterpret_cast<quint64>(fe); QGLFontTexture *font_tex = qt_font_textures.take(font_key); if (font_tex) { @@ -4640,7 +4646,9 @@ void QGLGlyphCache::cleanCache() QList<const QGLContext *> keys = qt_context_cache.keys(); for (int i=0; i < keys.size(); ++i) { QGLFontGlyphHash *font_cache = qt_context_cache.value(keys.at(i)); - qDeleteAll(*font_cache); + QGLFontGlyphHash::Iterator it = font_cache->begin(); + for (; it != font_cache->end(); ++it) + qt_delete_glyph_hash(it.value()); font_cache->clear(); } qDeleteAll(qt_context_cache); diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index 04fee08..117c910 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -200,6 +200,7 @@ public: QRegion scissorRegion; // Currently active scissor region. bool scissorActive; // True if scissor region is active. + bool scissorDirty; // True if scissor is dirty after native painting. QPaintEngine::DirtyFlags dirty; @@ -357,6 +358,7 @@ void QVGPaintEnginePrivate::init() rawVG = false; scissorActive = false; + scissorDirty = false; dirty = 0; @@ -984,6 +986,9 @@ static QImage colorizeBitmap(const QImage &image, const QColor &color) return dest; } +// defined in qpixmapdata_vg.cpp. +const uchar *qt_vg_imageBits(const QImage& image); + static VGImage toVGImage (const QImage & image, Qt::ImageConversionFlags flags = Qt::AutoColor) { @@ -1017,7 +1022,7 @@ static VGImage toVGImage break; } - const uchar *pixels = img.bits(); + const uchar *pixels = qt_vg_imageBits(img); VGImage vgImg = QVGImagePool::instance()->createPermanentImage (format, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER); @@ -1061,7 +1066,7 @@ static VGImage toVGImageSubRect break; } - const uchar *pixels = img.bits() + bpp * sr.x() + + const uchar *pixels = qt_vg_imageBits(img) + bpp * sr.x() + img.bytesPerLine() * sr.y(); VGImage vgImg = QVGImagePool::instance()->createPermanentImage @@ -1083,7 +1088,7 @@ static VGImage toVGImageWithOpacity(const QImage & image, qreal opacity) painter.drawImage(0, 0, image); painter.end(); - const uchar *pixels = img.bits(); + const uchar *pixels = qt_vg_imageBits(img); VGImage vgImg = QVGImagePool::instance()->createPermanentImage (VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER); @@ -1105,7 +1110,7 @@ static VGImage toVGImageWithOpacitySubRect painter.drawImage(QPoint(0, 0), image, sr); painter.end(); - const uchar *pixels = img.bits(); + const uchar *pixels = qt_vg_imageBits(img); VGImage vgImg = QVGImagePool::instance()->createPermanentImage (VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER); @@ -2083,6 +2088,7 @@ void QVGPaintEngine::updateScissor() // so there is no point doing any scissoring. vgSeti(VG_SCISSORING, VG_FALSE); d->scissorActive = false; + d->scissorDirty = false; return; } } else @@ -2100,6 +2106,7 @@ void QVGPaintEngine::updateScissor() // so there is no point doing any scissoring. vgSeti(VG_SCISSORING, VG_FALSE); d->scissorActive = false; + d->scissorDirty = false; return; } } else @@ -2109,11 +2116,12 @@ void QVGPaintEngine::updateScissor() if (region.isEmpty()) { vgSeti(VG_SCISSORING, VG_FALSE); d->scissorActive = false; + d->scissorDirty = false; return; } } - if (d->scissorActive && region == d->scissorRegion) + if (d->scissorActive && region == d->scissorRegion && !d->scissorDirty) return; QVector<QRect> rects = region.rects(); @@ -2131,6 +2139,7 @@ void QVGPaintEngine::updateScissor() vgSetiv(VG_SCISSOR_RECTS, count * 4, params.data()); vgSeti(VG_SCISSORING, VG_TRUE); + d->scissorDirty = false; d->scissorActive = true; d->scissorRegion = region; } @@ -3166,15 +3175,15 @@ void QVGFontGlyphCache::cacheGlyphs if (!scaledImage.isNull()) { // Not a space character if (scaledImage.format() == QImage::Format_Indexed8) { vgImage = vgCreateImage(VG_A_8, scaledImage.width(), scaledImage.height(), VG_IMAGE_QUALITY_FASTER); - vgImageSubData(vgImage, scaledImage.bits(), scaledImage.bytesPerLine(), VG_A_8, 0, 0, scaledImage.width(), scaledImage.height()); + vgImageSubData(vgImage, qt_vg_imageBits(scaledImage), scaledImage.bytesPerLine(), VG_A_8, 0, 0, scaledImage.width(), scaledImage.height()); } else if (scaledImage.format() == QImage::Format_Mono) { QImage img = scaledImage.convertToFormat(QImage::Format_Indexed8); vgImage = vgCreateImage(VG_A_8, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER); - vgImageSubData(vgImage, img.bits(), img.bytesPerLine(), VG_A_8, 0, 0, img.width(), img.height()); + vgImageSubData(vgImage, qt_vg_imageBits(img), img.bytesPerLine(), VG_A_8, 0, 0, img.width(), img.height()); } else { QImage img = scaledImage.convertToFormat(QImage::Format_ARGB32_Premultiplied); vgImage = vgCreateImage(VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER); - vgImageSubData(vgImage, img.bits(), img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0, img.width(), img.height()); + vgImageSubData(vgImage, qt_vg_imageBits(img), img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0, img.width(), img.height()); } } origin[0] = -metrics.x.toReal() + 0.5f; @@ -3333,6 +3342,7 @@ void QVGPaintEngine::endNativePainting() d->brushType = (VGPaintType)0; d->clearColor = QColor(); d->fillPaint = d->brushPaint; + d->scissorDirty = true; restoreState(QPaintEngine::AllDirty); d->dirty = dirty; d->rawVG = false; @@ -3640,7 +3650,7 @@ void QVGCompositionHelper::drawCursorPixmap if (vgImage == VG_INVALID_HANDLE) return; vgImageSubData - (vgImage, img.bits() + img.bytesPerLine() * (img.height() - 1), + (vgImage, qt_vg_imageBits(img) + img.bytesPerLine() * (img.height() - 1), -(img.bytesPerLine()), VG_sARGB_8888_PRE, 0, 0, img.width(), img.height()); @@ -3666,15 +3676,17 @@ void QVGCompositionHelper::setScissor(const QRegion& region) vgSetiv(VG_SCISSOR_RECTS, count * 4, params.data()); vgSeti(VG_SCISSORING, VG_TRUE); + d->scissorDirty = false; d->scissorActive = true; d->scissorRegion = region; } void QVGCompositionHelper::clearScissor() { - if (d->scissorActive) { + if (d->scissorActive || d->scissorDirty) { vgSeti(VG_SCISSORING, VG_FALSE); d->scissorActive = false; + d->scissorDirty = false; } } diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp index 358ec4d..7de2212 100644 --- a/src/openvg/qpixmapdata_vg.cpp +++ b/src/openvg/qpixmapdata_vg.cpp @@ -232,7 +232,7 @@ QPaintEngine* QVGPixmapData::paintEngine() const // This function works around QImage::bits() making a deep copy if the // QImage is not const. We force it to be const and then get the bits. // XXX: Should add a QImage::constBits() in the future to replace this. -static inline const uchar *qt_vg_imageBits(const QImage& image) +const uchar *qt_vg_imageBits(const QImage& image) { return image.bits(); } diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index c86af73..47b8786 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -103,6 +103,8 @@ public: void drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap, const QPointF &pos); void blit(const QRectF &dest, IDirectFBSurface *surface, const QRectF &src); + inline bool supportsStretchBlit() const; + inline void updateClip(); virtual void systemStateChanged(); @@ -526,11 +528,12 @@ void QDirectFBPaintEngine::drawImage(const QRectF &r, const QImage &image, #if !defined QT_NO_DIRECTFB_PREALLOCATED || defined QT_DIRECTFB_IMAGECACHE if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits) || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported) - || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip + || (d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) + || (!d->supportsStretchBlit() && state()->matrix.mapRect(r).size() != sr.size()) #ifndef QT_DIRECTFB_IMAGECACHE - || QDirectFBScreen::getSurfacePixelFormat(image.format()) == DSPF_UNKNOWN + || (QDirectFBScreen::getSurfacePixelFormat(image.format()) == DSPF_UNKNOWN) #elif defined QT_NO_DIRECTFB_PREALLOCATED - || QDirectFBPaintEnginePrivate::cacheCost(image) > imageCache.maxCost() + || (QDirectFBPaintEnginePrivate::cacheCost(image) > imageCache.maxCost()) #endif ) #endif @@ -573,10 +576,9 @@ void QDirectFBPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pixmap, Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(data); if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits) - || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported) - || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip - || (state()->renderHints & QPainter::SmoothPixmapTransform - && state()->matrix.mapRect(r).size() != sr.size())) { + || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported) + || (d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) + || (!d->supportsStretchBlit() && state()->matrix.mapRect(r).size() != sr.size())) { RASTERFALLBACK(DRAW_PIXMAP, r, pixmap.size(), sr); const QImage *img = dfbData->buffer(); d->lock(); @@ -606,8 +608,8 @@ void QDirectFBPaintEngine::drawTiledPixmap(const QRectF &r, QRasterPaintEngine::drawTiledPixmap(r, pixmap, offset); } else if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits) || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported) - || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip - || (state()->renderHints & QPainter::SmoothPixmapTransform && state()->matrix.isScaling())) { + || (d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) + || (!d->supportsStretchBlit() && state()->matrix.isScaling())) { RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), offset); QPixmapData *pixmapData = pixmap.pixmapData(); Q_ASSERT(pixmapData->classId() == QPixmapData::DirectFBClass); @@ -732,7 +734,7 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) case Qt::TexturePattern: { if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits) || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported) - || (state()->renderHints & QPainter::SmoothPixmapTransform && state()->matrix.isScaling())) { + || (!d->supportsStretchBlit() && state()->matrix.isScaling())) { break; } @@ -757,7 +759,7 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QColor &color) return; Q_D(QDirectFBPaintEngine); if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported) - || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip + || (d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) || !d->testCompositionMode(0, 0, &color)) { RASTERFALLBACK(FILL_RECT, rect, color, VOID_ARG()); d->lock(); @@ -1049,6 +1051,7 @@ void QDirectFBPaintEnginePrivate::blit(const QRectF &dest, IDirectFBSurface *s, if (dr.size() == sr.size()) { result = surface->Blit(surface, s, &sRect, dr.x(), dr.y()); } else { + Q_ASSERT(supportsStretchBlit()); const DFBRectangle dRect = { dr.x(), dr.y(), dr.width(), dr.height() }; result = surface->StretchBlit(surface, s, &sRect, &dRect); } @@ -1096,6 +1099,7 @@ void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, const QPix const QSize pixmapSize = dfbData->size(); IDirectFBSurface *sourceSurface = dfbData->directFBSurface(); if (transform.isScaling()) { + Q_ASSERT(supportsStretchBlit()); Q_ASSERT(qMin(transform.m11(), transform.m22()) >= 0); offset.rx() *= transform.m11(); offset.ry() *= transform.m22(); @@ -1184,6 +1188,16 @@ void QDirectFBPaintEnginePrivate::updateClip() } } +bool QDirectFBPaintEnginePrivate::supportsStretchBlit() const +{ +#ifdef QT_DIRECTFB_STRETCHBLIT + return !(q->state()->renderHints & QPainter::SmoothPixmapTransform); +#else + return false; +#endif +} + + void QDirectFBPaintEnginePrivate::systemStateChanged() { QRasterPaintEnginePrivate::systemStateChanged(); diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index b15888b..e78966c 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -470,6 +470,7 @@ QPixmap QDirectFBPixmapData::transformed(const QTransform &transform, return QPixmap(); QDirectFBPixmapData *data = new QDirectFBPixmapData(screen, QPixmapData::PixmapType); + data->setSerialNumber(++global_ser_no); DFBSurfaceBlittingFlags flags = DSBLIT_NOFX; data->alpha = alpha; if (alpha) { diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h index 6330582..61d9cf1 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h @@ -69,6 +69,9 @@ QT_MODULE(Gui) #if !defined QT_NO_DIRECTFB_IMAGEPROVIDER && !defined QT_DIRECTFB_IMAGEPROVIDER #define QT_DIRECTFB_IMAGEPROVIDER #endif +#if !defined QT_NO_DIRECTFB_STRETCHBLIT && !defined QT_DIRECTFB_STRETCHBLIT +#define QT_DIRECTFB_STRETCHBLIT +#endif #if !defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE && !defined QT_NO_DIRECTFB_IMAGEPROVIDER_KEEPALIVE #define QT_NO_DIRECTFB_IMAGEPROVIDER_KEEPALIVE #endif diff --git a/src/plugins/imageformats/tiff/qtiffhandler.cpp b/src/plugins/imageformats/tiff/qtiffhandler.cpp index 9538745..7ac9722 100644 --- a/src/plugins/imageformats/tiff/qtiffhandler.cpp +++ b/src/plugins/imageformats/tiff/qtiffhandler.cpp @@ -192,11 +192,10 @@ bool QTiffHandler::read(QImage *image) return false; } + // BitsPerSample defaults to 1 according to the TIFF spec. uint16 bitPerSample; - if (!TIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bitPerSample)) { - TIFFClose(tiff); - return false; - } + if (!TIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bitPerSample)) + bitPerSample = 1; bool grayscale = photometric == PHOTOMETRIC_MINISBLACK || photometric == PHOTOMETRIC_MINISWHITE; if (grayscale && bitPerSample == 1) { diff --git a/src/plugins/sqldrivers/sqlite_symbian/sqlite_symbian.pro b/src/plugins/sqldrivers/sqlite_symbian/sqlite_symbian.pro index 9687908..691cce1 100644 --- a/src/plugins/sqldrivers/sqlite_symbian/sqlite_symbian.pro +++ b/src/plugins/sqldrivers/sqlite_symbian/sqlite_symbian.pro @@ -3,7 +3,7 @@ TEMPLATE = subdirs # We just want to export the sqlite3 binaries for Symbian for platforms that do not have them. symbian { - !exists($${EPOCROOT}epoc32/release/armv5/lib/sqlite3.dso) { + !symbian_no_export_sqlite:!exists($${EPOCROOT}epoc32/release/armv5/lib/sqlite3.dso) { BLD_INF_RULES.prj_exports += ":zip SQLite3_v9.2.zip" } } diff --git a/src/s60installs/qt.iby b/src/s60installs/qt.iby index 41eb562..f24ac4b 100644 --- a/src/s60installs/qt.iby +++ b/src/s60installs/qt.iby @@ -90,27 +90,27 @@ file=ABI_DIR\BUILD_DIR\qts60plugin_5_0.dll SHARED_LIB_DIR\qts60plugin_5_0.dll S60_APP_RESOURCE(s60main) // imageformats stubs -data=\epoc32\winscw\c\resource\qt\plugins\imageformats\qgif.qtplugin resource\qt\plugins\imageformats\qgif.qtplugin -data=\epoc32\winscw\c\resource\qt\plugins\imageformats\qico.qtplugin resource\qt\plugins\imageformats\qico.qtplugin -data=\epoc32\winscw\c\resource\qt\plugins\imageformats\qjpeg.qtplugin resource\qt\plugins\imageformats\qjpeg.qtplugin -data=\epoc32\winscw\c\resource\qt\plugins\imageformats\qmng.qtplugin resource\qt\plugins\imageformats\qmng.qtplugin -data=\epoc32\winscw\c\resource\qt\plugins\imageformats\qsvg.qtplugin resource\qt\plugins\imageformats\qsvg.qtplugin -data=\epoc32\winscw\c\resource\qt\plugins\imageformats\qtiff.qtplugin resource\qt\plugins\imageformats\qtiff.qtplugin +data=\epoc32\data\qt\qtlibspluginstubs\qgif.qtplugin resource\qt\plugins\imageformats\qgif.qtplugin +data=\epoc32\data\qt\qtlibspluginstubs\qico.qtplugin resource\qt\plugins\imageformats\qico.qtplugin +data=\epoc32\data\qt\qtlibspluginstubs\qjpeg.qtplugin resource\qt\plugins\imageformats\qjpeg.qtplugin +data=\epoc32\data\qt\qtlibspluginstubs\qmng.qtplugin resource\qt\plugins\imageformats\qmng.qtplugin +data=\epoc32\data\qt\qtlibspluginstubs\qsvg.qtplugin resource\qt\plugins\imageformats\qsvg.qtplugin +data=\epoc32\data\qt\qtlibspluginstubs\qtiff.qtplugin resource\qt\plugins\imageformats\qtiff.qtplugin // codecs stubs -data=\epoc32\winscw\c\resource\qt\plugins\codecs\qcncodecs.qtplugin resource\qt\plugins\codecs\qcncodecs.qtplugin -data=\epoc32\winscw\c\resource\qt\plugins\codecs\qjpcodecs.qtplugin resource\qt\plugins\codecs\qjpcodecs.qtplugin -data=\epoc32\winscw\c\resource\qt\plugins\codecs\qkrcodecs.qtplugin resource\qt\plugins\codecs\qkrcodecs.qtplugin -data=\epoc32\winscw\c\resource\qt\plugins\codecs\qtwcodecs.qtplugin resource\qt\plugins\codecs\qtwcodecs.qtplugin +data=\epoc32\data\qt\qtlibspluginstubs\qcncodecs.qtplugin resource\qt\plugins\codecs\qcncodecs.qtplugin +data=\epoc32\data\qt\qtlibspluginstubs\qjpcodecs.qtplugin resource\qt\plugins\codecs\qjpcodecs.qtplugin +data=\epoc32\data\qt\qtlibspluginstubs\qkrcodecs.qtplugin resource\qt\plugins\codecs\qkrcodecs.qtplugin +data=\epoc32\data\qt\qtlibspluginstubs\qtwcodecs.qtplugin resource\qt\plugins\codecs\qtwcodecs.qtplugin // iconengines stubs -data=\epoc32\winscw\c\resource\qt\plugins\iconengines\qsvgicon.qtplugin resource\qt\plugins\iconengines\qsvgicon.qtplugin +data=\epoc32\data\qt\qtlibspluginstubs\qsvgicon.qtplugin resource\qt\plugins\iconengines\qsvgicon.qtplugin // Phonon MMF backend -data=\epoc32\winscw\c\resource\qt\plugins\phonon_backend\phonon_mmf.qtplugin resource\qt\plugins\phonon_backend\phonon_mmf.qtplugin +data=\epoc32\data\qt\qtlibspluginstubs\phonon_mmf.qtplugin resource\qt\plugins\phonon_backend\phonon_mmf.qtplugin // graphicssystems -data=\epoc32\winscw\c\resource\qt\plugins\graphicssystems\qvggraphicssystem.qtplugin resource\qt\plugins\graphicssystems\qvggraphicssystem.qtplugin +data=\epoc32\data\qt\qtlibspluginstubs\qvggraphicssystem.qtplugin resource\qt\plugins\graphicssystems\qvggraphicssystem.qtplugin // Stub sis file data=ZSYSTEM\install\qt.sis System\Install\qt.sis diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro index 37adfa9..e024396 100644 --- a/src/s60installs/s60installs.pro +++ b/src/s60installs/s60installs.pro @@ -105,10 +105,6 @@ symbian: { qtlibraries.sources += QtDeclarative.dll } - contains(QT_CONFIG, webkit): { - qtlibraries.sources += QtWebKit.dll - } - graphicssystems_plugins.path = c:$$QT_PLUGINS_BASE_DIR/graphicssystems contains(QT_CONFIG, openvg) { qtlibraries.sources += QtOpenVG.dll @@ -117,4 +113,9 @@ symbian: { BLD_INF_RULES.prj_exports += "qt.iby $$CORE_MW_LAYER_IBY_EXPORT_PATH(qt.iby)" BLD_INF_RULES.prj_exports += "qtdemoapps.iby $$CORE_APP_LAYER_IBY_EXPORT_PATH(qtdemoapps.iby)" + PLUGIN_STUBS = $$files(qmakepluginstubs/*) + for(STUB, PLUGIN_STUBS) { + STUB_FILENAME = $$basename(STUB) + BLD_INF_RULES.prj_exports += "qmakepluginstubs/$${STUB_FILENAME} /epoc32/data/qt/qtlibspluginstubs/$${STUB_FILENAME}" + } } diff --git a/tests/arthur/data/qps/aliasing.qps b/tests/arthur/data/qps/aliasing.qps new file mode 100644 index 0000000..59878f9 --- /dev/null +++ b/tests/arthur/data/qps/aliasing.qps @@ -0,0 +1,156 @@ + +path_moveTo convexPath 25 0 +path_lineTo convexPath 50 50 +path_lineTo convexPath 25 25 +path_lineTo convexPath 0 50 +path_closeSubpath convexPath + +pixmap_load border.png pixmap + +setRenderHint LineAntialiasing false +translate 10 10 + +begin_block drawing + setPen black 1 + setBrush 7f7fff + drawPath convexPath + + setFont "monospace" 8 + setPen black + drawText 0 68 "QwErTy@" + + + setPen black 1 + setBrush 7f7fff + drawRect 0 80 10 5 + + setPen black 1 + setBrush noBrush + drawRect 20 80 10 5 + + setPen noPen + setBrush 7f7fff + drawRect 40 80 10 5 + + + setPen black 2 + setBrush 7f7fff + drawRect 0 90 10 5 + + setPen black 2 + setBrush noBrush + drawRect 20 90 10 5 + + setPen noPen + setBrush 7f7fff + drawRect 40 90 10 5 + + + setPen black 3 + setBrush 7f7fff + drawRect 0 100 10 5 + + setPen black 3 + setBrush noBrush + drawRect 20 100 10 5 + + setPen noPen + setBrush 7f7fff + drawRect 40 100 10 5 + + + setPen black 1 + setBrush noBrush + drawLine 10 110 20 120 + drawLine 30 120 40 110 + + setPen black 2 + setBrush noBrush + drawLine 10 120 20 130 + drawLine 30 130 40 120 + + setPen black 3 + setBrush noBrush + drawLine 10 130 20 140 + drawLine 30 140 40 130 + + drawPixmap pixmap 0 150 + + setRenderHint SmoothPixmapTransform false + drawPixmap pixmap 20 150 15 15 0 0 10 10 + +end_block + +translate 0 180 +setRenderHint LineAntialiasing true +repeat_block drawing +drawText 15 185 "0.0" + +resetMatrix +translate 70.2 10.2 +setRenderHint LineAntialiasing false +repeat_block drawing +translate 0 180 +setRenderHint LineAntialiasing true +repeat_block drawing +translate -0.2 -0.2 +drawText 15 185 "0.2" + + +resetMatrix +translate 130.4 10.4 +setRenderHint LineAntialiasing false +repeat_block drawing +translate 0 180 +setRenderHint LineAntialiasing true +repeat_block drawing +translate -0.4 -0.4 +drawText 15 185 "0.4" + + +resetMatrix +translate 190.5 10.5 +setRenderHint LineAntialiasing false +repeat_block drawing +translate 0 180 +setRenderHint LineAntialiasing true +repeat_block drawing +translate -0.5 -0.5 +drawText 15 185 "0.5" + + +resetMatrix +translate 250.6 10.6 +setRenderHint LineAntialiasing false +repeat_block drawing +translate 0 180 +setRenderHint LineAntialiasing true +repeat_block drawing +translate -0.6 -0.6 +drawText 15 185 "0.6" + + +resetMatrix +translate 310.8 10.8 +setRenderHint LineAntialiasing false +repeat_block drawing +translate 0 180 +setRenderHint LineAntialiasing true +repeat_block drawing +translate -0.8 -0.8 +drawText 15 185 "0.8" + + +resetMatrix +translate 371 11 +setRenderHint LineAntialiasing false +repeat_block drawing +translate 0 180 +setRenderHint LineAntialiasing true +repeat_block drawing +drawText 15 185 "1.0" + + +resetMatrix +drawText 430 95 "Aliased" +drawText 430 275 "Anti-Aliased"
\ No newline at end of file diff --git a/tests/arthur/data/qps/aliasing_qps.png b/tests/arthur/data/qps/aliasing_qps.png Binary files differnew file mode 100644 index 0000000..183129b --- /dev/null +++ b/tests/arthur/data/qps/aliasing_qps.png diff --git a/tests/auto/qdatetime/tst_qdatetime.cpp b/tests/auto/qdatetime/tst_qdatetime.cpp index 32fa398..1140402 100644 --- a/tests/auto/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/qdatetime/tst_qdatetime.cpp @@ -147,16 +147,9 @@ Q_DECLARE_METATYPE(QTime) tst_QDateTime::tst_QDateTime() { -#ifdef Q_OS_SYMBIAN - // Symbian's timezone server cannot handle DST correctly for dates before year 1997 - uint x1 = QDateTime(QDate(2000, 1, 1), QTime()).toTime_t(); - uint x2 = QDateTime(QDate(2000, 6, 1), QTime()).toTime_t(); - europeanTimeZone = (x1 == 946681200 && x2 == 959810400); -#else uint x1 = QDateTime(QDate(1990, 1, 1), QTime()).toTime_t(); uint x2 = QDateTime(QDate(1990, 6, 1), QTime()).toTime_t(); europeanTimeZone = (x1 == 631148400 && x2 == 644191200); -#endif } tst_QDateTime::~tst_QDateTime() diff --git a/tests/auto/qfiledialog2/tst_qfiledialog2.cpp b/tests/auto/qfiledialog2/tst_qfiledialog2.cpp index 83ddd39..83380a5 100644 --- a/tests/auto/qfiledialog2/tst_qfiledialog2.cpp +++ b/tests/auto/qfiledialog2/tst_qfiledialog2.cpp @@ -130,6 +130,7 @@ private slots: void task259105_filtersCornerCases(); void QTBUG4419_lineEditSelectAll(); + void QTBUG6558_showDirsOnly(); private: QByteArray userSettings; @@ -1040,5 +1041,72 @@ void tst_QFiledialog::QTBUG4419_lineEditSelectAll() QCOMPARE(tempPath + QChar('/') + lineEdit->selectedText(), t->fileName()); } +void tst_QFiledialog::QTBUG6558_showDirsOnly() +{ + const QString tempPath = QDir::tempPath(); + QDir dirTemp(tempPath); + const QString tempName = QLatin1String("showDirsOnly.") + QString::number(qrand()); + dirTemp.mkdir(tempName); + dirTemp.cd(tempName); + QTRY_VERIFY(dirTemp.exists()); + + const QString dirPath = dirTemp.absolutePath(); + QDir dir(dirPath); + + //We create two dirs + dir.mkdir("a"); + dir.mkdir("b"); + + //Create a file + QFile tempFile(dirPath + "/plop.txt"); + tempFile.open(QIODevice::WriteOnly | QIODevice::Text); + QTextStream out(&tempFile); + out << "The magic number is: " << 49 << "\n"; + tempFile.close(); + + QNonNativeFileDialog fd(0, "TestFileDialog"); + + fd.setDirectory(dir.absolutePath()); + fd.setViewMode(QFileDialog::List); + fd.setAcceptMode(QFileDialog::AcceptSave); + fd.setOption(QFileDialog::ShowDirsOnly, true); + fd.show(); + + QApplication::setActiveWindow(&fd); + QTest::qWaitForWindowShown(&fd); + QTRY_COMPARE(fd.isVisible(), true); + QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget*>(&fd)); + + QFileSystemModel *model = qFindChild<QFileSystemModel*>(&fd, "qt_filesystem_model"); + QTRY_COMPARE(model->rowCount(model->index(dir.absolutePath())), 2); + + fd.setOption(QFileDialog::ShowDirsOnly, false); + QTRY_COMPARE(model->rowCount(model->index(dir.absolutePath())), 3); + + fd.setOption(QFileDialog::ShowDirsOnly, true); + QTRY_COMPARE(model->rowCount(model->index(dir.absolutePath())), 2); + + fd.setFileMode(QFileDialog::DirectoryOnly); + QTRY_COMPARE(model->rowCount(model->index(dir.absolutePath())), 2); + QTRY_COMPARE(bool(fd.options() & QFileDialog::ShowDirsOnly), true); + + fd.setFileMode(QFileDialog::AnyFile); + QTRY_COMPARE(model->rowCount(model->index(dir.absolutePath())), 3); + QTRY_COMPARE(bool(fd.options() & QFileDialog::ShowDirsOnly), false); + + fd.setDirectory(QDir::homePath()); + + //We remove the dirs + dir.rmdir("a"); + dir.rmdir("b"); + + //we delete the file + tempFile.remove(); + + dirTemp.cdUp(); + dirTemp.rmdir(tempName); + QTRY_VERIFY(!dir.exists()); +} + QTEST_MAIN(tst_QFiledialog) #include "tst_qfiledialog2.moc" diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index 84ea52b..5ea7100 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -1074,8 +1074,8 @@ void tst_QFileInfo::isHidden_data() #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) QTest::newRow("C:/RECYCLER") << QString::fromLatin1("C:/RECYCLER") << true; - QTest::newRow("C:/RECYCLER/.") << QString::fromLatin1("C:/RECYCLER/.") << false; - QTest::newRow("C:/RECYCLER/..") << QString::fromLatin1("C:/RECYCLER/..") << false; + QTest::newRow("C:/RECYCLER/.") << QString::fromLatin1("C:/RECYCLER/.") << true; + QTest::newRow("C:/RECYCLER/..") << QString::fromLatin1("C:/RECYCLER/..") << true; #endif #if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) diff --git a/tests/auto/qgl/tst_qgl.cpp b/tests/auto/qgl/tst_qgl.cpp index 532e550..a61eb8d 100644 --- a/tests/auto/qgl/tst_qgl.cpp +++ b/tests/auto/qgl/tst_qgl.cpp @@ -1824,17 +1824,12 @@ Q_GLOBAL_STATIC_WITH_ARGS(QGLContextResource, qt_shared_test, (qt_shared_test_fr void tst_QGL::shareRegister() { #ifdef QT_BUILD_INTERNAL - QGLShareRegister *shareReg = qgl_share_reg(); - QVERIFY(shareReg != 0); - // Create a context. QGLWidget *glw1 = new QGLWidget(); glw1->makeCurrent(); // Nothing should be sharing with glw1's context yet. - QList<const QGLContext *> list; - list = shareReg->shares(glw1->context()); - QCOMPARE(list.size(), 0); + QVERIFY(!glw1->isSharing()); // Create a guard for the first context. QGLSharedResourceGuard guard(glw1->context()); @@ -1867,16 +1862,6 @@ void tst_QGL::shareRegister() QVERIFY(guard.context() == glw1->context()); QVERIFY(guard.id() == 3); - // Now there are two items in the share lists. - list = shareReg->shares(glw1->context()); - QCOMPARE(list.size(), 2); - QVERIFY(list.contains(glw1->context())); - QVERIFY(list.contains(glw2->context())); - list = shareReg->shares(glw2->context()); - QCOMPARE(list.size(), 2); - QVERIFY(list.contains(glw1->context())); - QVERIFY(list.contains(glw2->context())); - // Check the sharing relationships. QVERIFY(QGLContext::areSharing(glw1->context(), glw1->context())); QVERIFY(QGLContext::areSharing(glw2->context(), glw2->context())); @@ -1902,18 +1887,6 @@ void tst_QGL::shareRegister() QVERIFY(qt_shared_test()->value(glw2->context()) == res1); QVERIFY(qt_shared_test()->value(glw3->context()) == res3); - // First two should still be sharing, but third is in its own list. - list = shareReg->shares(glw1->context()); - QCOMPARE(list.size(), 2); - QVERIFY(list.contains(glw1->context())); - QVERIFY(list.contains(glw2->context())); - list = shareReg->shares(glw2->context()); - QCOMPARE(list.size(), 2); - QVERIFY(list.contains(glw1->context())); - QVERIFY(list.contains(glw2->context())); - list = shareReg->shares(glw3->context()); - QCOMPARE(list.size(), 0); - // Check the sharing relationships again. QVERIFY(QGLContext::areSharing(glw1->context(), glw1->context())); QVERIFY(QGLContext::areSharing(glw2->context(), glw2->context())); @@ -1951,10 +1924,6 @@ void tst_QGL::shareRegister() QVERIFY(guard3.context() == glw3->context()); QVERIFY(guard3.id() == 5); - // Re-check the share list for the second context (should be empty now). - list = shareReg->shares(glw2->context()); - QCOMPARE(list.size(), 0); - // Clean up and check that the resources are properly deleted. delete glw2; QCOMPARE(tst_QGLResource::deletions, 1); diff --git a/tests/auto/qtextodfwriter/tst_qtextodfwriter.cpp b/tests/auto/qtextodfwriter/tst_qtextodfwriter.cpp index cfcbcfb..a61de99 100644 --- a/tests/auto/qtextodfwriter/tst_qtextodfwriter.cpp +++ b/tests/auto/qtextodfwriter/tst_qtextodfwriter.cpp @@ -175,6 +175,10 @@ void tst_QTextOdfWriter::testWriteStyle1_data() "<style:style style:name=\"c4\" style:family=\"text\"><style:text-properties fo:font-style=\"italic\" fo:font-family=\"Sans\"/></style:style>"; QTest::newRow("bold+italic") << text1 << 25 << "<style:style style:name=\"c4\" style:family=\"text\"><style:text-properties fo:font-style=\"italic\" fo:font-weight=\"bold\" fo:font-family=\"Sans\"/></style:style>"; + QString colorText = "<span style=\"color: #00FF00; background-color: #FF0000;\"> Color Text </span>"; + QTest::newRow("green/red") << colorText << 3 << + "<style:style style:name=\"c4\" style:family=\"text\"><style:text-properties fo:font-family=\"Sans\" fo:color=\"#00ff00\" fo:background-color=\"#ff0000\"/></style:style>"; + } void tst_QTextOdfWriter::testWriteStyle1() diff --git a/tests/auto/qurl/tst_qurl.cpp b/tests/auto/qurl/tst_qurl.cpp index 03e77aa..70cfb61 100644 --- a/tests/auto/qurl/tst_qurl.cpp +++ b/tests/auto/qurl/tst_qurl.cpp @@ -1682,6 +1682,12 @@ void tst_QUrl::toString_constructed_data() << QByteArray("//qt.nokia.com/index.html"); QTest::newRow("data2") << QString::fromLatin1("file") << n << n << n << -1 << QString::fromLatin1("/root") << QByteArray() << n << QString::fromLatin1("file:///root") << QByteArray("file:///root"); + QTest::newRow("userAndPass") << QString::fromLatin1("http") << QString::fromLatin1("dfaure") << QString::fromLatin1("kde") + << "kde.org" << 443 << QString::fromLatin1("/") << QByteArray() << n + << QString::fromLatin1("http://dfaure:kde@kde.org:443/") << QByteArray("http://dfaure:kde@kde.org:443/"); + QTest::newRow("PassWithoutUser") << QString::fromLatin1("http") << n << QString::fromLatin1("kde") + << "kde.org" << 443 << QString::fromLatin1("/") << QByteArray() << n + << QString::fromLatin1("http://:kde@kde.org:443/") << QByteArray("http://:kde@kde.org:443/"); } void tst_QUrl::toString_constructed() @@ -1717,6 +1723,7 @@ void tst_QUrl::toString_constructed() QVERIFY(url.isValid()); QCOMPARE(url.toString(), asString); + QCOMPARE(QString::fromLatin1(url.toEncoded()), QString::fromLatin1(asEncoded)); // readable in case of differences QCOMPARE(url.toEncoded(), asEncoded); } diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index 3e14b56..2d04cc5 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -66,6 +66,8 @@ #include <private/qapplication_p.h> #include <qcalendarwidget.h> #include <qmainwindow.h> +#include <qdockwidget.h> +#include <qtoolbar.h> #include <QtGui/qpaintengine.h> #include <private/qbackingstore_p.h> @@ -356,6 +358,7 @@ private slots: void paintOnScreenPossible(); #endif void reparentStaticWidget(); + void QTBUG6883_reparentStaticWidget2(); #ifdef Q_WS_QWS void updateOutsideSurfaceClip(); #endif @@ -8728,6 +8731,31 @@ void tst_QWidget::reparentStaticWidget() // Please don't crash. paintOnScreen.resize(paintOnScreen.size() + QSize(2, 2)); QTest::qWait(20); + +} + +void tst_QWidget::QTBUG6883_reparentStaticWidget2() +{ + QMainWindow mw; + QDockWidget *one = new QDockWidget("one", &mw); + mw.addDockWidget(Qt::LeftDockWidgetArea, one , Qt::Vertical); + + QWidget *child = new QWidget(); + child->setPalette(Qt::red); + child->setAutoFillBackground(true); + child->setAttribute(Qt::WA_StaticContents); + child->resize(100, 100); + one->setWidget(child); + + QToolBar *mainTools = mw.addToolBar("Main Tools"); + mainTools->addWidget(new QLineEdit); + + mw.show(); + QTest::qWaitForWindowShown(&mw); + + one->setFloating(true); + QTest::qWait(20); + //do not crash } #ifdef Q_WS_QWS @@ -9726,7 +9754,7 @@ public: void deleteBackingStore() { if (static_cast<QWidgetPrivate*>(d_ptr.data())->maybeBackingStore()) { - delete static_cast<QWidgetPrivate*>(d_ptr.data())->topData()->backingStore; + delete static_cast<QWidgetPrivate*>(d_ptr.data())->topData()->backingStore; static_cast<QWidgetPrivate*>(d_ptr.data())->topData()->backingStore = 0; } } diff --git a/tests/auto/uiloader/baseline/css_qtbug6855.ui b/tests/auto/uiloader/baseline/css_qtbug6855.ui new file mode 100644 index 0000000..0727f6b --- /dev/null +++ b/tests/auto/uiloader/baseline/css_qtbug6855.ui @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Form</class> + <widget class="QWidget" name="Form"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>212</width> + <height>108</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <property name="styleSheet"> + <string notr="true">QPushButton { padding: 20px; }</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QPushButton" name="pushButton"> + <property name="text"> + <string>Text not cropped</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>258</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="0"> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>218</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/tests/benchmarks/benchmarks.pro b/tests/benchmarks/benchmarks.pro index bb20dcf..0f760a1 100644 --- a/tests/benchmarks/benchmarks.pro +++ b/tests/benchmarks/benchmarks.pro @@ -5,6 +5,7 @@ SUBDIRS = containers-associative \ qbytearray \ qfileinfo \ qfile_vs_qnetworkaccessmanager \ + qhostinfo \ qpainter \ qtestlib-simple events \ qiodevice \ diff --git a/tests/benchmarks/qhostinfo/main.cpp b/tests/benchmarks/qhostinfo/main.cpp new file mode 100644 index 0000000..389443b --- /dev/null +++ b/tests/benchmarks/qhostinfo/main.cpp @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2009 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$ +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QDebug> +#include <QHostInfo> +#include <QStringList> +#include <QString> + +#include <qtest.h> +#include <qtesteventloop.h> + +class tst_qhostinfo : public QObject +{ + Q_OBJECT +private slots: + void lookupSpeed(); +}; + +class SignalReceiver : public QObject +{ + Q_OBJECT +public: + SignalReceiver(int nrc) : receiveCount(0), neededReceiveCount(nrc) {}; + int receiveCount; + int neededReceiveCount; +public slots: + void resultsReady(const QHostInfo) { + receiveCount++; + if (receiveCount == neededReceiveCount) + QTestEventLoop::instance().exitLoop(); + } +}; + +void tst_qhostinfo::lookupSpeed() +{ + QStringList hostnameList; + hostnameList << "www.ovi.com" << "www.nokia.com" << "qt.nokia.com" << "www.trolltech.com" << "troll.no" + << "www.qtcentre.org" << "forum.nokia.com" << "www.forum.nokia.com" << "wiki.forum.nokia.com" + << "www.nokia.no" << "nokia.de" << "127.0.0.1" << "----"; + // also add some duplicates: + hostnameList << "www.nokia.com" << "127.0.0.1" << "www.trolltech.com"; + const int COUNT = hostnameList.size(); + + SignalReceiver receiver(COUNT); + + QBENCHMARK { + for (int i = 0; i < hostnameList.size(); i++) + QHostInfo::lookupHost(hostnameList.at(i), &receiver, SLOT(resultsReady(const QHostInfo))); + QTestEventLoop::instance().enterLoop(20); + QVERIFY(!QTestEventLoop::instance().timeout()); + } +} + + +QTEST_MAIN(tst_qhostinfo) + +#include "main.moc" diff --git a/tests/benchmarks/qhostinfo/qhostinfo.pro b/tests/benchmarks/qhostinfo/qhostinfo.pro new file mode 100755 index 0000000..f18d6d7 --- /dev/null +++ b/tests/benchmarks/qhostinfo/qhostinfo.pro @@ -0,0 +1,13 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_qhostinfo +DEPENDPATH += . +INCLUDEPATH += . + +QT -= gui +QT += network + +CONFIG += release + +# Input +SOURCES += main.cpp |