minigame-tuanjie-transform-sdk/Runtime/wechat-default/unity-sdk/font/index.js

100 lines
3.9 KiB
JavaScript

import moduleHelper from '../module-helper';
import { formatJsonStr } from '../utils';
import fixCmapTable from './fix-cmap';
import readMetrics from './read-metrics';
import splitTTCToBufferOnlySC from './split-sc';
const { platform } = wx.getSystemInfoSync();
const tempCacheObj = {};
let fontDataCache;
let getFontPromise;
let isReadFromCache = false;
const isIOS = platform === 'ios';
const isAndroid = platform === 'android';
function handleGetFontData(config, forceLoad = false) {
const canGetWxCommonFont = !!GameGlobal.manager?.font?.getCommonFont;
if (!config && !canGetWxCommonFont) {
return Promise.reject('invalid usage');
}
if (!getFontPromise || forceLoad) {
getFontPromise = new Promise((resolve, reject) => {
if (!canGetWxCommonFont && !!config) {
const xhr = new GameGlobal.unityNamespace.UnityLoader.UnityCache.XMLHttpRequest();
xhr.open('GET', config.fallbackUrl, true);
xhr.responseType = 'arraybuffer';
xhr.onload = () => {
if ((xhr.status === 200 || xhr.status === 0) && xhr.response) {
const notoFontData = xhr.response;
fontDataCache = notoFontData;
isReadFromCache = xhr.isReadFromCache;
resolve();
}
};
xhr.onerror = reject;
xhr.send();
return;
}
GameGlobal.manager.font.getCommonFont({
success(fontData) {
if (isIOS) {
fixCmapTable(fontData);
}
if (isAndroid) {
const tempData = splitTTCToBufferOnlySC(fontData);
if (tempData) {
fontData = tempData;
}
}
fontDataCache = fontData;
resolve();
},
fail: reject,
});
});
}
return getFontPromise;
}
function WXGetFontRawData(conf, callbackId) {
const config = formatJsonStr(conf);
const loadFromRemote = !GameGlobal.manager?.font?.getCommonFont;
GameGlobal.manager.TimeLogger.timeStart('WXGetFontRawData');
handleGetFontData(config).then(() => {
if (fontDataCache) {
GameGlobal.manager.font.reportGetFontCost(GameGlobal.manager.TimeLogger.timeEnd('WXGetFontRawData'), { loadFromRemote, isReadFromCache, preloadWXFont: GameGlobal.unityNamespace.preloadWXFont });
const { ascent, descent, lineGap, unitsPerEm } = readMetrics(fontDataCache) || {};
tempCacheObj[callbackId] = fontDataCache;
moduleHelper.send('GetFontRawDataCallback', JSON.stringify({ callbackId, type: 'success', res: JSON.stringify({ byteLength: fontDataCache.byteLength, ascent, descent, lineGap, unitsPerEm }) }));
GameGlobal.manager.Logger.pluginLog(`[font] load font from ${loadFromRemote ? `network, url=${config.fallbackUrl}` : 'local'}`);
fontDataCache = null;
}
else {
GameGlobal.manager.Logger.pluginError('[font] load font error: empty content');
}
})
.catch((err) => {
GameGlobal.manager.Logger.pluginError('[font] load font error: ', err);
});
}
function WXShareFontBuffer(buffer, offset, callbackId) {
if (typeof tempCacheObj[callbackId] === 'string') {
GameGlobal.manager.Logger.pluginError('[font]内存写入异常');
}
buffer.set(new Uint8Array(tempCacheObj[callbackId]), offset);
delete tempCacheObj[callbackId];
}
export function preloadWxCommonFont() {
if (!!GameGlobal.unityNamespace.preloadWXFont && !!GameGlobal.manager?.font?.getCommonFont) {
handleGetFontData();
}
}
export default {
WXGetFontRawData,
WXShareFontBuffer,
};