Skip to content

Commit 0ef9820

Browse files
committed
Add feature load system fonts; Change default char to '□'
1 parent 63857fb commit 0ef9820

File tree

4 files changed

+119
-1
lines changed

4 files changed

+119
-1
lines changed

samples/FontStashSharp.Samples.DynamicSpriteFont/Game1.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ protected override void LoadContent()
8484
// Simple
8585
_fontSystem = new FontSystem();
8686
_fontSystem.AddFont(File.ReadAllBytes(@"Fonts/DroidSans.ttf"));
87+
_fontSystem.AddSystemFont("simsun");
88+
_fontSystem.AddSystemFont("seguiemj");
8789
_fontSystem.AddFont(File.ReadAllBytes(@"Fonts/DroidSansJapanese.ttf"));
8890
_fontSystem.AddFont(File.ReadAllBytes(@"Fonts/Symbola-Emoji.ttf"));
8991

src/FontStashSharp/FontSystem.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ public partial class FontSystem : IDisposable
2020

2121
private FontAtlas _currentAtlas;
2222

23+
private readonly SystemFonts _systemFonts;
24+
2325
public int TextureWidth => _settings.TextureWidth;
2426
public int TextureHeight => _settings.TextureHeight;
2527

@@ -46,6 +48,7 @@ public FontSystem(FontSystemSettings settings)
4648
}
4749

4850
_settings = settings.Clone();
51+
_systemFonts = new SystemFonts();
4952

5053
UseKernings = FontSystemDefaults.UseKernings;
5154
DefaultCharacter = FontSystemDefaults.DefaultCharacter;
@@ -77,6 +80,17 @@ public void Dispose()
7780
_fonts.Clear();
7881
}
7982

83+
public void AddSystemFont(string fileName, FT_Render_Mode_ renderMode = FT_RENDER_MODE_NORMAL)
84+
{
85+
var data = _systemFonts.GetFontData(fileName);
86+
87+
if (data.Length > 0)
88+
{
89+
var fontSource = FreeTypeLoader.Load(data, renderMode);
90+
_fontSources.Add(fontSource);
91+
}
92+
}
93+
8094
public void AddFont(byte[] data, FT_Render_Mode_ renderMode = FT_RENDER_MODE_NORMAL)
8195
{
8296
var fontSource = FreeTypeLoader.Load(data, renderMode);

src/FontStashSharp/FontSystemDefaults.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public static float FontResolutionFactor
5656
}
5757

5858
public static bool UseKernings { get; set; } = true;
59-
public static int? DefaultCharacter { get; set; } = '';
59+
public static int? DefaultCharacter { get; set; } = '';
6060

6161
public static int TextStyleLineHeight { get; set; } = 2;
6262
}

src/FontStashSharp/SystemFonts.cs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Runtime.InteropServices;
6+
7+
namespace FontStashSharp
8+
{
9+
public class SystemFonts
10+
{
11+
private static readonly IReadOnlyCollection<string> StandardFontLocations;
12+
13+
private readonly IReadOnlyCollection<string> _searchDirectories;
14+
private readonly IEnumerable<string> _paths;
15+
16+
static SystemFonts()
17+
{
18+
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
19+
{
20+
StandardFontLocations = new[]
21+
{
22+
@"%SYSTEMROOT%\Fonts",
23+
@"%APPDATA%\Microsoft\Windows\Fonts",
24+
@"%LOCALAPPDATA%\Microsoft\Windows\Fonts",
25+
};
26+
}
27+
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
28+
{
29+
StandardFontLocations = new[]
30+
{
31+
"%HOME%/.fonts/",
32+
"%HOME%/.local/share/fonts/",
33+
"/usr/local/share/fonts/",
34+
"/usr/share/fonts/",
35+
};
36+
}
37+
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
38+
{
39+
StandardFontLocations = new[]
40+
{
41+
// As documented on "Mac OS X: Font locations and their purposes"
42+
// https://web.archive.org/web/20191015122508/https://support.apple.com/en-us/HT201722
43+
"%HOME%/Library/Fonts/",
44+
"/Library/Fonts/",
45+
"/System/Library/Fonts/",
46+
"/Network/Library/Fonts/",
47+
};
48+
}
49+
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Create("Android")))
50+
{
51+
StandardFontLocations = new[]
52+
{
53+
"/system/fonts/"
54+
};
55+
}
56+
else
57+
{
58+
StandardFontLocations = Array.Empty<string>();
59+
}
60+
}
61+
62+
public SystemFonts()
63+
{
64+
string[] expanded = StandardFontLocations.Select(x => Environment.ExpandEnvironmentVariables(x)).ToArray();
65+
string[] existingDirectories = expanded.Where(x => Directory.Exists(x)).ToArray();
66+
67+
// We do this to provide a consistent experience with case sensitive file systems.
68+
_paths = existingDirectories
69+
.SelectMany(x => Directory.EnumerateFiles(x, "*.*", SearchOption.AllDirectories))
70+
.Where(x => Path.GetExtension(x).Equals(".ttf", StringComparison.OrdinalIgnoreCase)
71+
|| Path.GetExtension(x).Equals(".ttc", StringComparison.OrdinalIgnoreCase)
72+
|| Path.GetExtension(x).Equals(".otf", StringComparison.OrdinalIgnoreCase));
73+
74+
_searchDirectories = existingDirectories;
75+
}
76+
77+
public byte[] GetFontData(string fileName)
78+
{
79+
if (string.IsNullOrEmpty(fileName))
80+
{
81+
throw new ArgumentException("Font name cannot be null or empty.", nameof(fileName));
82+
}
83+
84+
foreach (string path in _paths)
85+
{
86+
if (Path.GetFileName(path).StartsWith(fileName, StringComparison.OrdinalIgnoreCase))
87+
{
88+
try
89+
{
90+
return File.ReadAllBytes(path);
91+
}
92+
catch
93+
{
94+
return Array.Empty<byte>();
95+
}
96+
}
97+
}
98+
99+
return Array.Empty<byte>();
100+
}
101+
}
102+
}

0 commit comments

Comments
 (0)