From 856d69b7dbff6c58d103cb114bb26be47345f9b0 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Sun, 13 Feb 2022 22:43:51 +0100 Subject: [PATCH] Fixed a formatting Code only knowing about the last Token that it is applied in Closes #3 --- CHANGELOG.md | 1 + MLEM/Formatting/Codes/Code.cs | 10 ++++++---- MLEM/Formatting/Codes/ImageCode.cs | 2 +- MLEM/Formatting/Codes/LinkCode.cs | 10 +++++++--- MLEM/Formatting/Codes/ShadowCode.cs | 2 +- MLEM/Formatting/Codes/UnderlineCode.cs | 4 ++-- MLEM/Formatting/Codes/WobblyCode.cs | 4 ++-- MLEM/Formatting/Token.cs | 7 ++----- MLEM/Formatting/TokenizedString.cs | 6 ++++++ 9 files changed, 28 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 094f66a..f1136df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ Improvements - Added InputHandler mouse and touch position querying that preserves the game's viewport Fixes +- **Fixed a formatting Code only knowing about the last Token that it is applied in** - Fixed StaticSpriteBatch handling rotated sprites incorrectly Removals diff --git a/MLEM/Formatting/Codes/Code.cs b/MLEM/Formatting/Codes/Code.cs index f08f075..2e12144 100644 --- a/MLEM/Formatting/Codes/Code.cs +++ b/MLEM/Formatting/Codes/Code.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Text.RegularExpressions; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; @@ -20,9 +21,10 @@ namespace MLEM.Formatting.Codes { /// public readonly Match Match; /// - /// The token that this formatting code is a part of + /// The tokens that this formatting code is a part of. + /// Note that this array only has multiple entries if additional tokens have to be started while this code is still applied. /// - public Token Token { get; internal set; } + public IList Tokens { get; internal set; } /// /// Creates a new formatting code based on a formatting code regex and its match. @@ -71,12 +73,12 @@ namespace MLEM.Formatting.Codes { } /// - public virtual bool DrawCharacter(GameTime time, SpriteBatch batch, char c, string cString, int indexInToken, ref Vector2 pos, GenericFont font, ref Color color, ref float scale, float depth) { + public virtual bool DrawCharacter(GameTime time, SpriteBatch batch, char c, string cString, Token token, int indexInToken, ref Vector2 pos, GenericFont font, ref Color color, ref float scale, float depth) { return false; } /// - public virtual void DrawSelf(GameTime time, SpriteBatch batch, Vector2 pos, GenericFont font, Color color, float scale, float depth) {} + public virtual void DrawSelf(GameTime time, SpriteBatch batch, Token token, Vector2 pos, GenericFont font, Color color, float scale, float depth) {} /// /// Creates a new formatting code from the given regex and regex match. diff --git a/MLEM/Formatting/Codes/ImageCode.cs b/MLEM/Formatting/Codes/ImageCode.cs index aef7616..1024e85 100644 --- a/MLEM/Formatting/Codes/ImageCode.cs +++ b/MLEM/Formatting/Codes/ImageCode.cs @@ -36,7 +36,7 @@ namespace MLEM.Formatting.Codes { } /// - public override void DrawSelf(GameTime time, SpriteBatch batch, Vector2 pos, GenericFont font, Color color, float scale, float depth) { + public override void DrawSelf(GameTime time, SpriteBatch batch, Token token, Vector2 pos, GenericFont font, Color color, float scale, float depth) { var actualColor = this.copyTextColor ? color : Color.White.CopyAlpha(color); batch.Draw(this.image.CurrentRegion, new RectangleF(pos, new Vector2(font.LineHeight * scale)), actualColor); } diff --git a/MLEM/Formatting/Codes/LinkCode.cs b/MLEM/Formatting/Codes/LinkCode.cs index 10d5c26..866c639 100644 --- a/MLEM/Formatting/Codes/LinkCode.cs +++ b/MLEM/Formatting/Codes/LinkCode.cs @@ -20,13 +20,17 @@ namespace MLEM.Formatting.Codes { /// /// True if this code is currently selected public virtual bool IsSelected() { - return this.isSelected(this.Token); + foreach (var token in this.Tokens) { + if (this.isSelected(token)) + return true; + } + return false; } /// - public override bool DrawCharacter(GameTime time, SpriteBatch batch, char c, string cString, int indexInToken, ref Vector2 pos, GenericFont font, ref Color color, ref float scale, float depth) { + public override bool DrawCharacter(GameTime time, SpriteBatch batch, char c, string cString, Token token, int indexInToken, ref Vector2 pos, GenericFont font, ref Color color, ref float scale, float depth) { // since we inherit from UnderlineCode, we can just call base if selected - return this.IsSelected() && base.DrawCharacter(time, batch, c, cString, indexInToken, ref pos, font, ref color, ref scale, depth); + return this.IsSelected() && base.DrawCharacter(time, batch, c, cString, token, indexInToken, ref pos, font, ref color, ref scale, depth); } } diff --git a/MLEM/Formatting/Codes/ShadowCode.cs b/MLEM/Formatting/Codes/ShadowCode.cs index 61055c4..aecdeff 100644 --- a/MLEM/Formatting/Codes/ShadowCode.cs +++ b/MLEM/Formatting/Codes/ShadowCode.cs @@ -18,7 +18,7 @@ namespace MLEM.Formatting.Codes { } /// - public override bool DrawCharacter(GameTime time, SpriteBatch batch, char c, string cString, int indexInToken, ref Vector2 pos, GenericFont font, ref Color color, ref float scale, float depth) { + public override bool DrawCharacter(GameTime time, SpriteBatch batch, char c, string cString, Token token, int indexInToken, ref Vector2 pos, GenericFont font, ref Color color, ref float scale, float depth) { font.DrawString(batch, cString, pos + this.offset * scale, this.color.CopyAlpha(color), 0, Vector2.Zero, scale, SpriteEffects.None, depth); // we return false since we still want regular drawing to occur return false; diff --git a/MLEM/Formatting/Codes/UnderlineCode.cs b/MLEM/Formatting/Codes/UnderlineCode.cs index ddee86c..df14e48 100644 --- a/MLEM/Formatting/Codes/UnderlineCode.cs +++ b/MLEM/Formatting/Codes/UnderlineCode.cs @@ -19,9 +19,9 @@ namespace MLEM.Formatting.Codes { } /// - public override bool DrawCharacter(GameTime time, SpriteBatch batch, char c, string cString, int indexInToken, ref Vector2 pos, GenericFont font, ref Color color, ref float scale, float depth) { + public override bool DrawCharacter(GameTime time, SpriteBatch batch, char c, string cString, Token token, int indexInToken, ref Vector2 pos, GenericFont font, ref Color color, ref float scale, float depth) { // don't underline spaces at the end of lines - if (c == ' ' && this.Token.DisplayString.Length > indexInToken + 1 && this.Token.DisplayString[indexInToken + 1] == '\n') + if (c == ' ' && token.DisplayString.Length > indexInToken + 1 && token.DisplayString[indexInToken + 1] == '\n') return false; var (w, h) = font.MeasureString(cString) * scale; var t = h * this.thickness; diff --git a/MLEM/Formatting/Codes/WobblyCode.cs b/MLEM/Formatting/Codes/WobblyCode.cs index 6723605..f2f34dd 100644 --- a/MLEM/Formatting/Codes/WobblyCode.cs +++ b/MLEM/Formatting/Codes/WobblyCode.cs @@ -28,8 +28,8 @@ namespace MLEM.Formatting.Codes { } /// - public override bool DrawCharacter(GameTime time, SpriteBatch batch, char c, string cString, int indexInToken, ref Vector2 pos, GenericFont font, ref Color color, ref float scale, float depth) { - var offset = new Vector2(0, (float) Math.Sin(this.Token.Index + indexInToken + this.TimeIntoAnimation.TotalSeconds * this.modifier) * font.LineHeight * this.heightModifier * scale); + public override bool DrawCharacter(GameTime time, SpriteBatch batch, char c, string cString, Token token, int indexInToken, ref Vector2 pos, GenericFont font, ref Color color, ref float scale, float depth) { + var offset = new Vector2(0, (float) Math.Sin(token.Index + indexInToken + this.TimeIntoAnimation.TotalSeconds * this.modifier) * font.LineHeight * this.heightModifier * scale); pos += offset; // we return false since we still want regular drawing to occur, we just changed the position return false; diff --git a/MLEM/Formatting/Token.cs b/MLEM/Formatting/Token.cs index 9b47836..ca18f00 100644 --- a/MLEM/Formatting/Token.cs +++ b/MLEM/Formatting/Token.cs @@ -50,9 +50,6 @@ namespace MLEM.Formatting { this.RawIndex = rawIndex; this.Substring = substring; this.RawSubstring = rawSubstring; - - foreach (var code in appliedCodes) - code.Token = this; } /// @@ -96,7 +93,7 @@ namespace MLEM.Formatting { /// The depth to draw at public void DrawSelf(GameTime time, SpriteBatch batch, Vector2 pos, GenericFont font, Color color, float scale, float depth) { foreach (var code in this.AppliedCodes) - code.DrawSelf(time, batch, pos, font, color, scale, depth); + code.DrawSelf(time, batch, this, pos, font, color, scale, depth); } /// @@ -114,7 +111,7 @@ namespace MLEM.Formatting { /// The depth to draw at public void DrawCharacter(GameTime time, SpriteBatch batch, char c, string cString, int indexInToken, Vector2 pos, GenericFont font, Color color, float scale, float depth) { foreach (var code in this.AppliedCodes) { - if (code.DrawCharacter(time, batch, c, cString, indexInToken, ref pos, font, ref color, ref scale, depth)) + if (code.DrawCharacter(time, batch, c, cString, this, indexInToken, ref pos, font, ref color, ref scale, depth)) return; } diff --git a/MLEM/Formatting/TokenizedString.cs b/MLEM/Formatting/TokenizedString.cs index 9dd2cef..585479a 100644 --- a/MLEM/Formatting/TokenizedString.cs +++ b/MLEM/Formatting/TokenizedString.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using System.Text; using Microsoft.Xna.Framework; @@ -44,8 +45,13 @@ namespace MLEM.Formatting { this.RawString = rawString; this.String = strg; this.Tokens = tokens; + // since a code can be present in multiple tokens, we use Distinct here this.AllCodes = tokens.SelectMany(t => t.AppliedCodes).Distinct().ToArray(); + // TODO this can probably be optimized by keeping track of a code's tokens while tokenizing + foreach (var code in this.AllCodes) + code.Tokens = new ReadOnlyCollection(this.Tokens.Where(t => t.AppliedCodes.Contains(code)).ToList()); + this.RecalculateTokenData(font, alignment); }