Currently, the getFontOffset() function in Engine requires access to the document element and is thus not compatible with web workers. In my own app I use the following code to patch it inside the web worker:
import { Engine } from "@babylonjs/core/Engines/engine";
let canvas: OffscreenCanvas|null = null;
let ctx: OffscreenCanvasRenderingContext2D|null = null;
interface FontOffset {
ascent: number
height: number
descent: number
}
function getFontOffset(font: string): FontOffset {
if (!canvas || !ctx) {
canvas = new OffscreenCanvas(64,64);
ctx = canvas.getContext('2d');
if (!ctx) {
throw Error('2D context in offscreen not available!')
}
}
ctx.font = font;
ctx.textBaseline = "alphabetic";
const descent = ctx.measureText('Hg').actualBoundingBoxDescent;
ctx.textBaseline = "bottom";
const ascent = ctx.measureText('Hg').actualBoundingBoxAscent;
return { ascent: ascent, height: ascent + descent, descent: descent };
}
export function patchEngine(engine: Engine) {
engine.getFontOffset = getFontOffset;
}
This code works fine for me, but creates different results compared to the original one. E.g. for “18px Arial” on Chrome/Windows the original code produces {ascent: 16, height: 21, descent: 5}, whereas my code {ascent: 17.03125, descent: 4, height: 21.03125}.
Since I don’t know if this would create any problem and have zero experience with pull requests I thought I post the code here instead.