using Microsoft.Extensions.Logging; using SkiaSharp; using Topten.RichTextKit; namespace ErsatzTV.Infrastructure.Streaming.Graphics; public sealed class CustomFontMapper(ILogger logger) : FontMapper { private readonly Dictionary> _customFonts = new(); public void LoadPrivateFont(Stream stream, string familyName) { SKTypeface typeface = SKTypeface.FromStream(stream) ?? throw new ArgumentException("Cannot load font from stream", nameof(stream)); string qualifiedName = familyName ?? typeface.FamilyName; if (typeface.FontSlant != SKFontStyleSlant.Upright) { qualifiedName += "-Italic"; } if (!_customFonts.TryGetValue(qualifiedName, out List listFonts)) { listFonts = []; _customFonts[qualifiedName] = listFonts; } listFonts.Add(typeface); } public override SKTypeface TypefaceFromStyle(IStyle style, bool ignoreFontVariants) { string qualifiedName = style.FontFamily; if (style.FontItalic) { qualifiedName += "-Italic"; } if (_customFonts.TryGetValue(qualifiedName, out List listFonts) && listFonts.Count != 0) { return listFonts.MinBy(font => Math.Abs(font.FontWeight - style.FontWeight))!; } logger.LogWarning("Could not find font {Name}; using default", qualifiedName); return base.TypefaceFromStyle(style, ignoreFontVariants); } }