using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.RegularExpressions; using CRD.Utils.Structs; namespace CRD.Utils.Muxing; public class FontsManager{ #region Singelton private static FontsManager? instance; private static readonly object padlock = new object(); public static FontsManager Instance{ get{ if (instance == null){ lock (padlock){ if (instance == null){ instance = new FontsManager(); } } } return instance; } } #endregion public Dictionary> Fonts{ get; private set; } = new(){ { "Adobe Arabic", new List{ "AdobeArabic-Bold.otf" } }, { "Andale Mono", new List{ "andalemo.ttf" } }, { "Arial", new List{ "arial.ttf", "arialbd.ttf", "arialbi.ttf", "ariali.ttf" } }, { "Arial Unicode MS", new List{ "arialuni.ttf" } }, { "Arial Black", new List{ "ariblk.ttf" } }, { "Comic Sans MS", new List{ "comic.ttf", "comicbd.ttf" } }, { "Courier New", new List{ "cour.ttf", "courbd.ttf", "courbi.ttf", "couri.ttf" } }, { "DejaVu LGC Sans Mono", new List{ "DejaVuLGCSansMono-Bold.ttf", "DejaVuLGCSansMono-BoldOblique.ttf", "DejaVuLGCSansMono-Oblique.ttf", "DejaVuLGCSansMono.ttf" } }, { "DejaVu Sans", new List{ "DejaVuSans-Bold.ttf", "DejaVuSans-BoldOblique.ttf", "DejaVuSans-ExtraLight.ttf", "DejaVuSans-Oblique.ttf", "DejaVuSans.ttf" } }, { "DejaVu Sans Condensed", new List{ "DejaVuSansCondensed-Bold.ttf", "DejaVuSansCondensed-BoldOblique.ttf", "DejaVuSansCondensed-Oblique.ttf", "DejaVuSansCondensed.ttf" } }, { "DejaVu Sans Mono", new List{ "DejaVuSansMono-Bold.ttf", "DejaVuSansMono-BoldOblique.ttf", "DejaVuSansMono-Oblique.ttf", "DejaVuSansMono.ttf" } }, { "Georgia", new List{ "georgia.ttf", "georgiab.ttf", "georgiai.ttf", "georgiaz.ttf" } }, { "Impact", new List{ "impact.ttf" } }, { "Rubik Black", new List{ "Rubik-Black.ttf", "Rubik-BlackItalic.ttf" } }, { "Rubik", new List{ "Rubik-Bold.ttf", "Rubik-BoldItalic.ttf", "Rubik-Italic.ttf", "Rubik-Light.ttf", "Rubik-LightItalic.ttf", "Rubik-Medium.ttf", "Rubik-MediumItalic.ttf", "Rubik-Regular.ttf" } }, { "Tahoma", new List{ "tahoma.ttf" } }, { "Times New Roman", new List{ "times.ttf", "timesbd.ttf", "timesbi.ttf", "timesi.ttf" } }, { "Trebuchet MS", new List{ "trebuc.ttf", "trebucbd.ttf", "trebucbi.ttf", "trebucit.ttf" } }, { "Verdana", new List{ "verdana.ttf", "verdanab.ttf", "verdanai.ttf", "verdanaz.ttf" } }, { "Webdings", new List{ "webdings.ttf" } }, }; public string root = "https://static.crunchyroll.com/vilos-v2/web/vilos/assets/libass-fonts/"; public static List ExtractFontsFromAss(string ass){ var lines = ass.Replace("\r", "").Split('\n'); var styles = new List(); foreach (var line in lines){ if (line.StartsWith("Style: ")){ var parts = line.Split(','); if (parts.Length > 1) styles.Add(parts[1].Trim()); } } var fontMatches = Regex.Matches(ass, @"\\fn([^\\}]+)"); foreach (Match match in fontMatches){ if (match.Groups.Count > 1) styles.Add(match.Groups[1].Value); } return styles.Distinct().ToList(); // Using Linq to remove duplicates } public Dictionary> GetDictFromKeyList(List keysList){ Dictionary> filteredDictionary = new Dictionary>(); foreach (string key in keysList){ if (Fonts.TryGetValue(key, out var font)){ filteredDictionary.Add(key, font); } } return filteredDictionary; } public static string GetFontMimeType(string fontFile){ if (Regex.IsMatch(fontFile, @"\.otf$")) return "application/vnd.ms-opentype"; else if (Regex.IsMatch(fontFile, @"\.ttf$")) return "application/x-truetype-font"; else return "application/octet-stream"; } public List MakeFontsList(string fontsDir, List subs){ Dictionary> fontsNameList = new Dictionary>(); List subsList = new List(); List fontsList = new List(); bool isNstr = true; foreach (var s in subs){ foreach (var keyValuePair in s.Fonts){ if (!fontsNameList.ContainsKey(keyValuePair.Key)){ fontsNameList.Add(keyValuePair.Key,keyValuePair.Value); } } subsList.Add(s.Language.Locale); } if (subsList.Count > 0){ Console.WriteLine("\nSubtitles: {0} (Total: {1})", string.Join(", ", subsList), subsList.Count); isNstr = false; } if (fontsNameList.Count > 0){ Console.WriteLine((isNstr ? "\n" : "") + "Required fonts: {0} (Total: {1})", string.Join(", ", fontsNameList), fontsNameList.Count); } foreach (var f in fontsNameList){ if (Fonts.TryGetValue(f.Key, out var fontFiles)){ foreach (var fontFile in fontFiles){ string fontPath = Path.Combine(fontsDir, fontFile); string mime = GetFontMimeType(fontFile); if (File.Exists(fontPath) && new FileInfo(fontPath).Length != 0){ fontsList.Add(new ParsedFont{ Name = fontFile, Path = fontPath, Mime = mime }); } } } } return fontsList; } } public class SubtitleFonts{ public LanguageItem Language{ get; set; } public Dictionary> Fonts{ get; set; } }