feat(编辑能力): 完善缺字诊断,优化字体选择体验
build.yaml / build (push) Successful in 40s

This commit is contained in:
xiaoqidun committed 2026-09-16 20:36:11 +08:00
1 parent bf27afea13
commit f924f008a3
9 files changed
+105 -29

No files matched your search

+3 -1
View File
@@ -273,12 +273,14 @@ a:focus-visible {
gap: 12px;
padding: 6px 8px;
line-height: 1.4;
overflow-wrap: anywhere;
cursor: pointer;
}
.font-listbox [role="option"] > span:first-child {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.font-option-source {
+2 -2
View File
@@ -1,4 +1,4 @@
import { CanvasEditor, canEditObject, objectEditReason } from "./ofdgo_edit.js";
import { CanvasEditor, canEditObject, missingGlyphMessage, objectEditReason } from "./ofdgo_edit.js";
import { FontManager, FontPicker } from "./ofdgo_font.js";
const MM_TO_PX = 96 / 25.4;
@@ -1727,7 +1727,7 @@ async function loadWASM() {
if (data.ok) {
request.resolve(data.data);
} else {
const err = new Error(data.error);
const err = new Error(missingGlyphMessage(data.missingGlyphs) || data.error);
if (data.canceled) {
err.name = "AbortError";
}
+10 -2
View File
@@ -122,13 +122,21 @@ export function canEditObject(item, capability) {
return Boolean(item) && (item.items || [item]).every(object => Boolean(object.capabilities?.[capability]));
}
export function missingGlyphMessage(diagnostic) {
if (!diagnostic) return "";
const characters = Array.from(diagnostic.characters);
const sample = characters.slice(0, 8).map(char => /[\p{C}\p{Z}\p{M}]/u.test(char)
? `U+${char.codePointAt(0).toString(16).toUpperCase().padStart(4, "0")}` : char).join(" ");
return `字体缺字:${sample}${characters.length > 8 ? ` 等 ${characters.length} 字` : ""},改选字体`;
}
export function objectEditReason(item) {
const reasons = (item?.items || (item ? [item] : [])).map(object => {
const reason = object.capabilities?.reason || "";
if (!reason) return "";
let message = "对象特性暂不支持";
if (reason.includes("embedded font")) message = "缺少内嵌字体";
else if (reason.includes("does not contain")) message = "字体缺字";
if (object.capabilities.missingGlyphs) message = missingGlyphMessage(object.capabilities.missingGlyphs);
else if (reason.includes("embedded font")) message = "缺少内嵌字体";
else if (reason.includes("color") || reason.includes("RGB")) message = "颜色样式暂不支持";
else if (reason.includes("draw parameter")) message = "绘制参数暂不支持";
else if (reason.includes("layer")) message = "图层特性暂不支持";
+3 -3
View File
@@ -80,7 +80,7 @@ export class FontPicker {
label.textContent = source;
option.append(label);
}
option.title = font.name || font.fullName;
option.title = [...new Set([font.fullName, font.name].filter(Boolean))].join(" · ");
this.list.append(option);
}
if (!this.matches.length) {
@@ -100,9 +100,9 @@ export class FontPicker {
position() {
if (!this.open) return;
const rect = this.input.getBoundingClientRect();
const rect = this.input.parentElement.getBoundingClientRect();
if (rect.right <= 0 || rect.left >= window.innerWidth) { this.close(); return; }
const width = Math.min(Math.max(rect.width, 260), window.innerWidth - 16);
const width = Math.min(rect.width, window.innerWidth - 16);
Object.assign(this.list.style, { left: `${Math.max(8, Math.min(rect.left, window.innerWidth - width - 8))}px`,
top: `${rect.bottom + 4}px`, width: `${width}px`, maxHeight: `${Math.max(40, Math.min(280, window.innerHeight - rect.bottom - 12))}px` });
}