From 3602bc35a7ea21a56c57495289bfe58be4470f0d Mon Sep 17 00:00:00 2001 From: Amit Haridas Date: Thu, 23 Jul 2026 00:09:12 +0530 Subject: [PATCH] feat(monospace): add path resolver for bundled TTF assets --- src/main/MonospaceFontConfig.js | 55 ++++++++++++++ .../monospace/MonospaceFontConfig.test.js | 75 +++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 src/main/MonospaceFontConfig.js create mode 100644 tests/unit/main/monospace/MonospaceFontConfig.test.js diff --git a/src/main/MonospaceFontConfig.js b/src/main/MonospaceFontConfig.js new file mode 100644 index 0000000..274750d --- /dev/null +++ b/src/main/MonospaceFontConfig.js @@ -0,0 +1,55 @@ +'use strict'; + +const fs = require('fs'); +const path = require('path'); +const { + getActiveMonoFont, + isLigaturesEnabled, + FAMILY_BY_KEY, +} = require('./settings/monospaceSettings'); + +const WEIGHT_BY_KEY = { 300: 'Light', 400: 'Regular', 500: 'Medium', 600: 'SemiBold', 700: 'Bold' }; + +function getAppRoot() { + if ( + process.resourcesPath && + fs.existsSync(path.join(process.resourcesPath, 'app.asar.unpacked')) + ) { + return process.resourcesPath; + } + return path.resolve(__dirname, '..', '..'); +} + +function getCandidatePaths(family, weight) { + const familyDir = family === 'Fira Code' ? 'FiraCode' : 'JetBrainsMono'; + const weightName = WEIGHT_BY_KEY[weight] || 'Regular'; + const filename = `${familyDir}-${weightName}.ttf`; + const candidates = []; + candidates.push(path.resolve(getAppRoot(), 'assets', 'fonts', filename)); + const packagedRoot = process.resourcesPath || getAppRoot(); + candidates.push(path.join(packagedRoot, 'app.asar.unpacked', 'assets', 'fonts', filename)); + return candidates; +} + +function getMonoFontTtfPath(familyKey, weight = 400) { + const family = FAMILY_BY_KEY[familyKey] || 'JetBrains Mono'; + const candidates = getCandidatePaths(family, weight); + for (const p of candidates) { + if (fs.existsSync(p)) return p; + } + const filename = path.basename(candidates[candidates.length - 1]); + console.warn( + `[MonospaceFontConfig] bundled font missing: ${filename}; falling back to system monospace` + ); + return null; +} + +function ligaturesEnabled(settings) { + return isLigaturesEnabled(settings); +} + +function getActiveFamily(settings) { + return getActiveMonoFont(settings); +} + +module.exports = { getMonoFontTtfPath, ligaturesEnabled, getActiveFamily }; diff --git a/tests/unit/main/monospace/MonospaceFontConfig.test.js b/tests/unit/main/monospace/MonospaceFontConfig.test.js new file mode 100644 index 0000000..a40b243 --- /dev/null +++ b/tests/unit/main/monospace/MonospaceFontConfig.test.js @@ -0,0 +1,75 @@ +const fs = require('fs'); +const path = require('path'); +const os = require('os'); + +describe('MonospaceFontConfig', () => { + let tmpDir; + let originalResourcesPath; + let originalCwd; + + beforeEach(() => { + tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mono-font-cfg-')); + originalResourcesPath = process.resourcesPath; + originalCwd = process.cwd(); + process.resourcesPath = undefined; + }); + + afterEach(() => { + process.resourcesPath = originalResourcesPath; + process.chdir(originalCwd); + fs.rmSync(tmpDir, { recursive: true, force: true }); + }); + + function loadFresh() { + delete require.cache[require.resolve('../../../../src/main/MonospaceFontConfig')]; + return require('../../../../src/main/MonospaceFontConfig'); + } + + test('resolves JetBrains Mono Regular TTF from repo assets', () => { + const repoRoot = path.resolve(__dirname, '../../../..'); + const fontsDir = path.join(repoRoot, 'assets', 'fonts'); + fs.mkdirSync(fontsDir, { recursive: true }); + const target = path.join(fontsDir, 'JetBrainsMono-Regular.ttf'); + fs.writeFileSync(target, 'fake-ttf'); + try { + const cfg = loadFresh(); + const result = cfg.getMonoFontTtfPath('jetbrains-mono', 400); + expect(result).toBe(target); + } finally { + fs.unlinkSync(target); + } + }); + + test('resolves Fira Code Bold TTF when family is fira-code and weight 700', () => { + const repoRoot = path.resolve(__dirname, '../../../..'); + const target = path.join(repoRoot, 'assets', 'fonts', 'FiraCode-Bold.ttf'); + fs.mkdirSync(path.dirname(target), { recursive: true }); + fs.writeFileSync(target, 'fake-ttf'); + try { + const cfg = loadFresh(); + const result = cfg.getMonoFontTtfPath('fira-code', 700); + expect(result).toBe(target); + } finally { + fs.unlinkSync(target); + } + }); + + test('returns null when TTF is missing', () => { + const cfg = loadFresh(); + const result = cfg.getMonoFontTtfPath('jetbrains-mono', 400); + expect(result).toBeNull(); + }); + + test('ligaturesEnabled delegates to settings', () => { + const cfg = loadFresh(); + expect(cfg.ligaturesEnabled({ monospaceLigatures: true })).toBe(true); + expect(cfg.ligaturesEnabled({ monospaceLigatures: false })).toBe(false); + expect(cfg.ligaturesEnabled({})).toBe(false); + }); + + test('getActiveFamily returns the human-readable family name', () => { + const cfg = loadFresh(); + expect(cfg.getActiveFamily({ monospaceFont: 'fira-code' })).toBe('Fira Code'); + expect(cfg.getActiveFamily({})).toBe('JetBrains Mono'); + }); +});