diff --git a/CHANGELOG.md b/CHANGELOG.md
index 42fb798..c020eca 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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
diff --git a/MLEM.Extended/Font/GenericBitmapFont.cs b/MLEM.Extended/Font/GenericBitmapFont.cs
index 922f6e7..db785b4 100644
--- a/MLEM.Extended/Font/GenericBitmapFont.cs
+++ b/MLEM.Extended/Font/GenericBitmapFont.cs
@@ -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;
}
- ///
- 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);
- }
-
- ///
- 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);
+ ///
+ 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);
}
}
diff --git a/MLEM.Extended/Font/GenericStashFont.cs b/MLEM.Extended/Font/GenericStashFont.cs
index 42d9d41..4afb137 100644
--- a/MLEM.Extended/Font/GenericStashFont.cs
+++ b/MLEM.Extended/Font/GenericStashFont.cs
@@ -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;
}
- ///
- 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);
- }
-
- ///
- 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);
- }
-
///
protected override float MeasureChar(char c) {
return this.Font.MeasureString(c.ToCachedString()).X;
}
+ ///
+ 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);
+ }
+
}
}
\ No newline at end of file
diff --git a/MLEM/Font/GenericFont.cs b/MLEM/Font/GenericFont.cs
index 97e23aa..8ea788b 100644
--- a/MLEM/Font/GenericFont.cs
+++ b/MLEM/Font/GenericFont.cs
@@ -54,11 +54,26 @@ namespace MLEM.Font {
/// The width of the given character with the default scale
protected abstract float MeasureChar(char c);
- ///
- public abstract void DrawString(SpriteBatch batch, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth);
+ ///
+ /// Draws the given character with the given data for use in .
+ /// Note that this method is only called internally.
+ ///
+ /// The sprite batch to draw with.
+ /// The character which will be drawn.
+ /// A string representation of the character which will be drawn.
+ /// The drawing location on screen.
+ /// A color mask.
+ /// A rotation of this character.
+ /// Center of the rotation. 0,0 by default.
+ /// A scaling of this character.
+ /// Modificators for drawing. Can be combined.
+ /// A depth of the layer of this character.
+ protected abstract void DrawChar(SpriteBatch batch, char c, string cString, 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);
+ 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);
+ }
///
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);
}
+ ///
+ 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;
+ }
+ }
+
///
/// Measures the width of the given string when drawn with this font's underlying font.
/// This method uses internally to calculate the size of known characters and calculates additional characters like , and .
diff --git a/MLEM/Font/GenericSpriteFont.cs b/MLEM/Font/GenericSpriteFont.cs
index 7634796..9f29567 100644
--- a/MLEM/Font/GenericSpriteFont.cs
+++ b/MLEM/Font/GenericSpriteFont.cs
@@ -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;
}
- ///
- 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);
- }
-
- ///
- 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);
+ ///
+ 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) {
diff --git a/Sandbox/GameImpl.cs b/Sandbox/GameImpl.cs
index 3354521..76cce39 100644
--- a/Sandbox/GameImpl.cs
+++ b/Sandbox/GameImpl.cs
@@ -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) {