1
0
Fork 0
flightgear/utils/fgqcanvas/fgqcanvasfontcache.cpp
2016-12-21 10:26:31 +00:00

132 lines
3.4 KiB
C++

#include "fgqcanvasfontcache.h"
#include <QNetworkAccessManager>
#include <QStandardPaths>
#include <QDebug>
#include <QUrl>
#include <QNetworkReply>
#include <QFontDatabase>
#include <QFile>
FGQCanvasFontCache::FGQCanvasFontCache(QNetworkAccessManager* nam, QObject *parent)
: QObject(parent)
, m_downloader(nam)
{
}
QFont FGQCanvasFontCache::fontForName(QByteArray name, bool* ok)
{
if (m_cache.contains(name)) {
if (ok) {
*ok = true;
}
return m_cache.value(name); // easy!
}
lookupFile(name);
if (m_cache.contains(name)) {
if (ok) {
*ok = true;
}
return m_cache.value(name);
}
if (ok) {
*ok = false;
}
return QFont(); // default font
}
static FGQCanvasFontCache* s_instance = nullptr;
void FGQCanvasFontCache::initialise(QNetworkAccessManager *nam)
{
Q_ASSERT(s_instance == nullptr);
s_instance = new FGQCanvasFontCache(nam);
}
FGQCanvasFontCache *FGQCanvasFontCache::instance()
{
return s_instance;
}
void FGQCanvasFontCache::setHost(QString hostName, int portNumber)
{
m_hostName = hostName;
m_port = portNumber;
}
void FGQCanvasFontCache::onFontDownloadFinished()
{
QByteArray fontPath = sender()->property("font").toByteArray();
qDebug() << "finished download of " << fontPath;
QDir cacheDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation));
QString absPath = cacheDir.absoluteFilePath(fontPath);
QFileInfo finfo(fontPath);
cacheDir.mkpath(finfo.dir().path());
QFile f(absPath);
if (!f.open(QIODevice::WriteOnly)) {
qWarning() << "failed to open cache file" << f.fileName();
}
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
Q_ASSERT(m_transfers.contains(reply));
f.write(reply->readAll());
f.close();
m_transfers.removeOne(reply);
// call ourselves again now it's cached;
lookupFile(fontPath);
}
void FGQCanvasFontCache::onFontDownloadError(QNetworkReply::NetworkError)
{
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
qWarning() << "font download failed:" << reply->errorString();
}
void FGQCanvasFontCache::lookupFile(QByteArray name)
{
QString path = QStandardPaths::locate(QStandardPaths::CacheLocation, name);
if (path.isEmpty()) {
QUrl url;
url.setScheme("http");
url.setHost(m_hostName);
url.setPort(m_port);
url.setPath("/Fonts/" + name);
Q_FOREACH (QNetworkReply* transfer, m_transfers) {
if (transfer->url() == url) {
return; // transfer already active
}
}
qDebug() << "reqeusting font" << url;
QNetworkReply* reply = m_downloader->get(QNetworkRequest(url));
reply->setProperty("font", name);
connect(reply, &QNetworkReply::finished, this, &FGQCanvasFontCache::onFontDownloadFinished);
// connect(reply, &QNetworkReply::error, this, &FGQCanvasFontCache::onFontDownloadError);
m_transfers.append(reply);
} else {
qDebug() << "found font" << name << "at path" << path;
int fontFamilyId = QFontDatabase::addApplicationFont(path);
QStringList families = QFontDatabase::applicationFontFamilies(fontFamilyId);
qDebug() << "families are:" << families;
// compute a QFont and cache
QFont font(families.front());
m_cache.insert(name, font);
}
}