Skip to content

Commit 4a75f1d

Browse files
authored
修复通过 fc-match 获取字体时未正确处理 TTC 文件的问题 (#3950)
1 parent e0805fc commit 4a75f1d

1 file changed

Lines changed: 42 additions & 2 deletions

File tree

HMCL/src/main/java/org/jackhuang/hmcl/setting/FontManager.java

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,15 @@
2121
import javafx.beans.property.SimpleObjectProperty;
2222
import javafx.scene.text.Font;
2323
import org.jackhuang.hmcl.Metadata;
24+
import org.jackhuang.hmcl.java.JavaRuntime;
2425
import org.jackhuang.hmcl.util.Lazy;
2526
import org.jackhuang.hmcl.util.io.JarUtils;
2627
import org.jackhuang.hmcl.util.platform.OperatingSystem;
2728
import org.jackhuang.hmcl.util.platform.SystemUtils;
2829

30+
import java.lang.invoke.MethodHandle;
31+
import java.lang.invoke.MethodHandles;
32+
import java.lang.invoke.MethodType;
2933
import java.net.MalformedURLException;
3034
import java.nio.file.Files;
3135
import java.nio.file.Path;
@@ -120,15 +124,51 @@ public static Font findByFcMatch() {
120124
return null;
121125

122126
try {
123-
String path = SystemUtils.run(fcMatch.toString(),
127+
String result = SystemUtils.run(fcMatch.toString(),
124128
":lang=" + Locale.getDefault().toLanguageTag(),
125-
"--format", "%{file}").trim();
129+
"--format", "%{family}\\n%{file}").trim();
130+
131+
String[] results = result.split("\\n");
132+
if (results.length != 2 || results[0].isEmpty() || results[1].isEmpty()) {
133+
LOG.warning("Unexpected output from fc-match: " + result);
134+
return null;
135+
}
136+
137+
String family = results[0].trim();
138+
String path = results[1];
139+
126140
Path file = Paths.get(path).toAbsolutePath().normalize();
127141
if (!Files.isRegularFile(file)) {
128142
LOG.warning("Font file does not exist: " + path);
129143
return null;
130144
}
131145

146+
if (JavaRuntime.CURRENT_VERSION >= 9) {
147+
try {
148+
MethodHandle methodHandle = MethodHandles.publicLookup().findStatic(Font.class, "loadFonts",
149+
MethodType.methodType(Font[].class, String.class, double.class));
150+
151+
Font[] fonts = (Font[]) methodHandle.invokeExact(file.toUri().toURL().toExternalForm(), DEFAULT_FONT_SIZE);
152+
if (fonts == null) {
153+
LOG.warning("Failed to load font from " + path);
154+
return null;
155+
} else if (fonts.length == 0) {
156+
LOG.warning("No fonts loaded from " + path);
157+
return null;
158+
}
159+
160+
for (Font font : fonts) {
161+
if (font.getFamily().equalsIgnoreCase(family)) {
162+
return font;
163+
}
164+
}
165+
166+
LOG.warning(String.format("Family '%s' not found in font file '%s'", family, path));
167+
return fonts[0];
168+
} catch (NoSuchMethodException | IllegalAccessException ignored) {
169+
}
170+
}
171+
132172
Font font = Font.loadFont(file.toUri().toURL().toExternalForm(), DEFAULT_FONT_SIZE);
133173
if (font == null)
134174
LOG.warning("Failed to load font from " + path);

0 commit comments

Comments
 (0)