From ee03482e47cf9ce285cf2d578a22fc0702e4a30c Mon Sep 17 00:00:00 2001
From: Yann Bodson <yann.bodson@nokia.com>
Date: Thu, 16 Sep 2010 14:50:05 +1000
Subject: Optimize FontLoader for "multi-use".

Task-number: QTBUG-13419
Reviewed-by: Michael Brasser
---
 src/declarative/util/qdeclarativefontloader.cpp | 199 +++++++++++++++---------
 src/declarative/util/qdeclarativefontloader_p.h |   2 +-
 2 files changed, 129 insertions(+), 72 deletions(-)

diff --git a/src/declarative/util/qdeclarativefontloader.cpp b/src/declarative/util/qdeclarativefontloader.cpp
index 1755855..91588b7 100644
--- a/src/declarative/util/qdeclarativefontloader.cpp
+++ b/src/declarative/util/qdeclarativefontloader.cpp
@@ -58,23 +58,91 @@
 
 QT_BEGIN_NAMESPACE
 
+#define FONTLOADER_MAXIMUM_REDIRECT_RECURSION 16
+
+class QDeclarativeFontObject : public QObject
+{
+Q_OBJECT
+
+public:
+    QDeclarativeFontObject(int _id);
+
+    void download(const QUrl &url, QNetworkAccessManager *manager);
+
+Q_SIGNALS:
+    void fontDownloaded(const QString&, QDeclarativeFontLoader::Status);
+
+private Q_SLOTS:
+    void replyFinished();
+
+public:
+    int id;
+
+private:
+    QNetworkReply *reply;
+    int redirectCount;
+
+    Q_DISABLE_COPY(QDeclarativeFontObject)
+};
+
+QDeclarativeFontObject::QDeclarativeFontObject(int _id = -1)
+    : QObject(0), id(_id), reply(0), redirectCount(0) {}
+
+
+void QDeclarativeFontObject::download(const QUrl &url, QNetworkAccessManager *manager)
+{
+    QNetworkRequest req(url);
+    req.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true);
+    reply = manager->get(req);
+    QObject::connect(reply, SIGNAL(finished()), this, SLOT(replyFinished()));
+}
+
+void QDeclarativeFontObject::replyFinished()
+{
+    if (reply) {
+        redirectCount++;
+        if (redirectCount < FONTLOADER_MAXIMUM_REDIRECT_RECURSION) {
+            QVariant redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
+            if (redirect.isValid()) {
+                QUrl url = reply->url().resolved(redirect.toUrl());
+                QNetworkAccessManager *manager = reply->manager();
+                reply->deleteLater();
+                reply = 0;
+                download(url, manager);
+                return;
+            }
+        }
+        redirectCount = 0;
+
+        if (!reply->error()) {
+            id = QFontDatabase::addApplicationFontFromData(reply->readAll());
+            if (id != -1)
+                emit fontDownloaded(QFontDatabase::applicationFontFamilies(id).at(0), QDeclarativeFontLoader::Ready);
+            else
+                emit fontDownloaded(QString(), QDeclarativeFontLoader::Error);
+        } else {
+            emit fontDownloaded(QString(), QDeclarativeFontLoader::Error);
+        }
+        reply->deleteLater();
+        reply = 0;
+    }
+}
+
+
 class QDeclarativeFontLoaderPrivate : public QObjectPrivate
 {
     Q_DECLARE_PUBLIC(QDeclarativeFontLoader)
 
 public:
-    QDeclarativeFontLoaderPrivate() : reply(0), status(QDeclarativeFontLoader::Null), redirectCount(0) {}
-
-    void addFontToDatabase(const QByteArray &);
+    QDeclarativeFontLoaderPrivate() : status(QDeclarativeFontLoader::Null) {}
 
     QUrl url;
     QString name;
-    QNetworkReply *reply;
     QDeclarativeFontLoader::Status status;
-    int redirectCount;
+    static QHash<QUrl, QDeclarativeFontObject*> fonts;
 };
 
-
+QHash<QUrl, QDeclarativeFontObject*> QDeclarativeFontLoaderPrivate::fonts;
 
 /*!
     \qmlclass FontLoader QDeclarativeFontLoader
@@ -127,30 +195,65 @@ void QDeclarativeFontLoader::setSource(const QUrl &url)
     if (url == d->url)
         return;
     d->url = qmlContext(this)->resolvedUrl(url);
-
-    d->status = Loading;
-    emit statusChanged();
     emit sourceChanged();
+
 #ifndef QT_NO_LOCALFILE_OPTIMIZED_QML
-    QString lf = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(d->url);
-    if (!lf.isEmpty()) {
-        int id = QFontDatabase::addApplicationFont(lf);
-        if (id != -1) {
-            d->name = QFontDatabase::applicationFontFamilies(id).at(0);
+    QString localFile = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(d->url);
+    if (!localFile.isEmpty()) {
+        if (!d->fonts.contains(d->url)) {
+            int id = QFontDatabase::addApplicationFont(localFile);
+            if (id != -1) {
+                updateFontInfo(QFontDatabase::applicationFontFamilies(id).at(0), Ready);
+                QDeclarativeFontObject *fo = new QDeclarativeFontObject(id);
+                d->fonts[d->url] = fo;
+            } else {
+                updateFontInfo(QString(), Error);
+            }
+        } else {
+            QDeclarativeFontObject *fo = d->fonts[d->url];
+            d->name = QFontDatabase::applicationFontFamilies(fo->id).at(0);
             emit nameChanged();
             d->status = QDeclarativeFontLoader::Ready;
-        } else {
-            d->status = QDeclarativeFontLoader::Error;
-            qmlInfo(this) << "Cannot load font: \"" << url.toString() << "\"";
+            emit statusChanged();
         }
-        emit statusChanged();
     } else
 #endif
     {
-        QNetworkRequest req(d->url);
-        req.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true);
-        d->reply = qmlEngine(this)->networkAccessManager()->get(req);
-        QObject::connect(d->reply, SIGNAL(finished()), this, SLOT(replyFinished()));
+        if (!d->fonts.contains(d->url)) {
+            QDeclarativeFontObject *fo = new QDeclarativeFontObject;
+            d->fonts[d->url] = fo;
+            fo->download(d->url, qmlEngine(this)->networkAccessManager());
+            d->status = Loading;
+            emit statusChanged();
+            QObject::connect(fo, SIGNAL(fontDownloaded(QString, QDeclarativeFontLoader::Status)),
+                this, SLOT(updateFontInfo(QString, QDeclarativeFontLoader::Status)));
+        } else {
+            QDeclarativeFontObject *fo = d->fonts[d->url];
+            if (fo->id == -1) {
+                d->status = Loading;
+                emit statusChanged();
+                QObject::connect(fo, SIGNAL(fontDownloaded(QString, QDeclarativeFontLoader::Status)),
+                    this, SLOT(updateFontInfo(QString, QDeclarativeFontLoader::Status)));
+            }
+            else
+                updateFontInfo(QFontDatabase::applicationFontFamilies(fo->id).at(0), Ready);
+        }
+    }
+}
+
+void QDeclarativeFontLoader::updateFontInfo(const QString& name, QDeclarativeFontLoader::Status status)
+{
+    Q_D(QDeclarativeFontLoader);
+
+    if (name != d->name) {
+        d->name = name;
+        emit nameChanged();
+    }
+    if (status != d->status) {
+        if (status == Error)
+            qmlInfo(this) << "Cannot load font: \"" << d->url.toString() << "\"";
+        d->status = status;
+        emit statusChanged();
     }
 }
 
@@ -177,7 +280,7 @@ QString QDeclarativeFontLoader::name() const
 void QDeclarativeFontLoader::setName(const QString &name)
 {
     Q_D(QDeclarativeFontLoader);
-    if (d->name == name )
+    if (d->name == name)
         return;
     d->name = name;
     emit nameChanged();
@@ -223,52 +326,6 @@ QDeclarativeFontLoader::Status QDeclarativeFontLoader::status() const
     return d->status;
 }
 
-#define FONTLOADER_MAXIMUM_REDIRECT_RECURSION 16
-
-void QDeclarativeFontLoader::replyFinished()
-{
-    Q_D(QDeclarativeFontLoader);
-    if (d->reply) {
-        d->redirectCount++;
-        if (d->redirectCount < FONTLOADER_MAXIMUM_REDIRECT_RECURSION) {
-            QVariant redirect = d->reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
-            if (redirect.isValid()) {
-                QUrl url = d->reply->url().resolved(redirect.toUrl());
-                d->reply->deleteLater();
-                d->reply = 0;
-                setSource(url);
-                return;
-            }
-        }
-        d->redirectCount=0;
-
-        if (!d->reply->error()) {
-            QByteArray ba = d->reply->readAll();
-            d->addFontToDatabase(ba);
-        } else {
-            d->status = Error;
-            qmlInfo(this) << "Cannot load font: \"" << d->reply->url().toString() << "\"";
-            emit statusChanged();
-        }
-        d->reply->deleteLater();
-        d->reply = 0;
-    }
-}
-
-void QDeclarativeFontLoaderPrivate::addFontToDatabase(const QByteArray &ba)
-{
-    Q_Q(QDeclarativeFontLoader);
-
-    int id = QFontDatabase::addApplicationFontFromData(ba);
-    if (id != -1) {
-        name = QFontDatabase::applicationFontFamilies(id).at(0);
-        emit q->nameChanged();
-        status = QDeclarativeFontLoader::Ready;
-    } else {
-        status = QDeclarativeFontLoader::Error;
-        qmlInfo(q) << "Cannot load font: \"" << url.toString() << "\"";
-    }
-    emit q->statusChanged();
-}
-
 QT_END_NAMESPACE
+
+#include <qdeclarativefontloader.moc>
diff --git a/src/declarative/util/qdeclarativefontloader_p.h b/src/declarative/util/qdeclarativefontloader_p.h
index 0344d99..bebd5a0 100644
--- a/src/declarative/util/qdeclarativefontloader_p.h
+++ b/src/declarative/util/qdeclarativefontloader_p.h
@@ -79,7 +79,7 @@ public:
     Status status() const;
 
 private Q_SLOTS:
-    void replyFinished();
+    void updateFontInfo(const QString&, QDeclarativeFontLoader::Status);
 
 Q_SIGNALS:
     void sourceChanged();
-- 
cgit v0.12


From 71ffdcb4da039acba8d34c2b23484bd335bd736d Mon Sep 17 00:00:00 2001
From: Joona Petrell <joona.t.petrell@nokia.com>
Date: Thu, 16 Sep 2010 17:44:27 +1000
Subject: Update QtDeclarative def files

Task-number:
Reviewed-by: Martin Jones
---
 src/s60installs/bwins/QtDeclarativeu.def | 24 +++++++++++++++++++++++-
 src/s60installs/eabi/QtDeclarativeu.def  | 22 ++++++++++++++++++++++
 2 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/src/s60installs/bwins/QtDeclarativeu.def b/src/s60installs/bwins/QtDeclarativeu.def
index a2bff5d..0193381 100644
--- a/src/s60installs/bwins/QtDeclarativeu.def
+++ b/src/s60installs/bwins/QtDeclarativeu.def
@@ -1689,5 +1689,27 @@ EXPORTS
 	?tr@QDeclarativePropertyChanges@@SA?AVQString@@PBD0@Z @ 1688 NONAME ; class QString QDeclarativePropertyChanges::tr(char const *, char const *)
 	?changeBindingInRevertList@QDeclarativeState@@QAE_NPAVQObject@@ABVQByteArray@@PAVQDeclarativeAbstractBinding@@@Z @ 1689 NONAME ; bool QDeclarativeState::changeBindingInRevertList(class QObject *, class QByteArray const &, class QDeclarativeAbstractBinding *)
 	?getStaticMetaObject@QDeclarativePropertyChanges@@SAABUQMetaObject@@XZ @ 1690 NONAME ; struct QMetaObject const & QDeclarativePropertyChanges::getStaticMetaObject(void)
-	?weakPointer@QDeclarativeAbstractBinding@@QAE?AV?$QWeakPointer@VQDeclarativeAbstractBinding@@@@XZ @ 1691 NONAME ; class QWeakPointer<class QDeclarativeAbstractBinding> QDeclarativeAbstractBinding::weakPointer(void)
+	?weakPointer@QDeclarativeAbstractBinding@@QAE?AV?$QWeakPointer@VQDeclarativeAbstractBinding@@@@XZ @ 1691 NONAME ABSENT ; class QWeakPointer<class QDeclarativeAbstractBinding> QDeclarativeAbstractBinding::weakPointer(void)
+	?getStaticMetaObject@QDeclarativeScriptAction@@SAABUQMetaObject@@XZ @ 1692 NONAME ; struct QMetaObject const & QDeclarativeScriptAction::getStaticMetaObject(void)
+	?qt_metacall@QDeclarativeScriptAction@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 1693 NONAME ; int QDeclarativeScriptAction::qt_metacall(enum QMetaObject::Call, int, void * *)
+	??1QDeclarativeScriptAction@@UAE@XZ @ 1694 NONAME ; QDeclarativeScriptAction::~QDeclarativeScriptAction(void)
+	?stateChangeScriptName@QDeclarativeScriptAction@@QBE?AVQString@@XZ @ 1695 NONAME ; class QString QDeclarativeScriptAction::stateChangeScriptName(void) const
+	?script@QDeclarativeScriptAction@@QBE?AVQDeclarativeScriptString@@XZ @ 1696 NONAME ; class QDeclarativeScriptString QDeclarativeScriptAction::script(void) const
+	?qt_metacast@QDeclarativeScriptAction@@UAEPAXPBD@Z @ 1697 NONAME ; void * QDeclarativeScriptAction::qt_metacast(char const *)
+	?tr@QDeclarativeScriptAction@@SA?AVQString@@PBD0@Z @ 1698 NONAME ; class QString QDeclarativeScriptAction::tr(char const *, char const *)
+	?setStateChangeScriptName@QDeclarativeScriptAction@@QAEXABVQString@@@Z @ 1699 NONAME ; void QDeclarativeScriptAction::setStateChangeScriptName(class QString const &)
+	??_EQDeclarativeScriptAction@@UAE@I@Z @ 1700 NONAME ; QDeclarativeScriptAction::~QDeclarativeScriptAction(unsigned int)
+	?d_func@QDeclarativeScriptAction@@ABEPBVQDeclarativeScriptActionPrivate@@XZ @ 1701 NONAME ; class QDeclarativeScriptActionPrivate const * QDeclarativeScriptAction::d_func(void) const
+	?weakPointer@QDeclarativeAbstractBinding@@AAE?AV?$QWeakPointer@VQDeclarativeAbstractBinding@@@@XZ @ 1702 NONAME ; class QWeakPointer<class QDeclarativeAbstractBinding> QDeclarativeAbstractBinding::weakPointer(void)
+	?trUtf8@QDeclarativeScriptAction@@SA?AVQString@@PBD0H@Z @ 1703 NONAME ; class QString QDeclarativeScriptAction::trUtf8(char const *, char const *, int)
+	?trUtf8@QDeclarativeScriptAction@@SA?AVQString@@PBD0@Z @ 1704 NONAME ; class QString QDeclarativeScriptAction::trUtf8(char const *, char const *)
+	?qtAnimation@QDeclarativeScriptAction@@MAEPAVQAbstractAnimation@@XZ @ 1705 NONAME ; class QAbstractAnimation * QDeclarativeScriptAction::qtAnimation(void)
+	??0QDeclarativeScriptAction@@QAE@PAVQObject@@@Z @ 1706 NONAME ; QDeclarativeScriptAction::QDeclarativeScriptAction(class QObject *)
+	?tr@QDeclarativeScriptAction@@SA?AVQString@@PBD0H@Z @ 1707 NONAME ; class QString QDeclarativeScriptAction::tr(char const *, char const *, int)
+	?d_func@QDeclarativeScriptAction@@AAEPAVQDeclarativeScriptActionPrivate@@XZ @ 1708 NONAME ; class QDeclarativeScriptActionPrivate * QDeclarativeScriptAction::d_func(void)
+	?transition@QDeclarativeScriptAction@@MAEXAAV?$QList@VQDeclarativeAction@@@@AAV?$QList@VQDeclarativeProperty@@@@W4TransitionDirection@QDeclarativeAbstractAnimation@@@Z @ 1709 NONAME ; void QDeclarativeScriptAction::transition(class QList<class QDeclarativeAction> &, class QList<class QDeclarativeProperty> &, enum QDeclarativeAbstractAnimation::TransitionDirection)
+	?staticMetaObject@QDeclarativeScriptAction@@2UQMetaObject@@B @ 1710 NONAME ; struct QMetaObject const QDeclarativeScriptAction::staticMetaObject
+	?setScript@QDeclarativeScriptAction@@QAEXABVQDeclarativeScriptString@@@Z @ 1711 NONAME ; void QDeclarativeScriptAction::setScript(class QDeclarativeScriptString const &)
+	?metaObject@QDeclarativeScriptAction@@UBEPBUQMetaObject@@XZ @ 1712 NONAME ; struct QMetaObject const * QDeclarativeScriptAction::metaObject(void) const
+	?getPointer@QDeclarativeAbstractBinding@@SA?AV?$QWeakPointer@VQDeclarativeAbstractBinding@@@@PAV1@@Z @ 1713 NONAME ; class QWeakPointer<class QDeclarativeAbstractBinding> QDeclarativeAbstractBinding::getPointer(class QDeclarativeAbstractBinding *)
 
diff --git a/src/s60installs/eabi/QtDeclarativeu.def b/src/s60installs/eabi/QtDeclarativeu.def
index 37325fa..2016ec7 100644
--- a/src/s60installs/eabi/QtDeclarativeu.def
+++ b/src/s60installs/eabi/QtDeclarativeu.def
@@ -1722,4 +1722,26 @@ EXPORTS
 	_ZNK27QDeclarativePropertyChanges8propertyERK10QByteArray @ 1721 NONAME
 	_ZTI27QDeclarativePropertyChanges @ 1722 NONAME
 	_ZTV27QDeclarativePropertyChanges @ 1723 NONAME
+	_ZN24QDeclarativeScriptAction10transitionER5QListI18QDeclarativeActionERS0_I20QDeclarativePropertyEN29QDeclarativeAbstractAnimation19TransitionDirectionE @ 1724 NONAME
+	_ZN24QDeclarativeScriptAction11qtAnimationEv @ 1725 NONAME
+	_ZN24QDeclarativeScriptAction11qt_metacallEN11QMetaObject4CallEiPPv @ 1726 NONAME
+	_ZN24QDeclarativeScriptAction11qt_metacastEPKc @ 1727 NONAME
+	_ZN24QDeclarativeScriptAction16staticMetaObjectE @ 1728 NONAME DATA 16
+	_ZN24QDeclarativeScriptAction19getStaticMetaObjectEv @ 1729 NONAME
+	_ZN24QDeclarativeScriptAction24setStateChangeScriptNameERK7QString @ 1730 NONAME
+	_ZN24QDeclarativeScriptAction9setScriptERK24QDeclarativeScriptString @ 1731 NONAME
+	_ZN24QDeclarativeScriptActionC1EP7QObject @ 1732 NONAME
+	_ZN24QDeclarativeScriptActionC2EP7QObject @ 1733 NONAME
+	_ZN24QDeclarativeScriptActionD0Ev @ 1734 NONAME
+	_ZN24QDeclarativeScriptActionD1Ev @ 1735 NONAME
+	_ZN24QDeclarativeScriptActionD2Ev @ 1736 NONAME
+	_ZNK24QDeclarativeScriptAction10metaObjectEv @ 1737 NONAME
+	_ZNK24QDeclarativeScriptAction21stateChangeScriptNameEv @ 1738 NONAME
+	_ZNK24QDeclarativeScriptAction6scriptEv @ 1739 NONAME
+	_ZTI24QDeclarativeScriptAction @ 1740 NONAME
+	_ZTV24QDeclarativeScriptAction @ 1741 NONAME
+	_ZThn12_N24QDeclarativeScriptActionD0Ev @ 1742 NONAME
+	_ZThn12_N24QDeclarativeScriptActionD1Ev @ 1743 NONAME
+	_ZThn8_N24QDeclarativeScriptActionD0Ev @ 1744 NONAME
+	_ZThn8_N24QDeclarativeScriptActionD1Ev @ 1745 NONAME
 
-- 
cgit v0.12