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

View File

@@ -7,6 +7,7 @@
* @property {Array<string>} families
* @property {string} style
* @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
* for font families that have commas in them.
* @param {string} The CSS font property.
* @return {FontParameters} The font families (or null if the input spec is invalid).
* @param {string} fontSpec The CSS font property.
* @param {function(FontParameters):void} callback Called with the font families
* (or null if the input spec is invalid).
*/
export const getFontParameters = (function() {
/**
@@ -80,26 +82,25 @@ export const getFontParameters = (function() {
* @type {Object<string, FontParameters>}
*/
const cache = {};
return function(font) {
return function(fontSpec, callback) {
if (!style) {
style = document.createElement('div').style;
}
if (!(font in cache)) {
style.font = font;
if (!(fontSpec in cache)) {
style.font = fontSpec;
const family = style.fontFamily;
const fontWeight = style.fontWeight;
const fontStyle = style.fontStyle;
style.font = '';
if (!family) {
return null;
callback(null);
}
const families = family.split(/,\s?/);
cache[font] = {
cache[fontSpec] = {
families: families,
weight: fontWeight,
style: fontStyle
weight: style.fontWeight,
style: style.fontStyle,
lineHeight: style.lineHeight
};
style.font = '';
}
return cache[font];
callback(cache[fontSpec]);
};
})();

View File

@@ -266,8 +266,7 @@ export const registerFont = (function() {
}
}
return function(fontSpec) {
const font = getFontParameters(fontSpec);
function fontCallback(font) {
if (!font) {
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} text Text.
* @return {number} Width.
* @return {TextMetrics} Text metrics.
*/
export function measureTextWidth(font, text) {
function measureText(font, text) {
if (!measureContext) {
measureContext = createCanvasContext2D(1, 1);
}
@@ -334,7 +357,16 @@ export function measureTextWidth(font, text) {
measureContext.font = 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;
for (let i = 0, ii = contextInstructions.length; i < ii; i += 2) {
if (Array.isArray(contextInstructions[i + 1])) {
CanvasRenderingContext2D.prototype[contextInstructions[i]].apply(context, contextInstructions[i + 1]);
context[contextInstructions[i]].apply(context, contextInstructions[i + 1]);
} else {
context[contextInstructions[i]] = contextInstructions[i + 1];
}