summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorOlivier Goffart <olivier.goffart@nokia.com>2011-01-25 18:56:33 +0100
committerOlivier Goffart <olivier.goffart@nokia.com>2011-01-25 18:56:33 +0100
commit5422e929cad04633a06c156cba96cfcd69262522 (patch)
treeafb3c9b76c05d80238a1ff76f4e8f4019fac1651 /src
parentac798c5d77c59ea8dfe29c9d1896fb6604e3a628 (diff)
parenta0e0a9378d10db9c8ab3ba4d59f5c576ee4cbc40 (diff)
Merge remote branch 'origin/4.7' into qt-master-from-4.7
Conflicts: configure src/network/bearer/bearer.pri
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/symbian/RegisterFileAllocatorSymbian.cpp6
-rw-r--r--src/3rdparty/phonon/phonon/factory.cpp18
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix.cpp1
-rw-r--r--src/corelib/kernel/qsharedmemory.cpp6
-rw-r--r--src/corelib/kernel/qsharedmemory_unix.cpp14
-rw-r--r--src/corelib/kernel/qsharedmemory_win.cpp3
-rw-r--r--src/corelib/kernel/qsystemsemaphore_symbian.cpp4
-rw-r--r--src/corelib/kernel/qsystemsemaphore_win.cpp3
-rw-r--r--src/dbus/qdbusconnection.cpp20
-rw-r--r--src/declarative/graphicsitems/qdeclarativeflickable.cpp2
-rw-r--r--src/declarative/graphicsitems/qdeclarativegridview.cpp4
-rw-r--r--src/declarative/graphicsitems/qdeclarativelistview.cpp4
-rw-r--r--src/declarative/graphicsitems/qdeclarativeloader.cpp60
-rw-r--r--src/declarative/graphicsitems/qdeclarativeloader_p_p.h2
-rw-r--r--src/declarative/graphicsitems/qdeclarativescalegrid.cpp10
-rw-r--r--src/declarative/graphicsitems/qdeclarativetext.cpp17
-rw-r--r--src/declarative/graphicsitems/qdeclarativetext_p_p.h1
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextedit.cpp37
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextedit_p_p.h1
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput.cpp25
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput_p_p.h1
-rw-r--r--src/declarative/qml/parser/qdeclarativejslexer.cpp2
-rw-r--r--src/gui/graphicsview/qgridlayoutengine.cpp5
-rw-r--r--src/gui/image/qgifhandler.cpp10
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_s60.cpp2
-rw-r--r--src/gui/kernel/qapplication_s60.cpp7
-rw-r--r--src/gui/painting/qdrawhelper.cpp2
-rw-r--r--src/gui/styles/qs60style.cpp6
-rw-r--r--src/gui/text/qfontdatabase.cpp20
-rw-r--r--src/gui/text/qfontdatabase_s60.cpp551
-rw-r--r--src/gui/text/qfontengine_s60.cpp5
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp42
-rw-r--r--src/network/access/qnetworkaccessmanager.h2
-rw-r--r--src/network/access/qnetworkaccessmanager_p.h2
-rw-r--r--src/network/access/qnetworkreplyimpl.cpp6
-rw-r--r--src/network/bearer/bearer.pri6
-rw-r--r--src/network/bearer/qsharednetworksession.cpp90
-rw-r--r--src/network/bearer/qsharednetworksession_p.h81
-rw-r--r--src/network/kernel/qauthenticator.cpp19
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp4
-rw-r--r--src/opengl/qglframebufferobject.cpp4
-rw-r--r--src/opengl/qglpixelbuffer.cpp4
-rw-r--r--src/opengl/qglpixmapfilter.cpp6
-rw-r--r--src/opengl/qpaintengine_opengl.cpp2
-rw-r--r--src/opengl/qpixmapdata_gl.cpp4
-rw-r--r--src/openvg/qpaintengine_vg.cpp10
-rw-r--r--src/openvg/qpixmapdata_vg.cpp16
47 files changed, 931 insertions, 216 deletions
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/symbian/RegisterFileAllocatorSymbian.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/symbian/RegisterFileAllocatorSymbian.cpp
index da5cc99239..e89dd7a868 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/symbian/RegisterFileAllocatorSymbian.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/symbian/RegisterFileAllocatorSymbian.cpp
@@ -83,10 +83,16 @@ void RegisterFileAllocator::grow(void* newEnd)
TInt nBytes = (TInt)(newEnd) - (TInt)(m_comEnd);
nBytes = SYMBIAN_ROUNDUPTOMULTIPLE(nBytes, m_poolSize);
TInt offset = (TInt)m_comEnd - (TInt)m_buffer;
+ // The reserved size is not guaranteed to be a multiple of the pool size.
+ TInt maxBytes = (TInt)m_resEnd - (TInt)m_comEnd;
+ if (nBytes > maxBytes)
+ nBytes = maxBytes;
TInt ret = m_chunk.Commit(offset, nBytes);
if (ret == KErrNone)
m_comEnd = (void*)(m_chunk.Base() + m_chunk.Size());
+ else
+ CRASH();
}
}
diff --git a/src/3rdparty/phonon/phonon/factory.cpp b/src/3rdparty/phonon/phonon/factory.cpp
index 2785dffe3e..b5e565b527 100644
--- a/src/3rdparty/phonon/phonon/factory.cpp
+++ b/src/3rdparty/phonon/phonon/factory.cpp
@@ -137,21 +137,15 @@ bool FactoryPrivate::createBackend()
QStringList plugins(dir.entryList(QDir::Files));
#ifdef Q_OS_SYMBIAN
- /* On Symbian OS we might have two plugins, one which uses Symbian
- * MMF framework("mmf"), and one which uses Real Networks's
- * Helix("hxphonon"). We prefer the latter because it's more
- * sophisticated, so we make sure the Helix backend is attempted
- * to be loaded first, and the MMF backend is used for backup. */
- {
- const int helix = plugins.indexOf(QLatin1String("hxphonon"));
- if (helix != -1)
- plugins.move(helix, 0);
- }
+ static const QString preferredPluginName = QLatin1String("phonon_mmf");
+ const int preferredPluginIndex = plugins.indexOf(preferredPluginName + ".qtplugin");
+ if (preferredPluginIndex != -1)
+ plugins.move(preferredPluginIndex, 0);
#endif
const QStringList files = dir.entryList(QDir::Files);
- for (int i = 0; i < files.count(); ++i) {
- QPluginLoader pluginLoader(libPath + files.at(i));
+ for (int i = 0; i < plugins.count(); ++i) {
+ QPluginLoader pluginLoader(libPath + plugins.at(i));
if (!pluginLoader.load()) {
pDebug() << Q_FUNC_INFO << " load failed:"
<< pluginLoader.errorString();
diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp
index 46604b0d93..25c02c4ee9 100644
--- a/src/corelib/kernel/qeventdispatcher_unix.cpp
+++ b/src/corelib/kernel/qeventdispatcher_unix.cpp
@@ -509,7 +509,6 @@ bool QTimerInfoList::unregisterTimer(int timerId)
}
}
// id not found
- qWarning("Application asked to unregister timer 0x%x which is not registered in this thread. Fix application.", timerId);
return false;
}
diff --git a/src/corelib/kernel/qsharedmemory.cpp b/src/corelib/kernel/qsharedmemory.cpp
index b61509e86c..78715a1966 100644
--- a/src/corelib/kernel/qsharedmemory.cpp
+++ b/src/corelib/kernel/qsharedmemory.cpp
@@ -458,11 +458,7 @@ bool QSharedMemory::detach()
return false;
#endif
- if (d->detach()) {
- d->size = 0;
- return true;
- }
- return false;
+ return d->detach();
}
/*!
diff --git a/src/corelib/kernel/qsharedmemory_unix.cpp b/src/corelib/kernel/qsharedmemory_unix.cpp
index fc0a4386cd..b30117f6c1 100644
--- a/src/corelib/kernel/qsharedmemory_unix.cpp
+++ b/src/corelib/kernel/qsharedmemory_unix.cpp
@@ -198,7 +198,7 @@ bool QSharedMemoryPrivate::create(int size)
}
// create
- if (-1 == shmget(handle(), size, 0666 | IPC_CREAT | IPC_EXCL)) {
+ if (-1 == shmget(unix_key, size, 0666 | IPC_CREAT | IPC_EXCL)) {
QString function = QLatin1String("QSharedMemory::create");
switch (errno) {
case EINVAL:
@@ -219,10 +219,7 @@ bool QSharedMemoryPrivate::create(int size)
bool QSharedMemoryPrivate::attach(QSharedMemory::AccessMode mode)
{
// grab the shared memory segment id
- if (!handle())
- return false;
-
- int id = shmget(handle(), 0, (mode == QSharedMemory::ReadOnly ? 0444 : 0660));
+ int id = shmget(unix_key, 0, (mode == QSharedMemory::ReadOnly ? 0444 : 0660));
if (-1 == id) {
setErrorString(QLatin1String("QSharedMemory::attach (shmget)"));
return false;
@@ -264,12 +261,11 @@ bool QSharedMemoryPrivate::detach()
return false;
}
memory = 0;
+ size = 0;
// Get the number of current attachments
- if (!handle())
- return false;
- int id = shmget(handle(), 0, 0444);
- unix_key = 0;
+ int id = shmget(unix_key, 0, 0444);
+ cleanHandle();
struct shmid_ds shmid_ds;
if (0 != shmctl(id, IPC_STAT, &shmid_ds)) {
diff --git a/src/corelib/kernel/qsharedmemory_win.cpp b/src/corelib/kernel/qsharedmemory_win.cpp
index 75ab4e8ad8..bc13e338bd 100644
--- a/src/corelib/kernel/qsharedmemory_win.cpp
+++ b/src/corelib/kernel/qsharedmemory_win.cpp
@@ -123,8 +123,8 @@ bool QSharedMemoryPrivate::cleanHandle()
{
if (hand != 0 && !CloseHandle(hand)) {
hand = 0;
- return false;
setErrorString(QLatin1String("QSharedMemory::cleanHandle"));
+ return false;
}
hand = 0;
return true;
@@ -183,6 +183,7 @@ bool QSharedMemoryPrivate::detach()
return false;
}
memory = 0;
+ size = 0;
// close handle
return cleanHandle();
diff --git a/src/corelib/kernel/qsystemsemaphore_symbian.cpp b/src/corelib/kernel/qsystemsemaphore_symbian.cpp
index 07cfffcff8..0d257b8f5e 100644
--- a/src/corelib/kernel/qsystemsemaphore_symbian.cpp
+++ b/src/corelib/kernel/qsystemsemaphore_symbian.cpp
@@ -73,6 +73,7 @@ void QSystemSemaphorePrivate::setErrorString(const QString &function, int err)
case KErrInUse:
errorString = QCoreApplication::tr("%1: out of resources", "QSystemSemaphore").arg(function);
error = QSystemSemaphore::OutOfResources;
+ break;
case KErrPermissionDenied:
errorString = QCoreApplication::tr("%1: permission denied", "QSystemSemaphore").arg(function);
error = QSystemSemaphore::PermissionDenied;
@@ -97,8 +98,7 @@ int QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode)
if (key.isEmpty())
return 0;
- QString safeName = makeKeyFileName();
- TPtrC name(qt_QString2TPtrC(safeName));
+ TPtrC name(qt_QString2TPtrC(fileName));
int err = KErrAlreadyExists;
int tryCount = 10;
// Sort out race conditions by retrying several times until existing handle is acquired.
diff --git a/src/corelib/kernel/qsystemsemaphore_win.cpp b/src/corelib/kernel/qsystemsemaphore_win.cpp
index 7f002f85bd..fad50f2ffb 100644
--- a/src/corelib/kernel/qsystemsemaphore_win.cpp
+++ b/src/corelib/kernel/qsystemsemaphore_win.cpp
@@ -86,8 +86,7 @@ HANDLE QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode)
// Create it if it doesn't already exists.
if (semaphore == 0) {
- QString safeName = makeKeyFileName();
- semaphore = CreateSemaphore(0, initialValue, MAXLONG, (wchar_t*)safeName.utf16());
+ semaphore = CreateSemaphore(0, initialValue, MAXLONG, (wchar_t*)fileName.utf16());
if (semaphore == NULL)
setErrorString(QLatin1String("QSystemSemaphore::handle"));
}
diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp
index eb312d2fe9..3fb63eb400 100644
--- a/src/dbus/qdbusconnection.cpp
+++ b/src/dbus/qdbusconnection.cpp
@@ -632,10 +632,26 @@ bool QDBusConnection::connect(const QString &service, const QString &path, const
if (!receiver || !slot || !d || !d->connection)
return false;
- if (!interface.isEmpty() && !QDBusUtil::isValidInterfaceName(interface))
- return false;
if (interface.isEmpty() && name.isEmpty())
return false;
+ if (!interface.isEmpty() && !QDBusUtil::isValidInterfaceName(interface)) {
+#ifndef QT_NO_DEBUG
+ qWarning("QDBusConnection::connect: interface name '%s' is not valid", interface.toLatin1().constData());
+#endif
+ return false;
+ }
+ if (!service.isEmpty() && !QDBusUtil::isValidBusName(service)) {
+#ifndef QT_NO_DEBUG
+ qWarning("QDBusConnection::connect: service name '%s' is not valid", service.toLatin1().constData());
+#endif
+ return false;
+ }
+ if (!path.isEmpty() && !QDBusUtil::isValidObjectPath(path)) {
+#ifndef QT_NO_DEBUG
+ qWarning("QDBusConnection::connect: object path '%s' is not valid", path.toLatin1().constData());
+#endif
+ return false;
+ }
QDBusWriteLocker locker(ConnectAction, d);
return d->connectSignal(service, path, interface, name, argumentMatch, signature, receiver, slot);
diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
index db63cda80d..d35718ba30 100644
--- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
@@ -299,7 +299,7 @@ void QDeclarativeFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal
timeline.move(data.move, maxExtent - dist/2, QEasingCurve(QEasingCurve::InQuad), fixupDuration/4);
timeline.move(data.move, maxExtent, QEasingCurve(QEasingCurve::OutExpo), 3*fixupDuration/4);
} else {
- timeline.set(data.move, minExtent);
+ timeline.set(data.move, maxExtent);
}
}
vTime = timeline.time();
diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp
index 89d74930d1..4c04a6b66b 100644
--- a/src/declarative/graphicsitems/qdeclarativegridview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp
@@ -2165,6 +2165,7 @@ void QDeclarativeGridView::positionViewAtIndex(int index, int mode)
if (d->layoutScheduled)
d->layout();
qreal pos = d->position();
+ qreal maxExtent = d->flow == QDeclarativeGridView::LeftToRight ? -maxYExtent() : -maxXExtent();
FxGridItem *item = d->visibleItem(index);
if (!item) {
int itemPos = d->rowPosAt(index);
@@ -2172,7 +2173,7 @@ void QDeclarativeGridView::positionViewAtIndex(int index, int mode)
QList<FxGridItem*> oldVisible = d->visibleItems;
d->visibleItems.clear();
d->visibleIndex = index - index % d->columns;
- d->setPosition(itemPos);
+ d->setPosition(qMin(qreal(itemPos), maxExtent));
// now release the reference to all the old visible items.
for (int i = 0; i < oldVisible.count(); ++i)
d->releaseItem(oldVisible.at(i));
@@ -2202,7 +2203,6 @@ void QDeclarativeGridView::positionViewAtIndex(int index, int mode)
if (itemPos < pos)
pos = itemPos;
}
- qreal maxExtent = d->flow == QDeclarativeGridView::LeftToRight ? -maxYExtent() : -maxXExtent();
pos = qMin(pos, maxExtent);
qreal minExtent = d->flow == QDeclarativeGridView::LeftToRight ? -minYExtent() : -minXExtent();
pos = qMax(pos, minExtent);
diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp
index b4fd57134c..b4b3fa70cb 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp
@@ -2603,6 +2603,7 @@ void QDeclarativeListView::positionViewAtIndex(int index, int mode)
d->layout();
qreal pos = d->position();
FxListItem *item = d->visibleItem(index);
+ qreal maxExtent = d->orient == QDeclarativeListView::Vertical ? -maxYExtent() : -maxXExtent();
if (!item) {
int itemPos = d->positionAt(index);
// save the currently visible items in case any of them end up visible again
@@ -2610,7 +2611,7 @@ void QDeclarativeListView::positionViewAtIndex(int index, int mode)
d->visibleItems.clear();
d->visiblePos = itemPos;
d->visibleIndex = index;
- d->setPosition(itemPos);
+ d->setPosition(qMin(qreal(itemPos), maxExtent));
// now release the reference to all the old visible items.
for (int i = 0; i < oldVisible.count(); ++i)
d->releaseItem(oldVisible.at(i));
@@ -2640,7 +2641,6 @@ void QDeclarativeListView::positionViewAtIndex(int index, int mode)
if (itemPos < pos)
pos = itemPos;
}
- qreal maxExtent = d->orient == QDeclarativeListView::Vertical ? -maxYExtent() : -maxXExtent();
pos = qMin(pos, maxExtent);
qreal minExtent = d->orient == QDeclarativeListView::Vertical ? -minYExtent() : -minXExtent();
pos = qMax(pos, minExtent);
diff --git a/src/declarative/graphicsitems/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp
index 86e438f925..ded2be31df 100644
--- a/src/declarative/graphicsitems/qdeclarativeloader.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp
@@ -48,7 +48,7 @@
QT_BEGIN_NAMESPACE
QDeclarativeLoaderPrivate::QDeclarativeLoaderPrivate()
- : item(0), component(0), ownComponent(false), isComponentComplete(false)
+ : item(0), component(0), ownComponent(false)
{
}
@@ -262,7 +262,6 @@ void QDeclarativeLoader::setSource(const QUrl &url)
d->clear();
d->source = url;
-
if (d->source.isEmpty()) {
emit sourceChanged();
emit statusChanged();
@@ -273,9 +272,18 @@ void QDeclarativeLoader::setSource(const QUrl &url)
d->component = new QDeclarativeComponent(qmlEngine(this), d->source, this);
d->ownComponent = true;
-
- if (d->isComponentComplete)
- d->load();
+ if (!d->component->isLoading()) {
+ d->_q_sourceLoaded();
+ } else {
+ connect(d->component, SIGNAL(statusChanged(QDeclarativeComponent::Status)),
+ this, SLOT(_q_sourceLoaded()));
+ connect(d->component, SIGNAL(progressChanged(qreal)),
+ this, SIGNAL(progressChanged()));
+ emit statusChanged();
+ emit progressChanged();
+ emit sourceChanged();
+ emit itemChanged();
+ }
}
/*!
@@ -316,7 +324,6 @@ void QDeclarativeLoader::setSourceComponent(QDeclarativeComponent *comp)
d->component = comp;
d->ownComponent = false;
-
if (!d->component) {
emit sourceChanged();
emit statusChanged();
@@ -325,8 +332,18 @@ void QDeclarativeLoader::setSourceComponent(QDeclarativeComponent *comp)
return;
}
- if (d->isComponentComplete)
- d->load();
+ if (!d->component->isLoading()) {
+ d->_q_sourceLoaded();
+ } else {
+ connect(d->component, SIGNAL(statusChanged(QDeclarativeComponent::Status)),
+ this, SLOT(_q_sourceLoaded()));
+ connect(d->component, SIGNAL(progressChanged(qreal)),
+ this, SIGNAL(progressChanged()));
+ emit progressChanged();
+ emit sourceChanged();
+ emit statusChanged();
+ emit itemChanged();
+ }
}
void QDeclarativeLoader::resetSourceComponent()
@@ -334,27 +351,6 @@ void QDeclarativeLoader::resetSourceComponent()
setSourceComponent(0);
}
-void QDeclarativeLoaderPrivate::load()
-{
- Q_Q(QDeclarativeLoader);
-
- if (!isComponentComplete || !component)
- return;
-
- if (!component->isLoading()) {
- _q_sourceLoaded();
- } else {
- QObject::connect(component, SIGNAL(statusChanged(QDeclarativeComponent::Status)),
- q, SLOT(_q_sourceLoaded()));
- QObject::connect(component, SIGNAL(progressChanged(qreal)),
- q, SIGNAL(progressChanged()));
- emit q->statusChanged();
- emit q->progressChanged();
- emit q->sourceChanged();
- emit q->itemChanged();
- }
-}
-
void QDeclarativeLoaderPrivate::_q_sourceLoaded()
{
Q_Q(QDeclarativeLoader);
@@ -469,11 +465,9 @@ QDeclarativeLoader::Status QDeclarativeLoader::status() const
void QDeclarativeLoader::componentComplete()
{
- Q_D(QDeclarativeLoader);
-
QDeclarativeItem::componentComplete();
- d->isComponentComplete = true;
- d->load();
+ if (status() == Ready)
+ emit loaded();
}
diff --git a/src/declarative/graphicsitems/qdeclarativeloader_p_p.h b/src/declarative/graphicsitems/qdeclarativeloader_p_p.h
index 81ca66dc0e..45ab595a4f 100644
--- a/src/declarative/graphicsitems/qdeclarativeloader_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeloader_p_p.h
@@ -72,13 +72,11 @@ public:
void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry);
void clear();
void initResize();
- void load();
QUrl source;
QGraphicsObject *item;
QDeclarativeComponent *component;
bool ownComponent : 1;
- bool isComponentComplete : 1;
void _q_sourceLoaded();
void _q_updateSize(bool loaderGeometryChanged = true);
diff --git a/src/declarative/graphicsitems/qdeclarativescalegrid.cpp b/src/declarative/graphicsitems/qdeclarativescalegrid.cpp
index 804e91d2d4..3ad0da61b6 100644
--- a/src/declarative/graphicsitems/qdeclarativescalegrid.cpp
+++ b/src/declarative/graphicsitems/qdeclarativescalegrid.cpp
@@ -136,12 +136,12 @@ QDeclarativeGridScaledImage::QDeclarativeGridScaledImage(QIODevice *data)
if (line.isEmpty() || line.startsWith(QLatin1Char('#')))
continue;
- QStringList list = line.split(QLatin1Char(':'));
- if (list.count() != 2)
+ int colonId = line.indexOf(QLatin1Char(':'));
+ if (colonId <= 0)
return;
-
- list[0] = list[0].trimmed();
- list[1] = list[1].trimmed();
+ QStringList list;
+ list.append(line.left(colonId).trimmed());
+ list.append(line.mid(colonId+1).trimmed());
if (list[0] == QLatin1String("border.left"))
l = list[1].toInt();
diff --git a/src/declarative/graphicsitems/qdeclarativetext.cpp b/src/declarative/graphicsitems/qdeclarativetext.cpp
index 2f3c8e5abc..640965cece 100644
--- a/src/declarative/graphicsitems/qdeclarativetext.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetext.cpp
@@ -736,19 +736,28 @@ QDeclarativeText::~QDeclarativeText()
QFont QDeclarativeText::font() const
{
Q_D(const QDeclarativeText);
- return d->font;
+ return d->sourceFont;
}
void QDeclarativeText::setFont(const QFont &font)
{
Q_D(QDeclarativeText);
- if (d->font == font)
+ if (d->sourceFont == font)
return;
+ d->sourceFont = font;
+ QFont oldFont = d->font;
d->font = font;
- d->updateLayout();
+ if (d->font.pointSizeF() != -1) {
+ // 0.5pt resolution
+ qreal size = qRound(d->font.pointSizeF()*2.0);
+ d->font.setPointSizeF(size/2.0);
+ }
+
+ if (oldFont != d->font)
+ d->updateLayout();
- emit fontChanged(d->font);
+ emit fontChanged(d->sourceFont);
}
/*!
diff --git a/src/declarative/graphicsitems/qdeclarativetext_p_p.h b/src/declarative/graphicsitems/qdeclarativetext_p_p.h
index 67f2289268..e749bc9c6e 100644
--- a/src/declarative/graphicsitems/qdeclarativetext_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetext_p_p.h
@@ -79,6 +79,7 @@ public:
QString text;
QFont font;
+ QFont sourceFont;
QColor color;
QDeclarativeText::TextStyle style;
QColor styleColor;
diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp
index 675f8d9eb1..cb62a2cad4 100644
--- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp
@@ -326,22 +326,35 @@ void QDeclarativeTextEdit::setTextFormat(TextFormat format)
QFont QDeclarativeTextEdit::font() const
{
Q_D(const QDeclarativeTextEdit);
- return d->font;
+ return d->sourceFont;
}
void QDeclarativeTextEdit::setFont(const QFont &font)
{
Q_D(QDeclarativeTextEdit);
+ if (d->sourceFont == font)
+ return;
+
+ d->sourceFont = font;
+ QFont oldFont = d->font;
d->font = font;
+ if (d->font.pointSizeF() != -1) {
+ // 0.5pt resolution
+ qreal size = qRound(d->font.pointSizeF()*2.0);
+ d->font.setPointSizeF(size/2.0);
+ }
- clearCache();
- d->document->setDefaultFont(d->font);
- if(d->cursor){
- d->cursor->setHeight(QFontMetrics(d->font).height());
- moveCursorDelegate();
+ if (oldFont != d->font) {
+ clearCache();
+ d->document->setDefaultFont(d->font);
+ if(d->cursor){
+ d->cursor->setHeight(QFontMetrics(d->font).height());
+ moveCursorDelegate();
+ }
+ updateSize();
+ update();
}
- updateSize();
- update();
+ emit fontChanged(d->sourceFont);
}
/*!
@@ -1352,8 +1365,12 @@ void QDeclarativeTextEdit::updateSize()
int dy = height();
// ### assumes that if the width is set, the text will fill to edges
// ### (unless wrap is false, then clipping will occur)
- if (widthValid() && d->document->textWidth() != width())
- d->document->setTextWidth(width());
+ if (widthValid()) {
+ if (d->document->textWidth() != width())
+ d->document->setTextWidth(width());
+ } else {
+ d->document->setTextWidth(-1);
+ }
dy -= (int)d->document->size().height();
int nyoff;
diff --git a/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h b/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h
index 68a9cc8ffd..3a4554170d 100644
--- a/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h
@@ -92,6 +92,7 @@ public:
QString text;
QFont font;
+ QFont sourceFont;
QColor color;
QColor selectionColor;
QColor selectedTextColor;
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
index 57a21778e7..ef3404f78e 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
@@ -213,24 +213,33 @@ void QDeclarativeTextInput::setText(const QString &s)
QFont QDeclarativeTextInput::font() const
{
Q_D(const QDeclarativeTextInput);
- return d->font;
+ return d->sourceFont;
}
void QDeclarativeTextInput::setFont(const QFont &font)
{
Q_D(QDeclarativeTextInput);
- if (d->font == font)
+ if (d->sourceFont == font)
return;
+ d->sourceFont = font;
+ QFont oldFont = d->font;
d->font = font;
+ if (d->font.pointSizeF() != -1) {
+ // 0.5pt resolution
+ qreal size = qRound(d->font.pointSizeF()*2.0);
+ d->font.setPointSizeF(size/2.0);
+ }
- d->control->setFont(d->font);
- if(d->cursorItem){
- d->cursorItem->setHeight(QFontMetrics(d->font).height());
- moveCursor();
+ if (oldFont != d->font) {
+ d->control->setFont(d->font);
+ if(d->cursorItem){
+ d->cursorItem->setHeight(QFontMetrics(d->font).height());
+ moveCursor();
+ }
+ updateSize();
}
- updateSize();
- emit fontChanged(d->font);
+ emit fontChanged(d->sourceFont);
}
/*!
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h
index 18e9c81de5..16827b32ac 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h
@@ -107,6 +107,7 @@ public:
QLineControl* control;
QFont font;
+ QFont sourceFont;
QColor color;
QColor selectionColor;
QColor selectedTextColor;
diff --git a/src/declarative/qml/parser/qdeclarativejslexer.cpp b/src/declarative/qml/parser/qdeclarativejslexer.cpp
index af955a476f..4dfef45ed5 100644
--- a/src/declarative/qml/parser/qdeclarativejslexer.cpp
+++ b/src/declarative/qml/parser/qdeclarativejslexer.cpp
@@ -619,7 +619,7 @@ int Lexer::lex()
} else {
setDone(Bad);
err = IllegalEscapeSequence;
- errmsg = QCoreApplication::translate("QDeclarativeParser", "Illegal escape squence");
+ errmsg = QCoreApplication::translate("QDeclarativeParser", "Illegal escape sequence");
}
} else if (current == 'x')
state = InHexEscape;
diff --git a/src/gui/graphicsview/qgridlayoutengine.cpp b/src/gui/graphicsview/qgridlayoutengine.cpp
index 41ede20276..375c7234e9 100644
--- a/src/gui/graphicsview/qgridlayoutengine.cpp
+++ b/src/gui/graphicsview/qgridlayoutengine.cpp
@@ -194,7 +194,8 @@ void QGridLayoutRowData::distributeMultiCells(const QGridLayoutRowInfo &rowInfo)
for (int k = 0; k < span; ++k) {
boxes[start + k].combine(extras[k]);
- stretches[start + k] = qMax(stretches[start + k], stretch);
+ if (stretch != 0)
+ stretches[start + k] = qMax(stretches[start + k], stretch);
}
}
multiCellMap.clear();
@@ -1481,7 +1482,7 @@ void QGridLayoutEngine::fillRowData(QGridLayoutRowData *rowData, const QLayoutSt
QGridLayoutBox *box;
if (effectiveRowSpan == 1) {
box = &rowBox;
- if (!userRowStretch)
+ if (!userRowStretch && itemStretch != 0)
rowStretch = qMax(rowStretch, itemStretch);
} else {
QGridLayoutMultiCellData &multiCell =
diff --git a/src/gui/image/qgifhandler.cpp b/src/gui/image/qgifhandler.cpp
index 4dd4743f78..7cb7373b44 100644
--- a/src/gui/image/qgifhandler.cpp
+++ b/src/gui/image/qgifhandler.cpp
@@ -1046,7 +1046,7 @@ QGifHandler::QGifHandler()
{
gifFormat = new QGIFFormat;
nextDelay = 100;
- loopCnt = 1;
+ loopCnt = -1;
frameNumber = -1;
scanIsCached = false;
}
@@ -1192,7 +1192,13 @@ int QGifHandler::loopCount() const
QGIFFormat::scan(device(), &imageSizes, &loopCnt);
scanIsCached = true;
}
- return loopCnt-1; // In GIF, loop count is iteration count, so subtract one
+
+ if (loopCnt == 0)
+ return -1;
+ else if (loopCnt == -1)
+ return 0;
+ else
+ return loopCnt;
}
int QGifHandler::currentImageNumber() const
diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
index ff199b14e6..1bef64de87 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
+++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
@@ -706,6 +706,7 @@ void QCoeFepInputContext::CancelFepInlineEdit()
QInputMethodEvent event(QLatin1String(""), attributes);
event.setCommitString(QLatin1String(""), 0, 0);
m_preeditString.clear();
+ m_inlinePosition = 0;
sendEvent(event);
}
@@ -853,6 +854,7 @@ void QCoeFepInputContext::commitCurrentString(bool cancelFepTransaction)
QInputMethodEvent event(QLatin1String(""), attributes);
event.setCommitString(m_preeditString, 0, 0);
m_preeditString.clear();
+ m_inlinePosition = 0;
sendEvent(event);
m_hasTempPreeditString = false;
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index 3a70dd5ade..554baa2888 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -1616,7 +1616,7 @@ void qt_init(QApplicationPrivate * /* priv */, int)
qRegisterMetaType<WId>("WId");
}
-extern void qt_cleanup_symbianFontDatabaseExtras(); // qfontdatabase_s60.cpp
+extern void qt_cleanup_symbianFontDatabase(); // qfontdatabase_s60.cpp
/*****************************************************************************
qt_cleanup() - cleans up when the application is finished
@@ -1633,7 +1633,7 @@ void qt_cleanup()
QFontCache::cleanup(); // Has to happen now, since QFontEngineS60 has FBS handles
QPixmapCache::clear(); // Has to happen now, since QS60PixmapData has FBS handles
- qt_cleanup_symbianFontDatabaseExtras();
+ qt_cleanup_symbianFontDatabase();
// S60 structure and window server session are freed in eventdispatcher destructor as they are needed there
// It's important that this happens here, before the event dispatcher gets
@@ -2019,6 +2019,9 @@ int QApplicationPrivate::symbianProcessWsEvent(const QSymbianEvent *symbianEvent
S60->wsSession().SetPointerCursorMode(EPointerCursorNormal);
}
#endif
+#ifdef QT_SOFTKEYS_ENABLED
+ QSoftKeyManager::updateSoftKeys();
+#endif
break;
case EEventFocusLost:
if (callSymbianEventFilters(symbianEvent))
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 9928dea781..59042963b0 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -43,7 +43,9 @@
#include <private/qpaintengine_raster_p.h>
#include <private/qpainter_p.h>
#include <private/qdrawhelper_x86_p.h>
+#ifdef QT_HAVE_ARM_SIMD
#include <private/qdrawhelper_arm_simd_p.h>
+#endif
#include <private/qdrawhelper_neon_p.h>
#include <private/qmath_p.h>
#include <qmath.h>
diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp
index c5e95f2e29..ecc2539f85 100644
--- a/src/gui/styles/qs60style.cpp
+++ b/src/gui/styles/qs60style.cpp
@@ -96,7 +96,8 @@ const layoutHeader QS60StylePrivate::m_layoutHeaders[] = {
{320,240,1,19,"QVGA Portrait"},
{360,640,1,19,"NHD Landscape"},
{640,360,1,19,"NHD Portrait"},
-{352,800,1,12,"E90 Landscape"}
+{352,800,1,12,"E90 Landscape"},
+{480,640,1,19,"VGA Landscape"}
// *** End of generated data ***
};
const int QS60StylePrivate::m_numberOfLayouts =
@@ -108,7 +109,8 @@ const short QS60StylePrivate::data[][MAX_PIXELMETRICS] = {
{5,0,-909,0,0,1,0,2,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,28,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,3,3,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1,106},
{7,0,-909,0,0,2,0,5,-1,25,69,46,37,37,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,44,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,13,3,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1,135},
{7,0,-909,0,0,2,0,5,-1,25,68,46,37,37,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,52,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,12,3,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1,135},
-{7,0,-909,0,0,2,0,2,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,30,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1,106}
+{7,0,-909,0,0,2,0,2,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,30,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1,106},
+{9,0,-909,0,0,2,0,5,-1,34,99,76,51,51,25,352,-909,-909,-909,29,25,7,0,0,43,34,42,76,7,7,2,-909,-909,0,9,14,0,23,39,30,30,37,37,9,391,40,0,-909,-909,-909,-909,0,0,29,2,-909,0,0,-909,29,-909,-909,-909,-909,115,37,96,48,96,19,19,9,1,25,-909,9,101,24,9,0,7,7,7,16,7,7,-909,3,-909,-909,-909,-909,9,9,3,1,184}
// *** End of generated data ***
};
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 20c72dde6b..8e92b1a23f 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -646,6 +646,10 @@ public:
{ }
~QFontDatabasePrivate() {
free();
+#if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
+ if (symbianExtras)
+ delete symbianExtras;
+#endif
}
QtFontFamily *family(const QString &f, bool = false);
void free() {
@@ -654,12 +658,6 @@ public:
::free(families);
families = 0;
count = 0;
-#if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
- if (symbianExtras) {
- delete symbianExtras;
- symbianExtras = 0;
- }
-#endif
// don't clear the memory fonts!
}
@@ -678,6 +676,10 @@ public:
QVector<FONTSIGNATURE> signatures;
#elif defined(Q_WS_MAC)
ATSFontContainerRef handle;
+#elif defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
+ QString temporaryFileName;
+ TInt screenDeviceFontFileId;
+ TUid fontStoreFontFileUid;
#endif
QStringList families;
};
@@ -704,7 +706,7 @@ public:
#if defined(Q_WS_QWS)
QDataStream *stream;
#elif defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
- const QSymbianFontDatabaseExtras *symbianExtras;
+ QSymbianFontDatabaseExtras *symbianExtras;
#endif
#if defined(Q_WS_QWS) || defined(Q_WS_QPA)
QStringList fallbackFamilies;
@@ -2573,6 +2575,8 @@ bool QFontDatabasePrivate::isApplicationFont(const QString &fileName)
\note Adding application fonts on Unix/X11 platforms without fontconfig is
currently not supported.
+ \note On Symbian, the font family names get truncated to a length of 20 characters.
+
\sa addApplicationFontFromData(), applicationFontFamilies(), removeApplicationFont()
*/
int QFontDatabase::addApplicationFont(const QString &fileName)
@@ -2603,6 +2607,8 @@ int QFontDatabase::addApplicationFont(const QString &fileName)
\bold{Note:} Adding application fonts on Unix/X11 platforms without fontconfig is
currently not supported.
+ \note On Symbian, the font family names get truncated to a length of 20 characters.
+
\sa addApplicationFont(), applicationFontFamilies(), removeApplicationFont()
*/
int QFontDatabase::addApplicationFontFromData(const QByteArray &fontData)
diff --git a/src/gui/text/qfontdatabase_s60.cpp b/src/gui/text/qfontdatabase_s60.cpp
index 6ba035e91f..ad6718904f 100644
--- a/src/gui/text/qfontdatabase_s60.cpp
+++ b/src/gui/text/qfontdatabase_s60.cpp
@@ -45,6 +45,8 @@
#include "qfontengine_s60_p.h"
#include "qabstractfileengine.h"
#include "qdesktopservices.h"
+#include "qtemporaryfile.h"
+#include "qtextcodec.h"
#include <private/qpixmap_s60_p.h>
#include <private/qt_s60_p.h>
#include "qendian.h"
@@ -114,7 +116,14 @@ public:
~QSymbianFontDatabaseExtrasImplementation();
const QSymbianTypeFaceExtras *extras(const QString &typeface, bool bold, bool italic) const;
- void addFontFileToFontStore(const QFileInfo &fontFileInfo);
+ void removeAppFontData(QFontDatabasePrivate::ApplicationFont *fnt);
+ static inline bool appFontLimitReached();
+ TUid addFontFileToFontStore(const QFileInfo &fontFileInfo);
+ static void clear();
+
+ static inline QString tempAppFontFolder();
+ static const QString appFontMarkerPrefix;
+ static QString appFontMarker(); // 'qaf<shortUid[+shortPid]>'
struct CFontFromFontStoreReleaser {
static inline void cleanup(CFont *font)
@@ -144,8 +153,75 @@ public:
mutable QList<const QSymbianTypeFaceExtras *> m_extras;
mutable QHash<QString, const QSymbianTypeFaceExtras *> m_extrasHash;
+ mutable QSet<QString> m_applicationFontFamilies;
};
+const QString QSymbianFontDatabaseExtrasImplementation::appFontMarkerPrefix =
+ QLatin1String("Q");
+
+inline QString QSymbianFontDatabaseExtrasImplementation::tempAppFontFolder()
+{
+ return QDir::toNativeSeparators(QDir::tempPath()) + QLatin1Char('\\');
+}
+
+QString QSymbianFontDatabaseExtrasImplementation::appFontMarker()
+{
+ static QString result;
+ if (result.isEmpty()) {
+ quint16 id = 0;
+ if (QSymbianTypeFaceExtras::symbianFontTableApiAvailable()) {
+ // We are allowed to load app fonts even from previous, crashed runs
+ // of this application, since we can access the font tables.
+ const quint32 uid = RProcess().Type().MostDerived().iUid;
+ id = static_cast<quint16>(uid + (uid >> 16));
+ } else {
+ // If no font table Api is available, we must not even load a font
+ // from a previous (crashed) run of this application. Reason: we
+ // won't get the font tables, they are not in the CFontStore.
+ // So, we use the pid, for more uniqueness.
+ id = static_cast<quint16>(RProcess().Id().Id());
+ }
+ result = appFontMarkerPrefix + QString::fromLatin1("%1").arg(id & 0x7fff, 3, 32, QLatin1Char('0'));
+ Q_ASSERT(appFontMarkerPrefix.length() == 1 && result.length() == 4);
+ }
+ return result;
+}
+
+static inline bool qt_symbian_fontNameHasAppFontMarker(const QString &fontName)
+{
+ const int idLength = 3; // Keep in sync with id length in appFontMarker().
+ const QString &prefix = QSymbianFontDatabaseExtrasImplementation::appFontMarkerPrefix;
+ if (fontName.length() < prefix.length() + idLength
+ || fontName.mid(fontName.length() - idLength - prefix.length(), prefix.length()) != prefix)
+ return false;
+ // Testing if the the id is base32 data
+ for (int i = fontName.length() - idLength; i < fontName.length(); ++i) {
+ const QChar &c = fontName.at(i);
+ if (!(c >= QLatin1Char('0') && c <= QLatin1Char('9')
+ || c >= QLatin1Char('a') && c <= QLatin1Char('v')))
+ return false;
+ }
+ return true;
+}
+
+// If fontName is an application font of this app, prepend the app font marker
+QString qt_symbian_fontNameWithAppFontMarker(const QString &fontName)
+{
+ QFontDatabasePrivate *db = privateDb();
+ Q_ASSERT(db);
+ const QSymbianFontDatabaseExtrasImplementation *dbExtras =
+ static_cast<const QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras);
+ return dbExtras->m_applicationFontFamilies.contains(fontName) ?
+ fontName + QSymbianFontDatabaseExtrasImplementation::appFontMarker()
+ : fontName;
+}
+
+static inline QString qt_symbian_appFontNameWithoutMarker(const QString &markedFontName)
+{
+ return markedFontName.left(markedFontName.length()
+ - QSymbianFontDatabaseExtrasImplementation::appFontMarker().length());
+}
+
QSymbianFontDatabaseExtrasImplementation::QSymbianFontDatabaseExtrasImplementation()
{
if (!QSymbianTypeFaceExtras::symbianFontTableApiAvailable()) {
@@ -170,10 +246,13 @@ QSymbianFontDatabaseExtrasImplementation::QSymbianFontDatabaseExtrasImplementati
}
}
-void qt_cleanup_symbianFontDatabaseExtras()
+void QSymbianFontDatabaseExtrasImplementation::clear()
{
+ QFontDatabasePrivate *db = privateDb();
+ if (!db)
+ return;
const QSymbianFontDatabaseExtrasImplementation *dbExtras =
- static_cast<const QSymbianFontDatabaseExtrasImplementation*>(privateDb()->symbianExtras);
+ static_cast<const QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras);
if (!dbExtras)
return; // initializeDb() has never been called
if (QSymbianTypeFaceExtras::symbianFontTableApiAvailable()) {
@@ -189,9 +268,32 @@ void qt_cleanup_symbianFontDatabaseExtras()
dbExtras->m_extrasHash.clear();
}
+void qt_cleanup_symbianFontDatabase()
+{
+ QFontDatabasePrivate *db = privateDb();
+ if (!db)
+ return;
+
+ QSymbianFontDatabaseExtrasImplementation::clear();
+
+ if (!db->applicationFonts.isEmpty()) {
+ QFontDatabase::removeAllApplicationFonts();
+ // We remove the left over temporary font files of Qt application.
+ // Active fonts are undeletable since the font server holds a handle
+ // on them, so we do not need to worry to delete other running
+ // applications' fonts.
+ const QDir dir(QSymbianFontDatabaseExtrasImplementation::tempAppFontFolder());
+ const QStringList filter(
+ QSymbianFontDatabaseExtrasImplementation::appFontMarkerPrefix + QLatin1String("*.ttf"));
+ foreach (const QFileInfo &ttfFile, dir.entryInfoList(filter))
+ QFile(ttfFile.absoluteFilePath()).remove();
+ db->applicationFonts.clear();
+ }
+}
+
QSymbianFontDatabaseExtrasImplementation::~QSymbianFontDatabaseExtrasImplementation()
{
- qt_cleanup_symbianFontDatabaseExtras();
+ qt_cleanup_symbianFontDatabase();
if (!QSymbianTypeFaceExtras::symbianFontTableApiAvailable()) {
delete m_store;
m_heap->Close();
@@ -215,9 +317,10 @@ COpenFont* OpenFontFromBitmapFont(const CBitmapFont* aBitmapFont)
}
#endif // FNTSTORE_H_INLINES_SUPPORT_FMM
-const QSymbianTypeFaceExtras *QSymbianFontDatabaseExtrasImplementation::extras(const QString &typeface,
+const QSymbianTypeFaceExtras *QSymbianFontDatabaseExtrasImplementation::extras(const QString &aTypeface,
bool bold, bool italic) const
{
+ const QString typeface = qt_symbian_fontNameWithAppFontMarker(aTypeface);
const QString searchKey = typeface + QString::number(int(bold)) + QString::number(int(italic));
if (!m_extrasHash.contains(searchKey)) {
TFontSpec searchSpec(qt_QString2TPtrC(typeface), 1);
@@ -263,12 +366,42 @@ const QSymbianTypeFaceExtras *QSymbianFontDatabaseExtrasImplementation::extras(c
return m_extrasHash.value(searchKey);
}
-void QSymbianFontDatabaseExtrasImplementation::addFontFileToFontStore(const QFileInfo &fontFileInfo)
+void QSymbianFontDatabaseExtrasImplementation::removeAppFontData(
+ QFontDatabasePrivate::ApplicationFont *fnt)
+{
+ clear();
+ if (!QSymbianTypeFaceExtras::symbianFontTableApiAvailable()
+ && fnt->fontStoreFontFileUid.iUid != 0)
+ m_store->RemoveFile(fnt->fontStoreFontFileUid);
+ if (!fnt->families.isEmpty())
+ m_applicationFontFamilies.remove(fnt->families.first());
+ if (fnt->screenDeviceFontFileId != 0)
+ S60->screenDevice()->RemoveFile(fnt->screenDeviceFontFileId);
+ QFile::remove(fnt->temporaryFileName);
+ *fnt = QFontDatabasePrivate::ApplicationFont();
+}
+
+bool QSymbianFontDatabaseExtrasImplementation::appFontLimitReached()
+{
+ QFontDatabasePrivate *db = privateDb();
+ if (!db)
+ return false;
+ const int maxAppFonts = 5;
+ int registeredAppFonts = 0;
+ foreach (const QFontDatabasePrivate::ApplicationFont &appFont, db->applicationFonts)
+ if (!appFont.families.isEmpty() && ++registeredAppFonts == maxAppFonts)
+ return true;
+ return false;
+}
+
+TUid QSymbianFontDatabaseExtrasImplementation::addFontFileToFontStore(const QFileInfo &fontFileInfo)
{
Q_ASSERT(!QSymbianTypeFaceExtras::symbianFontTableApiAvailable());
const QString fontFile = QDir::toNativeSeparators(fontFileInfo.absoluteFilePath());
- TPtrC fontFilePtr(qt_QString2TPtrC(fontFile));
- QT_TRAP_THROWING(m_store->AddFileL(fontFilePtr));
+ const TPtrC fontFilePtr(qt_QString2TPtrC(fontFile));
+ TUid fontUid = {0};
+ TRAP_IGNORE(fontUid = m_store->AddFileL(fontFilePtr));
+ return fontUid;
}
#else // QT_NO_FREETYPE
@@ -331,11 +464,23 @@ void QFontEngineMultiS60::loadEngine(int at)
Q_ASSERT(engines[at]);
}
-static bool addFontToScreenDevice(int screenDeviceFontIndex,
- const QSymbianFontDatabaseExtrasImplementation *dbExtras)
-{
+static bool registerScreenDeviceFont(int screenDeviceFontIndex,
+ const QSymbianFontDatabaseExtrasImplementation *dbExtras)
+{
TTypefaceSupport typefaceSupport;
S60->screenDevice()->TypefaceSupport(typefaceSupport, screenDeviceFontIndex);
+
+ QString familyName((const QChar*)typefaceSupport.iTypeface.iName.Ptr(), typefaceSupport.iTypeface.iName.Length());
+ if (qt_symbian_fontNameHasAppFontMarker(familyName)) {
+ const QString &marker = QSymbianFontDatabaseExtrasImplementation::appFontMarker();
+ if (familyName.endsWith(marker)) {
+ familyName = qt_symbian_appFontNameWithoutMarker(familyName);
+ dbExtras->m_applicationFontFamilies.insert(familyName);
+ } else {
+ return false; // This was somebody else's application font. Skip it.
+ }
+ }
+
CFont *font; // We have to get a font instance in order to know all the details
TFontSpec fontSpec(typefaceSupport.iTypeface.iName, 11);
if (S60->screenDevice()->GetNearestFontInPixels(font, fontSpec) != KErrNone)
@@ -351,7 +496,6 @@ static bool addFontToScreenDevice(int screenDeviceFontIndex,
styleKey.style = faceAttrib.IsItalic()?QFont::StyleItalic:QFont::StyleNormal;
styleKey.weight = faceAttrib.IsBold()?QFont::Bold:QFont::Normal;
- QString familyName((const QChar *)typefaceSupport.iTypeface.iName.Ptr(), typefaceSupport.iTypeface.iName.Length());
QtFontFamily *family = privateDb()->family(familyName, true);
family->fixedPitch = faceAttrib.IsMonoWidth();
QtFontFoundry *foundry = family->foundry(QString(), true);
@@ -398,7 +542,12 @@ static void initializeDb()
const QSymbianFontDatabaseExtrasImplementation *dbExtras =
static_cast<const QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras);
for (int i = 0; i < numTypeFaces; i++)
- addFontToScreenDevice(i, dbExtras);
+ registerScreenDeviceFont(i, dbExtras);
+
+ // We have to clear/release all CFonts, here, in case one of the fonts is
+ // an application font of another running Qt app. Otherwise the other Qt app
+ // cannot remove it's application font, anymore -> "Zombie Font".
+ QSymbianFontDatabaseExtrasImplementation::clear();
lock.relock();
@@ -421,20 +570,386 @@ static inline void load(const QString &family = QString(), int script = -1)
initializeDb();
}
+struct OffsetTable {
+ quint32 sfntVersion;
+ quint16 numTables, searchRange, entrySelector, rangeShift;
+};
+
+struct TableRecord {
+ quint32 tag, checkSum, offset, length;
+};
+
+struct NameTableHead {
+ quint16 format, count, stringOffset;
+};
+
+struct NameRecord {
+ quint16 platformID, encodingID, languageID, nameID, length, offset;
+};
+
+static quint32 ttfCalcChecksum(const char *data, quint32 bytesCount)
+{
+ quint32 result = 0;
+ const quint32 *ptr = reinterpret_cast<const quint32*>(data);
+ const quint32 *endPtr =
+ ptr + (bytesCount + sizeof(quint32) - 1) / sizeof(quint32);
+ while (ptr < endPtr) {
+ const quint32 unit32Value = *ptr++;
+ result += qFromBigEndian(unit32Value);
+ }
+ return result;
+}
+
+static inline quint32 toDWordBoundary(quint32 value)
+{
+ return (value + 3) & ~3;
+}
+
+static inline quint32 dWordPadding(quint32 value)
+{
+ return (4 - (value & 3)) & 3;
+}
+
+static inline bool ttfMarkNameTable(QByteArray &table, const QString &marker)
+{
+ const quint32 tableLength = static_cast<quint32>(table.size());
+
+ if (tableLength > 50000 // hard limit
+ || tableLength < sizeof(NameTableHead)) // corrupt name table
+ return false;
+
+ const NameTableHead *head = reinterpret_cast<const NameTableHead*>(table.constData());
+ const quint16 count = qFromBigEndian(head->count);
+ const quint16 stringOffset = qFromBigEndian(head->stringOffset);
+ if (count > 200 // hard limit
+ || stringOffset >= tableLength // corrupt name table
+ || sizeof(NameTableHead) + count * sizeof(NameRecord) >= tableLength) // corrupt name table
+ return false;
+
+ QTextEncoder encoder(QTextCodec::codecForName("UTF-16BE"), QTextCodec::IgnoreHeader);
+ const QByteArray markerUtf16BE = encoder.fromUnicode(marker);
+ const QByteArray markerAscii = marker.toAscii();
+
+ QByteArray markedTable;
+ markedTable.reserve(tableLength + marker.length() * 20); // Original size plus some extra
+ markedTable.append(table, stringOffset);
+ QByteArray markedStrings;
+ quint32 stringDataCount = stringOffset;
+ for (quint16 i = 0; i < count; ++i) {
+ const quint32 nameRecordOffset = sizeof(NameTableHead) + sizeof(NameRecord) * i;
+ NameRecord *nameRecord =
+ reinterpret_cast<NameRecord*>(markedTable.data() + nameRecordOffset);
+ const quint16 nameID = qFromBigEndian(nameRecord->nameID);
+ const quint16 platformID = qFromBigEndian(nameRecord->platformID);
+ const quint16 encodingID = qFromBigEndian(nameRecord->encodingID);
+ const quint16 offset = qFromBigEndian(nameRecord->offset);
+ const quint16 length = qFromBigEndian(nameRecord->length);
+ stringDataCount += length;
+ if (stringDataCount > 80000 // hard limit. String data may be > name table size. Multiple records can reference the same string.
+ || static_cast<quint32>(stringOffset + offset + length) > tableLength) // String outside bounds
+ return false;
+ const bool needsMarker =
+ nameID == 1 || nameID == 3 || nameID == 4 || nameID == 16 || nameID == 21;
+ const bool isUnicode =
+ platformID == 0 || platformID == 3 && encodingID == 1;
+ const QByteArray originalString =
+ QByteArray::fromRawData(table.constData() + stringOffset + offset, length);
+ QByteArray markedString;
+ if (needsMarker) {
+ const int maxBytesLength = (KMaxTypefaceNameLength - marker.length()) * (isUnicode ? 2 : 1);
+ markedString = originalString.left(maxBytesLength) + (isUnicode ? markerUtf16BE : markerAscii);
+ } else {
+ markedString = originalString;
+ }
+ nameRecord->offset = qToBigEndian(static_cast<quint16>(markedStrings.length()));
+ nameRecord->length = qToBigEndian(static_cast<quint16>(markedString.length()));
+ markedStrings.append(markedString);
+ }
+ markedTable.append(markedStrings);
+ table = markedTable;
+ return true;
+}
+
+const quint32 ttfMaxFileSize = 3500000;
+
+static inline bool ttfMarkAppFont(QByteArray &ttf, const QString &marker)
+{
+ const quint32 ttfChecksumNumber = 0xb1b0afba;
+ const quint32 alignment = 4;
+ const quint32 ttfLength = static_cast<quint32>(ttf.size());
+ if (ttfLength > ttfMaxFileSize // hard limit
+ || ttfLength % alignment != 0 // ttf sizes are always factors of 4
+ || ttfLength <= sizeof(OffsetTable) // ttf too short
+ || ttfCalcChecksum(ttf.constData(), ttf.size()) != ttfChecksumNumber) // ttf checksum is invalid
+ return false;
+
+ const OffsetTable *offsetTable = reinterpret_cast<const OffsetTable*>(ttf.constData());
+ const quint16 numTables = qFromBigEndian(offsetTable->numTables);
+ const quint32 recordsLength =
+ toDWordBoundary(sizeof(OffsetTable) + numTables * sizeof(TableRecord));
+ if (numTables > 30 // hard limit
+ || recordsLength + numTables * alignment > ttfLength) // Corrupt ttf. Tables would not fit, even if empty.
+ return false;
+
+ QByteArray markedTtf;
+ markedTtf.reserve(ttfLength + marker.length() * 20); // Original size plus some extra
+ markedTtf.append(ttf.constData(), recordsLength);
+
+ const quint32 ttfCheckSumAdjustmentOffset = 8; // Offset from the start of 'head'
+ int indexOfHeadTable = -1;
+ quint32 ttfDataSize = recordsLength;
+ typedef QPair<quint32, quint32> Range;
+ QList<Range> memoryRanges;
+ memoryRanges.reserve(numTables);
+ for (int i = 0; i < numTables; ++i) {
+ TableRecord *tableRecord =
+ reinterpret_cast<TableRecord*>(markedTtf.data() + sizeof(OffsetTable) + i * sizeof(TableRecord));
+ const quint32 offset = qFromBigEndian(tableRecord->offset);
+ const quint32 length = qFromBigEndian(tableRecord->length);
+ const quint32 lengthAligned = toDWordBoundary(length);
+ ttfDataSize += lengthAligned;
+ if (offset < recordsLength // must not intersect ttf header/records
+ || offset % alignment != 0 // must be aligned
+ || offset > ttfLength - alignment // table out of bounds
+ || offset + lengthAligned > ttfLength // table out of bounds
+ || ttfDataSize > ttfLength) // tables would not fit into the ttf
+ return false;
+
+ foreach (const Range &range, memoryRanges)
+ if (offset < range.first + range.second && offset + lengthAligned > range.first)
+ return false; // Overlaps with another table
+ memoryRanges.append(Range(offset, lengthAligned));
+
+ quint32 checkSum = qFromBigEndian(tableRecord->checkSum);
+ if (tableRecord->tag == qToBigEndian('head')) {
+ if (length < ttfCheckSumAdjustmentOffset + sizeof(quint32))
+ return false; // Invalid 'head' table
+ const quint32 *checkSumAdjustmentTag =
+ reinterpret_cast<const quint32*>(ttf.constData() + offset + ttfCheckSumAdjustmentOffset);
+ const quint32 checkSumAdjustment = qFromBigEndian(*checkSumAdjustmentTag);
+ checkSum += checkSumAdjustment;
+ indexOfHeadTable = i; // For the ttf checksum re-calculation, later
+ }
+ if (checkSum != ttfCalcChecksum(ttf.constData() + offset, length))
+ return false; // Table checksum is invalid
+
+ bool updateTableChecksum = false;
+ QByteArray table;
+ if (tableRecord->tag == qToBigEndian('name')) {
+ table = QByteArray(ttf.constData() + offset, length);
+ if (!ttfMarkNameTable(table, marker))
+ return false; // Name table was not markable.
+ updateTableChecksum = true;
+ } else {
+ table = QByteArray::fromRawData(ttf.constData() + offset, length);
+ }
+
+ tableRecord->offset = qToBigEndian(markedTtf.size());
+ tableRecord->length = qToBigEndian(table.size());
+ markedTtf.append(table);
+ markedTtf.append(QByteArray(dWordPadding(table.size()), 0)); // 0-padding
+ if (updateTableChecksum) {
+ TableRecord *tableRecord = // Need to recalculate, since markedTtf changed
+ reinterpret_cast<TableRecord*>(markedTtf.data() + sizeof(OffsetTable) + i * sizeof(TableRecord));
+ const quint32 offset = qFromBigEndian(tableRecord->offset);
+ const quint32 length = qFromBigEndian(tableRecord->length);
+ tableRecord->checkSum = qToBigEndian(ttfCalcChecksum(markedTtf.constData() + offset, length));
+ }
+ }
+ if (indexOfHeadTable == -1 // 'head' table is mandatory
+ || ttfDataSize != ttfLength) // We do not allow ttf data "holes". Neither does Symbian.
+ return false;
+ TableRecord *headRecord =
+ reinterpret_cast<TableRecord*>(markedTtf.data() + sizeof(OffsetTable) + indexOfHeadTable * sizeof(TableRecord));
+ quint32 *checkSumAdjustmentTag =
+ reinterpret_cast<quint32*>(markedTtf.data() + qFromBigEndian(headRecord->offset) + ttfCheckSumAdjustmentOffset);
+ *checkSumAdjustmentTag = 0;
+ const quint32 ttfChecksum = ttfCalcChecksum(markedTtf.constData(), markedTtf.count());
+ *checkSumAdjustmentTag = qToBigEndian(ttfChecksumNumber - ttfChecksum);
+ ttf = markedTtf;
+ return true;
+}
+
+static inline bool ttfCanSymbianLoadFont(const QByteArray &data, const QString &fileName)
+{
+ bool result = false;
+ QString ttfFileName;
+ QFile tempFileGuard;
+ QFileInfo info(fileName);
+ if (!data.isEmpty()) {
+ QTemporaryFile tempfile(QSymbianFontDatabaseExtrasImplementation::tempAppFontFolder()
+ + QSymbianFontDatabaseExtrasImplementation::appFontMarker()
+ + QLatin1String("XXXXXX.ttf"));
+ if (!tempfile.open() || tempfile.write(data) == -1)
+ return false;
+ ttfFileName = QDir::toNativeSeparators(QFileInfo(tempfile).canonicalFilePath());
+ tempfile.setAutoRemove(false);
+ tempfile.close();
+ tempFileGuard.setFileName(ttfFileName);
+ if (!tempFileGuard.open(QIODevice::ReadOnly))
+ return false;
+ } else if (info.isFile()) {
+ ttfFileName = QDir::toNativeSeparators(info.canonicalFilePath());
+ } else {
+ return false;
+ }
+
+ CFontStore *store = 0;
+ RHeap* heap = User::ChunkHeap(NULL, 0x1000, 0x20000);
+ if (heap) {
+ QT_TRAP_THROWING(
+ CleanupClosePushL(*heap);
+ store = CFontStore::NewL(heap);
+ CleanupStack::PushL(store);
+ COpenFontRasterizer *rasterizer = COpenFontRasterizer::NewL(TUid::Uid(0x101F7F5E));
+ CleanupStack::PushL(rasterizer);
+ store->InstallRasterizerL(rasterizer);
+ CleanupStack::Pop(rasterizer);
+ TUid fontUid = {-1};
+ TRAP_IGNORE(fontUid = store->AddFileL(qt_QString2TPtrC(ttfFileName)));
+ if (fontUid.iUid != -1)
+ result = true;
+ CleanupStack::PopAndDestroy(2, heap); // heap, store
+ );
+ }
+
+ if (tempFileGuard.isOpen())
+ tempFileGuard.remove();
+
+ return result;
+}
+
static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
{
- Q_UNUSED(fnt);
+ if (QSymbianFontDatabaseExtrasImplementation::appFontLimitReached()
+ || fnt->data.size() > ttfMaxFileSize // hard limit
+ || fnt->data.isEmpty() && (!fnt->fileName.endsWith(QLatin1String(".ttf"), Qt::CaseInsensitive) // Only buffer or .ttf
+ || QFileInfo(fnt->fileName).size() > ttfMaxFileSize)) // hard limit
+ return;
+
+// Using ttfCanSymbianLoadFont() causes crashes on app destruction (Symbian^3|PR1 and lower).
+// Therefore, not using it for now, but eventually in a later version.
+// if (!ttfCanSymbianLoadFont(fnt->data, fnt->fileName))
+// return;
+
+ QFontDatabasePrivate *db = privateDb();
+ if (!db)
+ return;
+
+ if (!db->count)
+ initializeDb();
+
+ QSymbianFontDatabaseExtrasImplementation *dbExtras =
+ static_cast<QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras);
+ if (!dbExtras)
+ return;
+
+ const QString &marker = QSymbianFontDatabaseExtrasImplementation::appFontMarker();
+
+ // The QTemporaryFile object being used in the following section must be
+ // destructed before letting Symbian load the TTF file. Symbian would not
+ // load it otherwise, because QTemporaryFile will still keep some handle
+ // on it. The scope is used to reduce the life time of the QTemporaryFile.
+ // In order to prevent other processes from modifying the file between the
+ // moment where the QTemporaryFile is destructed and the file is loaded by
+ // Symbian, we have a QFile "tempFileGuard" outside the scope which opens
+ // the file in ReadOnly mode while the QTemporaryFile is still alive.
+ QFile tempFileGuard;
+ {
+ QTemporaryFile tempfile(QSymbianFontDatabaseExtrasImplementation::tempAppFontFolder()
+ + marker + QLatin1String("XXXXXX.ttf"));
+ if (!tempfile.open())
+ return;
+ const QString tempFileName = QFileInfo(tempfile).canonicalFilePath();
+ if (fnt->data.isEmpty()) {
+ QFile sourceFile(fnt->fileName);
+ if (!sourceFile.open(QIODevice::ReadOnly))
+ return;
+ fnt->data = sourceFile.readAll();
+ }
+ if (!ttfMarkAppFont(fnt->data, marker) || tempfile.write(fnt->data) == -1)
+ return;
+ tempfile.setAutoRemove(false);
+ tempfile.close(); // Tempfile still keeps a file handle, forbidding write access
+ fnt->data.clear(); // The TTF data was marked and saved. Not needed in memory, anymore.
+ tempFileGuard.setFileName(tempFileName);
+ if (!tempFileGuard.open(QIODevice::ReadOnly))
+ return;
+ fnt->temporaryFileName = tempFileName;
+ }
+
+ const QString fullFileName = QDir::toNativeSeparators(fnt->temporaryFileName);
+ QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
+ const QStringList fontsOnServerBefore = qt_symbian_fontFamiliesOnFontServer();
+ const TInt err =
+ S60->screenDevice()->AddFile(qt_QString2TPtrC(fullFileName), fnt->screenDeviceFontFileId);
+ tempFileGuard.close(); // Did its job
+ const QStringList fontsOnServerAfter = qt_symbian_fontFamiliesOnFontServer();
+ if (err == KErrNone && fontsOnServerBefore.count() < fontsOnServerAfter.count()) { // Added to screen device?
+ int fontOnServerIndex = fontsOnServerAfter.count() - 1;
+ for (int i = 0; i < fontsOnServerBefore.count(); i++) {
+ if (fontsOnServerBefore.at(i) != fontsOnServerAfter.at(i)) {
+ fontOnServerIndex = i;
+ break;
+ }
+ }
+
+ // Must remove all font engines with their CFonts, first.
+ QFontCache::instance()->clear();
+ db->free();
+ QSymbianFontDatabaseExtrasImplementation::clear();
+
+ if (!QSymbianTypeFaceExtras::symbianFontTableApiAvailable())
+ fnt->fontStoreFontFileUid = dbExtras->addFontFileToFontStore(QFileInfo(fullFileName));
+
+ const QString &appFontName = fontsOnServerAfter.at(fontOnServerIndex);
+ fnt->families.append(qt_symbian_appFontNameWithoutMarker(appFontName));
+ if (!qt_symbian_fontNameHasAppFontMarker(appFontName)
+ || !registerScreenDeviceFont(fontOnServerIndex, dbExtras))
+ dbExtras->removeAppFontData(fnt);
+ } else {
+ if (fnt->screenDeviceFontFileId > 0)
+ S60->screenDevice()->RemoveFile(fnt->screenDeviceFontFileId); // May still have the file open!
+ QFile::remove(fnt->temporaryFileName);
+ *fnt = QFontDatabasePrivate::ApplicationFont();
+ }
+ lock.relock();
}
bool QFontDatabase::removeApplicationFont(int handle)
{
- Q_UNUSED(handle);
- return false;
+ QMutexLocker locker(fontDatabaseMutex());
+
+ QFontDatabasePrivate *db = privateDb();
+ if (!db || handle < 0 || handle >= db->applicationFonts.count())
+ return false;
+ QSymbianFontDatabaseExtrasImplementation *dbExtras =
+ static_cast<QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras);
+ if (!dbExtras)
+ return false;
+
+ QFontDatabasePrivate::ApplicationFont *fnt = &db->applicationFonts[handle];
+ if (fnt->families.isEmpty())
+ return true; // Nothing to remove. Return peacefully.
+
+ // Must remove all font engines with their CFonts, first
+ QFontCache::instance()->clear();
+ db->free();
+ dbExtras->removeAppFontData(fnt);
+
+ db->invalidate(); // This will just emit 'fontDatabaseChanged()'
+ return true;
}
bool QFontDatabase::removeAllApplicationFonts()
{
- return false;
+ QMutexLocker locker(fontDatabaseMutex());
+
+ const int applicationFontsCount = privateDb()->applicationFonts.count();
+ for (int i = 0; i < applicationFontsCount; ++i)
+ if (!removeApplicationFont(i))
+ return false;
+ return true;
}
bool QFontDatabase::supportsThreadedFontRendering()
@@ -467,7 +982,7 @@ QFontEngine *QFontDatabase::findFont(int script, const QFontPrivate *d, const QF
QFontDatabasePrivate *db = privateDb();
QtFontDesc desc;
QList<int> blacklistedFamilies;
- match(script, req, req.family, QString(), -1, &desc, blacklistedFamilies);
+ match(script, key.def, key.def.family, QString(), -1, &desc, blacklistedFamilies);
if (!desc.family) // falling back to application font
desc.family = db->family(QApplication::font().defaultFamily());
Q_ASSERT(desc.family);
diff --git a/src/gui/text/qfontengine_s60.cpp b/src/gui/text/qfontengine_s60.cpp
index 4317ee6a3c..e9b54e350f 100644
--- a/src/gui/text/qfontengine_s60.cpp
+++ b/src/gui/text/qfontengine_s60.cpp
@@ -244,10 +244,13 @@ static inline unsigned int getChar(const QChar *str, int &i, const int len)
return uc;
}
+extern QString qt_symbian_fontNameWithAppFontMarker(const QString &fontName); // qfontdatabase_s60.cpp
+
CFont *QFontEngineS60::fontWithSize(qreal size) const
{
CFont *result = 0;
- TFontSpec fontSpec(qt_QString2TPtrC(QFontEngine::fontDef.family), TInt(size));
+ const QString family = qt_symbian_fontNameWithAppFontMarker(QFontEngine::fontDef.family);
+ TFontSpec fontSpec(qt_QString2TPtrC(family), TInt(size));
fontSpec.iFontStyle.SetBitmapType(EAntiAliasedGlyphBitmap);
fontSpec.iFontStyle.SetPosture(QFontEngine::fontDef.style == QFont::StyleNormal?EPostureUpright:EPostureItalic);
fontSpec.iFontStyle.SetStrokeWeight(QFontEngine::fontDef.weight > QFont::Normal?EStrokeWeightBold:EStrokeWeightNormal);
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 27b7945fde..8f050d4111 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -48,6 +48,7 @@
#include "qabstractnetworkcache.h"
#include "QtNetwork/qnetworksession.h"
+#include "QtNetwork/private/qsharednetworksession_p.h"
#include "qnetworkaccesshttpbackend_p.h"
#include "qnetworkaccessftpbackend_p.h"
@@ -1343,11 +1344,8 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co
initializeSession = false;
- if (networkSession)
- delete networkSession;
-
if (!config.isValid()) {
- networkSession = 0;
+ networkSession.clear();
online = false;
if (networkAccessible == QNetworkAccessManager::NotAccessible)
@@ -1358,18 +1356,12 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co
return;
}
- networkSession = new QNetworkSession(config, q);
+ networkSession = QSharedNetworkSessionManager::getSession(config);
- QObject::connect(networkSession, SIGNAL(opened()), q, SIGNAL(networkSessionConnected()));
- QObject::connect(networkSession, SIGNAL(closed()), q, SLOT(_q_networkSessionClosed()));
- QObject::connect(networkSession, SIGNAL(stateChanged(QNetworkSession::State)),
+ QObject::connect(networkSession.data(), SIGNAL(opened()), q, SIGNAL(networkSessionConnected()));
+ QObject::connect(networkSession.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed()));
+ QObject::connect(networkSession.data(), SIGNAL(stateChanged(QNetworkSession::State)),
q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)));
- QObject::connect(networkSession, SIGNAL(newConfigurationActivated()),
- q, SLOT(_q_networkSessionNewConfigurationActivated()));
- QObject::connect(networkSession,
- SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool)),
- q,
- SLOT(_q_networkSessionPreferredConfigurationChanged(QNetworkConfiguration,bool)));
_q_networkSessionStateChanged(networkSession->state());
}
@@ -1379,32 +1371,16 @@ void QNetworkAccessManagerPrivate::_q_networkSessionClosed()
if (networkSession) {
networkConfiguration = networkSession->configuration().identifier();
- networkSession->deleteLater();
- networkSession = 0;
- }
-}
-
-void QNetworkAccessManagerPrivate::_q_networkSessionNewConfigurationActivated()
-{
- Q_Q(QNetworkAccessManager);
-
- if (networkSession) {
- networkSession->accept();
-
- emit q->networkSessionConnected();
+ networkSession.clear();
}
}
-void QNetworkAccessManagerPrivate::_q_networkSessionPreferredConfigurationChanged(const QNetworkConfiguration &, bool)
-{
- if (networkSession)
- networkSession->migrate();
-}
-
void QNetworkAccessManagerPrivate::_q_networkSessionStateChanged(QNetworkSession::State state)
{
Q_Q(QNetworkAccessManager);
+ if (state == QNetworkSession::Connected)
+ emit q->networkSessionConnected();
if (online) {
if (state != QNetworkSession::Connected && state != QNetworkSession::Roaming) {
online = false;
diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h
index f3e502c333..7ef009fc68 100644
--- a/src/network/access/qnetworkaccessmanager.h
+++ b/src/network/access/qnetworkaccessmanager.h
@@ -161,8 +161,6 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_replySslErrors(QList<QSslError>))
#if !defined(QT_NO_BEARERMANAGEMENT) && !defined(QT_MOBILITY_BEARER)
Q_PRIVATE_SLOT(d_func(), void _q_networkSessionClosed())
- Q_PRIVATE_SLOT(d_func(), void _q_networkSessionNewConfigurationActivated())
- Q_PRIVATE_SLOT(d_func(), void _q_networkSessionPreferredConfigurationChanged(QNetworkConfiguration,bool))
Q_PRIVATE_SLOT(d_func(), void _q_networkSessionStateChanged(QNetworkSession::State))
#endif
};
diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h
index ee16c256b8..cf4d2f3386 100644
--- a/src/network/access/qnetworkaccessmanager_p.h
+++ b/src/network/access/qnetworkaccessmanager_p.h
@@ -128,7 +128,7 @@ public:
#endif
#ifndef QT_NO_BEARERMANAGEMENT
- QNetworkSession *networkSession;
+ QSharedPointer<QNetworkSession> networkSession;
QString networkConfiguration;
QNetworkAccessManager::NetworkAccessibility networkAccessible;
bool online;
diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp
index 50dbcc267b..9069b14089 100644
--- a/src/network/access/qnetworkreplyimpl.cpp
+++ b/src/network/access/qnetworkreplyimpl.cpp
@@ -97,7 +97,7 @@ void QNetworkReplyImplPrivate::_q_startOperation()
// state changes.
state = WaitingForSession;
- QNetworkSession *session = manager->d_func()->networkSession;
+ QNetworkSession *session = manager->d_func()->networkSession.data();
if (session) {
Q_Q(QNetworkReplyImpl);
@@ -257,7 +257,7 @@ void QNetworkReplyImplPrivate::_q_networkSessionConnected()
if (manager.isNull())
return;
- QNetworkSession *session = manager->d_func()->networkSession;
+ QNetworkSession *session = manager->d_func()->networkSession.data();
if (!session)
return;
@@ -693,7 +693,7 @@ void QNetworkReplyImplPrivate::finished()
if (!manager.isNull()) {
#ifndef QT_NO_BEARERMANAGEMENT
- QNetworkSession *session = manager->d_func()->networkSession;
+ QNetworkSession *session = manager->d_func()->networkSession.data();
if (session && session->state() == QNetworkSession::Roaming &&
state == Working && errorCode != QNetworkReply::OperationCanceledError) {
// only content with a known size will fail with a temporary network failure error
diff --git a/src/network/bearer/bearer.pri b/src/network/bearer/bearer.pri
index bc5b0b595d..d58d5ec168 100644
--- a/src/network/bearer/bearer.pri
+++ b/src/network/bearer/bearer.pri
@@ -7,11 +7,13 @@ HEADERS += bearer/qnetworkconfiguration.h \
bearer/qnetworkconfiguration_p.h \
bearer/qnetworksession_p.h \
bearer/qbearerengine_p.h \
- bearer/qbearerplugin_p.h
+ bearer/qbearerplugin_p.h \
+ bearer/qsharednetworksession_p.h
SOURCES += bearer/qnetworksession.cpp \
bearer/qnetworkconfigmanager.cpp \
bearer/qnetworkconfiguration.cpp \
bearer/qnetworkconfigmanager_p.cpp \
bearer/qbearerengine.cpp \
- bearer/qbearerplugin.cpp
+ bearer/qbearerplugin.cpp \
+ bearer/qsharednetworksession.cpp
diff --git a/src/network/bearer/qsharednetworksession.cpp b/src/network/bearer/qsharednetworksession.cpp
new file mode 100644
index 0000000000..51b3a3253f
--- /dev/null
+++ b/src/network/bearer/qsharednetworksession.cpp
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsharednetworksession_p.h"
+#include "qbearerengine_p.h"
+#include <QThreadStorage>
+
+#ifndef QT_NO_BEARERMANAGEMENT
+
+QT_BEGIN_NAMESPACE
+
+QThreadStorage<QSharedNetworkSessionManager *> tls;
+
+inline QSharedNetworkSessionManager* sharedNetworkSessionManager()
+{
+ QSharedNetworkSessionManager* rv = tls.localData();
+ if (!rv) {
+ rv = new QSharedNetworkSessionManager;
+ tls.setLocalData(rv);
+ }
+ return rv;
+}
+
+QSharedPointer<QNetworkSession> QSharedNetworkSessionManager::getSession(QNetworkConfiguration config)
+{
+ QSharedNetworkSessionManager *m(sharedNetworkSessionManager());
+ //if already have a session, return it
+ if (m->sessions.contains(config)) {
+ QSharedPointer<QNetworkSession> p = m->sessions.value(config).toStrongRef();
+ if (!p.isNull())
+ return p;
+ }
+ //otherwise make one
+ QSharedPointer<QNetworkSession> session(new QNetworkSession(config));
+ m->sessions[config] = session;
+ return session;
+}
+
+void QSharedNetworkSessionManager::setSession(QNetworkConfiguration config, QSharedPointer<QNetworkSession> session)
+{
+ QSharedNetworkSessionManager *m(sharedNetworkSessionManager());
+ m->sessions[config] = session;
+}
+
+uint qHash(const QNetworkConfiguration& config)
+{
+ return ((uint)config.type()) | (((uint)config.bearerType()) << 8) | (((uint)config.purpose()) << 16);
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_BEARERMANAGEMENT
diff --git a/src/network/bearer/qsharednetworksession_p.h b/src/network/bearer/qsharednetworksession_p.h
new file mode 100644
index 0000000000..dc8416631b
--- /dev/null
+++ b/src/network/bearer/qsharednetworksession_p.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSHAREDNETWORKSESSIONPRIVATE_H
+#define QSHAREDNETWORKSESSIONPRIVATE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qnetworksession.h"
+#include "qnetworkconfiguration.h"
+#include <QHash>
+#include <QSharedPointer>
+#include <QWeakPointer>
+#include <QMutex>
+
+#ifndef QT_NO_BEARERMANAGEMENT
+
+QT_BEGIN_NAMESPACE
+
+class QSharedNetworkSessionManager
+{
+public:
+ static QSharedPointer<QNetworkSession> getSession(QNetworkConfiguration config);
+ static void setSession(QNetworkConfiguration config, QSharedPointer<QNetworkSession> session);
+private:
+ QHash<QNetworkConfiguration, QWeakPointer<QNetworkSession> > sessions;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_BEARERMANAGEMENT
+
+#endif //QSHAREDNETWORKSESSIONPRIVATE_H
+
diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp
index 73143e14f8..d61d3b7fa9 100644
--- a/src/network/kernel/qauthenticator.cpp
+++ b/src/network/kernel/qauthenticator.cpp
@@ -213,24 +213,6 @@ void QAuthenticator::setUser(const QString &user)
int separatorPosn = 0;
switch(d->method) {
- case QAuthenticatorPrivate::DigestMd5:
- if((separatorPosn = user.indexOf(QLatin1String("\\"))) != -1) {
- //domain name is present
- d->userDomain.clear();
- d->realm = user.left(separatorPosn);
- d->user = user.mid(separatorPosn + 1);
- } else if((separatorPosn = user.indexOf(QLatin1String("@"))) != -1) {
- //domain name is present
- d->userDomain.clear();
- d->realm = user.mid(separatorPosn + 1);
- d->user = user.left(separatorPosn);
- } else {
- d->user = user;
- d->realm.clear();
- d->userDomain.clear();
- }
- break;
-
case QAuthenticatorPrivate::Ntlm:
if((separatorPosn = user.indexOf(QLatin1String("\\"))) != -1) {
//domain name is present
@@ -253,6 +235,7 @@ void QAuthenticator::setUser(const QString &user)
break;
default:
d->user = user;
+ d->userDomain.clear();
break;
}
}
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 0c18778a5c..fe8554f092 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -102,7 +102,7 @@ extern Q_GUI_EXPORT bool qt_cleartype_enabled;
extern bool qt_applefontsmoothing_enabled;
#endif
-Q_DECL_IMPORT extern QImage qt_imageForBrush(int brushStyle, bool invert);
+Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert);
////////////////////////////////// Private Methods //////////////////////////////////////////
@@ -1162,7 +1162,7 @@ void QGL2PaintEngineEx::fill(const QVectorPath &path, const QBrush &brush)
d->fill(path);
}
-extern Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp
+Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp
void QGL2PaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp
index 031837fdb9..cda1c79a18 100644
--- a/src/opengl/qglframebufferobject.cpp
+++ b/src/opengl/qglframebufferobject.cpp
@@ -1216,8 +1216,8 @@ void QGLFramebufferObject::drawTexture(const QPointF &point, QMacCompatGLuint te
}
#endif
-Q_DECL_IMPORT extern int qt_defaultDpiX();
-Q_DECL_IMPORT extern int qt_defaultDpiY();
+Q_GUI_EXPORT int qt_defaultDpiX();
+Q_GUI_EXPORT int qt_defaultDpiY();
/*! \reimp */
int QGLFramebufferObject::metric(PaintDeviceMetric metric) const
diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp
index 3ce912a86b..ec6ac4c4c5 100644
--- a/src/opengl/qglpixelbuffer.cpp
+++ b/src/opengl/qglpixelbuffer.cpp
@@ -424,8 +424,8 @@ QPaintEngine *QGLPixelBuffer::paintEngine() const
#endif
}
-Q_DECL_IMPORT extern int qt_defaultDpiX();
-Q_DECL_IMPORT extern int qt_defaultDpiY();
+Q_GUI_EXPORT int qt_defaultDpiX();
+Q_GUI_EXPORT int qt_defaultDpiY();
/*! \reimp */
int QGLPixelBuffer::metric(PaintDeviceMetric metric) const
diff --git a/src/opengl/qglpixmapfilter.cpp b/src/opengl/qglpixmapfilter.cpp
index a3867ddd4e..aa075617bb 100644
--- a/src/opengl/qglpixmapfilter.cpp
+++ b/src/opengl/qglpixmapfilter.cpp
@@ -63,8 +63,8 @@
QT_BEGIN_NAMESPACE
// qpixmapfilter.cpp
-Q_DECL_IMPORT void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed = 0);
-Q_DECL_IMPORT QImage qt_halfScaled(const QImage &source);
+Q_GUI_EXPORT void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed = 0);
+Q_GUI_EXPORT QImage qt_halfScaled(const QImage &source);
void QGLPixmapFilterBase::bindTexture(const QPixmap &src) const
{
@@ -425,7 +425,7 @@ static inline uint nextMultiple(uint x, uint multiplier)
return x + multiplier - mod;
}
-Q_DECL_IMPORT void qt_memrotate90_gl(const quint32 *src, int srcWidth, int srcHeight, int srcStride,
+Q_GUI_EXPORT void qt_memrotate90_gl(const quint32 *src, int srcWidth, int srcHeight, int srcStride,
quint32 *dest, int dstStride);
bool QGLPixmapBlurFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &) const
diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp
index 2f1b8fdc1b..2c01ac4391 100644
--- a/src/opengl/qpaintengine_opengl.cpp
+++ b/src/opengl/qpaintengine_opengl.cpp
@@ -79,7 +79,7 @@
QT_BEGIN_NAMESPACE
-Q_DECL_IMPORT extern QImage qt_imageForBrush(int brushStyle, bool invert); //in qbrush.cpp
+Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert); //in qbrush.cpp
#ifdef QT_MAC_USE_COCOA
extern void *qt_current_nsopengl_context(); // qgl_mac.mm
#endif
diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp
index e52238650f..d12704dd29 100644
--- a/src/opengl/qpixmapdata_gl.cpp
+++ b/src/opengl/qpixmapdata_gl.cpp
@@ -739,8 +739,8 @@ QGLTexture* QGLPixmapData::texture() const
return &m_texture;
}
-Q_DECL_IMPORT extern int qt_defaultDpiX();
-Q_DECL_IMPORT extern int qt_defaultDpiY();
+Q_GUI_EXPORT int qt_defaultDpiX();
+Q_GUI_EXPORT int qt_defaultDpiY();
int QGLPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
{
diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp
index 09cbc361fc..a15f0c367e 100644
--- a/src/openvg/qpaintengine_vg.cpp
+++ b/src/openvg/qpaintengine_vg.cpp
@@ -77,8 +77,8 @@ static const qreal aliasedCoordinateDelta = 0.5 - 0.015625;
#if !defined(QVG_NO_DRAW_GLYPHS)
-Q_DECL_IMPORT extern int qt_defaultDpiX();
-Q_DECL_IMPORT extern int qt_defaultDpiY();
+Q_GUI_EXPORT int qt_defaultDpiX();
+Q_GUI_EXPORT int qt_defaultDpiY();
class QVGPaintEnginePrivate;
@@ -526,7 +526,7 @@ void QVGPaintEnginePrivate::setTransform
vgLoadMatrix(mat);
}
-Q_DECL_IMPORT extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale);
+Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale);
void QVGPaintEnginePrivate::updateTransform(QPaintDevice *pdev)
{
@@ -994,7 +994,7 @@ VGPath QVGPaintEnginePrivate::roundedRectPath(const QRectF &rect, qreal xRadius,
return vgpath;
}
-Q_DECL_IMPORT extern QImage qt_imageForBrush(int style, bool invert);
+Q_GUI_EXPORT QImage qt_imageForBrush(int style, bool invert);
static QImage colorizeBitmap(const QImage &image, const QColor &color)
{
@@ -1472,7 +1472,7 @@ void QVGPaintEnginePrivate::draw
(VGPath path, const QPen& pen, const QBrush& brush, VGint rule)
{
VGbitfield mode = 0;
- if (pen.style() != Qt::NoPen) {
+ if (qpen_style(pen) != Qt::NoPen && qbrush_style(qpen_brush(pen)) != Qt::NoBrush) {
ensurePen(pen);
mode |= VG_STROKE_PATH;
}
diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp
index 3f768fd97c..732b484f47 100644
--- a/src/openvg/qpixmapdata_vg.cpp
+++ b/src/openvg/qpixmapdata_vg.cpp
@@ -200,6 +200,9 @@ bool QVGPixmapData::fromData(const uchar *buffer, uint len, const char *format,
return !isNull();
}
+/*!
+ out-of-place conversion (inPlace == false) will always detach()
+ */
void QVGPixmapData::createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace)
{
if (image.size() == QSize(w, h))
@@ -216,11 +219,16 @@ void QVGPixmapData::createPixmapForImage(QImage &image, Qt::ImageConversionFlags
else
format = image.hasAlphaChannel() ? sourceFormat() : QImage::Format_RGB32;
- if (inPlace && image.data_ptr()->convertInPlace(format, flags))
+ if (inPlace && image.data_ptr()->convertInPlace(format, flags)) {
source = image;
- else
+ } else {
source = image.convertToFormat(format);
+ // convertToFormat won't detach the image if format stays the same.
+ if (image.format() == format)
+ source.detach();
+ }
+
recreate = true;
}
@@ -404,8 +412,8 @@ void QVGPixmapData::reclaimImages()
destroyImages();
}
-Q_DECL_IMPORT extern int qt_defaultDpiX();
-Q_DECL_IMPORT extern int qt_defaultDpiY();
+Q_GUI_EXPORT int qt_defaultDpiX();
+Q_GUI_EXPORT int qt_defaultDpiY();
int QVGPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
{