feat: async font loading (wip)
remark: potential risk of requesting fontinfo while loading
@@ -23,10 +23,13 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
+import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.BreakIterator;
import java.util.*;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -56,7 +59,7 @@ public final class WindowsFontHelper implements FontHelper {
STBTT_MS_LANG_SWEDISH,
STBTT_MS_LANG_ENGLISH};
- private final List<Font> availableFonts = new ArrayList<>();
+ private final List<Font> availableFonts = new CopyOnWriteArrayList<>();
private final Table<String, String, NativeTTFontInfo> loadedFontInfos = Tables.newCustomTable(new HashMap<>(), HashMap::new);
private final Map<Font, NativeTTFont> loadedNativeFonts = new HashMap<>();
@@ -93,14 +96,20 @@ public final class WindowsFontHelper implements FontHelper {
}
}
+ private boolean allLocalFontsInitialized = false;
+
private void initLocalFonts() {
+ var tasks = new ArrayList<CompletableFuture>();
for (Path fontFile : findLocalTTFonts()) {
+ tasks.add(CompletableFuture.runAsync(()->{
try {
loadNativeFontInfo(fontFile);
} catch (Exception e) {
LOGGER.debug("Cannot load local font. Path: " + fontFile, e);
}
+ }));
}
+ CompletableFuture.allOf(tasks.toArray(new CompletableFuture[0])).thenRun(() -> allLocalFontsInitialized = true);
}
private List<Path> findLocalTTFonts() {
@@ -341,7 +350,9 @@ public final class WindowsFontHelper implements FontHelper {
int charPoint = charPointBuffer.get(0);
if (!isSupportedCharacter(nativeTTFont, charPoint)) {
- continue;
+// continue;
+ charPoint = '\u001A';
+ charPointBuffer.put(0, charPoint);
}
float centerX = posX.get(0);
@@ -390,8 +401,10 @@ public final class WindowsFontHelper implements FontHelper {
}
private NativeTTFontInfo loadNativeFontInfo(Path path) throws IOException {
- byte[] bytes = Files.readAllBytes(path);
- ByteBuffer fontData = ByteBuffer.allocateDirect(bytes.length).put(bytes).flip();
+ try(var fileChannel = FileChannel.open(path)) {
+ ByteBuffer fontData = ByteBuffer.allocateDirect((int)fileChannel.size());
+ fileChannel.read(fontData);
+ fontData.flip();
var fontCount = stbtt_GetNumberOfFonts(fontData);
if (fontCount == -1) {
throw new IllegalArgumentException(String.format("Cannot determine the number of fonts in the font file. File: %s", path));
@@ -447,6 +460,7 @@ public final class WindowsFontHelper implements FontHelper {
}
return parent;
}
+ }
private NativeTTFontInfo loadNativeFontInfo(InputStream input) throws IOException {
byte[] bytes = IOUtils.toByteArray(input);
