{"record":{"id":"55354c3729755d69","repo":"BabylonJS/Babylon.js","slug":"getfontoffset-is-not-implemented","errorCode":null,"errorMessage":"getFontOffset is not implemented","messagePattern":"getFontOffset is not implemented","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/dev/core/src/Engines/abstractEngine.pure.ts","lineNumber":2647,"sourceCode":"     * @param bufferWidth destination buffer width\r\n     * @param bufferHeight destination buffer height\r\n     */\r\n    public resizeImageBitmap(image: HTMLImageElement | ImageBitmap, bufferWidth: number, bufferHeight: number): Uint8Array {\r\n        throw new Error(\"resizeImageBitmap is not implemented\");\r\n    }\r\n\r\n    /**\r\n     * Get the current error code of the webGL context\r\n     * @returns the error code\r\n     */\r\n    public abstract getError(): number;\r\n\r\n    /**\r\n     * Get Font size information\r\n     * @param font font name\r\n     */\r\n    public getFontOffset(font: string): { ascent: number; height: number; descent: number } {\r\n        throw new Error(\"getFontOffset is not implemented\");\r\n    }\r\n\r\n    protected static _CreateCanvas(width: number, height: number): ICanvas {\r\n        if (typeof document === \"undefined\") {\r\n            return <ICanvas>(<any>new OffscreenCanvas(width, height));\r\n        }\r\n        const canvas = <ICanvas>(<any>document.createElement(\"canvas\"));\r\n        canvas.width = width;\r\n        canvas.height = height;\r\n        return canvas;\r\n    }\r\n\r\n    /**\r\n     * Create a canvas. This method is overridden by other engines\r\n     * @param width width\r\n     * @param height height\r\n     * @returns ICanvas interface\r\n     */\r","sourceCodeStart":2629,"sourceCodeEnd":2665,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/core/src/Engines/abstractEngine.pure.ts#L2629-L2665","documentation":"AbstractEngine.getFontOffset returns font metrics (ascent/height/descent) needed for text rendering (GUI/dynamic textures). The pure base class throws because measuring font offset requires a rendering canvas with 2d context; only concrete engines implement it.","triggerScenarios":"Calling engine.getFontOffset(font) — directly or indirectly through GUI text blocks / DynamicTexture text measurement — on an engine lacking the override (pure engine, NullEngine, minimal builds).","commonSituations":"Server-side rendering of GUI with NullEngine; unit tests touching Babylon.GUI text layout in headless environments; custom engine subclasses missing getFontOffset.","solutions":["Use a real engine (WebGL/WebGPU) for text/GUI layout","Override getFontOffset in your engine subclass, measuring with a 2d canvas (measureText with actualBoundingBoxAscent/Descent)","Stub the method in tests returning fixed metrics","Precompute font metrics and inject them instead of querying the engine"],"exampleFix":"// before\nconst off = nullEngine.getFontOffset('12px Arial'); // throws\n// after\nnullEngine.getFontOffset = (font: string) => {\n  const ctx = document.createElement('canvas').getContext('2d')!;\n  ctx.font = font;\n  const m = ctx.measureText('Mg');\n  return { ascent: m.actualBoundingBoxAscent, height: m.actualBoundingBoxAscent + m.actualBoundingBoxDescent, descent: m.actualBoundingBoxDescent };\n};","handlingStrategy":"fallback","validationCode":"if (engine.getFontOffset === AbstractEngine.prototype.getFontOffset) {\n  // base version throws; use custom metrics via canvas measureText\n}","typeGuard":"function canMeasureFont(engine: AbstractEngine): boolean {\n  return engine.getFontOffset !== AbstractEngine.prototype.getFontOffset;\n}","tryCatchPattern":"try {\n  off = engine.getFontOffset(font);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('getFontOffset is not implemented')) {\n    off = measureFontOffsetWithCanvas(font); // 2d measureText fallback\n  } else throw e;\n}","preventionTips":["Run GUI/text layout with a real engine implementation","Provide a metrics override when using NullEngine for GUI layout tests","Cache font metrics once instead of querying per frame","Keep custom engines implementing all abstract text methods"],"tags":["abstract-method","font-metrics","engine","headless"],"backgroundTag":"method-not-implemented","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}