1
0
Fork 0
mirror of https://github.com/Ellpeck/MLEM.git synced 2024-05-09 19:18:44 +02:00

Generify GenericFont's string drawing

This commit is contained in:
Ell 2021-12-22 12:46:17 +01:00
parent 7f3abdada5
commit 17ed82fc3c
6 changed files with 130 additions and 34 deletions

View file

@ -8,6 +8,9 @@ Jump to version:
- [5.0.0](#500)
## 5.3.0 (Unreleased)
### MLEM
Improvements
- Generify GenericFont's string drawing
## 5.2.0
### MLEM

View file

@ -1,4 +1,3 @@
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using MLEM.Font;
@ -38,14 +37,9 @@ namespace MLEM.Extended.Font {
return region != null ? new Vector2(region.XAdvance, region.Height).X : 0;
}
/// <inheritdoc/>
public override void DrawString(SpriteBatch batch, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth) {
batch.DrawString(this.Font, text, position, color, rotation, origin, scale, effects, layerDepth);
}
/// <inheritdoc/>
public override void DrawString(SpriteBatch batch, StringBuilder text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth) {
batch.DrawString(this.Font, text, position, color, rotation, origin, scale, effects, layerDepth);
/// <inheritdoc />
protected override void DrawChar(SpriteBatch batch, char c, string cString, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth) {
batch.DrawString(this.Font, cString, position, color, rotation, origin, scale, effects, layerDepth);
}
}

View file

@ -1,4 +1,3 @@
using System.Text;
using FontStashSharp;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
@ -33,20 +32,15 @@ namespace MLEM.Extended.Font {
this.Italic = italic != null ? new GenericStashFont(italic) : this;
}
/// <inheritdoc />
public override void DrawString(SpriteBatch batch, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth) {
this.Font.DrawText(batch, text, position, color, scale, rotation, origin, layerDepth);
}
/// <inheritdoc />
public override void DrawString(SpriteBatch batch, StringBuilder text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth) {
this.Font.DrawText(batch, text, position, color, scale, rotation, origin, layerDepth);
}
/// <inheritdoc />
protected override float MeasureChar(char c) {
return this.Font.MeasureString(c.ToCachedString()).X;
}
/// <inheritdoc />
protected override void DrawChar(SpriteBatch batch, char c, string cString, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth) {
this.Font.DrawText(batch, cString, position, color, scale, rotation, origin, layerDepth);
}
}
}

View file

@ -54,11 +54,26 @@ namespace MLEM.Font {
/// <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)"/>
public abstract void DrawString(SpriteBatch batch, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth);
/// <summary>
/// Draws the given character with the given data for use in <see cref="DrawString(Microsoft.Xna.Framework.Graphics.SpriteBatch,System.Text.StringBuilder,Microsoft.Xna.Framework.Vector2,Microsoft.Xna.Framework.Color,float,Microsoft.Xna.Framework.Vector2,Microsoft.Xna.Framework.Vector2,Microsoft.Xna.Framework.Graphics.SpriteEffects,float)"/>.
/// Note that this method is only called internally.
/// </summary>
/// <param name="batch">The sprite batch to draw with.</param>
/// <param name="c">The character which will be drawn.</param>
/// <param name="cString">A string representation of the character which will be drawn.</param>
/// <param name="position">The drawing location on screen.</param>
/// <param name="color">A color mask.</param>
/// <param name="rotation">A rotation of this character.</param>
/// <param name="origin">Center of the rotation. 0,0 by default.</param>
/// <param name="scale">A scaling of this character.</param>
/// <param name="effects">Modificators for drawing. Can be combined.</param>
/// <param name="layerDepth">A depth of the layer of this character.</param>
protected abstract void DrawChar(SpriteBatch batch, char c, string cString, 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 abstract void DrawString(SpriteBatch batch, StringBuilder text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth);
public void DrawString(SpriteBatch batch, StringBuilder text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth) {
this.DrawString(batch, text.ToString(), position, color, rotation, origin, scale, effects, 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, float rotation, Vector2 origin, float scale, SpriteEffects effects, float layerDepth) {
@ -80,6 +95,64 @@ namespace MLEM.Font {
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, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth) {
var (flipX, flipY) = Vector2.Zero;
var flippedV = (effects & SpriteEffects.FlipVertically) != 0;
var flippedH = (effects & SpriteEffects.FlipHorizontally) != 0;
if (flippedV || flippedH) {
var (w, h) = this.MeasureString(text);
if (flippedH) {
origin.X *= -1;
flipX = -w;
}
if (flippedV) {
origin.Y *= -1;
flipY = this.LineHeight - h;
}
}
var trans = Matrix.Identity;
if (rotation == 0) {
trans.M11 = flippedH ? -scale.X : scale.X;
trans.M22 = flippedV ? -scale.Y : scale.Y;
trans.M41 = (flipX - origin.X) * trans.M11 + position.X;
trans.M42 = (flipY - origin.Y) * trans.M22 + position.Y;
} else {
var sin = (float) Math.Sin(rotation);
var cos = (float) Math.Cos(rotation);
trans.M11 = (flippedH ? -scale.X : scale.X) * cos;
trans.M12 = (flippedH ? -scale.X : scale.X) * sin;
trans.M21 = (flippedV ? -scale.Y : scale.Y) * -sin;
trans.M22 = (flippedV ? -scale.Y : scale.Y) * cos;
trans.M41 = (flipX - origin.X) * trans.M11 + (flipY - origin.Y) * trans.M21 + position.X;
trans.M42 = (flipX - origin.X) * trans.M12 + (flipY - origin.Y) * trans.M22 + position.Y;
}
var offset = Vector2.Zero;
for (var i = 0; i < text.Length; i++) {
var c = text[i];
if (c == '\n') {
offset.X = 0;
offset.Y += this.LineHeight;
continue;
}
var cString = c.ToCachedString();
var (cW, cH) = this.MeasureString(cString);
var charPos = offset;
if (flippedH)
charPos.X += cW;
if (flippedV)
charPos.Y += cH - this.LineHeight;
Vector2.Transform(ref charPos, ref trans, out charPos);
this.DrawChar(batch, c, cString, charPos, color, rotation, Vector2.Zero, scale, effects, layerDepth);
offset.X += cW;
}
}
/// <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"/>.

View file

@ -1,5 +1,4 @@
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using MLEM.Extensions;
@ -37,14 +36,9 @@ namespace MLEM.Font {
return this.Font.MeasureString(c.ToCachedString()).X;
}
/// <inheritdoc/>
public override void DrawString(SpriteBatch batch, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth) {
batch.DrawString(this.Font, text, position, color, rotation, origin, scale, effects, layerDepth);
}
/// <inheritdoc/>
public override void DrawString(SpriteBatch batch, StringBuilder text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth) {
batch.DrawString(this.Font, text, position, color, rotation, origin, scale, effects, layerDepth);
/// <inheritdoc />
protected override void DrawChar(SpriteBatch batch, char c, string cString, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth) {
batch.DrawString(this.Font, cString, position, color, rotation, origin, scale, effects, layerDepth);
}
private static SpriteFont SetDefaults(SpriteFont font) {

View file

@ -239,7 +239,7 @@ namespace Sandbox {
par.OnDrawn = (e, time, batch, a) => batch.DrawRectangle(e.DisplayArea.ToExtended(), Color.Red);
this.UiSystem.Add("Load", loadGroup);*/
var spillPanel = new Panel(Anchor.Center, new Vector2(100), Vector2.Zero);
/*var spillPanel = new Panel(Anchor.Center, new Vector2(100), Vector2.Zero);
var squishingGroup = spillPanel.AddChild(new SquishingGroup(Anchor.TopLeft, Vector2.One));
squishingGroup.AddChild(new Button(Anchor.TopLeft, new Vector2(30), "TL") {
OnUpdated = (e, time) => e.IsHidden = Input.IsKeyDown(Keys.D1),
@ -266,7 +266,45 @@ namespace Sandbox {
e.SetAreaDirty();
}
}).SetData("Ref", "Main");
this.UiSystem.Add("SpillTest", spillPanel);
this.UiSystem.Add("SpillTest", spillPanel);*/
var regularFont = spriteFont.Font;
var genericFont = spriteFont;
var index = 0;
var pos = new Vector2(100, 20);
var scale = 1F;
var origin = Vector2.Zero;
var rotation = 0F;
var effects = SpriteEffects.None;
this.OnDraw += (g, time) => {
const string testString = "This is a\ntest string\n\twith long lines.\nLet's write some more stuff. Let's\r\nsplit lines weirdly.";
if (Input.IsKeyPressed(Keys.I)) {
index++;
if (index == 1) {
scale = 2;
} else if (index == 2) {
origin = new Vector2(15, 15);
} else if (index == 3) {
rotation = 0.25F;
} else if (index == 4) {
effects = SpriteEffects.FlipHorizontally;
} else if (index == 5) {
effects = SpriteEffects.FlipVertically;
} else if (index == 6) {
effects = SpriteEffects.FlipHorizontally | SpriteEffects.FlipVertically;
}
}
this.SpriteBatch.Begin();
if (Input.IsKeyDown(Keys.LeftShift)) {
this.SpriteBatch.DrawString(regularFont, testString, pos, Color.Red, rotation, origin, scale, effects, 0);
} else {
genericFont.DrawString(this.SpriteBatch, testString, pos, Color.Green, rotation, origin, scale, effects, 0);
}
this.SpriteBatch.End();
};
}
protected override void DoUpdate(GameTime gameTime) {