diff --git a/README.en.md b/README.en.md index c48a5ca..5ccfa79 100644 --- a/README.en.md +++ b/README.en.md @@ -13,7 +13,7 @@ This project subsets fonts on the server side — pass in the text you need, get @@ -97,7 +97,7 @@ No SDK needed. One CSS block to use any Chinese font. Server returns only the ch ```css @font-face { font-family: "MyFont"; - src: url("https://webfont.shenzilong.cn/api?font=令东齐伋复刻体&text=你的文字&outType=woff2") format("woff2"); + src: url("https://webfont.shenzilong.cn/api?font=令东齐伋复刻体&text=你的文字&outType=ttf") format("truetype"); } ``` diff --git a/README.md b/README.md index 0eb5184..acf8049 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ @@ -98,7 +98,7 @@ Prompt: "生成一个东方禅意风格的茶品牌官网" ```css @font-face { font-family: "MyFont"; - src: url("https://webfont.shenzilong.cn/api?font=令东齐伋复刻体&text=你的文字&outType=woff2") format("woff2"); + src: url("https://webfont.shenzilong.cn/api?font=令东齐伋复刻体&text=你的文字&outType=ttf") format("truetype"); } ``` diff --git a/backend/routes/config.ts b/backend/routes/config.ts index e630de1..eda5847 100644 --- a/backend/routes/config.ts +++ b/backend/routes/config.ts @@ -8,7 +8,7 @@ export async function handleGetConfig(req: Request, _res: Response) { res: jsonResponse({ enableTempUpload, adminUploadEnabled: !!adminApiKey, - supportedOutTypes: ["woff2", "ttf"], + supportedOutTypes: ["ttf", "woff2"], /** 临时字体保留时限(秒) */ tempRetentionSeconds, /** 字体子集化最大并发数 */ diff --git a/packages/leafer-x-webfont/README.md b/packages/leafer-x-webfont/README.md index 8594e8f..2617af4 100644 --- a/packages/leafer-x-webfont/README.md +++ b/packages/leafer-x-webfont/README.md @@ -48,7 +48,7 @@ const blob = await leafer.export('png', { pixelRatio: 2 }) ```ts new WebFontPlugin(leafer, { baseUrl: 'https://webfont.shenzilong.cn', // 自部署时改这里 - outType: 'woff2', + outType: 'ttf', // 默认 ttf:子集场景无 brotli 编码/解码开销,端到端更快;流量敏感可改 'woff2' debounceMs: 120, watch: true, // 持续监听画布变化;静态海报导出可关掉 debug: false, diff --git a/packages/webfont-sdk/src/css-mode.ts b/packages/webfont-sdk/src/css-mode.ts index 7e13796..31cf0dd 100644 --- a/packages/webfont-sdk/src/css-mode.ts +++ b/packages/webfont-sdk/src/css-mode.ts @@ -16,7 +16,7 @@ export interface IWebFontOptions { baseUrl?: string /** CSS font-family 名,默认去掉扩展名的字体名 */ family?: string - /** 输出格式,默认 woff2 */ + /** 输出格式,默认 ttf:子集场景无 brotli 编码/解码开销,端到端更快(几 KB 的子集体积差异可忽略) */ outType?: 'woff2' | 'ttf' } @@ -145,7 +145,7 @@ export class WebFontCSSMode { ensurePreconnect(baseUrl) this.engine.ensureState(key, options.fontName, { baseUrl, - outType: options.outType ?? 'woff2', + outType: options.outType ?? 'ttf', onLoadChunk: this.makeOnLoadChunk(key, family), }) @@ -175,7 +175,7 @@ export class WebFontCSSMode { ensurePreconnect(baseUrl) this.engine.ensureState(key, options.fontName, { baseUrl, - outType: options.outType ?? 'woff2', + outType: options.outType ?? 'ttf', onLoadChunk: this.makeOnLoadChunk(key, family), }) @@ -248,7 +248,7 @@ export class WebFontCSSMode { ensurePreconnect(baseUrl) this.engine.ensureState(key, options.fontName, { baseUrl, - outType: options.outType ?? 'woff2', + outType: options.outType ?? 'ttf', onLoadChunk: this.makeOnLoadChunk(key, family), }) this.engine.submitText(key, options.text) diff --git a/packages/webfont-sdk/src/fontface-mode.ts b/packages/webfont-sdk/src/fontface-mode.ts index 2046c0a..2bc49d5 100644 --- a/packages/webfont-sdk/src/fontface-mode.ts +++ b/packages/webfont-sdk/src/fontface-mode.ts @@ -15,7 +15,7 @@ export interface IFontFaceOptions { baseUrl?: string /** 注册用的 family 名,默认去掉扩展名 */ family?: string - /** 输出格式,默认 woff2(Node 端自动降级 ttf,见 loadFontFace) */ + /** 输出格式,默认 ttf:子集场景无 brotli 编码/解码开销,端到端更快(Node 端也强制 ttf,见 loadFontFace) */ outType?: 'woff2' | 'ttf' } @@ -80,8 +80,8 @@ export class WebFontFontFaceMode { const family = options.family ?? fontName.replace(/\.(ttf|otf|woff2?|ttc)$/i, '').trim() const key = IncrementalEngine.fontKey(fontName, family) const baseUrl = options.baseUrl ?? this.defaultBaseUrl - /** Node 模式统一用 ttf:woff2 注册返回 null 不可靠(探针实证) */ - const outType = this.nodeEnv ? 'ttf' : options.outType ?? 'woff2' + /** Node 模式统一用 ttf:woff2 注册返回 null 不可靠(探针实证);浏览器默认也是 ttf(见 IFontFaceOptions.outType 注释) */ + const outType = this.nodeEnv ? 'ttf' : options.outType ?? 'ttf' /** 浏览器分支:FontFace + unicodeRange(多 chunk 同 family 按字符精确生效) */ const handleChunkBrowser = async (chunk: LoadedChunk): Promise => { diff --git a/public/webfont-sdk.js b/public/webfont-sdk.js index 0bcaf2d..4d3fa61 100644 --- a/public/webfont-sdk.js +++ b/public/webfont-sdk.js @@ -250,7 +250,7 @@ ensurePreconnect(baseUrl); this.engine.ensureState(key, options.fontName, { baseUrl, - outType: options.outType ?? "woff2", + outType: options.outType ?? "ttf", onLoadChunk: this.makeOnLoadChunk(key, family) }); if (this.pollTasks.has(options.selector)) clearInterval(this.pollTasks.get(options.selector).timer); @@ -273,7 +273,7 @@ ensurePreconnect(baseUrl); this.engine.ensureState(key, options.fontName, { baseUrl, - outType: options.outType ?? "woff2", + outType: options.outType ?? "ttf", onLoadChunk: this.makeOnLoadChunk(key, family) }); if (this.observeTasks.has(options.selector)) this.observeTasks.get(options.selector).dispose(); @@ -323,7 +323,7 @@ ensurePreconnect(baseUrl); this.engine.ensureState(key, options.fontName, { baseUrl, - outType: options.outType ?? "woff2", + outType: options.outType ?? "ttf", onLoadChunk: this.makeOnLoadChunk(key, family) }); this.engine.submitText(key, options.text); @@ -519,8 +519,8 @@ const family = options.family ?? fontName.replace(/\.(ttf|otf|woff2?|ttc)$/i, "").trim(); const key = IncrementalEngine.fontKey(fontName, family); const baseUrl = options.baseUrl ?? this.defaultBaseUrl; - /** Node 模式统一用 ttf:woff2 注册返回 null 不可靠(探针实证) */ - const outType = this.nodeEnv ? "ttf" : options.outType ?? "woff2"; + /** Node 模式统一用 ttf:woff2 注册返回 null 不可靠(探针实证);浏览器默认也是 ttf(见 IFontFaceOptions.outType 注释) */ + const outType = this.nodeEnv ? "ttf" : options.outType ?? "ttf"; /** 浏览器分支:FontFace + unicodeRange(多 chunk 同 family 按字符精确生效) */ const handleChunkBrowser = async (chunk) => { const unicodeRanges = chunk.chars.map((c) => "U+" + c.codePointAt(0).toString(16).padStart(4, "0")).join(", "); diff --git a/skills/chinese-web-font.md b/skills/chinese-web-font.md index ef4c1b8..631ad66 100644 --- a/skills/chinese-web-font.md +++ b/skills/chinese-web-font.md @@ -15,7 +15,7 @@ description: 中文字体按需裁剪与加载能力,可让 AI 在生成中文 ``` @@ -33,13 +33,13 @@ GET https://webfont.shenzilong.cn/api/fonts ### 其他接口 ``` -GET https://webfont.shenzilong.cn/api?font={name}&text={chars}&outType=woff2 — 裁剪字体 +GET https://webfont.shenzilong.cn/api?font={name}&text={chars}&outType=ttf — 裁剪字体 GET https://webfont.shenzilong.cn/api/fonts — 列出可用字体 GET https://webfont.shenzilong.cn/api/config — 服务配置 POST https://webfont.shenzilong.cn/api/upload?mode=temp — 临时上传字体 ``` -字体名支持模糊匹配(精确 > 前缀 > 包含)。`outType` 支持 `woff2` 和 `ttf`。 +字体名支持模糊匹配(精确 > 前缀 > 包含)。`outType` 支持 `ttf`(默认,服务端裁剪快 2~6 倍,子集场景端到端更快)和 `woff2`(体积小 ~50%,流量敏感时用)。 ### SDK 增量加载 diff --git a/src/TypographyDemo.vue b/src/TypographyDemo.vue index e0e80e0..0cfaadb 100644 --- a/src/TypographyDemo.vue +++ b/src/TypographyDemo.vue @@ -26,7 +26,7 @@ onMounted(() => { fontName: "令东齐伋复刻体.ttf", selector: ".demo-after .zh-font", family: "ZenSerif", - outType: "woff2", + outType: "ttf", }) }) diff --git a/src/i18n.ts b/src/i18n.ts index 711c038..4db8410 100644 --- a/src/i18n.ts +++ b/src/i18n.ts @@ -84,8 +84,8 @@ const messages = { outputFormat: "输出格式", woff2Label: "WOFF2 体积更小", ttfLabel: "TTF 速度更快", - woff2Desc: "约压缩 50%,适合生产", - ttfDesc: "无编码开销,适合开发", + woff2Desc: "体积小约 50%,流量敏感时用", + ttfDesc: "无编码/解码开销,端到端更快", // UploadSection.vue uploadTip: "支持 .ttf 和 .otf 格式,建议上传 .ttf 字体文件以获得最佳兼容性", @@ -194,8 +194,8 @@ const messages = { outputFormat: "Format", woff2Label: "WOFF2 Smaller", ttfLabel: "TTF Faster", - woff2Desc: "~50% smaller, for production", - ttfDesc: "No encoding overhead, for dev", + woff2Desc: "~50% smaller, for traffic-sensitive cases", + ttfDesc: "No encode/decode overhead, faster end-to-end", // UploadSection.vue uploadTip: "Supports .ttf and .otf. .ttf recommended for best compatibility", diff --git a/src/pages/FontDetail.vue b/src/pages/FontDetail.vue index d25d301..0b80c88 100644 --- a/src/pages/FontDetail.vue +++ b/src/pages/FontDetail.vue @@ -116,16 +116,16 @@ const allPreviewText = computed(() => { /** 子集字体 URL(合并所有预览文字) */ const subsetFontUrl = computed(() => { if (!allPreviewText.value) return ""; - return `${origin.value}/api?font=${encodeURIComponent(fontName.value)}&text=${encodeURIComponent(allPreviewText.value)}&outType=woff2`; + return `${origin.value}/api?font=${encodeURIComponent(fontName.value)}&text=${encodeURIComponent(allPreviewText.value)}&outType=ttf`; }); -/** 动态注入 @font-face —— API 返回二进制 woff2,需用 @font-face 引入而非 */ +/** 动态注入 @font-face —— API 返回二进制 ttf,需用 @font-face 引入而非 */ let injectedStyle: HTMLStyleElement | null = null; watchEffect(() => { /** SSG/SSR 阶段没有 document */ if (typeof document === "undefined") return; const css = subsetFontUrl.value - ? `@font-face { font-family: "${fontName.value}"; src: url("${subsetFontUrl.value}") format("woff2"); }` + ? `@font-face { font-family: "${fontName.value}"; src: url("${subsetFontUrl.value}") format("truetype"); }` : ""; if (!css) return; if (!injectedStyle) { @@ -155,7 +155,7 @@ watchEffect(() => { fontName: font, text, family: font, - outType: "woff2", + outType: "ttf", }) ?? null; } else { charsetLoader.update(text); @@ -167,7 +167,7 @@ const usageCode = computed(() => `` diff --git a/src/pages/Home.vue b/src/pages/Home.vue index 15cf902..9909ebe 100644 --- a/src/pages/Home.vue +++ b/src/pages/Home.vue @@ -44,7 +44,7 @@ const outType = ref<"woff2" | "ttf">("ttf"); const serverConfig = ref({ enableTempUpload: false, adminUploadEnabled: false, - supportedOutTypes: ["woff2", "ttf"], + supportedOutTypes: ["ttf", "woff2"], }); onMounted(async () => { @@ -60,7 +60,7 @@ onMounted(async () => { const [fontList, config] = await Promise.all([ fetchFonts().catch(() => [] as FontInfo[]), - fetchConfig().catch((): ServerConfig => ({ enableTempUpload: false, adminUploadEnabled: false, supportedOutTypes: ["woff2", "ttf"] })), + fetchConfig().catch((): ServerConfig => ({ enableTempUpload: false, adminUploadEnabled: false, supportedOutTypes: ["ttf", "woff2"] })), ]); fonts.value = fontList; serverConfig.value = config; @@ -220,7 +220,7 @@ async function refreshFonts() { :fonts="fonts" :selectedFont="selectedFont" :onFontChange="onFontChange" - :supportedOutTypes="serverConfig.supportedOutTypes || ['woff2', 'ttf']" + :supportedOutTypes="serverConfig.supportedOutTypes || ['ttf', 'woff2']" :outType="outType" :onOutTypeChange="(v: 'woff2' | 'ttf') => outType = v" />