using System; using System.Collections.Generic; using System.IO; using System.Linq; using PdfSharp.Fonts; using System.Globalization; namespace Logof_Client; public class StableFontResolver : IFontResolver { // family -> style -> bytes private readonly Dictionary> _families = new(StringComparer.OrdinalIgnoreCase); private readonly List _orderedFamilies = new(); public StableFontResolver(string fontsDirectory) { try { if (string.IsNullOrEmpty(fontsDirectory)) return; if (!Directory.Exists(fontsDirectory)) return; var files = Directory.EnumerateFiles(fontsDirectory, "*.ttf"); foreach (var f in files) { try { var baseName = Path.GetFileNameWithoutExtension(f); if (string.IsNullOrEmpty(baseName)) continue; // Try to split family and style by hyphen or underscore var family = baseName; var style = "Regular"; var idx = baseName.IndexOf('-'); if (idx < 0) idx = baseName.IndexOf('_'); if (idx > 0) { family = baseName.Substring(0, idx); style = baseName.Substring(idx + 1); } // Normalize common style names style = NormalizeStyle(style); var data = File.ReadAllBytes(f); if (data == null || data.Length == 0) continue; if (!_families.TryGetValue(family, out var dict)) { dict = new Dictionary(StringComparer.OrdinalIgnoreCase); _families[family] = dict; _orderedFamilies.Add(family); } if (!dict.ContainsKey(style)) dict[style] = data; } catch { // ignore individual font load errors } } } catch { // ignore resolver init errors } } private static string NormalizeStyle(string s) { if (string.IsNullOrEmpty(s)) return "Regular"; s = s.ToLowerInvariant(); if (s.Contains("bold") && s.Contains("italic")) return "BoldItalic"; if (s.Contains("bold")) return "Bold"; if (s.Contains("italic") || s.Contains("oblique")) return "Italic"; if (s.Contains("regular") || s == "r") return "Regular"; return CultureInfo.InvariantCulture.TextInfo.ToTitleCase(s); } public FontResolverInfo ResolveTypeface(string familyName, bool isBold, bool isItalic) { // If requested family exists, pick corresponding style if available string familyToUse = null; if (!string.IsNullOrEmpty(familyName) && _families.ContainsKey(familyName)) familyToUse = familyName; if (familyToUse == null && _orderedFamilies.Count > 0) familyToUse = _orderedFamilies[0]; if (familyToUse == null) return new FontResolverInfo("Arial"); var style = "Regular"; if (isBold && isItalic) style = "BoldItalic"; else if (isBold) style = "Bold"; else if (isItalic) style = "Italic"; // Face name format: Family#Style return new FontResolverInfo($"{familyToUse}#{style}"); } public byte[] GetFont(string faceName) { if (string.IsNullOrEmpty(faceName)) return null; // faceName expected as "Family#Style" or just "Family" var family = faceName; var style = "Regular"; var idx = faceName.IndexOf('#'); if (idx >= 0) { family = faceName.Substring(0, idx); style = faceName.Substring(idx + 1); } style = NormalizeStyle(style); if (_families.TryGetValue(family, out var dict)) { // Try exact style if (dict.TryGetValue(style, out var data)) return data; // Fallback order if (style != "Regular" && dict.TryGetValue("Regular", out data)) return data; if (dict.TryGetValue("Bold", out data)) return data; if (dict.TryGetValue("Italic", out data)) return data; // Any available foreach (var kv in dict) return kv.Value; } return null; } }