Skip to content

Commit 7988397

Browse files
WeebDataHoarderTheOneric
authored andcommitted
Implement lazy font loading (off by default)
Extracts default.woff2 from binary, embeds fonts.conf, removes .data files on output. Use --memory-init-file=0 to remove .mem files on output. Specify fallbackFont to override default.woff2. If lazyFileLoading is set to true, use FS.createLazyFile(). This is off by default, as it depends on correct HTTP headers sent back.
1 parent e459c8e commit 7988397

7 files changed

Lines changed: 39 additions & 14 deletions

File tree

Makefile

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,16 +156,16 @@ EMCC_COMMON_ARGS = \
156156
$(LDFLAGS) \
157157
-s AUTO_NATIVE_LIBRARIES=0 \
158158
-s EXPORTED_FUNCTIONS="['_main', '_malloc']" \
159+
-s DEFAULT_LIBRARY_FUNCS_TO_INCLUDE="['\$$Browser']" \
159160
-s EXPORTED_RUNTIME_METHODS="['ccall', 'cwrap', 'getValue', 'FS_createPreloadedFile', 'FS_createPath']" \
160-
--use-preload-plugins \
161-
--preload-file assets/default.woff2 \
162-
--preload-file assets/fonts.conf \
161+
--embed-file assets/fonts.conf \
163162
-s ALLOW_MEMORY_GROWTH=1 \
164163
-s NO_FILESYSTEM=0 \
164+
--memory-init-file=0 \
165165
--no-heap-copy \
166166
-o $@
167167

168-
dist: src/subtitles-octopus-worker.bc dist/js/subtitles-octopus-worker.js dist/js/subtitles-octopus-worker-legacy.js dist/js/subtitles-octopus.js dist/js/COPYRIGHT
168+
dist: src/subtitles-octopus-worker.bc dist/js/subtitles-octopus-worker.js dist/js/subtitles-octopus-worker-legacy.js dist/js/subtitles-octopus.js dist/js/COPYRIGHT dist/js/default.woff2
169169

170170
dist/js/subtitles-octopus-worker.js: src/subtitles-octopus-worker.bc src/pre-worker.js src/SubOctpInterface.js src/post-worker.js build/lib/brotli/js/decode.js
171171
mkdir -p dist/js
@@ -205,6 +205,9 @@ dist/license/all:
205205
dist/js/COPYRIGHT: dist/license/all
206206
cp "$<" "$@"
207207

208+
dist/js/default.woff2:
209+
cp assets/default.woff2 "$@"
210+
208211
# Clean Tasks
209212

210213
clean: clean-dist clean-libs clean-octopus

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ When creating an instance of SubtitleOctopus, you can set the following options:
114114
- `fonts`: An array of links to the fonts used in the subtitle. (Optional)
115115
- `availableFonts`: Object with all available fonts - Key is font name in lower
116116
case, value is link: `{"arial": "/font1.ttf"}` (Optional)
117+
- `fallbackFont`: URL to override fallback font, for example, with a CJK one. Default fallback font is Liberation Sans (Optional)
118+
- `lazyFileLoading`: A boolean, whether to load files in a lazy way via [FS.createLazyFile()](https://emscripten.org/docs/api_reference/Filesystem-API.html#FS.createLazyFile). [Requires](https://github.com/emscripten-core/emscripten/blob/c7b21c32fef92799da05d15ba1939b6394fe0373/src/library_fs.js#L1679-L1856) `Access-Control-Expose-Headers` for `Accept-Ranges, Content-Length, and Content-Encoding`. If encoding is compressed or length is not set, file will be fully fetched instead of just a HEAD request.
117119
- `timeOffset`: The amount of time the subtitles should be offset from the
118120
video. (Default: `0`)
119121
- `onReady`: Function that's called when SubtitlesOctopus is ready. (Optional)

src/SubtitleOctopus.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <stdlib.h>
77
#include <stdarg.h>
88
#include <string.h>
9+
#include <string>
910
#include <cstdint>
1011
#include <ass/ass.h>
1112

@@ -247,6 +248,8 @@ class SubtitleOctopus {
247248

248249
int status;
249250

251+
std::string defaultFont;
252+
250253
SubtitleOctopus() {
251254
status = 0;
252255
ass_library = NULL;
@@ -281,7 +284,11 @@ class SubtitleOctopus {
281284
scanned_events = i;
282285
}
283286

284-
void initLibrary(int frame_w, int frame_h) {
287+
void initLibrary(int frame_w, int frame_h, char* default_font) {
288+
if (default_font != NULL) {
289+
defaultFont.assign(default_font);
290+
}
291+
285292
ass_library = ass_library_init();
286293
if (!ass_library) {
287294
fprintf(stderr, "jso: ass_library_init failed!\n");
@@ -353,11 +360,11 @@ class SubtitleOctopus {
353360
void reloadLibrary() {
354361
quitLibrary();
355362

356-
initLibrary(canvas_w, canvas_h);
363+
initLibrary(canvas_w, canvas_h, NULL);
357364
}
358365

359366
void reloadFonts() {
360-
ass_set_fonts(ass_renderer, "/assets/default.woff2", NULL, ASS_FONTPROVIDER_FONTCONFIG, "/assets/fonts.conf", 1);
367+
ass_set_fonts(ass_renderer, defaultFont.c_str(), NULL, ASS_FONTPROVIDER_FONTCONFIG, "/assets/fonts.conf", 1);
361368
}
362369

363370
void setMargin(int top, int bottom, int left, int right) {

src/SubtitleOctopus.idl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ interface SubtitleOctopus {
172172
attribute ASS_Library ass_library;
173173
void setLogLevel(long level);
174174
void setDropAnimations(long value);
175-
void initLibrary(long frame_w, long frame_h);
175+
void initLibrary(long frame_w, long frame_h, DOMString default_font);
176176
void createTrack(DOMString subfile);
177177
void createTrackMem(DOMString buf, unsigned long bufsize);
178178
void removeTrack();

src/post-worker.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,18 @@ self.writeFontToFS = function(font) {
3232
self.fontMap_[font] = true;
3333

3434
if (!self.availableFonts.hasOwnProperty(font)) return;
35-
var content = readBinary(self.availableFonts[font]);
3635

37-
Module["FS"].writeFile('/fonts/font' + (self.fontId++) + '-' + self.availableFonts[font].split('/').pop(), content, {
38-
encoding: 'binary'
39-
});
36+
self.loadFontFile('font' + (self.fontId++) + '-', self.availableFonts[font]);
4037
};
4138

39+
self.loadFontFile = function (fontId, path) {
40+
if (self.lazyFileLoading && path.indexOf("blob:") !== 0) {
41+
Module["FS"].createLazyFile("/fonts", fontId + path.split('/').pop(), path, true, false);
42+
} else {
43+
Module["FS"].createPreloadedFile("/fonts", fontId + path.split('/').pop(), path, true, false);
44+
}
45+
}
46+
4247
/**
4348
* Write all font's mentioned in the .ass file to the virtual FS.
4449
* @param {!string} content the file content.
@@ -553,6 +558,8 @@ function onMessageFromMainEmscriptenThread(message) {
553558
}
554559

555560
self.availableFonts = message.data.availableFonts;
561+
self.fallbackFont = message.data.fallbackFont;
562+
self.lazyFileLoading = message.data.lazyFileLoading;
556563
self.debug = message.data.debug;
557564
if (!hasNativeConsole && self.debug) {
558565
console = makeCustomConsole();

src/pre-worker.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,12 @@ Module["preRun"].push(function () {
9494

9595
self.subContent = null;
9696

97+
self.loadFontFile(".fallback-", self.fallbackFont);
98+
9799
//Module["FS"].mount(Module["FS"].filesystems.IDBFS, {}, '/fonts');
98100
var fontFiles = self.fontFiles || [];
99101
for (var i = 0; i < fontFiles.length; i++) {
100-
Module["FS_createPreloadedFile"]("/fonts", 'font' + i + '-' + fontFiles[i].split('/').pop(), fontFiles[i], true, true);
102+
self.loadFontFile('font' + i + '-', fontFiles[i]);
101103
}
102104
});
103105

@@ -111,7 +113,7 @@ Module['onRuntimeInitialized'] = function () {
111113
self.blendW = Module._malloc(4);
112114
self.blendH = Module._malloc(4);
113115

114-
self.octObj.initLibrary(screen.width, screen.height);
116+
self.octObj.initLibrary(screen.width, screen.height, "/fonts/.fallback-" + self.fallbackFont.split('/').pop());
115117
self.octObj.setDropAnimations(self.dropAllAnimations);
116118
self.octObj.createTrack("/sub.ass");
117119
self.ass_track = self.octObj.track;

src/subtitles-octopus.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ var SubtitlesOctopus = function (options) {
2727
self.canvasParent = null; // (internal) HTML canvas parent element
2828
self.fonts = options.fonts || []; // Array with links to fonts used in sub (optional)
2929
self.availableFonts = options.availableFonts || []; // Object with all available fonts (optional). Key is font name in lower case, value is link: {"arial": "/font1.ttf"}
30+
self.fallbackFont = options.fallbackFont || 'default.woff2'; // URL to override fallback font, for example, with a CJK one. Default fallback font is Liberation Sans (Optional)
31+
self.lazyFileLoading = options.lazyFileLoading || false; // Load fonts in a lazy way. Requires Access-Control-Expose-Headers for Accept-Ranges, Content-Length, and Content-Encoding. If Content-Encoding is compressed, file will be fully fetched instead of just a HEAD request.
3032
self.onReadyEvent = options.onReady; // Function called when SubtitlesOctopus is ready (optional)
3133
if (supportsWebAssembly) {
3234
self.workerUrl = options.workerUrl || 'subtitles-octopus-worker.js'; // Link to WebAssembly worker
@@ -112,6 +114,8 @@ var SubtitlesOctopus = function (options) {
112114
subContent: self.subContent,
113115
fonts: self.fonts,
114116
availableFonts: self.availableFonts,
117+
fallbackFont: self.fallbackFont,
118+
lazyFileLoading: self.lazyFileLoading,
115119
debug: self.debug,
116120
targetFps: self.targetFps,
117121
libassMemoryLimit: self.libassMemoryLimit,

0 commit comments

Comments
 (0)