UNPKG

@cf-wasm/og

Version:

Generate Open Graph Images dynamically from HTML/CSS without a browser.

88 lines (87 loc) 2.85 kB
const require_font = require("./font.cjs"); //#region src/core/language.ts /** Language font map */ const LANGUAGE_FONT_MAP = { "ja-JP": "Noto+Sans+JP", "ko-KR": "Noto+Sans+KR", "zh-CN": "Noto+Sans+SC", "zh-TW": "Noto+Sans+TC", "zh-HK": "Noto+Sans+HK", "th-TH": "Noto+Sans+Thai", "bn-IN": "Noto+Sans+Bengali", "ar-AR": "Noto+Sans+Arabic", "ta-IN": "Noto+Sans+Tamil", "ml-IN": "Noto+Sans+Malayalam", "he-IL": "Noto+Sans+Hebrew", "te-IN": "Noto+Sans+Telugu", devanagari: "Noto+Sans+Devanagari", kannada: "Noto+Sans+Kannada", symbol: ["Noto+Sans+Symbols", "Noto+Sans+Symbols+2"], math: "Noto+Sans+Math", unknown: "Noto+Sans" }; function convert(input) { return input.split(", ").map((r) => { const [start, end] = r.replaceAll("U+", "").split("-").map((hex) => Number.parseInt(hex, 16)); if (typeof end !== "number" || Number.isNaN(end)) return start; return [start, end]; }); } function checkSegmentInRange(segment, range) { const codePoint = segment.codePointAt(0); if (!codePoint) return false; return range.some((value) => { if (typeof value === "number") return codePoint === value; const [start, end] = value; return start <= codePoint && codePoint <= end; }); } var FontDetector = class { constructor() { this.rangesByLang = {}; } addDetectors(input) { const matches = input.matchAll(/font-family:\s*'(.+?)';.+?unicode-range:\s*(.+?);/gms); for (const [, _lang, range] of matches) { const lang = _lang.replaceAll(" ", "+"); this.rangesByLang[lang] ??= []; this.rangesByLang[lang].push(...convert(range)); } } detectSegment(segment, fonts) { for (const font of fonts) { const range = this.rangesByLang[font]; if (range && checkSegmentInRange(segment, range)) return font; } return null; } async load(fonts) { let params = ""; const existingLang = Object.keys(this.rangesByLang); const langNeedsToLoad = fonts.filter((font) => !existingLang.includes(font)); if (langNeedsToLoad.length === 0) return; for (const font of langNeedsToLoad) params += `family=${font}&`; params += "display=swap"; const cssUrl = `https://fonts.googleapis.com/css2?${params}`; const fontFace = await require_font.googleFonts.loadCss(cssUrl, "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"); this.addDetectors(fontFace); } async detect(text, fonts) { await this.load(fonts); const result = {}; for (const segment of text) { const lang = this.detectSegment(segment, fonts); if (lang) { result[lang] = result[lang] || ""; result[lang] += segment; } } return result; } }; //#endregion exports.FontDetector = FontDetector; exports.LANGUAGE_FONT_MAP = LANGUAGE_FONT_MAP; exports.checkSegmentInRange = checkSegmentInRange; exports.convert = convert; //# sourceMappingURL=language.cjs.map