Make font loading work in workers

This commit is contained in:
Andreas Hocevar
2020-03-16 23:23:34 +01:00
parent bb1ca76bcc
commit 06f6ba13c8
2 changed files with 53 additions and 20 deletions
+14 -13
View File
@@ -7,6 +7,7 @@
* @property {Array<string>} families * @property {Array<string>} families
* @property {string} style * @property {string} style
* @property {string} weight * @property {string} weight
* @property {string} lineHeight
*/ */
@@ -68,8 +69,9 @@ export const CLASS_COLLAPSED = 'ol-collapsed';
/** /**
* Get the list of font families from a font spec. Note that this doesn't work * Get the list of font families from a font spec. Note that this doesn't work
* for font families that have commas in them. * for font families that have commas in them.
* @param {string} The CSS font property. * @param {string} fontSpec The CSS font property.
* @return {FontParameters} The font families (or null if the input spec is invalid). * @param {function(FontParameters):void} callback Called with the font families
* (or null if the input spec is invalid).
*/ */
export const getFontParameters = (function() { export const getFontParameters = (function() {
/** /**
@@ -80,26 +82,25 @@ export const getFontParameters = (function() {
* @type {Object<string, FontParameters>} * @type {Object<string, FontParameters>}
*/ */
const cache = {}; const cache = {};
return function(font) { return function(fontSpec, callback) {
if (!style) { if (!style) {
style = document.createElement('div').style; style = document.createElement('div').style;
} }
if (!(font in cache)) { if (!(fontSpec in cache)) {
style.font = font; style.font = fontSpec;
const family = style.fontFamily; const family = style.fontFamily;
const fontWeight = style.fontWeight;
const fontStyle = style.fontStyle;
style.font = '';
if (!family) { if (!family) {
return null; callback(null);
} }
const families = family.split(/,\s?/); const families = family.split(/,\s?/);
cache[font] = { cache[fontSpec] = {
families: families, families: families,
weight: fontWeight, weight: style.fontWeight,
style: fontStyle style: style.fontStyle,
lineHeight: style.lineHeight
}; };
style.font = '';
} }
return cache[font]; callback(cache[fontSpec]);
}; };
})(); })();
+39 -7
View File
@@ -266,8 +266,7 @@ export const registerFont = (function() {
} }
} }
return function(fontSpec) { function fontCallback(font) {
const font = getFontParameters(fontSpec);
if (!font) { if (!font) {
return; return;
} }
@@ -285,6 +284,31 @@ export const registerFont = (function() {
} }
} }
} }
}
return function(fontSpec) {
if (WINDOW) {
getFontParameters(fontSpec, fontCallback);
} else {
/** @type {any} */
const worker = self;
worker.postMessage({
type: 'getFontParameters',
font: fontSpec
});
worker.addEventListener('message', function handler(event) {
if (event.data.type === 'getFontParameters') {
worker.removeEventListener('message', handler);
const font = event.data.font;
fontCallback(font);
if (!textHeights[fontSpec]) {
const metrics = measureText(fontSpec, 'Žg');
const lineHeight = isNaN(font.lineHeight) ? 1.2 : Number(font.lineHeight);
textHeights[fontSpec] = lineHeight * (metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent);
}
}
});
}
}; };
})(); })();
@@ -320,13 +344,12 @@ export const measureTextHeight = (function() {
}; };
})(); })();
/** /**
* @param {string} font Font. * @param {string} font Font.
* @param {string} text Text. * @param {string} text Text.
* @return {number} Width. * @return {TextMetrics} Text metrics.
*/ */
export function measureTextWidth(font, text) { function measureText(font, text) {
if (!measureContext) { if (!measureContext) {
measureContext = createCanvasContext2D(1, 1); measureContext = createCanvasContext2D(1, 1);
} }
@@ -334,7 +357,16 @@ export function measureTextWidth(font, text) {
measureContext.font = font; measureContext.font = font;
measureFont = measureContext.font; measureFont = measureContext.font;
} }
return measureContext.measureText(text).width; return measureContext.measureText(text);
}
/**
* @param {string} font Font.
* @param {string} text Text.
* @return {number} Width.
*/
export function measureTextWidth(font, text) {
return measureText(font, text).width;
} }
@@ -434,7 +466,7 @@ function executeLabelInstructions(label, context) {
const contextInstructions = label.contextInstructions; const contextInstructions = label.contextInstructions;
for (let i = 0, ii = contextInstructions.length; i < ii; i += 2) { for (let i = 0, ii = contextInstructions.length; i < ii; i += 2) {
if (Array.isArray(contextInstructions[i + 1])) { if (Array.isArray(contextInstructions[i + 1])) {
CanvasRenderingContext2D.prototype[contextInstructions[i]].apply(context, contextInstructions[i + 1]); context[contextInstructions[i]].apply(context, contextInstructions[i + 1]);
} else { } else {
context[contextInstructions[i]] = contextInstructions[i + 1]; context[contextInstructions[i]] = contextInstructions[i + 1];
} }