diff options
| -rw-r--r-- | docker/Dockerfile | 1 | ||||
| -rwxr-xr-x | docker/build-inner.sh | 61 | ||||
| -rw-r--r-- | src/src/main.cpp | 44 | ||||
| -rw-r--r-- | src/src/moapplication.cpp | 33 |
4 files changed, 126 insertions, 13 deletions
diff --git a/docker/Dockerfile b/docker/Dockerfile index 376f711..a2c0f67 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -12,6 +12,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ # Build essentials build-essential cmake meson ninja-build ccache \ git curl wget file binutils patchelf pkg-config ca-certificates \ + fonts-dejavu-core \ # Library dependencies libboost-all-dev \ libsqlite3-dev \ diff --git a/docker/build-inner.sh b/docker/build-inner.sh index 135ffff..5c14fce 100755 --- a/docker/build-inner.sh +++ b/docker/build-inner.sh @@ -57,6 +57,33 @@ OUT_DIR="/src/build/staging" rm -rf "${OUT_DIR}" mkdir -p "${OUT_DIR}/plugins" "${OUT_DIR}/lib" +# ── Bundled fallback fonts ── +# The release uses a minimal fontconfig file so bundled fontconfig doesn't try +# to parse newer host configs. Ship a known Latin UI font so that generic +# families don't resolve to symbol-only fonts on hosts like Fedora/Bazzite. +mkdir -p "${OUT_DIR}/fonts" "${OUT_DIR}/licenses" +DEJAVU_DIR="" +for candidate in \ + /usr/share/fonts/truetype/dejavu \ + /usr/share/fonts/dejavu \ + /usr/share/fonts/TTF; do + if [ -f "${candidate}/DejaVuSans.ttf" ]; then + DEJAVU_DIR="${candidate}" + break + fi +done +if [ -z "${DEJAVU_DIR}" ]; then + echo "ERROR: DejaVu Sans font not found in build container" + exit 1 +fi +for font in DejaVuSans.ttf DejaVuSans-Bold.ttf DejaVuSansMono.ttf DejaVuSansMono-Bold.ttf; do + cp -f "${DEJAVU_DIR}/${font}" "${OUT_DIR}/fonts/" +done +if [ -f /usr/share/doc/fonts-dejavu-core/copyright ]; then + cp -f /usr/share/doc/fonts-dejavu-core/copyright \ + "${OUT_DIR}/licenses/fonts-dejavu-core.txt" +fi + # ── Main binary + helpers ── cp -f "${RUNDIR}/ModOrganizer" "${OUT_DIR}/ModOrganizer-core" [ -f "${RUNDIR}/README-PORTABLE.txt" ] && cp -f "${RUNDIR}/README-PORTABLE.txt" "${OUT_DIR}/" @@ -616,19 +643,45 @@ export QT_QPA_PLATFORM_PLUGIN_PATH="${RUN}/qt6plugins/platforms" # newer /etc/fonts configuration, older bundled fontconfig can warn on syntax # like xsi:nil and newer generic families. Use a minimal compatible config for # Fluorine itself; launched games/tools restore the user's original env. -mkdir -p "${RUN}/etc/fonts" -cat > "${RUN}/etc/fonts/fonts.conf" <<EOF +if [ -z "${FLUORINE_DISABLE_FONTCONFIG_FIX:-}" ]; then + mkdir -p "${RUN}/etc/fonts" + cat > "${RUN}/etc/fonts/fonts.conf" <<EOF <?xml version="1.0"?> <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd"> <fontconfig> + <dir>${RUN}/fonts</dir> <dir>/usr/share/fonts</dir> <dir>/usr/local/share/fonts</dir> <dir prefix="xdg">fonts</dir> <cachedir prefix="xdg">fontconfig</cachedir> + + <alias> + <family>sans-serif</family> + <prefer><family>DejaVu Sans</family></prefer> + </alias> + <alias> + <family>monospace</family> + <prefer><family>DejaVu Sans Mono</family></prefer> + </alias> + <alias> + <family>MS Shell Dlg 2</family> + <prefer><family>DejaVu Sans</family></prefer> + </alias> + <alias> + <family>Segoe UI</family> + <prefer><family>DejaVu Sans</family></prefer> + </alias> + <alias> + <family>Arial</family> + <prefer><family>DejaVu Sans</family></prefer> + </alias> </fontconfig> EOF -export FONTCONFIG_FILE="${RUN}/etc/fonts/fonts.conf" -export FONTCONFIG_PATH="${RUN}/etc/fonts" + export FONTCONFIG_FILE="${RUN}/etc/fonts/fonts.conf" + export FONTCONFIG_PATH="${RUN}/etc/fonts" +else + unset FONTCONFIG_FILE FONTCONFIG_PATH +fi # Raise open file descriptor limit — large modlists with FUSE VFS # can easily exceed the default 1024 diff --git a/src/src/main.cpp b/src/src/main.cpp index fc10456..74c5aa6 100644 --- a/src/src/main.cpp +++ b/src/src/main.cpp @@ -34,15 +34,43 @@ int run(int argc, char* argv[]); namespace { -const char* COMPAT_FONTCONFIG = R"(<?xml version="1.0"?> +QString compatibleFontconfig(const QString& appDir) +{ + const QString fontDir = QDir(appDir).filePath(QStringLiteral("fonts")).toHtmlEscaped(); + + return QStringLiteral(R"(<?xml version="1.0"?> <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd"> <fontconfig> + <dir>%1</dir> <dir>/usr/share/fonts</dir> <dir>/usr/local/share/fonts</dir> <dir prefix="xdg">fonts</dir> <cachedir prefix="xdg">fontconfig</cachedir> + + <alias> + <family>sans-serif</family> + <prefer><family>DejaVu Sans</family></prefer> + </alias> + <alias> + <family>monospace</family> + <prefer><family>DejaVu Sans Mono</family></prefer> + </alias> + <alias> + <family>MS Shell Dlg 2</family> + <prefer><family>DejaVu Sans</family></prefer> + </alias> + <alias> + <family>Segoe UI</family> + <prefer><family>DejaVu Sans</family></prefer> + </alias> + <alias> + <family>Arial</family> + <prefer><family>DejaVu Sans</family></prefer> + </alias> </fontconfig> -)"; +)") + .arg(fontDir); +} void configureCompatibleFontconfig(int argc, char* argv[]) { @@ -61,13 +89,11 @@ void configureCompatibleFontconfig(int argc, char* argv[]) const QString fontDir = QDir(appDir).filePath(QStringLiteral("etc/fonts")); const QString configPath = QDir(fontDir).filePath(QStringLiteral("fonts.conf")); - if (!QFileInfo::exists(configPath)) { - QDir().mkpath(fontDir); - QFile config(configPath); - if (config.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) { - config.write(COMPAT_FONTCONFIG); - config.close(); - } + QDir().mkpath(fontDir); + QFile config(configPath); + if (config.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) { + config.write(compatibleFontconfig(appDir).toUtf8()); + config.close(); } if (QFileInfo::exists(configPath)) { diff --git a/src/src/moapplication.cpp b/src/src/moapplication.cpp index 16ffb62..9fea4ef 100644 --- a/src/src/moapplication.cpp +++ b/src/src/moapplication.cpp @@ -45,6 +45,8 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include <QDesktopServices> #include <QEvent> #include <QFile> +#include <QFont> +#include <QFontDatabase> #include <QPainter> #include <QProxyStyle> #include <QRegularExpression> @@ -135,6 +137,36 @@ void addLinuxLibrariesToPath() env::prependToPath(libsPath); } +void configureApplicationFont() +{ + const QDir fontDir(QCoreApplication::applicationDirPath() + "/fonts"); + const QStringList bundledFonts{ + "DejaVuSans.ttf", + "DejaVuSans-Bold.ttf", + "DejaVuSansMono.ttf", + "DejaVuSansMono-Bold.ttf", + }; + + QString uiFamily; + for (const QString& font : bundledFonts) { + const int id = QFontDatabase::addApplicationFont(fontDir.filePath(font)); + if (id < 0 || !uiFamily.isEmpty()) { + continue; + } + + const QStringList families = QFontDatabase::applicationFontFamilies(id); + if (!families.isEmpty()) { + uiFamily = families.first(); + } + } + + if (!uiFamily.isEmpty()) { + QFont font = QApplication::font(); + font.setFamily(uiFamily); + QApplication::setFont(font); + } +} + #ifdef MO2_WEBENGINE void configureQtWebEngineProcessPath() { @@ -205,6 +237,7 @@ void configureQtWebEngineProcessPath() MOApplication::MOApplication(int& argc, char** argv) : QApplication(argc, argv) { TimeThis const tt("MOApplication()"); + configureApplicationFont(); // Ensure the app name is always "ModOrganizer" regardless of the binary // filename (settings/profile lookups key off this). |
