UNPKG

faj-cli

Version:

FAJ - A powerful CLI resume builder with AI enhancement and multi-format export

195 lines 8.04 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.SystemFontLoader = void 0; const fs = __importStar(require("fs/promises")); const path = __importStar(require("path")); const Logger_1 = require("../../utils/Logger"); const os = __importStar(require("os")); class SystemFontLoader { logger; // Common system font paths for different platforms // Prioritize OTF/TTF over TTC for better compatibility fontPaths = { darwin: [ '/Library/Fonts/Arial Unicode.ttf', '/System/Library/Fonts/PingFang.ttc', '/System/Library/Fonts/Helvetica.ttc', '/System/Library/Fonts/STHeiti Light.ttc', '/System/Library/Fonts/STHeiti Medium.ttc', '/System/Library/Fonts/Hiragino Sans GB.ttc' ], linux: [ '/usr/share/fonts/opentype/noto-cjk/NotoSansCJK-Regular.otf', '/usr/share/fonts/opentype/noto-cjk/NotoSansCJK-Bold.otf', '/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf', '/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', '/usr/share/fonts/truetype/wqy/wqy-microhei.ttf', '/usr/share/fonts/truetype/wqy/wqy-zenhei.ttf', '/usr/share/fonts/opentype/noto/NotoSansCJK-SC-Regular.otf', '/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc', '/usr/share/fonts/truetype/google-noto-cjk/NotoSansCJK-Regular.ttc', '/usr/share/fonts/wenquanyi/wqy-microhei/wqy-microhei.ttc' ], win32: [ 'C:\\Windows\\Fonts\\msyh.ttc', 'C:\\Windows\\Fonts\\simsun.ttc', 'C:\\Windows\\Fonts\\simhei.ttf', 'C:\\Windows\\Fonts\\simkai.ttf', 'C:\\Windows\\Fonts\\STKAITI.TTF', 'C:\\Windows\\Fonts\\STFANGSO.TTF' ] }; // WSL paths for Windows fonts wslFontPaths = [ '/mnt/c/Windows/Fonts/msyh.ttc', '/mnt/c/Windows/Fonts/simsun.ttc', '/mnt/c/Windows/Fonts/simhei.ttf', '/mnt/c/Windows/Fonts/STKAITI.TTF' ]; constructor() { this.logger = new Logger_1.Logger('SystemFontLoader'); } async findSystemFonts() { const platform = os.platform(); this.logger.info(`Detecting system fonts on ${platform}...`); let regularFont = null; let boldFont = null; // Get platform-specific font paths let pathsToCheck = this.fontPaths[platform] || []; // Also check WSL paths if on Linux (might be WSL) if (platform === 'linux') { pathsToCheck = [...pathsToCheck, ...this.wslFontPaths]; } // Check additional font directories const additionalDirs = await this.getAdditionalFontDirs(); for (const dir of additionalDirs) { try { const files = await fs.readdir(dir); for (const file of files) { if (file.match(/\.(ttf|otf|ttc)$/i)) { pathsToCheck.push(path.join(dir, file)); } } } catch { // Directory doesn't exist or can't be read } } // Try to find suitable fonts for (const fontPath of pathsToCheck) { try { await fs.access(fontPath); const fontData = await fs.readFile(fontPath); // Check if it's a CJK font by name const fontName = path.basename(fontPath).toLowerCase(); // Skip TTC files as they're not well supported by pdf-lib if (fontName.endsWith('.ttc')) { this.logger.debug(`Skipping TTC font: ${fontPath}`); continue; } const isCJKFont = this.isCJKFont(fontName); if (isCJKFont) { if (!regularFont) { regularFont = fontData; this.logger.success(`Found CJK font: ${fontPath}`); } // Try to find a bold variant if (!boldFont && (fontName.includes('bold') || fontName.includes('heavy'))) { boldFont = fontData; this.logger.success(`Found bold CJK font: ${fontPath}`); } } // If we have both, we can stop if (regularFont && boldFont) { break; } } catch { // Font file not accessible } } // If no bold font found, use regular for both if (regularFont && !boldFont) { boldFont = regularFont; this.logger.info('Using regular font for bold as well'); } if (!regularFont) { this.logger.warn('No CJK fonts found on system. PDF may not display Chinese/Japanese/Korean text correctly.'); this.logger.info('Consider installing fonts like Noto Sans CJK, WenQuanYi, or Microsoft YaHei.'); } return { regular: regularFont, bold: boldFont }; } async getAdditionalFontDirs() { const dirs = []; // User font directories const homeDir = os.homedir(); dirs.push(path.join(homeDir, '.fonts'), path.join(homeDir, '.local', 'share', 'fonts')); // System font directories dirs.push('/usr/share/fonts', '/usr/local/share/fonts', '/opt/local/share/fonts'); return dirs; } isCJKFont(fontName) { const cjkPatterns = [ 'cjk', 'chinese', 'sc', 'tc', 'cn', 'jp', 'kr', 'noto', 'pingfang', 'heiti', 'songti', 'kaiti', 'microsoft yahei', 'msyh', 'simsun', 'simhei', 'wenquanyi', 'wqy', 'droid sans fallback', 'hiragino', 'yu gothic', 'meiryo', 'malgun', 'arial unicode', 'code2000', 'unifont' ]; return cjkPatterns.some(pattern => fontName.includes(pattern)); } async listAvailableFonts() { const platform = os.platform(); const availableFonts = []; let pathsToCheck = this.fontPaths[platform] || []; if (platform === 'linux') { pathsToCheck = [...pathsToCheck, ...this.wslFontPaths]; } for (const fontPath of pathsToCheck) { try { await fs.access(fontPath); availableFonts.push(fontPath); } catch { // Not available } } return availableFonts; } } exports.SystemFontLoader = SystemFontLoader; //# sourceMappingURL=SystemFontLoader.js.map