106 lines
2.1 KiB
JavaScript
106 lines
2.1 KiB
JavaScript
const opentype = require('./vendor/opentype.js')
|
|
const { generateSvgFromFont } = require('./svg-builder')
|
|
|
|
const MAX_FONT_CACHE = 4
|
|
const fontCache = new Map()
|
|
|
|
function touchCache(key, value) {
|
|
if (fontCache.has(key)) {
|
|
fontCache.delete(key)
|
|
}
|
|
fontCache.set(key, value)
|
|
|
|
while (fontCache.size > MAX_FONT_CACHE) {
|
|
const firstKey = fontCache.keys().next().value
|
|
fontCache.delete(firstKey)
|
|
}
|
|
}
|
|
|
|
function sendResult(requestId, success, data, error) {
|
|
worker.postMessage({
|
|
requestId,
|
|
success,
|
|
data,
|
|
error,
|
|
})
|
|
}
|
|
|
|
function handleLoadFont(requestId, payload) {
|
|
const { fontId, fontBuffer } = payload || {}
|
|
if (!fontId || !fontBuffer) {
|
|
throw new Error('加载字体参数无效')
|
|
}
|
|
|
|
const font = opentype.parse(fontBuffer)
|
|
touchCache(fontId, {
|
|
font,
|
|
loadedAt: Date.now(),
|
|
})
|
|
|
|
return { fontId }
|
|
}
|
|
|
|
function handleGenerateSvg(payload) {
|
|
const {
|
|
fontId,
|
|
text,
|
|
fontSize,
|
|
fillColor,
|
|
letterSpacing,
|
|
maxCharsPerLine,
|
|
} = payload || {}
|
|
|
|
if (!fontId) {
|
|
throw new Error('缺少 fontId')
|
|
}
|
|
|
|
const cached = fontCache.get(fontId)
|
|
if (!cached || !cached.font) {
|
|
throw new Error('字体未加载,请先加载字体')
|
|
}
|
|
|
|
touchCache(fontId, cached)
|
|
|
|
return generateSvgFromFont({
|
|
text,
|
|
font: cached.font,
|
|
fontSize,
|
|
fillColor,
|
|
letterSpacing,
|
|
maxCharsPerLine,
|
|
})
|
|
}
|
|
|
|
worker.onMessage((message) => {
|
|
const { requestId, type, payload } = message || {}
|
|
|
|
try {
|
|
if (!requestId) {
|
|
throw new Error('缺少 requestId')
|
|
}
|
|
|
|
if (type === 'load-font') {
|
|
const data = handleLoadFont(requestId, payload)
|
|
sendResult(requestId, true, data)
|
|
return
|
|
}
|
|
|
|
if (type === 'generate-svg') {
|
|
const data = handleGenerateSvg(payload)
|
|
sendResult(requestId, true, data)
|
|
return
|
|
}
|
|
|
|
if (type === 'clear-cache') {
|
|
fontCache.clear()
|
|
sendResult(requestId, true, { ok: true })
|
|
return
|
|
}
|
|
|
|
throw new Error(`未知的任务类型: ${type}`)
|
|
} catch (error) {
|
|
const messageText = error && error.message ? error.message : String(error)
|
|
sendResult(requestId, false, null, messageText)
|
|
}
|
|
})
|