using System.Collections.Generic; using TMPro; using UnityEngine; namespace AibisDream.Framework { [CreateAssetMenu(fileName = "TypographyProfile", menuName = "AIBIS Dream/Typography/Profile")] public sealed class TypographyProfile : ScriptableObject { [SerializeField] private TypographyProfileKind profileKind; [SerializeField] private List styles = new(); public TypographyProfileKind ProfileKind => profileKind; public IReadOnlyList Styles => styles; public TypographyStyle Resolve(TypographyRole role) { TypographyStyle body = null; if (styles == null) return null; foreach (TypographyStyle style in styles) { if (style == null || !style.IsUsable) continue; if (style.Role == role) return style; if (style.Role == TypographyRole.Body) body = style; } return body; } public IEnumerable GetValidationErrors() { if (styles == null || styles.Count == 0) { yield return $"{name}: 没有配置任何 TypographyStyle。"; yield break; } var seenRoles = new HashSet(); foreach (TypographyStyle style in styles) { if (style == null) { yield return $"{name}: 存在空的 TypographyStyle。"; continue; } if (!seenRoles.Add(style.Role)) yield return $"{name}: Role {style.Role} 重复配置。"; if (!style.IsUsable) yield return $"{name}: Role {style.Role} 没有字体。"; } if (!seenRoles.Contains(TypographyRole.Body)) yield return $"{name}: 缺少 Body 回退样式。"; } public void Configure(TypographyProfileKind kind, IEnumerable configuredStyles) { profileKind = kind; styles = configuredStyles != null ? new List(configuredStyles) : new List(); } internal void ApplyFallbacks() { if (styles == null) return; var configuredFonts = new HashSet(); foreach (TypographyStyle style in styles) { if (style?.Font != null && configuredFonts.Add(style.Font)) style.ApplyFallbacks(); } } } }