Skip to content

Commit

Permalink
Add support for adding custom fonts in a package (Mudlet#1683)
Browse files Browse the repository at this point in the history
* Added getAvailableFonts() and support for loading fonts via packages/modules
  • Loading branch information
vadi2 authored May 25, 2018
1 parent 2f266cb commit 9b39738
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 17 deletions.
55 changes: 43 additions & 12 deletions src/FontManager.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (C) 2009-2014 by Vadim Peretokin - vperetokin@gmail.com *
* Copyright (C) 2009, 2018 by Vadim Peretokin - vperetokin@gmail.com *
* Copyright (C) 2014 by Ahmed Charles - acharles@outlook.com *
* Copyright (C) 2017 by Stephen Lyons - slysven@viginmedia.com *
* *
Expand All @@ -21,12 +21,12 @@


#include "FontManager.h"

#include "mudlet.h"

#include "pre_guard.h"
#include <QDir>
#include <QDebug>
#include <QDir>
#include <QFileInfo>
#include <QFontDatabase>
#include <QString>
#include <QStringList>
Expand Down Expand Up @@ -56,17 +56,48 @@ void FontManager::loadFonts(const QString& folder)
{
// Check what happens with this: "Adding application fonts on Unix/X11 platforms without fontconfig is currently not supported."
QStringList filters;
filters << QStringLiteral("*.ttf")
<< QStringLiteral("*.otf");
filters << QStringLiteral("*.ttf") << QStringLiteral("*.otf");
QDir dir = folder;
dir.setNameFilters(filters);

foreach (QString fontfile, dir.entryList(QDir::Files | QDir::Readable | QDir::NoDotAndDotDot)) {
QString fontFilePathName = QStringLiteral("%1/%2").arg(dir.absolutePath(), fontfile);
if (QFontDatabase::addApplicationFont(fontFilePathName) == -1) {
// At the point that addFonts() is called we have a GUI application
// in the making and can use qDebug() and not rely on iostream class
qWarning() << "FontManager::loadFonts() ERROR - Could not load the font in the file: " << fontFilePathName;
}
foreach (QString fontFile, dir.entryList(QDir::Files | QDir::Readable | QDir::NoDotAndDotDot)) {
QString fontFilePathName = QStringLiteral("%1/%2").arg(dir.absolutePath(), fontFile);
loadFont(fontFilePathName);
}
}

void FontManager::loadFont(const QString& filePath)
{
if (fontAlreadyLoaded(filePath)) {
return;
}

auto fontID = QFontDatabase::addApplicationFont(filePath);

// remember even if the font failed to load so we don't spam messages on fonts that repeat
rememberFont(filePath, fontID);

if (fontID == -1) {
qWarning() << "FontManager::loadFonts() warning - Could not load the font(s) in the file: " << filePath;
}
}

bool FontManager::fontAlreadyLoaded(const QString& filePath)
{
QFileInfo fontFile(filePath);
auto fileName = fontFile.fileName();

return loadedFonts.contains(fileName);
}

void FontManager::rememberFont(const QString& filePath, int fontID)
{
QFileInfo fontFile(filePath);
auto fileName = fontFile.fileName();

if (loadedFonts.contains(fileName)) {
return;
}

loadedFonts.insert(fileName, fontID);
}
9 changes: 9 additions & 0 deletions src/FontManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/

#include "pre_guard.h"
#include <QMap>
#include "post_guard.h"

class QString;

Expand All @@ -29,9 +32,15 @@ class FontManager
{
public:
void addFonts();
void loadFont(const QString& filePath);
bool fontAlreadyLoaded(const QString& filePath);

private:
void loadFonts(const QString& folder);
void rememberFont(const QString& fileName, int fontID);

QMap<QString, int> loadedFonts;

};

#endif // MUDLET_FONTMANAGER_H
34 changes: 33 additions & 1 deletion src/Host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include <QtUiTools>
#include <QApplication>
#include <QDir>
#include <QDirIterator>
#include <QMessageBox>
#include <QStringBuilder>
#include "post_guard.h"
Expand Down Expand Up @@ -755,7 +756,7 @@ bool Host::installPackage(const QString& fileName, int module)
{
// As the pointed to dialog is only used now WITHIN this method and this
// method can be re-entered, it is best to use a local rather than a class
// pointer just in case we accidently reenter this method in the future.
// pointer just in case we accidentally reenter this method in the future.
QDialog* pUnzipDialog = Q_NULLPTR;

// Module notes:
Expand Down Expand Up @@ -927,6 +928,11 @@ bool Host::installPackage(const QString& fileName, int module)
// reorder permanent and temporary triggers: perm first, temp second
mTriggerUnit.reorderTriggersAfterPackageImport();

// make any fonts in the package available to Mudlet for use
if (module != 2) {
installPackageFonts(packageName);
}

// raise 2 events - a generic one and a more detailed one to serve both
// a simple need ("I just want the install event") and a more specific need
// ("I specifically need to know when the module was synced")
Expand Down Expand Up @@ -1194,6 +1200,32 @@ QString Host::readProfileData(const QString& item)
return ret;
}

// makes fonts in a given package/module be available for Mudlet scripting
// does not install font system-wide
void Host::installPackageFonts(const QString &packageName)
{
auto packagePath = mudlet::getMudletPath(mudlet::profilePackagePath, getName(), packageName);

QDirIterator it(packagePath, QDirIterator::Subdirectories);
while (it.hasNext()) {
auto filePath = it.next();

if (filePath.endsWith(QLatin1String(".otf"), Qt::CaseInsensitive) || filePath.endsWith(QLatin1String(".ttf"), Qt::CaseInsensitive) ||
filePath.endsWith(QLatin1String(".ttc"), Qt::CaseInsensitive) || filePath.endsWith(QLatin1String(".otc"), Qt::CaseInsensitive)) {

mudlet::self()->mFontManager.loadFont(filePath);
}
}
}

// ensures fonts from all installed packages are loaded in Mudlet
void Host::refreshPackageFonts()
{
for (const auto& package : mInstalledPackages) {
installPackageFonts(package);
}
}

void Host::setWideAmbiguousEAsianGlyphs(const Qt::CheckState state)
{
bool localState = false;
Expand Down
3 changes: 3 additions & 0 deletions src/Host.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ class Host : public QObject
void saveModules(int);
void reloadModule(const QString& moduleName);
bool blockScripts() { return mBlockScriptCompile; }
void refreshPackageFonts();

void registerEventHandler(const QString&, TScript*);
void registerAnonymousEventHandler(const QString& name, const QString& fun);
Expand Down Expand Up @@ -416,6 +417,8 @@ class Host : public QObject

// keeps track of all of the array writers we're currently operating with
QHash<QString, XMLexport*> writers;

void installPackageFonts(const QString &packageName);
};

#endif // MUDLET_HOST_H
14 changes: 14 additions & 0 deletions src/TLuaInterpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11952,6 +11952,19 @@ double TLuaInterpreter::condenseMapLoad()
return loadTime;
}

int TLuaInterpreter::getAvailableFonts(lua_State* L)
{
auto fontList = mudlet::self()->getAvailableFonts();

lua_newtable(L);
for (auto& font : fontList) {
lua_pushstring(L, font.toUtf8().constData());
lua_pushboolean(L, true);
lua_settable(L, -3);
}
return 1;
}

void TLuaInterpreter::set_lua_table(const QString& tableName, QStringList& variableList)
{
lua_State* L = pGlobalLua;
Expand Down Expand Up @@ -12391,6 +12404,7 @@ void TLuaInterpreter::initLuaGlobals()
lua_register(pGlobalLua, "getColumnCount", TLuaInterpreter::getColumnCount);
lua_register(pGlobalLua, "getRowCount", TLuaInterpreter::getRowCount);
lua_register(pGlobalLua, "getOS", TLuaInterpreter::getOS);
lua_register(pGlobalLua, "getAvailableFonts", TLuaInterpreter::getAvailableFonts);
// PLACEMARKER: End of main Lua interpreter functions registration


Expand Down
1 change: 1 addition & 0 deletions src/TLuaInterpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ class TLuaInterpreter : public QThread
static int getColumnCount(lua_State*);
static int getRowCount(lua_State*);
static int getOS(lua_State*);
static int getAvailableFonts(lua_State* L);
// PLACEMARKER: End of Lua functions declarations
static const QMap<Qt::MouseButton, QString> mMouseButtons;
void freeLuaRegistryIndex(int index);
Expand Down
1 change: 1 addition & 0 deletions src/dlgConnectionProfiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1505,6 +1505,7 @@ void dlgConnectionProfiles::slot_connectToServer()
XMLimport importer(pHost);
qDebug() << "[LOADING PROFILE]:" << file.fileName();
importer.importPackage(&file, nullptr); // TODO: Missing false return value handler
pHost->refreshPackageFonts();
} else {
needsGenericPackagesInstall = true;
}
Expand Down
3 changes: 0 additions & 3 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
***************************************************************************/


#include "FontManager.h"
#include "HostManager.h"
#include "mudlet.h"

Expand Down Expand Up @@ -544,8 +543,6 @@ int main(int argc, char* argv[])
#endif

mudlet::debugMode = false;
FontManager fm;
fm.addFonts();

if (show_splash) {
splash_message.append("Done.\n\n"
Expand Down
13 changes: 13 additions & 0 deletions src/mudlet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
#include <QTableWidget>
#include <QTextCharFormat>
#include <QToolBar>
#include <QFontDatabase>
#include "post_guard.h"

#include <zip.h>
Expand Down Expand Up @@ -139,6 +140,7 @@ mudlet* mudlet::self()

mudlet::mudlet()
: QMainWindow()
, mFontManager()
, mToolbarIconSize(0)
, mEditorTreeWidgetIconSize(0)
, mWindowMinimized(false)
Expand Down Expand Up @@ -498,6 +500,9 @@ mudlet::mudlet()
#endif
// Edbee has a singleton that needs some initialisation
initEdbee();

// load bundled fonts
mFontManager.addFonts();
}

QSettings* mudlet::getQSettings()
Expand Down Expand Up @@ -2861,6 +2866,7 @@ void mudlet::doAutoLogin(const QString& profile_name)
XMLimport importer(pHost);
qDebug() << "[LOADING PROFILE]:" << file.fileName();
importer.importPackage(&file); // TODO: Missing false return value handler
pHost->refreshPackageFonts();
}

pHost->setLogin(readProfileData(profile_name, QStringLiteral("login")));
Expand Down Expand Up @@ -3692,3 +3698,10 @@ void mudlet::slot_newDataOnHost(const QString& hostName, const bool isLowerPrior
}
}
}

QStringList mudlet::getAvailableFonts()
{
QFontDatabase database;

return database.families(QFontDatabase::Any);
}
5 changes: 4 additions & 1 deletion src/mudlet.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@


#include "HostManager.h"
#include "FontManager.h"

#include "edbee/views/texttheme.h"
#include "ui_main_window.h"
Expand Down Expand Up @@ -85,7 +86,8 @@ class mudlet : public QMainWindow, public Ui::main_window
static mudlet* self();
// This method allows better debugging when mudlet::self() is called inappropriately.
static void start();
HostManager& getHostManager() { return mHostManager; }
HostManager& getHostManager() { return mHostManager; }
FontManager mFontManager;
QPointer<QSettings> mpSettings;
void addSubWindow(TConsole* p);
int getColumnNumber(Host* pHost, QString& name);
Expand Down Expand Up @@ -199,6 +201,7 @@ class mudlet : public QMainWindow, public Ui::main_window
void playSound(QString s, int);
int getColumnCount(Host* pHost, QString& name);
int getRowCount(Host* pHost, QString& name);
QStringList getAvailableFonts();

static const bool scmIsDevelopmentVersion;
QTime mReplayTime;
Expand Down

0 comments on commit 9b39738

Please sign in to comment.