This commit is contained in:
Loskh 2026-01-05 15:20:17 +08:00 committed by GitHub
commit 688e2f1a70
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 118 additions and 39 deletions

View file

@ -1,4 +1,4 @@
using Dalamud.Storage.Assets;
using Dalamud.Storage.Assets;
using TerraFX.Interop.DirectX;
@ -124,6 +124,13 @@ public enum DalamudAsset
[DalamudAssetPath("UIRes", "tsmShade.png")]
TitleScreenMenuShade = 1013,
/// <summary>
/// <see cref="DalamudAssetPurpose.Font"/>: Noto Sans CJK Medium.
/// </summary>
[DalamudAsset(DalamudAssetPurpose.Font)]
[DalamudAssetPath("UIRes", "NotoSansCJK-Medium.ttc")]
NotoSansCJKMedium = 2000,
/// <summary>
/// <see cref="DalamudAssetPurpose.TextureFromPng"/>: Atlas containing badges.
/// </summary>
@ -134,17 +141,24 @@ public enum DalamudAsset
/// <summary>
/// <see cref="DalamudAssetPurpose.Font"/>: Noto Sans CJK JP Medium.
/// </summary>
[Obsolete("Use NotoSansCJKMedium instead.")]
[DalamudAsset(DalamudAssetPurpose.Font)]
[DalamudAssetPath("UIRes", "NotoSansCJKjp-Regular.otf")]
[DalamudAssetPath("UIRes", "NotoSansCJKjp-Medium.otf")]
[DalamudAssetPath("UIRes", "NotoSansCJK-Medium.ttc")]
NotoSansJpMedium = 2000,
/// <summary>
/// <see cref="DalamudAssetPurpose.Font"/>: Noto Sans CJK Regular.
/// </summary>
[DalamudAsset(DalamudAssetPurpose.Font)]
[DalamudAssetPath("UIRes", "NotoSansCJK-Regular.ttc")]
NotoSansCJKRegular = 2001,
/// <summary>
/// <see cref="DalamudAssetPurpose.Font"/>: Noto Sans CJK KR Regular.
/// </summary>
[Obsolete("Use NotoSansCJKRegular instead.")]
[DalamudAsset(DalamudAssetPurpose.Font)]
[DalamudAssetPath("UIRes", "NotoSansCJKkr-Regular.otf")]
[DalamudAssetPath("UIRes", "NotoSansKR-Regular.otf")]
[DalamudAssetPath("UIRes", "NotoSansCJK-Regular.ttc")]
NotoSansKrRegular = 2001,
/// <summary>

View file

@ -38,7 +38,8 @@ public interface IFontFamilyId : IObjectWithLocalizableName
public static List<IFontFamilyId> ListDalamudFonts() =>
new()
{
new DalamudAssetFontAndFamilyId(DalamudAsset.NotoSansJpMedium),
new DalamudAssetFontAndFamilyId(DalamudAsset.NotoSansCJKMedium),
new DalamudAssetFontAndFamilyId(DalamudAsset.NotoSansCJKRegular),
new DalamudAssetFontAndFamilyId(DalamudAsset.InconsolataRegular),
new DalamudAssetFontAndFamilyId(DalamudAsset.FontAwesomeFreeSolid),
};

View file

@ -24,6 +24,29 @@ public interface IFontSpec
/// </summary>
float LineHeightPx { get; }
/// <summary>
/// Gets the font face index within a TrueType Collection (TTC) file.
/// </summary>
/// <remarks>
/// This property only applies to <see cref="DalamudAsset.NotoSansCJKRegular"/> and
/// <see cref="DalamudAsset.NotoSansCJKMedium"/>, which are TTC fonts bundling
/// multiple language-specific CJK glyph sets (Japanese, Traditional Chinese,
/// Simplified Chinese, Korean) into a single file.
///
/// The index corresponds to the font face order in the TTC:
/// <list type="bullet">
/// <item><description>0 = Japanese</description></item>
/// <item><description>1 = Traditional Chinese</description></item>
/// <item><description>2 = Simplified Chinese</description></item>
/// <item><description>3 = Korean</description></item>
/// </list>
///
/// This value is ignored for all other <see cref="DalamudAsset"/> entries.
/// Only one glyph set can be active at a time. In most cases, you can omit this—
/// Dalamud automatically selects the appropriate face based on the UI language.
/// </remarks>
int FontNo { get; }
/// <summary>
/// Creates a font handle corresponding to this font specification.
/// </summary>

View file

@ -65,6 +65,10 @@ public record SingleFontSpec : IFontSpec
[JsonProperty]
public ushort[]? GlyphRanges { get; init; }
/// <inheritdoc/>
[JsonProperty]
public int FontNo { get; init; }
/// <inheritdoc/>
public string ToLocalizedString(string localeCode)
{
@ -99,6 +103,7 @@ public record SingleFontSpec : IFontSpec
tk,
new()
{
FontNo = this.FontNo,
SizePx = this.SizePx,
GlyphRanges = this.GlyphRanges,
MergeFont = mergeFont,

View file

@ -128,7 +128,7 @@ public sealed class SingleFontChooserDialog : IDisposable
this.popupImGuiName = $"{this.title}##{nameof(SingleFontChooserDialog)}[{this.counter}]";
this.atlas = newAsyncAtlas;
this.selectedFont = new() { FontId = DalamudDefaultFontAndFamilyId.Instance };
Encoding.UTF8.GetBytes("Font preview.\n0123456789!", this.fontPreviewText);
Encoding.UTF8.GetBytes("Font preview.\n0123456789!\n遍角次亮采之门门上插刀、直字拐弯、天上平板、船顶漏雨。\n다람쥐 헌 쳇바퀴에 타고파", this.fontPreviewText);
}
/// <summary>Called when the selected font spec has changed.</summary>
@ -891,7 +891,21 @@ public sealed class SingleFontChooserDialog : IDisposable
this.selectedFontWeight = font.Weight;
this.selectedFontStretch = font.Stretch;
this.selectedFontStyle = font.Style;
this.selectedFont = this.selectedFont with { FontId = font };
int fontNo = 0;
if (family is DalamudAssetFontAndFamilyId { Asset: DalamudAsset.NotoSansCJKRegular or DalamudAsset.NotoSansCJKMedium })
{
var dalamudConfiguration = Service<DalamudConfiguration>.Get();
fontNo = dalamudConfiguration.EffectiveLanguage switch
{
"jp" => 0,
"tw" => 1,
"zh" => 2,
"ko" => 3,
_ => 0,
};
}
this.selectedFont = this.selectedFont with { FontId = font, FontNo = fontNo };
}
return changed;

View file

@ -370,10 +370,7 @@ internal sealed partial class FontAtlasFactory
return this.factory.AddFont(
this,
asset,
fontConfig with
{
FontNo = 0,
});
fontConfig);
}
}
@ -561,32 +558,39 @@ internal sealed partial class FontAtlasFactory
return;
var dalamudConfiguration = Service<DalamudConfiguration>.Get();
if (dalamudConfiguration.EffectiveLanguage == "ko"
|| Service<DalamudIme>.GetNullable()?.EncounteredHangul is true)
var ime = Service<DalamudIme>.GetNullable();
string langTag = null;
// fontNo: 0 = japanese, 1 = traditional chinese, 2 = simplified chinese, 3 = korean
int fontNo = 0;
if (dalamudConfiguration.EffectiveLanguage == "tw")
{
this.AddDalamudAssetFont(
DalamudAsset.NotoSansKrRegular,
fontConfig with
{
MergeFont = targetFont,
GlyphRanges = default(FluentGlyphRangeBuilder).WithLanguage("ko-kr").BuildExact(),
});
langTag = "zh-hant";
fontNo = 1;
}
else if (dalamudConfiguration.EffectiveLanguage == "zh" || ime?.EncounteredHan is true)
{
langTag = "zh-hans";
fontNo = 2;
}
else if (dalamudConfiguration.EffectiveLanguage == "ko" || ime?.EncounteredHangul is true)
{
langTag = "ko-kr";
fontNo = 3;
}
if (Service<DalamudConfiguration>.Get().EffectiveLanguage == "tw")
Log.Debug($"Loading extra glyphs for language tag '{langTag}' (font no {fontNo})");
if (langTag != null)
{
this.AttachWindowsDefaultFont(CultureInfo.GetCultureInfo("zh-hant"), fontConfig with
{
GlyphRanges = default(FluentGlyphRangeBuilder).WithLanguage("zh-hant").BuildExact(),
});
}
else if (Service<DalamudConfiguration>.Get().EffectiveLanguage == "zh"
|| Service<DalamudIme>.GetNullable()?.EncounteredHan is true)
{
this.AttachWindowsDefaultFont(CultureInfo.GetCultureInfo("zh-hans"), fontConfig with
{
GlyphRanges = default(FluentGlyphRangeBuilder).WithLanguage("zh-hans").BuildExact(),
});
this.AddDalamudAssetFont(
DalamudAsset.NotoSansCJKRegular,
fontConfig with
{
FontNo = fontNo,
MergeFont = targetFont,
GlyphRanges = default(FluentGlyphRangeBuilder).WithLanguage(langTag).BuildExact(),
});
}
}
@ -628,7 +632,7 @@ internal sealed partial class FontAtlasFactory
if (this.data.ConfigData.Length == 0)
{
this.AddDalamudAssetFont(
DalamudAsset.NotoSansJpMedium,
DalamudAsset.NotoSansCJKRegular,
new() { GlyphRanges = new ushort[] { ' ', ' ', '\0' }, SizePx = 1 });
}

View file

@ -412,14 +412,14 @@ internal class GamePrebakedFontHandle : FontHandle
private ImFontPtr CreateTemplateFont(IFontAtlasBuildToolkitPreBuild toolkitPreBuild, float sizePx)
{
var font = toolkitPreBuild.AddDalamudAssetFont(
DalamudAsset.NotoSansJpMedium,
DalamudAsset.NotoSansCJKMedium,
new()
{
GlyphRanges = new ushort[] { ' ', ' ', '\0' },
SizePx = sizePx,
});
this.templatedFonts.Add(font);
return font;
return font;
}
private unsafe void PatchFontMetricsIfNecessary(GameFontStyle style, ImFontPtr font, float atlasScale)

View file

@ -1,4 +1,4 @@
using System.Numerics;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Text;
@ -48,8 +48,26 @@ public struct SafeFontConfig
}
/// <summary>
/// Gets or sets the index of font within a TTF/OTF file.
/// Gets or sets the font face index within a TrueType Collection (TTC) file.
/// </summary>
/// <remarks>
/// This property only applies to <see cref="DalamudAsset.NotoSansCJKRegular"/> and
/// <see cref="DalamudAsset.NotoSansCJKMedium"/>, which are TTC fonts bundling
/// multiple language-specific CJK glyph sets (Japanese, Traditional Chinese,
/// Simplified Chinese, Korean) into a single file.
///
/// The index corresponds to the font face order in the TTC:
/// <list type="bullet">
/// <item><description>0 = Japanese</description></item>
/// <item><description>1 = Traditional Chinese</description></item>
/// <item><description>2 = Simplified Chinese</description></item>
/// <item><description>3 = Korean</description></item>
/// </list>
///
/// This value is ignored for all other <see cref="DalamudAsset"/> entries.
/// Only one glyph set can be active at a time. In most cases, you can omit this—
/// Dalamud automatically selects the appropriate face based on the UI language.
/// </remarks>
public int FontNo
{
get => this.Raw.FontNo;