From 0220163ca27c3f97e623591a231473c42b907012 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Tue, 23 Jun 2015 10:28:54 +0200 Subject: Cleanup fontloader cache when QGuiApplication is destroyed If this cache is used for a second instance of QGuiApplication then the cache is invalid. Change-Id: I02ca16dc03a1239b0ed50c7bcfbf87880ca8d948 Task-number: QTBUG-40861 Reviewed-by: Tim Blechmann Reviewed-by: Laszlo Agocs --- src/quick/util/qquickfontloader.cpp | 58 ++++++++++++++--- .../quick/qquickfontloader_static/data/font.ttf | Bin 0 -> 51984 bytes .../qquickfontloader_static.pro | 12 ++++ .../tst_qquickfontloader_static.cpp | 69 +++++++++++++++++++++ tests/auto/quick/quick.pro | 1 + 5 files changed, 132 insertions(+), 8 deletions(-) create mode 100644 tests/auto/quick/qquickfontloader_static/data/font.ttf create mode 100644 tests/auto/quick/qquickfontloader_static/qquickfontloader_static.pro create mode 100644 tests/auto/quick/qquickfontloader_static/tst_qquickfontloader_static.cpp diff --git a/src/quick/util/qquickfontloader.cpp b/src/quick/util/qquickfontloader.cpp index 67df47fb37..496acaa8e3 100644 --- a/src/quick/util/qquickfontloader.cpp +++ b/src/quick/util/qquickfontloader.cpp @@ -47,6 +47,8 @@ #include #include +#include + QT_BEGIN_NAMESPACE #define FONTLOADER_MAXIMUM_REDIRECT_RECURSION 16 @@ -132,10 +134,50 @@ public: QUrl url; QString name; QQuickFontLoader::Status status; - static QHash fonts; }; -QHash QQuickFontLoaderPrivate::fonts; +static void q_QFontLoaderFontsStaticReset(); +static void q_QFontLoaderFontsAddReset() +{ + qAddPostRoutine(q_QFontLoaderFontsStaticReset); +} +class QFontLoaderFonts +{ +public: + QFontLoaderFonts() + { + qAddPostRoutine(q_QFontLoaderFontsStaticReset); + qAddPreRoutine(q_QFontLoaderFontsAddReset); + } + + ~QFontLoaderFonts() + { + qRemovePostRoutine(q_QFontLoaderFontsStaticReset); + reset(); + } + + + void reset() + { + QVector deleted; + QHash::iterator it; + for (it = map.begin(); it != map.end(); ++it) { + if (!deleted.contains(it.value())) { + deleted.append(it.value()); + delete it.value(); + } + } + map.clear(); + } + + QHash map; +}; +Q_GLOBAL_STATIC(QFontLoaderFonts, fontLoaderFonts); + +static void q_QFontLoaderFontsStaticReset() +{ + fontLoaderFonts()->reset(); +} /*! \qmltype FontLoader @@ -193,29 +235,29 @@ void QQuickFontLoader::setSource(const QUrl &url) QString localFile = QQmlFile::urlToLocalFileOrQrc(d->url); if (!localFile.isEmpty()) { - if (!d->fonts.contains(d->url)) { + if (!fontLoaderFonts()->map.contains(d->url)) { int id = QFontDatabase::addApplicationFont(localFile); if (id != -1) { updateFontInfo(QFontDatabase::applicationFontFamilies(id).at(0), Ready); QQuickFontObject *fo = new QQuickFontObject(id); - d->fonts[d->url] = fo; + fontLoaderFonts()->map[d->url] = fo; } else { updateFontInfo(QString(), Error); } } else { - updateFontInfo(QFontDatabase::applicationFontFamilies(d->fonts[d->url]->id).at(0), Ready); + updateFontInfo(QFontDatabase::applicationFontFamilies(fontLoaderFonts()->map[d->url]->id).at(0), Ready); } } else { - if (!d->fonts.contains(d->url)) { + if (!fontLoaderFonts()->map.contains(d->url)) { QQuickFontObject *fo = new QQuickFontObject; - d->fonts[d->url] = fo; + fontLoaderFonts()->map[d->url] = fo; fo->download(d->url, qmlEngine(this)->networkAccessManager()); d->status = Loading; emit statusChanged(); QObject::connect(fo, SIGNAL(fontDownloaded(QString,QQuickFontLoader::Status)), this, SLOT(updateFontInfo(QString,QQuickFontLoader::Status))); } else { - QQuickFontObject *fo = d->fonts[d->url]; + QQuickFontObject *fo = fontLoaderFonts()->map[d->url]; if (fo->id == -1) { d->status = Loading; emit statusChanged(); diff --git a/tests/auto/quick/qquickfontloader_static/data/font.ttf b/tests/auto/quick/qquickfontloader_static/data/font.ttf new file mode 100644 index 0000000000..aae50d5035 Binary files /dev/null and b/tests/auto/quick/qquickfontloader_static/data/font.ttf differ diff --git a/tests/auto/quick/qquickfontloader_static/qquickfontloader_static.pro b/tests/auto/quick/qquickfontloader_static/qquickfontloader_static.pro new file mode 100644 index 0000000000..f6835c05c0 --- /dev/null +++ b/tests/auto/quick/qquickfontloader_static/qquickfontloader_static.pro @@ -0,0 +1,12 @@ +CONFIG += testcase +TARGET = tst_qquickfontloader_static +macx:CONFIG -= app_bundle + +SOURCES += tst_qquickfontloader_static.cpp + +include (../../shared/util.pri) + +TESTDATA = data/* + +QT += core-private gui-private qml-private quick-private network testlib +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickfontloader_static/tst_qquickfontloader_static.cpp b/tests/auto/quick/qquickfontloader_static/tst_qquickfontloader_static.cpp new file mode 100644 index 0000000000..f7f00172ba --- /dev/null +++ b/tests/auto/quick/qquickfontloader_static/tst_qquickfontloader_static.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** 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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include "../../shared/util.h" +#include + +QByteArray qmltemplate("import QtQuick 2.0\n" +"\n" +"Rectangle {\n" +" width: 400\n" +" height: 400\n" +" color: \"red\"\n" +" FontLoader { id: fixedFont; source: \"%1\" }\n" +" Text {\n" +" text: \"hello world\"\n" +" anchors.centerIn: parent\n" +" font.family: fixedFont.name\n" +" }\n" +"}\n"); + +int main(int argc, char **argv) +{ + for (int i = 0; i < 3; i++) { + QGuiApplication app(argc, argv); + QQmlDataTest dataTest; + dataTest.initTestCase(); + QQuickView window; + QQmlComponent component (window.engine()); + QUrl current = QUrl::fromLocalFile(""); + qmltemplate.replace("%1", dataTest.testFileUrl("font.ttf").toString().toLocal8Bit()); + component.setData(qmltemplate, current); + window.setContent(current, &component, component.create()); + window.show(); + QTest::qWaitForWindowActive(&window); + } +} diff --git a/tests/auto/quick/quick.pro b/tests/auto/quick/quick.pro index 5593fd94f6..f25a28d45b 100644 --- a/tests/auto/quick/quick.pro +++ b/tests/auto/quick/quick.pro @@ -18,6 +18,7 @@ PRIVATETESTS += \ qquickapplication \ qquickbehaviors \ qquickfontloader \ + qquickfontloader_static \ qquickfontmetrics \ qquickimageprovider \ qquickpath \ -- cgit v1.2.3