@@ -38,62 +38,109 @@ 默认为微软雅黑 Bold
3838 zh : "将自定义字体作为游戏原字体的回退,尽可能使用游戏原字体" ) ]
3939 private static readonly bool addAsFallback = true ;
4040
41+ [ ConfigEntry (
42+ en : """
43+ Font path(s) specifically for SEGA_MaruGothicDB SDF.
44+ Use semicolon to separate multiple paths.
45+ If empty, uses the general paths above.
46+ """ ,
47+ zh : """
48+ SEGA_MaruGothicDB SDF 的单独字体路径
49+ 使用分号分隔多个路径
50+ 留空则使用上方的总设置
51+ """ ) ]
52+ private static readonly string maruGothicPaths = "" ;
53+
54+ [ ConfigEntry (
55+ en : """
56+ Font path(s) specifically for SEGA_NewRodinN v2-EB_0 SDF.
57+ Use semicolon to separate multiple paths.
58+ If empty, uses the general paths above.
59+ """ ,
60+ zh : """
61+ SEGA_NewRodinN v2-EB_0 SDF 的单独字体路径
62+ 使用分号分隔多个路径
63+ 留空则使用上方的总设置
64+ """ ) ]
65+ private static readonly string newRodinPaths = "" ;
66+
4167 private static List < TMP_FontAsset > fontAssets = [ ] ;
68+ private static List < TMP_FontAsset > maruGothicFontAssets = [ ] ;
69+ private static List < TMP_FontAsset > newRodinFontAssets = [ ] ;
4270 private static readonly List < TMP_FontAsset > processedFonts = [ ] ;
71+ private static readonly Dictionary < string , TMP_FontAsset > fontAssetCache = new ( ) ;
4372
44- public static void OnBeforePatch ( )
73+ private static List < TMP_FontAsset > LoadFonts ( string pathsStr )
4574 {
46- var paths = Fonts . paths
75+ var resolvedPaths = pathsStr
4776 . Split ( ';' )
4877 . Where ( p => ! string . IsNullOrWhiteSpace ( p ) )
4978 . Select ( FileSystem . ResolvePath ) ;
50- var fonts = paths
51- . Select ( p =>
79+
80+ var result = new List < TMP_FontAsset > ( ) ;
81+ foreach ( var p in resolvedPaths )
82+ {
83+ if ( fontAssetCache . TryGetValue ( p , out var cached ) )
84+ {
85+ result . Add ( cached ) ;
86+ continue ;
87+ }
88+
89+ var font = new Font ( p ) ;
90+ if ( font == null )
5291 {
53- var font = new Font ( p ) ;
54- if ( font == null )
55- {
56- MelonLogger . Warning ( $ "[Fonts] Font not found: { p } ") ;
57- }
58- return font ;
59- } )
60- . Where ( f => f != null ) ;
61- fontAssets = fonts
62- . Select ( f => TMP_FontAsset . CreateFontAsset ( f , 90 , 9 , GlyphRenderMode . SDFAA , 8192 , 8192 ) )
63- . ToList ( ) ;
64-
65- fontAssets . ForEach ( f => f . ReadFontAssetDefinition ( ) ) ;
66-
67- if ( fontAssets . Count == 0 )
92+ MelonLogger . Warning ( $ "[Fonts] Font not found: { p } ") ;
93+ continue ;
94+ }
95+
96+ var asset = TMP_FontAsset . CreateFontAsset ( font , 90 , 9 , GlyphRenderMode . SDFAA , 8192 , 8192 ) ;
97+ asset . ReadFontAssetDefinition ( ) ;
98+ fontAssetCache [ p ] = asset ;
99+ result . Add ( asset ) ;
100+ }
101+
102+ return result ;
103+ }
104+
105+ public static void OnBeforePatch ( )
106+ {
107+ fontAssets = LoadFonts ( paths ) ;
108+
109+ if ( ! string . IsNullOrWhiteSpace ( maruGothicPaths ) )
110+ maruGothicFontAssets = LoadFonts ( maruGothicPaths ) ;
111+
112+ if ( ! string . IsNullOrWhiteSpace ( newRodinPaths ) )
113+ newRodinFontAssets = LoadFonts ( newRodinPaths ) ;
114+
115+ if ( fontAssets . Count == 0 && maruGothicFontAssets . Count == 0 && newRodinFontAssets . Count == 0 )
68116 {
69117 MelonLogger . Warning ( "[Fonts] No font loaded." ) ;
70118 }
71- // else if (addAsFallback)
72- // {
73- // fallbackFontAssets = fontAssets;
74- // }
75- // else
76- // {
77- // replacementFontAsset = fontAssets[0];
78- // fallbackFontAssets = fontAssets.Skip(1).ToList();
79- // }
119+ }
120+
121+ private static List < TMP_FontAsset > GetFallbackFonts ( string fontName )
122+ {
123+ return fontName switch
124+ {
125+ "SEGA_MaruGothicDB SDF" when maruGothicFontAssets . Count > 0 => maruGothicFontAssets ,
126+ "SEGA_NewRodinN v2-EB_0 SDF" when newRodinFontAssets . Count > 0 => newRodinFontAssets ,
127+ _ => fontAssets
128+ } ;
80129 }
81130
82131 [ HarmonyPatch ( typeof ( TextMeshProUGUI ) , "Awake" ) ]
83132 [ HarmonyPostfix ]
84133 public static void PostAwake ( TextMeshProUGUI __instance )
85134 {
86- if ( fontAssets . Count == 0 ) return ;
135+ var fallbackFonts = GetFallbackFonts ( __instance . font . name ) ;
136+ if ( fallbackFonts . Count == 0 ) return ;
87137 if ( processedFonts . Contains ( __instance . font ) ) return ;
88138
89139 if ( ! addAsFallback )
90140 {
91141 __instance . font . ClearFontAssetData ( ) ;
92142 }
93- if ( fontAssets . Count > 0 )
94- {
95- ProcessFallback ( __instance ) ;
96- }
143+ ProcessFallback ( __instance , fallbackFonts ) ;
97144
98145 processedFonts . Add ( __instance . font ) ;
99146 }
@@ -117,9 +164,9 @@ public static void PostAwake(TextMeshProUGUI __instance)
117164// // }
118165// }
119166
120- private static void ProcessFallback ( TextMeshProUGUI __instance )
167+ private static void ProcessFallback ( TextMeshProUGUI __instance , List < TMP_FontAsset > fonts )
121168 {
122- foreach ( var fontAsset in fontAssets )
169+ foreach ( var fontAsset in fonts )
123170 {
124171 __instance . font . fallbackFontAssetTable . Add ( fontAsset ) ;
125172 }
0 commit comments