1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "QtQuick1/private/qdeclarativefontloader_p.h"
44 #include <QtDeclarative/qdeclarativecontext.h>
45 #include <QtDeclarative/qdeclarativeengine.h>
47 #include <QStringList>
50 #include <QNetworkRequest>
51 #include <QNetworkReply>
52 #include <QFontDatabase>
54 #include <private/qobject_p.h>
55 #include <QtDeclarative/private/qdeclarativeengine_p.h>
56 #include <QtDeclarative/qdeclarativeinfo.h>
62 #define FONTLOADER_MAXIMUM_REDIRECT_RECURSION 16
64 class QDeclarative1FontObject : public QObject
69 QDeclarative1FontObject(int _id);
71 void download(const QUrl &url, QNetworkAccessManager *manager);
74 void fontDownloaded(const QString&, QDeclarative1FontLoader::Status);
86 Q_DISABLE_COPY(QDeclarative1FontObject)
89 QDeclarative1FontObject::QDeclarative1FontObject(int _id = -1)
90 : QObject(0), id(_id), reply(0), redirectCount(0) {}
93 void QDeclarative1FontObject::download(const QUrl &url, QNetworkAccessManager *manager)
95 QNetworkRequest req(url);
96 req.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true);
97 reply = manager->get(req);
98 QObject::connect(reply, SIGNAL(finished()), this, SLOT(replyFinished()));
101 void QDeclarative1FontObject::replyFinished()
105 if (redirectCount < FONTLOADER_MAXIMUM_REDIRECT_RECURSION) {
106 QVariant redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
107 if (redirect.isValid()) {
108 QUrl url = reply->url().resolved(redirect.toUrl());
109 QNetworkAccessManager *manager = reply->manager();
110 reply->deleteLater();
112 download(url, manager);
118 if (!reply->error()) {
119 id = QFontDatabase::addApplicationFontFromData(reply->readAll());
121 emit fontDownloaded(QFontDatabase::applicationFontFamilies(id).at(0), QDeclarative1FontLoader::Ready);
123 emit fontDownloaded(QString(), QDeclarative1FontLoader::Error);
125 emit fontDownloaded(QString(), QDeclarative1FontLoader::Error);
127 reply->deleteLater();
133 class QDeclarative1FontLoaderPrivate : public QObjectPrivate
135 Q_DECLARE_PUBLIC(QDeclarative1FontLoader)
138 QDeclarative1FontLoaderPrivate() : status(QDeclarative1FontLoader::Null) {}
142 QDeclarative1FontLoader::Status status;
143 static QHash<QUrl, QDeclarative1FontObject*> fonts;
146 QHash<QUrl, QDeclarative1FontObject*> QDeclarative1FontLoaderPrivate::fonts;
149 \qmlclass FontLoader QDeclarative1FontLoader
150 \inqmlmodule QtQuick 1
151 \ingroup qml-utility-elements
153 \brief The FontLoader element allows fonts to be loaded by name or URL.
155 The FontLoader element is used to load fonts by name or URL.
157 The \l status indicates when the font has been loaded, which is useful
158 for fonts loaded from remote sources.
165 FontLoader { id: fixedFont; name: "Courier" }
166 FontLoader { id: webFont; source: "http://www.mysite.com/myfont.ttf" }
168 Text { text: "Fixed-size font"; font.family: fixedFont.name }
169 Text { text: "Fancy font"; font.family: webFont.name }
173 \sa {declarative/text/fonts}{Fonts example}
175 QDeclarative1FontLoader::QDeclarative1FontLoader(QObject *parent)
176 : QObject(*(new QDeclarative1FontLoaderPrivate), parent)
180 QDeclarative1FontLoader::~QDeclarative1FontLoader()
185 \qmlproperty url QtQuick1::FontLoader::source
186 The url of the font to load.
188 QUrl QDeclarative1FontLoader::source() const
190 Q_D(const QDeclarative1FontLoader);
194 void QDeclarative1FontLoader::setSource(const QUrl &url)
196 Q_D(QDeclarative1FontLoader);
199 d->url = qmlContext(this)->resolvedUrl(url);
200 emit sourceChanged();
202 #ifndef QT_NO_LOCALFILE_OPTIMIZED_QML
203 QString localFile = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(d->url);
204 if (!localFile.isEmpty()) {
205 if (!d->fonts.contains(d->url)) {
206 int id = QFontDatabase::addApplicationFont(localFile);
208 updateFontInfo(QFontDatabase::applicationFontFamilies(id).at(0), Ready);
209 QDeclarative1FontObject *fo = new QDeclarative1FontObject(id);
210 d->fonts[d->url] = fo;
212 updateFontInfo(QString(), Error);
215 updateFontInfo(QFontDatabase::applicationFontFamilies(d->fonts[d->url]->id).at(0), Ready);
220 if (!d->fonts.contains(d->url)) {
221 QDeclarative1FontObject *fo = new QDeclarative1FontObject;
222 d->fonts[d->url] = fo;
223 fo->download(d->url, qmlEngine(this)->networkAccessManager());
225 emit statusChanged();
226 QObject::connect(fo, SIGNAL(fontDownloaded(QString,QDeclarative1FontLoader::Status)),
227 this, SLOT(updateFontInfo(QString,QDeclarative1FontLoader::Status)));
229 QDeclarative1FontObject *fo = d->fonts[d->url];
232 emit statusChanged();
233 QObject::connect(fo, SIGNAL(fontDownloaded(QString,QDeclarative1FontLoader::Status)),
234 this, SLOT(updateFontInfo(QString,QDeclarative1FontLoader::Status)));
237 updateFontInfo(QFontDatabase::applicationFontFamilies(fo->id).at(0), Ready);
242 void QDeclarative1FontLoader::updateFontInfo(const QString& name, QDeclarative1FontLoader::Status status)
244 Q_D(QDeclarative1FontLoader);
246 if (name != d->name) {
250 if (status != d->status) {
252 qmlInfo(this) << "Cannot load font: \"" << d->url.toString() << "\"";
254 emit statusChanged();
259 \qmlproperty string QtQuick1::FontLoader::name
261 This property holds the name of the font family.
262 It is set automatically when a font is loaded using the \c url property.
264 Use this to set the \c font.family property of a \c Text item.
269 width: 200; height: 50
273 source: "http://www.mysite.com/myfont.ttf"
277 font.family: webFont.name
282 QString QDeclarative1FontLoader::name() const
284 Q_D(const QDeclarative1FontLoader);
288 void QDeclarative1FontLoader::setName(const QString &name)
290 Q_D(QDeclarative1FontLoader);
296 emit statusChanged();
300 \qmlproperty enumeration QtQuick1::FontLoader::status
302 This property holds the status of font loading. It can be one of:
304 \o FontLoader.Null - no font has been set
305 \o FontLoader.Ready - the font has been loaded
306 \o FontLoader.Loading - the font is currently being loaded
307 \o FontLoader.Error - an error occurred while loading the font
310 Use this status to provide an update or respond to the status change in some way.
311 For example, you could:
314 \o Trigger a state change:
316 State { name: 'loaded'; when: loader.status == FontLoader.Ready }
319 \o Implement an \c onStatusChanged signal handler:
323 onStatusChanged: if (loader.status == FontLoader.Ready) console.log('Loaded')
327 \o Bind to the status value:
329 Text { text: loader.status == FontLoader.Ready ? 'Loaded' : 'Not loaded' }
333 QDeclarative1FontLoader::Status QDeclarative1FontLoader::status() const
335 Q_D(const QDeclarative1FontLoader);
343 #include <qdeclarativefontloader.moc>