From 3e9db1f1259053ef97e587b30154957cababb3eb Mon Sep 17 00:00:00 2001 From: sudacode Date: Fri, 27 Feb 2026 00:03:07 -0800 Subject: [PATCH] feat(config): refresh subtitle style defaults and drop plugin legacy startup alias --- config.example.jsonc | 37 ++++++++++++++------- docs/configuration.md | 20 +++++++---- docs/public/config.example.jsonc | 31 ++++++++++++----- plugin/subminer.conf | 3 -- plugin/subminer.lua | 8 +---- src/config/config.test.ts | 16 ++++++++- src/config/definitions/defaults-subtitle.ts | 26 +++++++++++---- src/renderer/subtitle-render.ts | 4 +-- src/types.ts | 18 ++++++++-- 9 files changed, 114 insertions(+), 49 deletions(-) diff --git a/config.example.jsonc b/config.example.jsonc index d32ca21..2c61a92 100644 --- a/config.example.jsonc +++ b/config.example.jsonc @@ -13,11 +13,11 @@ "auto_start_overlay": false, // When overlay connects to mpv, automatically show overlay and hide mpv subtitles. Values: true | false // ========================================== - // Visible Overlay Subtitle Binding (Legacy) - // Backward-compatible key. Runtime ignores this value. - // MPV subtitles are automatically hidden whenever any overlay subtitle mode is visible. + // Visible Overlay Subtitle Binding + // Control whether visible overlay toggles also toggle MPV subtitle visibility. + // When enabled, visible overlay hides MPV subtitles; when disabled, MPV subtitles are left unchanged. // ========================================== - "bind_visible_overlay_to_mpv_sub_visibility": true, // Legacy compatibility key (runtime no-op). Values: true | false + "bind_visible_overlay_to_mpv_sub_visibility": true, // Link visible overlay toggles to MPV primary subtitle visibility. Values: true | false // ========================================== // Texthooker Server @@ -112,17 +112,23 @@ // Hot-reload: subtitle style changes apply live without restarting SubMiner. // ========================================== "subtitleStyle": { - // Additional CSS declarations are also allowed and applied directly to subtitle roots/containers (for example: lineHeight, textShadow, -webkit-text-stroke, backdropFilter). "enableJlpt": false, // Enable JLPT vocabulary level underlines. When disabled, JLPT tagging lookup and underlines are skipped. Values: true | false "preserveLineBreaks": false, // Preserve line breaks in visible overlay subtitle rendering. When false, line breaks are flattened to spaces for a single-line flow. Values: true | false - "hoverTokenColor": "#f4dbd6", // Hex color used for hovered subtitle token highlight in the overlay. - "hoverTokenBackgroundColor": "#363a4fd6", // CSS color used for hovered subtitle token background highlight in the overlay. - "fontFamily": "M PLUS 1, Noto Sans CJK JP Regular, Noto Sans CJK JP, Hiragino Sans, Hiragino Kaku Gothic ProN, Yu Gothic, Arial Unicode MS, Arial, sans-serif", // Font family setting. + "hoverTokenColor": "#f4dbd6", // Hex color used for hovered subtitle token highlight in mpv. + "hoverTokenBackgroundColor": "rgba(54, 58, 79, 0.84)", // CSS color used for hovered subtitle token background highlight in mpv. + "fontFamily": "M PLUS 1 Medium, Source Han Sans JP, Noto Sans CJK JP", // Font family setting. "fontSize": 35, // Font size setting. "fontColor": "#cad3f5", // Font color setting. - "fontWeight": "normal", // Font weight setting. + "fontWeight": "600", // Font weight setting. + "lineHeight": 1.35, // Line height setting. + "letterSpacing": "-0.01em", // Letter spacing setting. + "wordSpacing": 0, // Word spacing setting. + "fontKerning": "normal", // Font kerning setting. + "textRendering": "geometricPrecision", // Text rendering setting. + "textShadow": "0 3px 10px rgba(0,0,0,0.69)", // Text shadow setting. "fontStyle": "normal", // Font style setting. "backgroundColor": "rgb(30, 32, 48, 0.88)", // Background color setting. + "backdropFilter": "blur(6px)", // Backdrop filter setting. "nPlusOneColor": "#c6a0f6", // N plus one color setting. "knownWordColor": "#a6da95", // Known word color setting. "jlptColors": { @@ -147,12 +153,19 @@ ] // Five colors used for rank bands when mode is `banded` (from most common to least within topX). }, // Frequency dictionary setting. "secondary": { + "fontFamily": "Manrope, Inter", // Font family setting. "fontSize": 24, // Font size setting. - "fontColor": "#ffffff", // Font color setting. + "fontColor": "#cad3f5", // Font color setting. + "lineHeight": 1.35, // Line height setting. + "letterSpacing": "-0.01em", // Letter spacing setting. + "wordSpacing": 0, // Word spacing setting. + "fontKerning": "normal", // Font kerning setting. + "textRendering": "geometricPrecision", // Text rendering setting. + "textShadow": "0 3px 10px rgba(0,0,0,0.69)", // Text shadow setting. "backgroundColor": "transparent", // Background color setting. + "backdropFilter": "blur(6px)", // Backdrop filter setting. "fontWeight": "normal", // Font weight setting. - "fontStyle": "normal", // Font style setting. - "fontFamily": "M PLUS 1, Noto Sans CJK JP Regular, Noto Sans CJK JP, Hiragino Sans, Hiragino Kaku Gothic ProN, Yu Gothic, Arial Unicode MS, Arial, sans-serif" // Font family setting. + "fontStyle": "normal" // Font style setting. } // Secondary setting. }, // Primary and secondary subtitle styling. diff --git a/docs/configuration.md b/docs/configuration.md index d747bb9..faaf219 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -724,15 +724,23 @@ See `config.example.jsonc` for detailed configuration options. ```json { "subtitleStyle": { - "fontFamily": "Noto Sans CJK JP Regular, Noto Sans CJK JP, Arial Unicode MS, Arial, sans-serif", + "fontFamily": "M PLUS 1 Medium, Source Han Sans JP, Noto Sans CJK JP", "fontSize": 35, "fontColor": "#cad3f5", - "fontWeight": "normal", + "fontWeight": "600", + "lineHeight": 1.35, + "letterSpacing": "-0.01em", + "wordSpacing": 0, + "fontKerning": "normal", + "textRendering": "geometricPrecision", + "textShadow": "0 3px 10px rgba(0,0,0,0.69)", "fontStyle": "normal", "backgroundColor": "rgb(30, 32, 48, 0.88)", + "backdropFilter": "blur(6px)", "secondary": { + "fontFamily": "Manrope, Inter", "fontSize": 24, - "fontColor": "#ffffff", + "fontColor": "#cad3f5", "backgroundColor": "transparent" } } @@ -741,10 +749,10 @@ See `config.example.jsonc` for detailed configuration options. | Option | Values | Description | | ---------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------- | -| `fontFamily` | string | CSS font-family value (default: `"Noto Sans CJK JP Regular, ..."`) | +| `fontFamily` | string | CSS font-family value (default: `"M PLUS 1 Medium, Source Han Sans JP, Noto Sans CJK JP"`) | | `fontSize` | number (px) | Font size in pixels (default: `35`) | | `fontColor` | string | Any CSS color value (default: `"#cad3f5"`) | -| `fontWeight` | string | CSS font-weight, e.g. `"bold"`, `"normal"`, `"600"` (default: `"normal"`) | +| `fontWeight` | string | CSS font-weight, e.g. `"bold"`, `"normal"`, `"600"` (default: `"600"`) | | `fontStyle` | string | `"normal"` or `"italic"` (default: `"normal"`) | | `backgroundColor` | string | Any CSS color, including `"transparent"` (default: `"rgb(30, 32, 48, 0.88)"`) | | `enableJlpt` | boolean | Enable JLPT level underline styling (`false` by default) | @@ -772,7 +780,7 @@ Lookup behavior: In `single` mode all highlights use `singleColor`; in `banded` mode tokens map to five ascending color bands from most common to least common inside the topX window. -Secondary subtitle defaults: `fontSize: 24`, `fontColor: "#ffffff"`, `backgroundColor: "transparent"`. Any property not set in `secondary` falls back to the CSS defaults. +Secondary subtitle defaults: `fontFamily: "Manrope, Inter"`, `fontSize: 24`, `fontColor: "#cad3f5"`, `backgroundColor: "transparent"`. Any property not set in `secondary` falls back to the CSS defaults. **See `config.example.jsonc`** for the complete list of subtitle style configuration options. diff --git a/docs/public/config.example.jsonc b/docs/public/config.example.jsonc index 4c0103c..2c61a92 100644 --- a/docs/public/config.example.jsonc +++ b/docs/public/config.example.jsonc @@ -17,7 +17,7 @@ // Control whether visible overlay toggles also toggle MPV subtitle visibility. // When enabled, visible overlay hides MPV subtitles; when disabled, MPV subtitles are left unchanged. // ========================================== - "bind_visible_overlay_to_mpv_sub_visibility": true, // Link visible overlay toggles to MPV subtitle visibility (primary and secondary). Values: true | false + "bind_visible_overlay_to_mpv_sub_visibility": true, // Link visible overlay toggles to MPV primary subtitle visibility. Values: true | false // ========================================== // Texthooker Server @@ -112,17 +112,23 @@ // Hot-reload: subtitle style changes apply live without restarting SubMiner. // ========================================== "subtitleStyle": { - // Additional CSS declarations are also allowed and applied directly to subtitle roots/containers (for example: lineHeight, textShadow, -webkit-text-stroke, backdropFilter). "enableJlpt": false, // Enable JLPT vocabulary level underlines. When disabled, JLPT tagging lookup and underlines are skipped. Values: true | false "preserveLineBreaks": false, // Preserve line breaks in visible overlay subtitle rendering. When false, line breaks are flattened to spaces for a single-line flow. Values: true | false - "hoverTokenColor": "#f4dbd6", // Hex color used for hovered subtitle token highlight in the overlay. - "hoverTokenBackgroundColor": "#363a4fd6", // CSS color used for hovered subtitle token background highlight in the overlay. - "fontFamily": "M PLUS 1, Noto Sans CJK JP Regular, Noto Sans CJK JP, Hiragino Sans, Hiragino Kaku Gothic ProN, Yu Gothic, Arial Unicode MS, Arial, sans-serif", // Font family setting. + "hoverTokenColor": "#f4dbd6", // Hex color used for hovered subtitle token highlight in mpv. + "hoverTokenBackgroundColor": "rgba(54, 58, 79, 0.84)", // CSS color used for hovered subtitle token background highlight in mpv. + "fontFamily": "M PLUS 1 Medium, Source Han Sans JP, Noto Sans CJK JP", // Font family setting. "fontSize": 35, // Font size setting. "fontColor": "#cad3f5", // Font color setting. - "fontWeight": "normal", // Font weight setting. + "fontWeight": "600", // Font weight setting. + "lineHeight": 1.35, // Line height setting. + "letterSpacing": "-0.01em", // Letter spacing setting. + "wordSpacing": 0, // Word spacing setting. + "fontKerning": "normal", // Font kerning setting. + "textRendering": "geometricPrecision", // Text rendering setting. + "textShadow": "0 3px 10px rgba(0,0,0,0.69)", // Text shadow setting. "fontStyle": "normal", // Font style setting. "backgroundColor": "rgb(30, 32, 48, 0.88)", // Background color setting. + "backdropFilter": "blur(6px)", // Backdrop filter setting. "nPlusOneColor": "#c6a0f6", // N plus one color setting. "knownWordColor": "#a6da95", // Known word color setting. "jlptColors": { @@ -147,12 +153,19 @@ ] // Five colors used for rank bands when mode is `banded` (from most common to least within topX). }, // Frequency dictionary setting. "secondary": { + "fontFamily": "Manrope, Inter", // Font family setting. "fontSize": 24, // Font size setting. - "fontColor": "#ffffff", // Font color setting. + "fontColor": "#cad3f5", // Font color setting. + "lineHeight": 1.35, // Line height setting. + "letterSpacing": "-0.01em", // Letter spacing setting. + "wordSpacing": 0, // Word spacing setting. + "fontKerning": "normal", // Font kerning setting. + "textRendering": "geometricPrecision", // Text rendering setting. + "textShadow": "0 3px 10px rgba(0,0,0,0.69)", // Text shadow setting. "backgroundColor": "transparent", // Background color setting. + "backdropFilter": "blur(6px)", // Backdrop filter setting. "fontWeight": "normal", // Font weight setting. - "fontStyle": "normal", // Font style setting. - "fontFamily": "M PLUS 1, Noto Sans CJK JP Regular, Noto Sans CJK JP, Hiragino Sans, Hiragino Kaku Gothic ProN, Yu Gothic, Arial Unicode MS, Arial, sans-serif" // Font family setting. + "fontStyle": "normal" // Font style setting. } // Secondary setting. }, // Primary and secondary subtitle styling. diff --git a/plugin/subminer.conf b/plugin/subminer.conf index 9b975fa..5fe8c23 100644 --- a/plugin/subminer.conf +++ b/plugin/subminer.conf @@ -26,9 +26,6 @@ auto_start=no # Automatically show visible overlay when overlay starts auto_start_visible_overlay=no -# Legacy alias (maps to auto_start_visible_overlay) -# auto_start_overlay=no - # Show OSD messages for overlay status osd_messages=yes diff --git a/plugin/subminer.lua b/plugin/subminer.lua index d5a9a16..9dd6cfd 100644 --- a/plugin/subminer.lua +++ b/plugin/subminer.lua @@ -134,7 +134,6 @@ local opts = { texthooker_port = 5174, backend = "auto", auto_start = true, - auto_start_overlay = false, -- legacy alias, maps to auto_start_visible_overlay auto_start_visible_overlay = false, osd_messages = true, log_level = "info", @@ -1438,12 +1437,7 @@ local function parse_start_script_message_overrides(...) end local function resolve_visible_overlay_startup() - local visible = coerce_bool(opts.auto_start_visible_overlay, false) - -- Backward compatibility for old config key. - if coerce_bool(opts.auto_start_overlay, false) then - visible = true - end - return visible + return coerce_bool(opts.auto_start_visible_overlay, false) end local function apply_startup_overlay_preferences() diff --git a/src/config/config.test.ts b/src/config/config.test.ts index 0337efa..b756ee8 100644 --- a/src/config/config.test.ts +++ b/src/config/config.test.ts @@ -28,7 +28,21 @@ test('loads defaults when config is missing', () => { assert.equal(config.subtitleStyle.backgroundColor, 'rgb(30, 32, 48, 0.88)'); assert.equal(config.subtitleStyle.preserveLineBreaks, false); assert.equal(config.subtitleStyle.hoverTokenColor, '#f4dbd6'); - assert.equal(config.subtitleStyle.hoverTokenBackgroundColor, '#363a4fd6'); + assert.equal(config.subtitleStyle.hoverTokenBackgroundColor, 'rgba(54, 58, 79, 0.84)'); + assert.equal( + config.subtitleStyle.fontFamily, + 'M PLUS 1 Medium, Source Han Sans JP, Noto Sans CJK JP', + ); + assert.equal(config.subtitleStyle.fontWeight, '600'); + assert.equal(config.subtitleStyle.lineHeight, 1.35); + assert.equal(config.subtitleStyle.letterSpacing, '-0.01em'); + assert.equal(config.subtitleStyle.wordSpacing, 0); + assert.equal(config.subtitleStyle.fontKerning, 'normal'); + assert.equal(config.subtitleStyle.textRendering, 'geometricPrecision'); + assert.equal(config.subtitleStyle.textShadow, '0 3px 10px rgba(0,0,0,0.69)'); + assert.equal(config.subtitleStyle.backdropFilter, 'blur(6px)'); + assert.equal(config.subtitleStyle.secondary.fontFamily, 'Manrope, Inter'); + assert.equal(config.subtitleStyle.secondary.fontColor, '#cad3f5'); assert.equal(config.immersionTracking.enabled, true); assert.equal(config.immersionTracking.dbPath, ''); assert.equal(config.immersionTracking.batchSize, 25); diff --git a/src/config/definitions/defaults-subtitle.ts b/src/config/definitions/defaults-subtitle.ts index 315f114..1f959ae 100644 --- a/src/config/definitions/defaults-subtitle.ts +++ b/src/config/definitions/defaults-subtitle.ts @@ -5,14 +5,20 @@ export const SUBTITLE_DEFAULT_CONFIG: Pick = { enableJlpt: false, preserveLineBreaks: false, hoverTokenColor: '#f4dbd6', - hoverTokenBackgroundColor: '#363a4fd6', - fontFamily: - 'M PLUS 1, Noto Sans CJK JP Regular, Noto Sans CJK JP, Hiragino Sans, Hiragino Kaku Gothic ProN, Yu Gothic, Arial Unicode MS, Arial, sans-serif', + hoverTokenBackgroundColor: 'rgba(54, 58, 79, 0.84)', + fontFamily: 'M PLUS 1 Medium, Source Han Sans JP, Noto Sans CJK JP', fontSize: 35, fontColor: '#cad3f5', - fontWeight: 'normal', + fontWeight: '600', + lineHeight: 1.35, + letterSpacing: '-0.01em', + wordSpacing: 0, + fontKerning: 'normal', + textRendering: 'geometricPrecision', + textShadow: '0 3px 10px rgba(0,0,0,0.69)', fontStyle: 'normal', backgroundColor: 'rgb(30, 32, 48, 0.88)', + backdropFilter: 'blur(6px)', nPlusOneColor: '#c6a0f6', knownWordColor: '#a6da95', jlptColors: { @@ -31,13 +37,19 @@ export const SUBTITLE_DEFAULT_CONFIG: Pick = { bandedColors: ['#ed8796', '#f5a97f', '#f9e2af', '#a6e3a1', '#8aadf4'], }, secondary: { + fontFamily: 'Manrope, Inter', fontSize: 24, - fontColor: '#ffffff', + fontColor: '#cad3f5', + lineHeight: 1.35, + letterSpacing: '-0.01em', + wordSpacing: 0, + fontKerning: 'normal', + textRendering: 'geometricPrecision', + textShadow: '0 3px 10px rgba(0,0,0,0.69)', backgroundColor: 'transparent', + backdropFilter: 'blur(6px)', fontWeight: 'normal', fontStyle: 'normal', - fontFamily: - 'M PLUS 1, Noto Sans CJK JP Regular, Noto Sans CJK JP, Hiragino Sans, Hiragino Kaku Gothic ProN, Yu Gothic, Arial Unicode MS, Arial, sans-serif', }, }, }; diff --git a/src/renderer/subtitle-render.ts b/src/renderer/subtitle-render.ts index b4480a3..ea71915 100644 --- a/src/renderer/subtitle-render.ts +++ b/src/renderer/subtitle-render.ts @@ -509,7 +509,7 @@ function renderSubtitle(data: SubtitleData | string): void { if (style.fontColor) { ctx.dom.subtitleRoot.style.color = style.fontColor; } - if (style.fontWeight) ctx.dom.subtitleRoot.style.fontWeight = style.fontWeight; + if (style.fontWeight) ctx.dom.subtitleRoot.style.fontWeight = String(style.fontWeight); if (style.fontStyle) ctx.dom.subtitleRoot.style.fontStyle = style.fontStyle; const knownWordColor = style.knownWordColor ?? ctx.state.knownWordColor ?? '#a6da95'; const nPlusOneColor = style.nPlusOneColor ?? ctx.state.nPlusOneColor ?? '#c6a0f6'; @@ -639,7 +639,7 @@ function renderSubtitle(data: SubtitleData | string): void { ctx.dom.secondarySubRoot.style.color = secondaryStyle.fontColor; } if (secondaryStyle.fontWeight) { - ctx.dom.secondarySubRoot.style.fontWeight = secondaryStyle.fontWeight; + ctx.dom.secondarySubRoot.style.fontWeight = String(secondaryStyle.fontWeight); } if (secondaryStyle.fontStyle) { ctx.dom.secondarySubRoot.style.fontStyle = secondaryStyle.fontStyle; diff --git a/src/types.ts b/src/types.ts index 1affa73..eb08b60 100644 --- a/src/types.ts +++ b/src/types.ts @@ -274,8 +274,15 @@ export interface SubtitleStyleConfig { fontFamily?: string; fontSize?: number; fontColor?: string; - fontWeight?: string; + fontWeight?: string | number; fontStyle?: string; + lineHeight?: string | number; + letterSpacing?: string; + wordSpacing?: string | number; + fontKerning?: string; + textRendering?: string; + textShadow?: string; + backdropFilter?: string; backgroundColor?: string; nPlusOneColor?: string; knownWordColor?: string; @@ -298,8 +305,15 @@ export interface SubtitleStyleConfig { fontFamily?: string; fontSize?: number; fontColor?: string; - fontWeight?: string; + fontWeight?: string | number; fontStyle?: string; + lineHeight?: string | number; + letterSpacing?: string; + wordSpacing?: string | number; + fontKerning?: string; + textRendering?: string; + textShadow?: string; + backdropFilter?: string; backgroundColor?: string; }; }