Wait for custom fonts to load before continuing (#401)
This commit is contained in:
1 parent
ce39f140de
commit
cecd467dd2
2 files changed
+58
-4
No files matched your search
@@ -160,6 +160,7 @@ class FontManager extends EventEmitter {
|
||||
* @param {string} family
|
||||
* @param {string} fallback
|
||||
* @param {Asset} asset scratch-storage asset
|
||||
* @returns {Promise<unknown>} Resolves when the font is ready.
|
||||
*/
|
||||
addCustomFont (family, fallback, asset) {
|
||||
if (!this.isValidCustomFont(family)) {
|
||||
@@ -171,8 +172,9 @@ class FontManager extends EventEmitter {
|
||||
fallback,
|
||||
asset
|
||||
});
|
||||
this.updateRenderer();
|
||||
const promise = this.updateRenderer();
|
||||
this.changed();
|
||||
return promise;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -208,9 +210,12 @@ class FontManager extends EventEmitter {
|
||||
this.changed();
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Promise<unknown>} Resolves when fonts are ready.
|
||||
*/
|
||||
updateRenderer () {
|
||||
if (!this.runtime.renderer || !this.runtime.renderer.setCustomFonts) {
|
||||
return;
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
const fontfaces = {};
|
||||
@@ -222,7 +227,7 @@ class FontManager extends EventEmitter {
|
||||
fontfaces[family] = fontface;
|
||||
}
|
||||
}
|
||||
this.runtime.renderer.setCustomFonts(fontfaces);
|
||||
return this.runtime.renderer.setCustomFonts(fontfaces);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -273,6 +278,7 @@ class FontManager extends EventEmitter {
|
||||
return;
|
||||
}
|
||||
|
||||
const fontPromises = [];
|
||||
for (const font of json) {
|
||||
if (!font || typeof font !== 'object') {
|
||||
continue;
|
||||
@@ -305,12 +311,14 @@ class FontManager extends EventEmitter {
|
||||
this.runtime.storage.AssetType.Font,
|
||||
md5ext
|
||||
);
|
||||
this.addCustomFont(family, fallback, asset);
|
||||
fontPromises.push(this.addCustomFont(family, fallback, asset));
|
||||
}
|
||||
} catch (e) {
|
||||
log.error('could not add font', e);
|
||||
}
|
||||
}
|
||||
|
||||
await Promise.all(fontPromises);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ const assert = require('node:assert');
|
||||
const _makeTestStorage = require('../fixtures/make-test-storage');
|
||||
const Runtime = require('../../src/engine/runtime');
|
||||
const VirtualMachine = require('../../src/virtual-machine');
|
||||
const JSZip = require('@turbowarp/jszip');
|
||||
|
||||
const emptyProjectFixture = path.join(__dirname, '..', 'fixtures', 'tw-empty-project.sb3');
|
||||
|
||||
@@ -731,3 +732,48 @@ test('overriding existing fonts', () => {
|
||||
assert.strictEqual(setCustomFontsCalls, 3);
|
||||
assert.deepEqual(fontManager.getFonts().map(i => i.name), ['TESTFONT']);
|
||||
});
|
||||
|
||||
test('deserialize waits for renderer to load fonts', async () => {
|
||||
const zip = new JSZip();
|
||||
zip.file('8e0b5e4ad4e3b2b9a8b4e9bd0ec4de2c.ttf', new Uint8Array([1, 2, 3]));
|
||||
|
||||
let resolveSetCustomFontsCalled;
|
||||
const setCustomFontsCalled = new Promise(resolve => {
|
||||
resolveSetCustomFontsCalled = resolve;
|
||||
});
|
||||
let resolveFontsLoaded;
|
||||
const mockRenderer = {
|
||||
setLayerGroupOrdering: () => {},
|
||||
setCustomFonts: () => {
|
||||
resolveSetCustomFontsCalled();
|
||||
return new Promise(resolve => {
|
||||
resolveFontsLoaded = resolve;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const rt = new Runtime();
|
||||
rt.attachRenderer(mockRenderer);
|
||||
rt.attachStorage(makeTestStorage());
|
||||
|
||||
let deserialized = false;
|
||||
const promise = rt.fontManager.deserialize([
|
||||
{
|
||||
system: false,
|
||||
family: 'TestFont',
|
||||
fallback: 'sans-serif',
|
||||
md5ext: '8e0b5e4ad4e3b2b9a8b4e9bd0ec4de2c.ttf'
|
||||
}
|
||||
], zip, false).then(() => {
|
||||
deserialized = true;
|
||||
});
|
||||
|
||||
await setCustomFontsCalled;
|
||||
await new Promise(resolve => setTimeout(resolve));
|
||||
assert.strictEqual(deserialized, false, 'still waiting for fonts');
|
||||
|
||||
resolveFontsLoaded();
|
||||
await promise;
|
||||
assert.strictEqual(deserialized, true);
|
||||
assert.deepEqual(rt.fontManager.getFonts().map(i => i.name), ['TestFont']);
|
||||
});
|
||||
Reference in new issue
Block a user