Skip to content

Commit

Permalink
Merge pull request #50 from dmitrylyzo/WeebDataHoarder/lazy-fonts
Browse files Browse the repository at this point in the history
[WeebDataHoarder] Implement lazy font loading + customizable fallback font
  • Loading branch information
dmitrylyzo authored Jun 8, 2023
2 parents 3df655a + 06edd4f commit d6f76d8
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 14 deletions.
11 changes: 7 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -155,16 +155,16 @@ all-src:
EMCC_COMMON_ARGS = \
$(LDFLAGS) \
-s EXPORTED_FUNCTIONS="['_main', '_malloc']" \
-s DEFAULT_LIBRARY_FUNCS_TO_INCLUDE="['\$$Browser']" \
-s EXPORTED_RUNTIME_METHODS="['ccall', 'cwrap', 'getValue', 'FS_createPreloadedFile', 'FS_createPath']" \
--use-preload-plugins \
--preload-file assets/default.woff2 \
--preload-file assets/fonts.conf \
--embed-file assets/fonts.conf \
-s ALLOW_MEMORY_GROWTH=1 \
-s NO_FILESYSTEM=0 \
--memory-init-file=0 \
--no-heap-copy \
-o $@

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: 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

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
mkdir -p dist/js
Expand Down Expand Up @@ -202,6 +202,9 @@ dist/license/all:
dist/js/COPYRIGHT: dist/license/all
cp "$<" "$@"

dist/js/default.woff2:
cp assets/default.woff2 "$@"

# Clean Tasks

clean: clean-dist clean-libs clean-octopus
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ When creating an instance of SubtitleOctopus, you can set the following options:
- `fonts`: An array of links to the fonts used in the subtitle. (Optional)
- `availableFonts`: Object with all available fonts - Key is font name in lower
case, value is link: `{"arial": "/font1.ttf"}` (Optional)
- `fallbackFont`: URL to override fallback font, for example, with a CJK one. Default fallback font is Liberation Sans (Optional)
- `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.
- `timeOffset`: The amount of time the subtitles should be offset from the
video. (Default: `0`)
- `onReady`: Function that's called when SubtitlesOctopus is ready. (Optional)
Expand Down
13 changes: 10 additions & 3 deletions src/SubtitleOctopus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <string>
#include <ass/ass.h>

#include "libass.cpp"
Expand Down Expand Up @@ -294,6 +295,8 @@ class SubtitleOctopus {

int status;

std::string defaultFont;

SubtitleOctopus(): ass_library(NULL), ass_renderer(NULL), track(NULL), canvas_w(0), canvas_h(0), status(0), m_is_event_animated(NULL), m_drop_animations(false) {
}

Expand All @@ -311,7 +314,11 @@ class SubtitleOctopus {
return m_drop_animations;
}

void initLibrary(int frame_w, int frame_h) {
void initLibrary(int frame_w, int frame_h, char* default_font) {
if (default_font != NULL) {
defaultFont.assign(default_font);
}

ass_library = ass_library_init();
if (!ass_library) {
fprintf(stderr, "jso: ass_library_init failed!\n");
Expand Down Expand Up @@ -390,11 +397,11 @@ class SubtitleOctopus {
void reloadLibrary() {
quitLibrary();

initLibrary(canvas_w, canvas_h);
initLibrary(canvas_w, canvas_h, NULL);
}

void reloadFonts() {
ass_set_fonts(ass_renderer, "/assets/default.woff2", NULL, ASS_FONTPROVIDER_FONTCONFIG, "/assets/fonts.conf", 1);
ass_set_fonts(ass_renderer, defaultFont.c_str(), NULL, ASS_FONTPROVIDER_FONTCONFIG, "/assets/fonts.conf", 1);
}

void setMargin(int top, int bottom, int left, int right) {
Expand Down
2 changes: 1 addition & 1 deletion src/SubtitleOctopus.idl
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ interface SubtitleOctopus {
void setLogLevel(long level);
void setDropAnimations(long value);
long getDropAnimations();
void initLibrary(long frame_w, long frame_h);
void initLibrary(long frame_w, long frame_h, DOMString default_font);
void createTrack(DOMString subfile);
void createTrackMem(DOMString buf, unsigned long bufsize);
void removeTrack();
Expand Down
15 changes: 11 additions & 4 deletions src/post-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,18 @@ self.writeFontToFS = function(font) {
self.fontMap_[font] = true;

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

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

self.loadFontFile = function (fontId, path) {
if (self.lazyFileLoading && path.indexOf("blob:") !== 0) {
Module["FS"].createLazyFile("/fonts", fontId + path.split('/').pop(), path, true, false);
} else {
Module["FS"].createPreloadedFile("/fonts", fontId + path.split('/').pop(), path, true, false);
}
}

/**
* Write all font's mentioned in the .ass file to the virtual FS.
* @param {!string} content the file content.
Expand Down Expand Up @@ -611,6 +616,8 @@ function onMessageFromMainEmscriptenThread(message) {
}

self.availableFonts = message.data.availableFonts;
self.fallbackFont = message.data.fallbackFont;
self.lazyFileLoading = message.data.lazyFileLoading;
self.debug = message.data.debug;
if (!hasNativeConsole && self.debug) {
console = makeCustomConsole();
Expand Down
6 changes: 4 additions & 2 deletions src/pre-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,12 @@ Module["preRun"].push(function () {

self.subContent = null;

self.loadFontFile(".fallback-", self.fallbackFont);

//Module["FS"].mount(Module["FS"].filesystems.IDBFS, {}, '/fonts');
var fontFiles = self.fontFiles || [];
for (var i = 0; i < fontFiles.length; i++) {
Module["FS_createPreloadedFile"]("/fonts", 'font' + i + '-' + fontFiles[i].split('/').pop(), fontFiles[i], true, true);
self.loadFontFile('font' + i + '-', fontFiles[i]);
}
});

Expand All @@ -100,7 +102,7 @@ Module['onRuntimeInitialized'] = function () {

self.changed = Module._malloc(4);

self.octObj.initLibrary(screen.width, screen.height);
self.octObj.initLibrary(screen.width, screen.height, "/fonts/.fallback-" + self.fallbackFont.split('/').pop());
self.octObj.setDropAnimations(!!self.dropAllAnimations);
self.octObj.createTrack("/sub.ass");
self.ass_track = self.octObj.track;
Expand Down
4 changes: 4 additions & 0 deletions src/subtitles-octopus.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ var SubtitlesOctopus = function (options) {
self.canvasParent = null; // (internal) HTML canvas parent element
self.fonts = options.fonts || []; // Array with links to fonts used in sub (optional)
self.availableFonts = options.availableFonts || []; // Object with all available fonts (optional). Key is font name in lower case, value is link: {"arial": "/font1.ttf"}
self.fallbackFont = options.fallbackFont || 'default.woff2'; // URL to override fallback font, for example, with a CJK one. Default fallback font is Liberation Sans (Optional)
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.
self.onReadyEvent = options.onReady; // Function called when SubtitlesOctopus is ready (optional)
if (supportsWebAssembly) {
self.workerUrl = options.workerUrl || 'subtitles-octopus-worker.js'; // Link to WebAssembly worker
Expand Down Expand Up @@ -144,6 +146,8 @@ var SubtitlesOctopus = function (options) {
subContent: self.subContent,
fonts: self.fonts,
availableFonts: self.availableFonts,
fallbackFont: self.fallbackFont,
lazyFileLoading: self.lazyFileLoading,
debug: self.debug,
targetFps: self.targetFps,
libassMemoryLimit: self.libassMemoryLimit,
Expand Down

0 comments on commit d6f76d8

Please sign in to comment.