mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-29 16:44:23 +08:00
1 parent
f4429b126a
commit
f8c8259502
2 files changed
+39
-25
No files matched your search
+18
-16
@@ -4363,17 +4363,18 @@ function editorFonts(item) {
|
|||||||
return [...embedded.values(), ...fonts];
|
return [...embedded.values(), ...fonts];
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadEditorFonts() {
|
async function loadEditorFonts(requestPermission = true) {
|
||||||
const tab = documentTab(), target = tab.state;
|
const tab = documentTab(), target = tab.state;
|
||||||
const tasks = [];
|
const tasks = [];
|
||||||
if (!state.fontCatalogLoading && fontManager.canReadLocal() && !fontManager.catalogLoaded && fontManager.permission !== "denied") {
|
if (!state.fontCatalogLoading && fontManager.canReadLocal() && !fontManager.catalogLoaded && fontManager.permission !== "denied"
|
||||||
|
&& (requestPermission || fontManager.permission === "granted")) {
|
||||||
target.fontCatalogLoading = true;
|
target.fontCatalogLoading = true;
|
||||||
tasks.push((async () => {
|
tasks.push((async () => {
|
||||||
try {
|
try {
|
||||||
await fontManager.queryLocal();
|
await fontManager.queryLocal();
|
||||||
if (isForegroundDocument(tab)) refreshEditorFonts();
|
refreshEditorFonts();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (isForegroundDocument(tab)) setStatus(err?.name === "NotAllowedError" ? "系统字体未授权" : String(err.message || err));
|
if (requestPermission && isForegroundDocument(tab)) setStatus(err?.name === "NotAllowedError" ? "系统字体未授权" : String(err.message || err));
|
||||||
} finally {
|
} finally {
|
||||||
target.fontCatalogLoading = false;
|
target.fontCatalogLoading = false;
|
||||||
}
|
}
|
||||||
@@ -4381,12 +4382,15 @@ async function loadEditorFonts() {
|
|||||||
}
|
}
|
||||||
if (!state.fontFacesLoading && fontManager.userFonts.some(font => font.enabled && !font.faces)) {
|
if (!state.fontFacesLoading && fontManager.userFonts.some(font => font.enabled && !font.faces)) {
|
||||||
target.fontFacesLoading = true;
|
target.fontFacesLoading = true;
|
||||||
|
const wasmSeq = target.wasmSeq;
|
||||||
|
const current = () => !tab.closed && !target.wasmExited && target.wasmSeq === wasmSeq;
|
||||||
tasks.push((async () => {
|
tasks.push((async () => {
|
||||||
try {
|
try {
|
||||||
await fontManager.loadFaces(data => callTabWASM(tab, "ofdgoFontFaces", data));
|
await fontManager.loadFaces(data => callTabWASM(tab, "ofdgoFontFaces", data), current);
|
||||||
if (isForegroundDocument(tab)) refreshEditorFonts();
|
refreshEditorFonts();
|
||||||
} finally {
|
} finally {
|
||||||
target.fontFacesLoading = false;
|
target.fontFacesLoading = false;
|
||||||
|
if (!current() && state.ready) loadEditorFonts(false);
|
||||||
}
|
}
|
||||||
})());
|
})());
|
||||||
}
|
}
|
||||||
@@ -4394,11 +4398,7 @@ async function loadEditorFonts() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function refreshEditorFonts() {
|
function refreshEditorFonts() {
|
||||||
const open = fontPicker.open;
|
updateTextFonts(canvasEditor.selected, true, true);
|
||||||
const selected = state.textFonts[Number(fontPicker.value)];
|
|
||||||
const query = el.textFont.value === (selected?.fullName || selected?.name || "") ? "" : el.textFont.value;
|
|
||||||
updateTextFonts(canvasEditor.selected, true);
|
|
||||||
if (open && !el.textFont.disabled) { if (query) el.textFont.value = query; fontPicker.show(query, false); }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function readTextFont(font, tab = documentTab()) {
|
async function readTextFont(font, tab = documentTab()) {
|
||||||
@@ -4413,14 +4413,14 @@ async function readTextFont(font, tab = documentTab()) {
|
|||||||
return result.bytes;
|
return result.bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateTextFonts(item, refresh = false) {
|
function updateTextFonts(item, refresh = false, preserve = false) {
|
||||||
item = selectedText(item);
|
item = selectedText(item);
|
||||||
const rich = canvasEditor.input?.rich;
|
const rich = canvasEditor.input?.rich;
|
||||||
if (rich) {
|
if (rich) {
|
||||||
const format = rich.state(), id = format.font;
|
const format = rich.state(), id = format.font;
|
||||||
const key = `rich:${id ?? "mixed"}:${rich.faces.size}`;
|
const key = `rich:${id ?? "mixed"}:${rich.faces.size}`;
|
||||||
if (refresh || state.textFontID !== key) {
|
if (refresh || state.textFontID !== key) {
|
||||||
if (document.activeElement === el.textFont && fontPicker.open) return;
|
if (!preserve && document.activeElement === el.textFont && fontPicker.open) return;
|
||||||
state.textFontID = key;
|
state.textFontID = key;
|
||||||
state.textFonts = editorFonts(null);
|
state.textFonts = editorFonts(null);
|
||||||
for (const font of rich.faces.keys()) {
|
for (const font of rich.faces.keys()) {
|
||||||
@@ -4429,7 +4429,7 @@ function updateTextFonts(item, refresh = false) {
|
|||||||
name: state.doc?.fonts?.find(value => value.id === font)?.fontName || (font === rich.editing.item.font ? rich.editing.item.fontName : "") || font,
|
name: state.doc?.fonts?.find(value => value.id === font)?.fontName || (font === rich.editing.item.font ? rich.editing.item.fontName : "") || font,
|
||||||
embedded: !rich.imports.has(font) }), richKey: font });
|
embedded: !rich.imports.has(font) }), richKey: font });
|
||||||
}
|
}
|
||||||
fontPicker.setFonts(state.textFonts, id === undefined ? null : state.textFonts.find(font => font.richKey === id));
|
fontPicker.setFonts(state.textFonts, id === undefined ? null : state.textFonts.find(font => font.richKey === id), preserve);
|
||||||
el.textFont.placeholder = id === undefined ? "混合" : "";
|
el.textFont.placeholder = id === undefined ? "混合" : "";
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -4446,7 +4446,7 @@ function updateTextFonts(item, refresh = false) {
|
|||||||
state.textFonts.unshift(selected);
|
state.textFonts.unshift(selected);
|
||||||
}
|
}
|
||||||
const mixed = (item?.items || item?.richText) && !id;
|
const mixed = (item?.items || item?.richText) && !id;
|
||||||
fontPicker.setFonts(state.textFonts, mixed ? null : selected || state.textFonts[0]);
|
fontPicker.setFonts(state.textFonts, mixed ? null : selected || state.textFonts[0], preserve);
|
||||||
el.textFont.placeholder = mixed ? "混合" : "";
|
el.textFont.placeholder = mixed ? "混合" : "";
|
||||||
if (!id && !item?.items && !item?.richText) state.textDefaults.fontChoice = state.textFonts[Number(fontPicker.value)];
|
if (!id && !item?.items && !item?.richText) state.textDefaults.fontChoice = state.textFonts[Number(fontPicker.value)];
|
||||||
}
|
}
|
||||||
@@ -5262,6 +5262,7 @@ async function boot() {
|
|||||||
updateControls();
|
updateControls();
|
||||||
updateLocalFontButton();
|
updateLocalFontButton();
|
||||||
await fontManager.refreshPermission();
|
await fontManager.refreshPermission();
|
||||||
|
loadEditorFonts(false);
|
||||||
if (openSeq === state.openSeq) {
|
if (openSeq === state.openSeq) {
|
||||||
setStatus(fontsRestored ? STATUS.ready : "字体读取失败");
|
setStatus(fontsRestored ? STATUS.ready : "字体读取失败");
|
||||||
setBusy(false);
|
setBusy(false);
|
||||||
@@ -6281,7 +6282,8 @@ async function changeFont(font, changes) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function renderFontList() {
|
function renderFontList() {
|
||||||
updateTextFonts(canvasEditor.selected, true);
|
refreshEditorFonts();
|
||||||
|
if (state.ready) loadEditorFonts(false);
|
||||||
el.fontList.replaceChildren();
|
el.fontList.replaceChildren();
|
||||||
const fonts = fontManager.records();
|
const fonts = fontManager.records();
|
||||||
if (!fonts.length) {
|
if (!fonts.length) {
|
||||||
|
|||||||
@@ -5,13 +5,14 @@ export class FontPicker {
|
|||||||
Object.assign(this, { input, toggle, list, onChange, onOpen, fonts: [], value: "", active: -1, open: false });
|
Object.assign(this, { input, toggle, list, onChange, onOpen, fonts: [], value: "", active: -1, open: false });
|
||||||
input.addEventListener("input", () => this.show(input.value));
|
input.addEventListener("input", () => this.show(input.value));
|
||||||
input.addEventListener("focus", () => input.select());
|
input.addEventListener("focus", () => input.select());
|
||||||
input.addEventListener("click", () => { if (!this.open) this.show(); });
|
input.addEventListener("pointerdown", event => { if (event.button === 0 && !this.open) event.preventDefault(); });
|
||||||
|
input.addEventListener("click", () => { if (!this.open) { input.focus(); input.select(); this.show(); } });
|
||||||
input.addEventListener("keydown", event => this.keyDown(event));
|
input.addEventListener("keydown", event => this.keyDown(event));
|
||||||
input.addEventListener("blur", () => { this.commitExact(); this.close(); });
|
input.addEventListener("blur", () => { this.commitExact(); this.close(); });
|
||||||
toggle.addEventListener("pointerdown", event => event.preventDefault());
|
toggle.addEventListener("pointerdown", event => event.preventDefault());
|
||||||
toggle.addEventListener("click", () => {
|
toggle.addEventListener("click", () => {
|
||||||
if (this.open) this.close();
|
if (this.open) this.close();
|
||||||
else { input.focus(); this.show(); }
|
else { input.focus(); input.select(); this.show(); }
|
||||||
});
|
});
|
||||||
list.addEventListener("pointerdown", event => {
|
list.addEventListener("pointerdown", event => {
|
||||||
if (event.target.closest(".font-option")) event.preventDefault();
|
if (event.target.closest(".font-option")) event.preventDefault();
|
||||||
@@ -23,8 +24,9 @@ export class FontPicker {
|
|||||||
window.addEventListener("resize", () => this.close());
|
window.addEventListener("resize", () => this.close());
|
||||||
}
|
}
|
||||||
|
|
||||||
setFonts(fonts, selected) {
|
setFonts(fonts, selected, preserve = false) {
|
||||||
this.close();
|
const open = preserve && this.open;
|
||||||
|
if (!open) this.close();
|
||||||
this.fonts = fonts;
|
this.fonts = fonts;
|
||||||
this.names = new Map();
|
this.names = new Map();
|
||||||
for (const font of fonts) {
|
for (const font of fonts) {
|
||||||
@@ -33,7 +35,12 @@ export class FontPicker {
|
|||||||
}
|
}
|
||||||
const key = font => font?.richKey || font?.id || font?.postscriptName;
|
const key = font => font?.richKey || font?.id || font?.postscriptName;
|
||||||
this.value = !fonts.length ? "" : selected === null ? "-1" : String(Math.max(0, fonts.findIndex(font => key(font) === key(selected))));
|
this.value = !fonts.length ? "" : selected === null ? "-1" : String(Math.max(0, fonts.findIndex(font => key(font) === key(selected))));
|
||||||
this.restore();
|
if (open) {
|
||||||
|
const active = this.matches[this.active]?.font;
|
||||||
|
this.show(this.query, false);
|
||||||
|
const index = active ? this.matches.findIndex(({ font }) => !font.disabled && key(font) === key(active)) : -1;
|
||||||
|
if (index >= 0) this.activate(index);
|
||||||
|
} else this.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
setDisabled(disabled) {
|
setDisabled(disabled) {
|
||||||
@@ -43,7 +50,11 @@ export class FontPicker {
|
|||||||
|
|
||||||
restore() {
|
restore() {
|
||||||
const font = this.fonts[Number(this.value)];
|
const font = this.fonts[Number(this.value)];
|
||||||
this.input.value = font?.fullName || font?.name || "";
|
const value = font?.fullName || font?.name || "";
|
||||||
|
if (this.input.value !== value) {
|
||||||
|
this.input.value = value;
|
||||||
|
if (document.activeElement === this.input) this.input.select();
|
||||||
|
}
|
||||||
this.input.scrollLeft = 0;
|
this.input.scrollLeft = 0;
|
||||||
this.input.title = font ? [this.input.value, this.sourceLabel(font)].filter(Boolean).join(" · ") : "";
|
this.input.title = font ? [this.input.value, this.sourceLabel(font)].filter(Boolean).join(" · ") : "";
|
||||||
}
|
}
|
||||||
@@ -56,6 +67,7 @@ export class FontPicker {
|
|||||||
|
|
||||||
show(query = "", load = true) {
|
show(query = "", load = true) {
|
||||||
if (this.input.disabled) return;
|
if (this.input.disabled) return;
|
||||||
|
this.query = query;
|
||||||
const normalize = value => value.normalize("NFKC").toLocaleLowerCase().replace(/\s+/g, " ").trim();
|
const normalize = value => value.normalize("NFKC").toLocaleLowerCase().replace(/\s+/g, " ").trim();
|
||||||
const terms = normalize(query).split(" ").filter(Boolean);
|
const terms = normalize(query).split(" ").filter(Boolean);
|
||||||
this.matches = this.fonts.map((font, index) => ({ font, index })).filter(({ font }) => {
|
this.matches = this.fonts.map((font, index) => ({ font, index })).filter(({ font }) => {
|
||||||
@@ -314,12 +326,12 @@ export class FontManager {
|
|||||||
}), ...this.catalog];
|
}), ...this.catalog];
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadFaces(inspect) {
|
async loadFaces(inspect, current = () => true) {
|
||||||
while (true) {
|
while (current()) {
|
||||||
const file = this.userFonts.find(font => font.enabled && !font.faces);
|
const file = this.userFonts.find(font => font.enabled && !font.faces);
|
||||||
if (!file) return;
|
if (!file) return;
|
||||||
try { file.faces = await inspect(await this.read(file)); }
|
try { file.faces = await inspect(await this.read(file)); }
|
||||||
catch { file.faces = []; }
|
catch { if (!current()) return; file.faces = []; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user