diff --git a/MLEM.Extended/Font/GenericStashFont.cs b/MLEM.Extended/Font/GenericStashFont.cs
index 0d2988b..a6f2b9e 100644
--- a/MLEM.Extended/Font/GenericStashFont.cs
+++ b/MLEM.Extended/Font/GenericStashFont.cs
@@ -33,7 +33,7 @@ namespace MLEM.Extended.Font {
///
protected override float MeasureCharacter(int codePoint) {
- return this.Font.MeasureString(this.ConvertCachedUtf32(codePoint)).X;
+ return this.Font.MeasureString(CodePointSource.ToString(codePoint)).X;
}
///
diff --git a/MLEM/Extensions/CharExtensions.cs b/MLEM/Extensions/CharExtensions.cs
index 4b550b8..143c9f2 100644
--- a/MLEM/Extensions/CharExtensions.cs
+++ b/MLEM/Extensions/CharExtensions.cs
@@ -5,7 +5,7 @@ namespace MLEM.Extensions {
///
/// A set of extensions for dealing with
///
- [Obsolete("ToCachedString is deprecated. Consider using a more robust, custom implementation for text caching.")]
+ [Obsolete("ToCachedString is deprecated. Consider using a more robust, custom implementation for text caching, or CodePointSource.ToString for UTF-32 caching.")]
public static class CharExtensions {
private static readonly Dictionary Cache = new Dictionary();
@@ -16,7 +16,7 @@ namespace MLEM.Extensions {
///
/// The character to turn into a string
/// A string representing the character
- [Obsolete("ToCachedString is deprecated. Consider using a more robust, custom implementation for text caching.")]
+ [Obsolete("ToCachedString is deprecated. Consider using a more robust, custom implementation for text caching, or CodePointSource.ToString for UTF-32 caching.")]
public static string ToCachedString(this char c) {
if (!CharExtensions.Cache.TryGetValue(c, out var ret)) {
ret = c.ToString();
diff --git a/MLEM/Font/CodePointSource.cs b/MLEM/Font/CodePointSource.cs
index 93be007..fe4e3d2 100644
--- a/MLEM/Font/CodePointSource.cs
+++ b/MLEM/Font/CodePointSource.cs
@@ -4,10 +4,12 @@ using System.Text;
namespace MLEM.Font {
///
- /// A code point source is a wrapper around a or that allows retrieving UTF-32 code points at a given index using . Additionally, it allows enumerating every code point in the underlying or .
+ /// A code point source is a wrapper around a or that allows retrieving UTF-32 code points at a given index using . Additionally, it allows enumerating every code point in the underlying or . This class also contains , which converts a code point into its representation, but caches the result to avoid allocating excess memory.
///
public readonly struct CodePointSource : IEnumerable {
+ private static readonly Dictionary StringCache = new Dictionary();
+
private readonly string strg;
private readonly StringBuilder builder;
private char this[int index] => this.strg?[index] ?? this.builder[index];
@@ -42,7 +44,7 @@ namespace MLEM.Font {
///
/// The index at which to return the code point, which is measured in characters.
/// Whether the represents a low surrogate. If this is , the represents a high surrogate and the low surrogate will be looked for in the following character. If this is , the represents a low surrogate and the high surrogate will be looked for in the previous character.
- ///
+ /// The code point at the given location, as well as its length.
public (int CodePoint, int Length) GetCodePoint(int index, bool indexLowSurrogate = false) {
var curr = this[index];
if (indexLowSurrogate) {
@@ -80,5 +82,18 @@ namespace MLEM.Font {
return this.GetEnumerator();
}
+ ///
+ /// Converts the given UTF-32 into a string using , but caches the result in a cache to avoid allocating excess memory.
+ ///
+ /// The UTF-32 code point to convert.
+ /// The string representation of the code point.
+ public static string ToString(int codePoint) {
+ if (!CodePointSource.StringCache.TryGetValue(codePoint, out var ret)) {
+ ret = char.ConvertFromUtf32(codePoint);
+ CodePointSource.StringCache.Add(codePoint, ret);
+ }
+ return ret;
+ }
+
}
}
diff --git a/MLEM/Font/GenericFont.cs b/MLEM/Font/GenericFont.cs
index 5eaf081..2895a99 100644
--- a/MLEM/Font/GenericFont.cs
+++ b/MLEM/Font/GenericFont.cs
@@ -48,8 +48,6 @@ namespace MLEM.Font {
///
public abstract float LineHeight { get; }
- private readonly Dictionary codePointCache = new Dictionary();
-
///
/// Measures the width of the given code point with the default scale for use in .
/// Note that this method does not support , and for most generic fonts, which is why should be used even for single characters.
@@ -175,19 +173,6 @@ namespace MLEM.Font {
return this.SplitStringSeparate(new CodePointSource(text), width, scale, null);
}
- ///
- /// Converts the given UTF-32 into a string using , but caches the result in a cache to avoid allocating excess memory.
- ///
- /// The UTF-32 code point to convert.
- /// The string representation of the code point.
- public string ConvertCachedUtf32(int codePoint) {
- if (!this.codePointCache.TryGetValue(codePoint, out var ret)) {
- ret = char.ConvertFromUtf32(codePoint);
- this.codePointCache.Add(codePoint, ret);
- }
- return ret;
- }
-
internal Vector2 MeasureString(CodePointSource text, bool ignoreTrailingSpaces, Func fontFunction) {
var size = Vector2.Zero;
if (text.Length <= 0)
@@ -240,9 +225,9 @@ namespace MLEM.Font {
var innerIndex = fromBack ? text.Length - 1 - index : index;
var (codePoint, length) = text.GetCodePoint(innerIndex, fromBack);
if (fromBack) {
- total.Insert(0, this.ConvertCachedUtf32(codePoint));
+ total.Insert(0, CodePointSource.ToString(codePoint));
} else {
- total.Append(this.ConvertCachedUtf32(codePoint));
+ total.Append(CodePointSource.ToString(codePoint));
}
if (this.MeasureString(new CodePointSource(total + ellipsis), false, fontFunction).X * scale >= width) {
@@ -273,7 +258,7 @@ namespace MLEM.Font {
currWidth = 0;
} else {
var font = fontFunction?.Invoke(index) ?? this;
- var character = this.ConvertCachedUtf32(codePoint);
+ var character = CodePointSource.ToString(codePoint);
var charWidth = font.MeasureString(character).X * scale;
if (codePoint == ' ' || codePoint == GenericFont.Emsp || codePoint == GenericFont.Zwsp) {
// remember the location of this (breaking!) space
@@ -349,7 +334,7 @@ namespace MLEM.Font {
offset.X = 0;
offset.Y += this.LineHeight;
} else {
- var character = this.ConvertCachedUtf32(codePoint);
+ var character = CodePointSource.ToString(codePoint);
var charSize = this.MeasureString(character);
var charPos = offset;
diff --git a/MLEM/Font/GenericSpriteFont.cs b/MLEM/Font/GenericSpriteFont.cs
index d038f4c..178a289 100644
--- a/MLEM/Font/GenericSpriteFont.cs
+++ b/MLEM/Font/GenericSpriteFont.cs
@@ -35,7 +35,7 @@ namespace MLEM.Font {
///
protected override float MeasureCharacter(int codePoint) {
- return this.Font.MeasureString(this.ConvertCachedUtf32(codePoint)).X;
+ return this.Font.MeasureString(CodePointSource.ToString(codePoint)).X;
}
///
diff --git a/MLEM/Formatting/TokenizedString.cs b/MLEM/Formatting/TokenizedString.cs
index 918a59d..7dc3825 100644
--- a/MLEM/Formatting/TokenizedString.cs
+++ b/MLEM/Formatting/TokenizedString.cs
@@ -164,7 +164,7 @@ namespace MLEM.Formatting {
var line = new CodePointSource(token.SplitDisplayString[l]);
while (charIndex < line.Length) {
var (codePoint, length) = line.GetCodePoint(charIndex);
- var character = drawFont.ConvertCachedUtf32(codePoint);
+ var character = CodePointSource.ToString(codePoint);
if (indexInToken == 0)
token.DrawSelf(time, batch, pos + innerOffset, drawFont, color, scale, depth);