UNPKG

playcanvas

Version:

Open-source WebGL/WebGPU 3D engine for the web

124 lines (123 loc) 3.02 kB
import { path } from "../../core/path.js"; import { string } from "../../core/string.js"; import { http } from "../../platform/net/http.js"; import { Font } from "../font/font.js"; import { ResourceHandler } from "./handler.js"; function upgradeDataSchema(data) { if (data.version < 3) { if (data.version < 2) { data.info.maps = data.info.maps || [{ width: data.info.width, height: data.info.height }]; } data.chars = Object.keys(data.chars || {}).reduce((newChars, key) => { const existing = data.chars[key]; const newKey = existing.letter !== void 0 ? existing.letter : string.fromCodePoint(key); if (data.version < 2) { existing.map = existing.map || 0; } newChars[newKey] = existing; return newChars; }, {}); data.version = 3; } return data; } class FontHandler extends ResourceHandler { constructor(app) { super(app, "font"); this._loader = app.loader; this.maxRetries = 0; } load(url, callback, asset) { if (typeof url === "string") { url = { load: url, original: url }; } const self = this; if (path.getExtension(url.original) === ".json") { http.get(url.load, { retry: this.maxRetries > 0, maxRetries: this.maxRetries }, (err, response) => { if (!err) { const data = upgradeDataSchema(response); self._loadTextures(url.load.replace(".json", ".png"), data, (err2, textures) => { if (err2) { callback(err2); } else { callback(null, { data, textures }); } }); } else { callback(`Error loading font resource: ${url.original} [${err}]`); } }); } else { if (asset && asset.data) { asset.data = upgradeDataSchema(asset.data); } this._loadTextures(url.load, asset && asset.data, callback); } } _loadTextures(url, data, callback) { const numTextures = data.info.maps.length; let numLoaded = 0; let error = null; const textures = new Array(numTextures); const loader = this._loader; const loadTexture = function(index) { const onLoaded = function(err, texture) { if (error) return; if (err) { error = err; callback(err); return; } texture.upload(); textures[index] = texture; numLoaded++; if (numLoaded === numTextures) { callback(null, textures); } }; if (index === 0) { loader.load(url, "texture", onLoaded); } else { loader.load(url.replace(".png", `${index}.png`), "texture", onLoaded); } }; for (let i = 0; i < numTextures; i++) { loadTexture(i); } } open(url, data, asset) { let font; if (data.textures) { font = new Font(data.textures, data.data); } else { font = new Font(data, null); } return font; } patch(asset, assets) { const font = asset.resource; if (!font.data && asset.data) { font.data = asset.data; } else if (!asset.data && font.data) { asset.data = font.data; } if (asset.data) { asset.data = upgradeDataSchema(asset.data); } } } export { FontHandler };