diff --git a/frontend/bindings/voidraft/internal/models/models.ts b/frontend/bindings/voidraft/internal/models/models.ts index 810f45d..0a4e4ed 100644 --- a/frontend/bindings/voidraft/internal/models/models.ts +++ b/frontend/bindings/voidraft/internal/models/models.ts @@ -253,6 +253,21 @@ export class EditorConfig { */ "fontSize": number; + /** + * 字体族 + */ + "fontFamily": string; + + /** + * 字体粗细 + */ + "fontWeight": string; + + /** + * 行高 + */ + "lineHeight": number; + /** * 是否启用Tab缩进 */ @@ -283,6 +298,15 @@ export class EditorConfig { if (!("fontSize" in $$source)) { this["fontSize"] = 0; } + if (!("fontFamily" in $$source)) { + this["fontFamily"] = ""; + } + if (!("fontWeight" in $$source)) { + this["fontWeight"] = ""; + } + if (!("lineHeight" in $$source)) { + this["lineHeight"] = 0; + } if (!("enableTabIndent" in $$source)) { this["enableTabIndent"] = false; } diff --git a/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_Sans/HarmonyOS_Sans_Black.ttf b/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_Sans/HarmonyOS_Sans_Black.ttf new file mode 100644 index 0000000..e551ec3 Binary files /dev/null and b/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_Sans/HarmonyOS_Sans_Black.ttf differ diff --git a/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_Sans/HarmonyOS_Sans_Bold.ttf b/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_Sans/HarmonyOS_Sans_Bold.ttf new file mode 100644 index 0000000..d4a5771 Binary files /dev/null and b/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_Sans/HarmonyOS_Sans_Bold.ttf differ diff --git a/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_Sans/HarmonyOS_Sans_Light.ttf b/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_Sans/HarmonyOS_Sans_Light.ttf new file mode 100644 index 0000000..ca84eb1 Binary files /dev/null and b/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_Sans/HarmonyOS_Sans_Light.ttf differ diff --git a/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_Sans/HarmonyOS_Sans_Medium.ttf b/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_Sans/HarmonyOS_Sans_Medium.ttf new file mode 100644 index 0000000..c71de84 Binary files /dev/null and b/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_Sans/HarmonyOS_Sans_Medium.ttf differ diff --git a/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_Sans/HarmonyOS_Sans_Regular.ttf b/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_Sans/HarmonyOS_Sans_Regular.ttf new file mode 100644 index 0000000..830b2af Binary files /dev/null and b/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_Sans/HarmonyOS_Sans_Regular.ttf differ diff --git a/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_Sans/HarmonyOS_Sans_Semibold.ttf b/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_Sans/HarmonyOS_Sans_Semibold.ttf new file mode 100644 index 0000000..27551a3 Binary files /dev/null and b/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_Sans/HarmonyOS_Sans_Semibold.ttf differ diff --git a/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_Sans/HarmonyOS_Sans_Thin.ttf b/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_Sans/HarmonyOS_Sans_Thin.ttf new file mode 100644 index 0000000..56c5ae5 Binary files /dev/null and b/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_Sans/HarmonyOS_Sans_Thin.ttf differ diff --git a/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_SansSC/HarmonyOS_SansSC_Black.ttf b/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_SansSC/HarmonyOS_SansSC_Black.ttf new file mode 100644 index 0000000..184e791 Binary files /dev/null and b/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_SansSC/HarmonyOS_SansSC_Black.ttf differ diff --git a/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_SansSC/HarmonyOS_SansSC_Bold.ttf b/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_SansSC/HarmonyOS_SansSC_Bold.ttf new file mode 100644 index 0000000..2a3791f Binary files /dev/null and b/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_SansSC/HarmonyOS_SansSC_Bold.ttf differ diff --git a/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_SansSC/HarmonyOS_SansSC_Light.ttf b/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_SansSC/HarmonyOS_SansSC_Light.ttf new file mode 100644 index 0000000..c376b15 Binary files /dev/null and b/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_SansSC/HarmonyOS_SansSC_Light.ttf differ diff --git a/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_SansSC/HarmonyOS_SansSC_Medium.ttf b/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_SansSC/HarmonyOS_SansSC_Medium.ttf new file mode 100644 index 0000000..527457d Binary files /dev/null and b/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_SansSC/HarmonyOS_SansSC_Medium.ttf differ diff --git a/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_SansSC/HarmonyOS_SansSC_Regular.ttf b/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_SansSC/HarmonyOS_SansSC_Regular.ttf new file mode 100644 index 0000000..02456d2 Binary files /dev/null and b/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_SansSC/HarmonyOS_SansSC_Regular.ttf differ diff --git a/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_SansSC/HarmonyOS_SansSC_Semibold.ttf b/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_SansSC/HarmonyOS_SansSC_Semibold.ttf new file mode 100644 index 0000000..b2c59ca Binary files /dev/null and b/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_SansSC/HarmonyOS_SansSC_Semibold.ttf differ diff --git a/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_SansSC/HarmonyOS_SansSC_Thin.ttf b/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_SansSC/HarmonyOS_SansSC_Thin.ttf new file mode 100644 index 0000000..0420a61 Binary files /dev/null and b/frontend/src/assets/fonts/HarmonyOS Sans/HarmonyOS_SansSC/HarmonyOS_SansSC_Thin.ttf differ diff --git a/frontend/src/assets/styles/fonts.css b/frontend/src/assets/styles/fonts.css new file mode 100644 index 0000000..6433e99 --- /dev/null +++ b/frontend/src/assets/styles/fonts.css @@ -0,0 +1,146 @@ +/* HarmonyOS Sans 字体定义 */ + +/* HarmonyOS Sans Regular */ +@font-face { + font-family: 'HarmonyOS Sans'; + src: url('../fonts/HarmonyOS Sans/HarmonyOS_Sans/HarmonyOS_Sans_Regular.ttf') format('truetype'); + font-weight: 400; + font-style: normal; + font-display: swap; +} + +/* HarmonyOS Sans Light */ +@font-face { + font-family: 'HarmonyOS Sans'; + src: url('../fonts/HarmonyOS Sans/HarmonyOS_Sans/HarmonyOS_Sans_Light.ttf') format('truetype'); + font-weight: 300; + font-style: normal; + font-display: swap; +} + +/* HarmonyOS Sans Medium */ +@font-face { + font-family: 'HarmonyOS Sans'; + src: url('../fonts/HarmonyOS Sans/HarmonyOS_Sans/HarmonyOS_Sans_Medium.ttf') format('truetype'); + font-weight: 500; + font-style: normal; + font-display: swap; +} + +/* HarmonyOS Sans Semibold */ +@font-face { + font-family: 'HarmonyOS Sans'; + src: url('../fonts/HarmonyOS Sans/HarmonyOS_Sans/HarmonyOS_Sans_Semibold.ttf') format('truetype'); + font-weight: 600; + font-style: normal; + font-display: swap; +} + +/* HarmonyOS Sans Bold */ +@font-face { + font-family: 'HarmonyOS Sans'; + src: url('../fonts/HarmonyOS Sans/HarmonyOS_Sans/HarmonyOS_Sans_Bold.ttf') format('truetype'); + font-weight: 700; + font-style: normal; + font-display: swap; +} + +/* HarmonyOS Sans Black */ +@font-face { + font-family: 'HarmonyOS Sans'; + src: url('../fonts/HarmonyOS Sans/HarmonyOS_Sans/HarmonyOS_Sans_Black.ttf') format('truetype'); + font-weight: 900; + font-style: normal; + font-display: swap; +} + +/* HarmonyOS Sans Thin */ +@font-face { + font-family: 'HarmonyOS Sans'; + src: url('../fonts/HarmonyOS Sans/HarmonyOS_Sans/HarmonyOS_Sans_Thin.ttf') format('truetype'); + font-weight: 100; + font-style: normal; + font-display: swap; +} + +/* HarmonyOS Sans SC 简体中文字体 */ + +/* HarmonyOS Sans SC Regular */ +@font-face { + font-family: 'HarmonyOS Sans SC'; + src: url('../fonts/HarmonyOS Sans/HarmonyOS_SansSC/HarmonyOS_SansSC_Regular.ttf') format('truetype'); + font-weight: 400; + font-style: normal; + font-display: swap; +} + +/* HarmonyOS Sans SC Light */ +@font-face { + font-family: 'HarmonyOS Sans SC'; + src: url('../fonts/HarmonyOS Sans/HarmonyOS_SansSC/HarmonyOS_SansSC_Light.ttf') format('truetype'); + font-weight: 300; + font-style: normal; + font-display: swap; +} + +/* HarmonyOS Sans SC Medium */ +@font-face { + font-family: 'HarmonyOS Sans SC'; + src: url('../fonts/HarmonyOS Sans/HarmonyOS_SansSC/HarmonyOS_SansSC_Medium.ttf') format('truetype'); + font-weight: 500; + font-style: normal; + font-display: swap; +} + +/* HarmonyOS Sans SC Semibold */ +@font-face { + font-family: 'HarmonyOS Sans SC'; + src: url('../fonts/HarmonyOS Sans/HarmonyOS_SansSC/HarmonyOS_SansSC_Semibold.ttf') format('truetype'); + font-weight: 600; + font-style: normal; + font-display: swap; +} + +/* HarmonyOS Sans SC Bold */ +@font-face { + font-family: 'HarmonyOS Sans SC'; + src: url('../fonts/HarmonyOS Sans/HarmonyOS_SansSC/HarmonyOS_SansSC_Bold.ttf') format('truetype'); + font-weight: 700; + font-style: normal; + font-display: swap; +} + +/* HarmonyOS Sans SC Black */ +@font-face { + font-family: 'HarmonyOS Sans SC'; + src: url('../fonts/HarmonyOS Sans/HarmonyOS_SansSC/HarmonyOS_SansSC_Black.ttf') format('truetype'); + font-weight: 900; + font-style: normal; + font-display: swap; +} + +/* HarmonyOS Sans SC Thin */ +@font-face { + font-family: 'HarmonyOS Sans SC'; + src: url('../fonts/HarmonyOS Sans/HarmonyOS_SansSC/HarmonyOS_SansSC_Thin.ttf') format('truetype'); + font-weight: 100; + font-style: normal; + font-display: swap; +} + +/* 字体加载优化 */ +.font-loading { + font-family: system-ui, -apple-system, sans-serif; +} + +.font-loaded { + font-family: 'HarmonyOS Sans SC', 'HarmonyOS Sans', 'Microsoft YaHei', 'PingFang SC', 'Helvetica Neue', Arial, sans-serif; +} + +/* CodeMirror 专用字体类 */ +.cm-harmonyos-font { + font-family: 'HarmonyOS Sans SC', 'HarmonyOS Sans', 'Microsoft YaHei', 'PingFang SC', 'Helvetica Neue', Arial, sans-serif !important; + font-feature-settings: 'liga' 1, 'calt' 1; + font-variant-ligatures: contextual; + text-rendering: optimizeLegibility; +} \ No newline at end of file diff --git a/frontend/src/assets/styles/index.css b/frontend/src/assets/styles/index.css index d32c399..9b40cb2 100644 --- a/frontend/src/assets/styles/index.css +++ b/frontend/src/assets/styles/index.css @@ -1,3 +1,4 @@ /* 导入所有CSS文件 */ @import 'normalize.css'; -@import 'variables.css'; \ No newline at end of file +@import 'variables.css'; +@import "fonts.css"; \ No newline at end of file diff --git a/frontend/src/editor/Editor.vue b/frontend/src/editor/Editor.vue index 1e748a3..c1c93bc 100644 --- a/frontend/src/editor/Editor.vue +++ b/frontend/src/editor/Editor.vue @@ -15,6 +15,8 @@ import { updateTabConfig, createAutoSavePlugin, createSaveShortcutPlugin, + createFontExtensionFromBackend, + updateFontConfig, } from './extensions'; import { useI18n } from 'vue-i18n'; import { DocumentService } from '@/../bindings/voidraft/internal/services'; @@ -56,6 +58,14 @@ const createEditor = async () => { configStore.config.tabType ); + // 创建字体扩展 + const fontExtension = createFontExtensionFromBackend({ + fontFamily: configStore.config.fontFamily, + fontSize: configStore.config.fontSize, + lineHeight: configStore.config.lineHeight, + fontWeight: configStore.config.fontWeight + }); + // 创建统计信息更新扩展 const statsExtension = createStatsUpdateExtension( editorStore.updateDocumentStats @@ -82,6 +92,7 @@ const createEditor = async () => { const extensions: Extension[] = [ ...basicExtensions, ...tabExtensions, + fontExtension, statsExtension, saveShortcutPlugin, autoSavePlugin @@ -143,6 +154,17 @@ const reconfigureTabSettings = () => { ); }; +// 重新配置字体设置 +const reconfigureFontSettings = () => { + if (!editorStore.editorView) return; + updateFontConfig(editorStore.editorView as EditorView, { + fontFamily: configStore.config.fontFamily, + fontSize: configStore.config.fontSize, + lineHeight: configStore.config.lineHeight, + fontWeight: configStore.config.fontWeight + }); +}; + // 监听Tab设置变化 watch(() => configStore.config.tabSize, reconfigureTabSettings); watch(() => configStore.config.enableTabIndent, reconfigureTabSettings); @@ -150,9 +172,19 @@ watch(() => configStore.config.tabType, reconfigureTabSettings); // 监听字体大小变化 watch(() => configStore.config.fontSize, () => { + reconfigureFontSettings(); editorStore.applyFontSize(); }); +// 监听字体族变化 +watch(() => configStore.config.fontFamily, reconfigureFontSettings); + +// 监听字体粗细变化 +watch(() => configStore.config.fontWeight, reconfigureFontSettings); + +// 监听行高变化 +watch(() => configStore.config.lineHeight, reconfigureFontSettings); + onMounted(() => { // 创建编辑器 createEditor(); diff --git a/frontend/src/editor/extensions/fontExtension.ts b/frontend/src/editor/extensions/fontExtension.ts new file mode 100644 index 0000000..269a0ca --- /dev/null +++ b/frontend/src/editor/extensions/fontExtension.ts @@ -0,0 +1,219 @@ +import { EditorView } from '@codemirror/view'; +import { Extension, Compartment } from '@codemirror/state'; + +// 字体配置接口 +export interface FontConfig { + fontFamily: string; + fontSize?: number; + lineHeight?: number; + fontWeight?: string; +} + +// 创建字体配置compartment +export const fontCompartment = new Compartment(); + +// 默认鸿蒙字体配置 +export const HARMONYOS_FONT_CONFIG: FontConfig = { + fontFamily: '"HarmonyOS Sans SC", "HarmonyOS Sans", "Microsoft YaHei", "PingFang SC", "Helvetica Neue", Arial, sans-serif', + fontSize: 14, + lineHeight: 1.5, + fontWeight: 'normal' +}; + +// 从后端配置创建字体配置 +export function createFontConfigFromBackend(backendConfig: { + fontFamily?: string; + fontSize?: number; + lineHeight?: number; + fontWeight?: string; +}): FontConfig { + return { + fontFamily: backendConfig.fontFamily || HARMONYOS_FONT_CONFIG.fontFamily, + fontSize: backendConfig.fontSize || HARMONYOS_FONT_CONFIG.fontSize, + lineHeight: backendConfig.lineHeight || HARMONYOS_FONT_CONFIG.lineHeight, + fontWeight: backendConfig.fontWeight || HARMONYOS_FONT_CONFIG.fontWeight, + }; +} + +// 创建字体样式扩展 +export function createFontExtension(config: Partial = {}): Extension { + const fontConfig = { ...HARMONYOS_FONT_CONFIG, ...config }; + + const styles: Record = { + '&': { + fontFamily: fontConfig.fontFamily, + ...(fontConfig.fontSize && { fontSize: `${fontConfig.fontSize}px` }), + ...(fontConfig.lineHeight && { lineHeight: fontConfig.lineHeight.toString() }), + ...(fontConfig.fontWeight && { fontWeight: fontConfig.fontWeight }), + }, + '.cm-content': { + fontFamily: fontConfig.fontFamily, + ...(fontConfig.fontSize && { fontSize: `${fontConfig.fontSize}px` }), + ...(fontConfig.lineHeight && { lineHeight: fontConfig.lineHeight.toString() }), + ...(fontConfig.fontWeight && { fontWeight: fontConfig.fontWeight }), + }, + '.cm-editor': { + fontFamily: fontConfig.fontFamily, + }, + '.cm-scroller': { + fontFamily: fontConfig.fontFamily, + }, + '.cm-gutters': { + fontFamily: fontConfig.fontFamily, + ...(fontConfig.fontSize && { fontSize: `${fontConfig.fontSize}px` }), + }, + '.cm-lineNumbers': { + fontFamily: fontConfig.fontFamily, + ...(fontConfig.fontSize && { fontSize: `${Math.max(10, fontConfig.fontSize - 1)}px` }), + }, + '.cm-tooltip': { + fontFamily: fontConfig.fontFamily, + ...(fontConfig.fontSize && { fontSize: `${Math.max(12, fontConfig.fontSize - 1)}px` }), + }, + '.cm-completionLabel': { + fontFamily: fontConfig.fontFamily, + }, + '.cm-completionDetail': { + fontFamily: fontConfig.fontFamily, + } + }; + + return EditorView.theme(styles); +} + +// 创建响应式字体大小扩展 +export function createResponsiveFontExtension(baseFontSize: number = 14): Extension { + return fontCompartment.of(createFontExtension({ + fontSize: baseFontSize, + lineHeight: 1.5 + })); +} + +// 从后端配置创建字体扩展 +export function createFontExtensionFromBackend(backendConfig: { + fontFamily?: string; + fontSize?: number; + lineHeight?: number; + fontWeight?: string; +}): Extension { + const fontConfig = createFontConfigFromBackend(backendConfig); + return fontCompartment.of(createFontExtension(fontConfig)); +} + +// 动态更新字体配置 +export function updateFontConfig(view: EditorView, config: Partial): void { + const newFontExtension = createFontExtension(config); + + // 使用compartment重新配置字体扩展 + view.dispatch({ + effects: fontCompartment.reconfigure(newFontExtension) + }); +} + +// 预设字体配置 +export const FONT_PRESETS = { + // 鸿蒙字体系列 + harmonyos: { + name: '鸿蒙字体', + fontFamily: '"HarmonyOS Sans SC", "HarmonyOS Sans", "Microsoft YaHei", "PingFang SC", "Helvetica Neue", Arial, sans-serif', + fontSize: 14, + lineHeight: 1.5, + fontWeight: 'normal' + }, + harmonyosCondensed: { + name: '鸿蒙紧凑字体', + fontFamily: '"HarmonyOS Sans Condensed", "HarmonyOS Sans SC", "HarmonyOS Sans", "Microsoft YaHei", "PingFang SC", "Helvetica Neue", Arial, sans-serif', + fontSize: 14, + lineHeight: 1.4, + fontWeight: 'normal' + }, + + // 编程专用字体 + jetbrainsMono: { + name: 'JetBrains Mono', + fontFamily: '"JetBrains Mono", "Fira Code", "SF Mono", Monaco, Consolas, "Ubuntu Mono", monospace', + fontSize: 14, + lineHeight: 1.5, + fontWeight: 'normal' + }, + firaCode: { + name: 'Fira Code', + fontFamily: '"Fira Code", "JetBrains Mono", "SF Mono", Monaco, Consolas, "Ubuntu Mono", monospace', + fontSize: 14, + lineHeight: 1.5, + fontWeight: 'normal' + }, + sourceCodePro: { + name: 'Source Code Pro', + fontFamily: '"Source Code Pro", "SF Mono", Monaco, Consolas, "Ubuntu Mono", monospace', + fontSize: 14, + lineHeight: 1.5, + fontWeight: 'normal' + }, + + // 系统字体 + systemMono: { + name: '系统等宽字体', + fontFamily: '"SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas, "Courier New", monospace', + fontSize: 14, + lineHeight: 1.5, + fontWeight: 'normal' + }, + cascadiaCode: { + name: 'Cascadia Code', + fontFamily: '"Cascadia Code", "SF Mono", Monaco, Consolas, "Ubuntu Mono", monospace', + fontSize: 14, + lineHeight: 1.5, + fontWeight: 'normal' + }, + + // 中文友好字体 + microsoftYaHei: { + name: '微软雅黑', + fontFamily: '"Microsoft YaHei", "PingFang SC", "Helvetica Neue", Arial, sans-serif', + fontSize: 14, + lineHeight: 1.5, + fontWeight: 'normal' + }, + pingFang: { + name: '苹方字体', + fontFamily: '"PingFang SC", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif', + fontSize: 14, + lineHeight: 1.5, + fontWeight: 'normal' + }, + + // 经典字体 + arial: { + name: 'Arial', + fontFamily: 'Arial, "Helvetica Neue", Helvetica, sans-serif', + fontSize: 14, + lineHeight: 1.5, + fontWeight: 'normal' + }, + helvetica: { + name: 'Helvetica', + fontFamily: '"Helvetica Neue", Helvetica, Arial, sans-serif', + fontSize: 14, + lineHeight: 1.5, + fontWeight: 'normal' + } +} as const; + +// 字体预设类型 +export type FontPresetKey = keyof typeof FONT_PRESETS; + +// 获取所有字体预设选项 +export function getFontPresetOptions() { + return Object.entries(FONT_PRESETS).map(([key, preset]) => ({ + value: key as FontPresetKey, + label: preset.name, + fontFamily: preset.fontFamily + })); +} + +// 根据预设创建字体扩展 +export function createPresetFontExtension(preset: keyof typeof FONT_PRESETS, overrides: Partial = {}): Extension { + const config = { ...FONT_PRESETS[preset], ...overrides }; + return createFontExtension(config); +} \ No newline at end of file diff --git a/frontend/src/editor/extensions/index.ts b/frontend/src/editor/extensions/index.ts index 22f2480..5386b43 100644 --- a/frontend/src/editor/extensions/index.ts +++ b/frontend/src/editor/extensions/index.ts @@ -2,4 +2,5 @@ export * from './tabExtension'; export * from './wheelZoomExtension'; export * from './statsExtension'; -export * from './autoSaveExtension'; \ No newline at end of file +export * from './autoSaveExtension'; +export * from './fontExtension'; \ No newline at end of file diff --git a/frontend/src/i18n/locales/en-US.ts b/frontend/src/i18n/locales/en-US.ts index b089a0f..feb7677 100644 --- a/frontend/src/i18n/locales/en-US.ts +++ b/frontend/src/i18n/locales/en-US.ts @@ -66,6 +66,13 @@ export default { selectDirectory: 'Select Directory', fontSize: 'Font Size', fontSizeDescription: 'Editor font size', + fontSettings: 'Font Settings', + fontPreset: 'Font Preset', + fontPresetDescription: 'Choose a predefined font combination', + fontWeight: 'Font Weight', + fontWeightDescription: 'Set the thickness of the font', + lineHeight: 'Line Height', + lineHeightDescription: 'Set the spacing between text lines', tabSettings: 'Tab Settings', tabSize: 'Tab Size', tabType: 'Tab Type', diff --git a/frontend/src/i18n/locales/zh-CN.ts b/frontend/src/i18n/locales/zh-CN.ts index ce99bfc..5dde485 100644 --- a/frontend/src/i18n/locales/zh-CN.ts +++ b/frontend/src/i18n/locales/zh-CN.ts @@ -66,6 +66,13 @@ export default { selectDirectory: '选择目录', fontSize: '字体大小', fontSizeDescription: '编辑器字体大小', + fontSettings: '字体设置', + fontPreset: '字体预设', + fontPresetDescription: '选择预设的字体组合', + fontWeight: '字体粗细', + fontWeightDescription: '设置字体的粗细程度', + lineHeight: '行高', + lineHeightDescription: '设置文本行之间的间距', tabSettings: 'Tab 设置', tabSize: 'Tab 大小', tabType: 'Tab 类型', diff --git a/frontend/src/router/index.ts b/frontend/src/router/index.ts index 8c6d838..ca56a07 100644 --- a/frontend/src/router/index.ts +++ b/frontend/src/router/index.ts @@ -1,4 +1,4 @@ -import {createRouter, createWebHistory, RouteRecordRaw} from 'vue-router'; +import {createRouter, createWebHashHistory, createWebHistory, RouteRecordRaw} from 'vue-router'; import Editor from '@/editor/Editor.vue'; import Settings from '@/settings/Settings.vue'; import GeneralPage from '@/settings/pages/GeneralPage.vue'; @@ -49,7 +49,7 @@ const routes: RouteRecordRaw[] = [ ]; const router = createRouter({ - history: createWebHistory(), + history: createWebHashHistory(), routes: routes }); diff --git a/frontend/src/settings/pages/EditingPage.vue b/frontend/src/settings/pages/EditingPage.vue index 254e963..d32882a 100644 --- a/frontend/src/settings/pages/EditingPage.vue +++ b/frontend/src/settings/pages/EditingPage.vue @@ -6,10 +6,54 @@ import SettingSection from '../components/SettingSection.vue'; import SettingItem from '../components/SettingItem.vue'; import ToggleSwitch from '../components/ToggleSwitch.vue'; import { TabType } from '@/../bindings/voidraft/internal/models/models'; +import { getFontPresetOptions, type FontPresetKey } from '@/editor/extensions/fontExtension'; const { t } = useI18n(); const configStore = useConfigStore(); +// 字体预设选项 +const fontPresetOptions = getFontPresetOptions(); +const currentFontPreset = computed(() => configStore.getCurrentFontPreset()); + +// 字体预设选择 +const handleFontPresetChange = (event: Event) => { + const target = event.target as HTMLSelectElement; + const presetKey = target.value; + if (presetKey && presetKey !== 'custom') { + configStore.setFontPreset(presetKey as FontPresetKey); + } +}; + +// 字体粗细选项 +const fontWeightOptions = [ + { value: '100', label: '极细 (100)' }, + { value: '200', label: '超细 (200)' }, + { value: '300', label: '细 (300)' }, + { value: 'normal', label: '正常 (400)' }, + { value: '500', label: '中等 (500)' }, + { value: '600', label: '半粗 (600)' }, + { value: 'bold', label: '粗体 (700)' }, + { value: '800', label: '超粗 (800)' }, + { value: '900', label: '极粗 (900)' } +]; + +// 字体粗细选择 +const handleFontWeightChange = (event: Event) => { + const target = event.target as HTMLSelectElement; + configStore.setFontWeight(target.value); +}; + +// 行高控制 +const increaseLineHeight = () => { + const newLineHeight = Math.min(3.0, configStore.config.lineHeight + 0.1); + configStore.setLineHeight(Math.round(newLineHeight * 10) / 10); +}; + +const decreaseLineHeight = () => { + const newLineHeight = Math.max(1.0, configStore.config.lineHeight - 0.1); + configStore.setLineHeight(Math.round(newLineHeight * 10) / 10); +}; + // 字体大小控制 const increaseFontSize = () => { configStore.increaseFontSize(); @@ -38,7 +82,27 @@ const decreaseTabSize = () => {