import type { FontSpec } from './types'; import { MissingFontSpecError, buildMissingFontSpecMessage } from './errors'; /** * 校验 fontSpec 必填字段。 * 约束:缺失字段必须报错(简体中文),避免跨端漂移。 */ export function assertFontSpecComplete(fontSpec: Partial | undefined | null): asserts fontSpec is FontSpec { if (!fontSpec) { throw new MissingFontSpecError(buildMissingFontSpecMessage(['fontFamily', 'fontWeight', 'fontSize'])); } const missing: string[] = []; if (!fontSpec.fontFamily) missing.push('fontFamily'); if (!fontSpec.fontWeight) missing.push('fontWeight'); if (fontSpec.fontSize === undefined || fontSpec.fontSize === null) missing.push('fontSize'); if (missing.length) throw new MissingFontSpecError(buildMissingFontSpecMessage(missing)); if (!Number.isFinite(fontSpec.fontSize)) { throw new MissingFontSpecError('fontSpec.fontSize 必须是有限数值(number)。请检查调用 wrapText() 时传入的 fontSize。'); } } /** * 生成 fontSpecKey(确定性)。 * 规则:`fontFamily|fontWeight|fontSize`(顺序固定) */ export function buildFontSpecKey(fontSpec: Partial | undefined | null): string { assertFontSpecComplete(fontSpec); return `${fontSpec.fontFamily}|${fontSpec.fontWeight}|${String(fontSpec.fontSize)}`; }