mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-10-31 21:00:51 +01:00
moved the new ConvertCachedUtf32 to CodePointSource
This commit is contained in:
parent
be7676d37e
commit
d5e5d1d536
6 changed files with 26 additions and 26 deletions
|
@ -33,7 +33,7 @@ namespace MLEM.Extended.Font {
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override float MeasureCharacter(int codePoint) {
|
protected override float MeasureCharacter(int codePoint) {
|
||||||
return this.Font.MeasureString(this.ConvertCachedUtf32(codePoint)).X;
|
return this.Font.MeasureString(CodePointSource.ToString(codePoint)).X;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|
|
@ -5,7 +5,7 @@ namespace MLEM.Extensions {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A set of extensions for dealing with <see cref="char"/>
|
/// A set of extensions for dealing with <see cref="char"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[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 {
|
public static class CharExtensions {
|
||||||
|
|
||||||
private static readonly Dictionary<char, string> Cache = new Dictionary<char, string>();
|
private static readonly Dictionary<char, string> Cache = new Dictionary<char, string>();
|
||||||
|
@ -16,7 +16,7 @@ namespace MLEM.Extensions {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="c">The character to turn into a string</param>
|
/// <param name="c">The character to turn into a string</param>
|
||||||
/// <returns>A string representing the character</returns>
|
/// <returns>A string representing the character</returns>
|
||||||
[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) {
|
public static string ToCachedString(this char c) {
|
||||||
if (!CharExtensions.Cache.TryGetValue(c, out var ret)) {
|
if (!CharExtensions.Cache.TryGetValue(c, out var ret)) {
|
||||||
ret = c.ToString();
|
ret = c.ToString();
|
||||||
|
|
|
@ -4,10 +4,12 @@ using System.Text;
|
||||||
|
|
||||||
namespace MLEM.Font {
|
namespace MLEM.Font {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A code point source is a wrapper around a <see cref="string"/> or <see cref="StringBuilder"/> that allows retrieving UTF-32 code points at a given index using <see cref="GetCodePoint"/>. Additionally, it allows enumerating every code point in the underlying <see cref="string"/> or <see cref="StringBuilder"/>.
|
/// A code point source is a wrapper around a <see cref="string"/> or <see cref="StringBuilder"/> that allows retrieving UTF-32 code points at a given index using <see cref="GetCodePoint"/>. Additionally, it allows enumerating every code point in the underlying <see cref="string"/> or <see cref="StringBuilder"/>. This class also contains <see cref="ToString(int)"/>, which converts a code point into its <see cref="string"/> representation, but caches the result to avoid allocating excess memory.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly struct CodePointSource : IEnumerable<int> {
|
public readonly struct CodePointSource : IEnumerable<int> {
|
||||||
|
|
||||||
|
private static readonly Dictionary<int, string> StringCache = new Dictionary<int, string>();
|
||||||
|
|
||||||
private readonly string strg;
|
private readonly string strg;
|
||||||
private readonly StringBuilder builder;
|
private readonly StringBuilder builder;
|
||||||
private char this[int index] => this.strg?[index] ?? this.builder[index];
|
private char this[int index] => this.strg?[index] ?? this.builder[index];
|
||||||
|
@ -42,7 +44,7 @@ namespace MLEM.Font {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="index">The index at which to return the code point, which is measured in characters.</param>
|
/// <param name="index">The index at which to return the code point, which is measured in characters.</param>
|
||||||
/// <param name="indexLowSurrogate">Whether the <paramref name="index"/> represents a low surrogate. If this is <see langword="false"/>, the <paramref name="index"/> represents a high surrogate and the low surrogate will be looked for in the following character. If this is <see langword="true"/>, the <paramref name="index"/> represents a low surrogate and the high surrogate will be looked for in the previous character.</param>
|
/// <param name="indexLowSurrogate">Whether the <paramref name="index"/> represents a low surrogate. If this is <see langword="false"/>, the <paramref name="index"/> represents a high surrogate and the low surrogate will be looked for in the following character. If this is <see langword="true"/>, the <paramref name="index"/> represents a low surrogate and the high surrogate will be looked for in the previous character.</param>
|
||||||
/// <returns></returns>
|
/// <returns>The code point at the given location, as well as its length.</returns>
|
||||||
public (int CodePoint, int Length) GetCodePoint(int index, bool indexLowSurrogate = false) {
|
public (int CodePoint, int Length) GetCodePoint(int index, bool indexLowSurrogate = false) {
|
||||||
var curr = this[index];
|
var curr = this[index];
|
||||||
if (indexLowSurrogate) {
|
if (indexLowSurrogate) {
|
||||||
|
@ -80,5 +82,18 @@ namespace MLEM.Font {
|
||||||
return this.GetEnumerator();
|
return this.GetEnumerator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts the given UTF-32 <paramref name="codePoint"/> into a string using <see cref="char.ConvertFromUtf32"/>, but caches the result in a <see cref="Dictionary{TKey,TValue}"/> cache to avoid allocating excess memory.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="codePoint">The UTF-32 code point to convert.</param>
|
||||||
|
/// <returns>The string representation of the code point.</returns>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,8 +48,6 @@ namespace MLEM.Font {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract float LineHeight { get; }
|
public abstract float LineHeight { get; }
|
||||||
|
|
||||||
private readonly Dictionary<int, string> codePointCache = new Dictionary<int, string>();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Measures the width of the given code point with the default scale for use in <see cref="MeasureString(string,bool)"/>.
|
/// Measures the width of the given code point with the default scale for use in <see cref="MeasureString(string,bool)"/>.
|
||||||
/// Note that this method does not support <see cref="Nbsp"/>, <see cref="Zwsp"/> and <see cref="Emsp"/> for most generic fonts, which is why <see cref="MeasureString(string,bool)"/> should be used even for single characters.
|
/// Note that this method does not support <see cref="Nbsp"/>, <see cref="Zwsp"/> and <see cref="Emsp"/> for most generic fonts, which is why <see cref="MeasureString(string,bool)"/> should be used even for single characters.
|
||||||
|
@ -175,19 +173,6 @@ namespace MLEM.Font {
|
||||||
return this.SplitStringSeparate(new CodePointSource(text), width, scale, null);
|
return this.SplitStringSeparate(new CodePointSource(text), width, scale, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Converts the given UTF-32 <paramref name="codePoint"/> into a string using <see cref="char.ConvertFromUtf32"/>, but caches the result in a <see cref="Dictionary{TKey,TValue}"/> cache to avoid allocating excess memory.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="codePoint">The UTF-32 code point to convert.</param>
|
|
||||||
/// <returns>The string representation of the code point.</returns>
|
|
||||||
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<int, GenericFont> fontFunction) {
|
internal Vector2 MeasureString(CodePointSource text, bool ignoreTrailingSpaces, Func<int, GenericFont> fontFunction) {
|
||||||
var size = Vector2.Zero;
|
var size = Vector2.Zero;
|
||||||
if (text.Length <= 0)
|
if (text.Length <= 0)
|
||||||
|
@ -240,9 +225,9 @@ namespace MLEM.Font {
|
||||||
var innerIndex = fromBack ? text.Length - 1 - index : index;
|
var innerIndex = fromBack ? text.Length - 1 - index : index;
|
||||||
var (codePoint, length) = text.GetCodePoint(innerIndex, fromBack);
|
var (codePoint, length) = text.GetCodePoint(innerIndex, fromBack);
|
||||||
if (fromBack) {
|
if (fromBack) {
|
||||||
total.Insert(0, this.ConvertCachedUtf32(codePoint));
|
total.Insert(0, CodePointSource.ToString(codePoint));
|
||||||
} else {
|
} else {
|
||||||
total.Append(this.ConvertCachedUtf32(codePoint));
|
total.Append(CodePointSource.ToString(codePoint));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.MeasureString(new CodePointSource(total + ellipsis), false, fontFunction).X * scale >= width) {
|
if (this.MeasureString(new CodePointSource(total + ellipsis), false, fontFunction).X * scale >= width) {
|
||||||
|
@ -273,7 +258,7 @@ namespace MLEM.Font {
|
||||||
currWidth = 0;
|
currWidth = 0;
|
||||||
} else {
|
} else {
|
||||||
var font = fontFunction?.Invoke(index) ?? this;
|
var font = fontFunction?.Invoke(index) ?? this;
|
||||||
var character = this.ConvertCachedUtf32(codePoint);
|
var character = CodePointSource.ToString(codePoint);
|
||||||
var charWidth = font.MeasureString(character).X * scale;
|
var charWidth = font.MeasureString(character).X * scale;
|
||||||
if (codePoint == ' ' || codePoint == GenericFont.Emsp || codePoint == GenericFont.Zwsp) {
|
if (codePoint == ' ' || codePoint == GenericFont.Emsp || codePoint == GenericFont.Zwsp) {
|
||||||
// remember the location of this (breaking!) space
|
// remember the location of this (breaking!) space
|
||||||
|
@ -349,7 +334,7 @@ namespace MLEM.Font {
|
||||||
offset.X = 0;
|
offset.X = 0;
|
||||||
offset.Y += this.LineHeight;
|
offset.Y += this.LineHeight;
|
||||||
} else {
|
} else {
|
||||||
var character = this.ConvertCachedUtf32(codePoint);
|
var character = CodePointSource.ToString(codePoint);
|
||||||
var charSize = this.MeasureString(character);
|
var charSize = this.MeasureString(character);
|
||||||
|
|
||||||
var charPos = offset;
|
var charPos = offset;
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace MLEM.Font {
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override float MeasureCharacter(int codePoint) {
|
protected override float MeasureCharacter(int codePoint) {
|
||||||
return this.Font.MeasureString(this.ConvertCachedUtf32(codePoint)).X;
|
return this.Font.MeasureString(CodePointSource.ToString(codePoint)).X;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|
|
@ -164,7 +164,7 @@ namespace MLEM.Formatting {
|
||||||
var line = new CodePointSource(token.SplitDisplayString[l]);
|
var line = new CodePointSource(token.SplitDisplayString[l]);
|
||||||
while (charIndex < line.Length) {
|
while (charIndex < line.Length) {
|
||||||
var (codePoint, length) = line.GetCodePoint(charIndex);
|
var (codePoint, length) = line.GetCodePoint(charIndex);
|
||||||
var character = drawFont.ConvertCachedUtf32(codePoint);
|
var character = CodePointSource.ToString(codePoint);
|
||||||
|
|
||||||
if (indexInToken == 0)
|
if (indexInToken == 0)
|
||||||
token.DrawSelf(time, batch, pos + innerOffset, drawFont, color, scale, depth);
|
token.DrawSelf(time, batch, pos + innerOffset, drawFont, color, scale, depth);
|
||||||
|
|
Loading…
Reference in a new issue