1
0
Fork 0
mirror of https://github.com/Ellpeck/MLEM.git synced 2024-05-20 16:01:23 +02:00

Fixed GenericFont's SplitString using incorrect width for special characters and improved documentation

This commit is contained in:
Ell 2021-07-28 17:22:47 +02:00
parent 57f8e56c38
commit 516265bf5b
5 changed files with 42 additions and 25 deletions

View file

@ -19,6 +19,7 @@ Improvements
Fixes Fixes
- Set default values for InputHandler held and pressed keys to avoid an exception if buttons are held in the very first frame - Set default values for InputHandler held and pressed keys to avoid an exception if buttons are held in the very first frame
- Fixed GenericFont MeasureString using incorrect width for Zwsp and OneEmSpace
### MLEM.Ui ### MLEM.Ui
Additions Additions

View file

@ -33,9 +33,9 @@ namespace MLEM.Extended.Font {
} }
/// <inheritdoc /> /// <inheritdoc />
protected override Vector2 MeasureChar(char c) { protected override float MeasureChar(char c) {
var region = this.Font.GetCharacterRegion(c); var region = this.Font.GetCharacterRegion(c);
return region != null ? new Vector2(region.XAdvance, region.Height) : Vector2.Zero; return region != null ? new Vector2(region.XAdvance, region.Height).X : 0;
} }
/// <inheritdoc/> /// <inheritdoc/>

View file

@ -53,8 +53,8 @@ namespace MLEM.Extended.Font {
} }
/// <inheritdoc /> /// <inheritdoc />
protected override Vector2 MeasureChar(char c) { protected override float MeasureChar(char c) {
return this.Font.MeasureString(c.ToCachedString()); return this.Font.MeasureString(c.ToCachedString()).X;
} }
private static float CalculateLineHeight(SpriteFontBase font) { private static float CalculateLineHeight(SpriteFontBase font) {

View file

@ -1,6 +1,7 @@
using System.Text; using System.Text;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using MLEM.Extensions;
using MLEM.Misc; using MLEM.Misc;
namespace MLEM.Font { namespace MLEM.Font {
@ -37,11 +38,19 @@ namespace MLEM.Font {
/// </summary> /// </summary>
public abstract GenericFont Italic { get; } public abstract GenericFont Italic { get; }
///<inheritdoc cref="SpriteFont.LineSpacing"/> /// <summary>
/// The height of each line of text of this font.
/// This is the value that the text's draw position is offset by every time a newline character is reached.
/// </summary>
public abstract float LineHeight { get; } public abstract float LineHeight { get; }
///<inheritdoc cref="SpriteFont.MeasureString(string)"/> /// <summary>
protected abstract Vector2 MeasureChar(char c); /// Measures the width of the given character with the default scale for use in <see cref="MeasureString"/>.
/// Note that this method does not support <see cref="Nbsp"/>, <see cref="Zwsp"/> and <see cref="OneEmSpace"/> for most generic fonts, which is why <see cref="MeasureString"/> should be used even for single characters.
/// </summary>
/// <param name="c">The character whose width to calculate</param>
/// <returns>The width of the given character with the default scale</returns>
protected abstract float MeasureChar(char c);
///<inheritdoc cref="SpriteBatch.DrawString(SpriteFont,string,Vector2,Color,float,Vector2,float,SpriteEffects,float)"/> ///<inheritdoc cref="SpriteBatch.DrawString(SpriteFont,string,Vector2,Color,float,Vector2,float,SpriteEffects,float)"/>
public abstract void DrawString(SpriteBatch batch, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth); public abstract void DrawString(SpriteBatch batch, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth);
@ -49,27 +58,34 @@ namespace MLEM.Font {
///<inheritdoc cref="SpriteBatch.DrawString(SpriteFont,string,Vector2,Color,float,Vector2,float,SpriteEffects,float)"/> ///<inheritdoc cref="SpriteBatch.DrawString(SpriteFont,string,Vector2,Color,float,Vector2,float,SpriteEffects,float)"/>
public abstract void DrawString(SpriteBatch batch, StringBuilder text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth); public abstract void DrawString(SpriteBatch batch, StringBuilder text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth);
///<inheritdoc cref="SpriteBatch.DrawString(SpriteFont,string,Vector2,Color,float,Vector2,float,SpriteEffects,float)"/>
public void DrawString(SpriteBatch batch, string text, Vector2 position, Color color) {
this.DrawString(batch, text, position, color, 0, Vector2.Zero, Vector2.One, SpriteEffects.None, 0);
}
///<inheritdoc cref="SpriteBatch.DrawString(SpriteFont,string,Vector2,Color,float,Vector2,float,SpriteEffects,float)"/> ///<inheritdoc cref="SpriteBatch.DrawString(SpriteFont,string,Vector2,Color,float,Vector2,float,SpriteEffects,float)"/>
public void DrawString(SpriteBatch batch, string text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects effects, float layerDepth) { public void DrawString(SpriteBatch batch, string text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects effects, float layerDepth) {
this.DrawString(batch, text, position, color, rotation, origin, new Vector2(scale), effects, layerDepth); this.DrawString(batch, text, position, color, rotation, origin, new Vector2(scale), effects, layerDepth);
} }
///<inheritdoc cref="SpriteBatch.DrawString(SpriteFont,string,Vector2,Color,float,Vector2,float,SpriteEffects,float)"/>
public void DrawString(SpriteBatch batch, StringBuilder text, Vector2 position, Color color) {
this.DrawString(batch, text, position, color, 0, Vector2.Zero, Vector2.One, SpriteEffects.None, 0);
}
///<inheritdoc cref="SpriteBatch.DrawString(SpriteFont,string,Vector2,Color,float,Vector2,float,SpriteEffects,float)"/> ///<inheritdoc cref="SpriteBatch.DrawString(SpriteFont,string,Vector2,Color,float,Vector2,float,SpriteEffects,float)"/>
public void DrawString(SpriteBatch batch, StringBuilder text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects effects, float layerDepth) { public void DrawString(SpriteBatch batch, StringBuilder text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects effects, float layerDepth) {
this.DrawString(batch, text, position, color, rotation, origin, new Vector2(scale), effects, layerDepth); this.DrawString(batch, text, position, color, rotation, origin, new Vector2(scale), effects, layerDepth);
} }
///<inheritdoc cref="SpriteFont.MeasureString(string)"/> ///<inheritdoc cref="SpriteBatch.DrawString(SpriteFont,string,Vector2,Color,float,Vector2,float,SpriteEffects,float)"/>
public void DrawString(SpriteBatch batch, string text, Vector2 position, Color color) {
this.DrawString(batch, text, position, color, 0, Vector2.Zero, Vector2.One, SpriteEffects.None, 0);
}
///<inheritdoc cref="SpriteBatch.DrawString(SpriteFont,string,Vector2,Color,float,Vector2,float,SpriteEffects,float)"/>
public void DrawString(SpriteBatch batch, StringBuilder text, Vector2 position, Color color) {
this.DrawString(batch, text, position, color, 0, Vector2.Zero, Vector2.One, SpriteEffects.None, 0);
}
/// <summary>
/// Measures the width of the given string when drawn with this font's underlying font.
/// This method uses <see cref="MeasureChar"/> internally to calculate the size of known characters and calculates additional characters like <see cref="Nbsp"/>, <see cref="Zwsp"/> and <see cref="OneEmSpace"/>.
/// If the text contains newline characters (\n), the size returned will represent a rectangle that encompasses the width of the longest line and the string's full height.
/// </summary>
/// <param name="text">The text whose size to calculate</param>
/// <param name="ignoreTrailingSpaces">Whether trailing whitespace should be ignored in the returned size, causing the end of each line to be effectively trimmed</param>
/// <returns>The size of the string when drawn with this font</returns>
public Vector2 MeasureString(string text, bool ignoreTrailingSpaces = false) { public Vector2 MeasureString(string text, bool ignoreTrailingSpaces = false) {
var size = Vector2.Zero; var size = Vector2.Zero;
if (text.Length <= 0) if (text.Length <= 0)
@ -85,7 +101,7 @@ namespace MLEM.Font {
xOffset += this.LineHeight; xOffset += this.LineHeight;
break; break;
case Nbsp: case Nbsp:
xOffset += this.MeasureChar(' ').X; xOffset += this.MeasureChar(' ');
break; break;
case Zwsp: case Zwsp:
// don't add width for a zero-width space // don't add width for a zero-width space
@ -96,10 +112,10 @@ namespace MLEM.Font {
i = text.Length - 1; i = text.Length - 1;
break; break;
} }
xOffset += this.MeasureChar(' ').X; xOffset += this.MeasureChar(' ');
break; break;
default: default:
xOffset += this.MeasureChar(text[i]).X; xOffset += this.MeasureChar(text[i]);
break; break;
} }
// increase x size if this line is the longest // increase x size if this line is the longest
@ -164,9 +180,9 @@ namespace MLEM.Font {
widthSinceLastSpace = 0; widthSinceLastSpace = 0;
currWidth = 0; currWidth = 0;
} else { } else {
var cWidth = this.MeasureChar(c).X * scale; var cWidth = this.MeasureString(c.ToCachedString()).X * scale;
if (c == ' ' || c == OneEmSpace || c == Zwsp) { if (c == ' ' || c == OneEmSpace || c == Zwsp) {
// remember the location of this space // remember the location of this (breaking!) space
lastSpaceIndex = ret.Length; lastSpaceIndex = ret.Length;
widthSinceLastSpace = 0; widthSinceLastSpace = 0;
} else if (currWidth + cWidth >= width) { } else if (currWidth + cWidth >= width) {

View file

@ -33,8 +33,8 @@ namespace MLEM.Font {
} }
/// <inheritdoc /> /// <inheritdoc />
protected override Vector2 MeasureChar(char c) { protected override float MeasureChar(char c) {
return this.Font.MeasureString(c.ToCachedString()); return this.Font.MeasureString(c.ToCachedString()).X;
} }
/// <inheritdoc/> /// <inheritdoc/>