From 4291ae5f166784bbb560f0aac2580f3bcc931552 Mon Sep 17 00:00:00 2001 From: Glavo Date: Tue, 20 May 2025 00:25:56 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9C=A8=20Linux=20=E5=B9=B3=E5=8F=B0=E9=80=9A?= =?UTF-8?q?=E8=BF=87=20fc-match=20=E6=9F=A5=E8=AF=A2=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E5=AD=97=E4=BD=93=20(#3922)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jackhuang/hmcl/setting/FontManager.java | 59 +++++++++++++++---- .../hmcl/util/platform/SystemUtils.java | 6 ++ .../platform/macos/MacOSHardwareDetector.java | 4 +- 3 files changed, 55 insertions(+), 14 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/FontManager.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/FontManager.java index 62b06c32e..346f18997 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/FontManager.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/FontManager.java @@ -23,10 +23,14 @@ import javafx.scene.text.Font; import org.jackhuang.hmcl.Metadata; import org.jackhuang.hmcl.util.Lazy; import org.jackhuang.hmcl.util.io.JarUtils; +import org.jackhuang.hmcl.util.platform.OperatingSystem; +import org.jackhuang.hmcl.util.platform.SystemUtils; import java.net.MalformedURLException; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Locale; import static org.jackhuang.hmcl.setting.ConfigHolder.config; import static org.jackhuang.hmcl.util.logging.Logger.LOG; @@ -52,15 +56,33 @@ public final class FontManager { return font; Path thisJar = JarUtils.thisJarPath(); - if (thisJar != null && thisJar.getParent() != null) - return tryLoadDefaultFont(thisJar.getParent()); + if (thisJar != null && thisJar.getParent() != null) { + font = tryLoadDefaultFont(thisJar.getParent()); + if (font != null) + return font; + } - return null; + if (OperatingSystem.CURRENT_OS.isLinuxOrBSD() + && Locale.getDefault() != Locale.ROOT + && !"en".equals(Locale.getDefault().getLanguage())) + return findByFcMatch(); + else + return null; }); - private static final ObjectProperty fontProperty = new SimpleObjectProperty<>(getDefaultFont()); + private static final ObjectProperty fontProperty; static { + String fontFamily = config().getLauncherFontFamily(); + if (fontFamily == null) + fontFamily = System.getProperty("hmcl.font.override"); + if (fontFamily == null) + fontFamily = System.getenv("HMCL_FONT"); + + Font font = fontFamily == null ? DEFAULT_FONT.get() : Font.font(fontFamily, DEFAULT_FONT_SIZE); + fontProperty = new SimpleObjectProperty<>(font); + + LOG.info("Font: " + (font != null ? font.getName() : Font.getDefault().getName())); fontProperty.addListener((obs, oldValue, newValue) -> { if (newValue != null) config().setLauncherFontFamily(newValue.getFamily()); @@ -90,14 +112,29 @@ public final class FontManager { return null; } - private static Font getDefaultFont() { - String fontFamily = config().getLauncherFontFamily(); - if (fontFamily == null) - fontFamily = System.getProperty("hmcl.font.override"); - if (fontFamily == null) - fontFamily = System.getenv("HMCL_FONT"); + public static Font findByFcMatch() { + Path fcMatch = SystemUtils.which("fc-match"); + if (fcMatch == null) + return null; - return fontFamily == null ? DEFAULT_FONT.get() : Font.font(fontFamily, DEFAULT_FONT_SIZE); + try { + String path = SystemUtils.run(fcMatch.toString(), + ":lang=" + Locale.getDefault().toLanguageTag(), + "--format", "%{file}").trim(); + Path file = Paths.get(path).toAbsolutePath().normalize(); + if (!Files.isRegularFile(file)) { + LOG.warning("Font file does not exist: " + path); + return null; + } + + Font font = Font.loadFont(file.toUri().toURL().toExternalForm(), DEFAULT_FONT_SIZE); + if (font == null) + LOG.warning("Failed to load font from " + path); + return font; + } catch (Throwable e) { + LOG.warning("Failed to get default font with fc-match", e); + return null; + } } public static ObjectProperty fontProperty() { diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/SystemUtils.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/SystemUtils.java index a78e2e2ae..cec9da1ac 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/SystemUtils.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/SystemUtils.java @@ -21,6 +21,7 @@ import org.jackhuang.hmcl.java.JavaRuntime; import org.jackhuang.hmcl.task.Schedulers; import org.jackhuang.hmcl.util.Lang; import org.jackhuang.hmcl.util.function.ExceptionalFunction; +import org.jackhuang.hmcl.util.io.IOUtils; import org.jetbrains.annotations.Nullable; import java.io.File; @@ -75,6 +76,11 @@ public final class SystemUtils { return managedProcess.getProcess().waitFor(); } + public static String run(String... command) throws Exception { + return run(Arrays.asList(command), + inputStream -> IOUtils.readFullyAsString(inputStream, OperatingSystem.NATIVE_CHARSET)); + } + public static T run(List command, ExceptionalFunction convert) throws Exception { File nul = OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS ? new File("NUL") diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/macos/MacOSHardwareDetector.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/macos/MacOSHardwareDetector.java index ed6233738..14b7cfc70 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/macos/MacOSHardwareDetector.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/macos/MacOSHardwareDetector.java @@ -23,7 +23,6 @@ import com.google.gson.JsonObject; import org.jackhuang.hmcl.util.KeyValuePairUtils; import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.gson.JsonUtils; -import org.jackhuang.hmcl.util.io.IOUtils; import org.jackhuang.hmcl.util.platform.OperatingSystem; import org.jackhuang.hmcl.util.platform.SystemUtils; import org.jackhuang.hmcl.util.platform.hardware.CentralProcessor; @@ -103,8 +102,7 @@ public final class MacOSHardwareDetector extends HardwareDetector { String json = null; try { - json = SystemUtils.run(Arrays.asList("/usr/sbin/system_profiler", "SPDisplaysDataType", "-json"), - inputStream -> IOUtils.readFullyAsString(inputStream, OperatingSystem.NATIVE_CHARSET)); + json = SystemUtils.run("/usr/sbin/system_profiler", "SPDisplaysDataType", "-json"); JsonObject object = JsonUtils.GSON.fromJson(json, JsonObject.class); JsonArray spDisplaysDataType = object.getAsJsonArray("SPDisplaysDataType");