1
0
Fork 0
mirror of https://github.com/Ellpeck/MLEM.git synced 2024-06-13 01:23:51 +02:00

Cache TokenizedString inner offsets for non-Left text alignments

This commit is contained in:
Ell 2021-10-04 23:57:58 +02:00
parent f021215066
commit 9743c05e1a
3 changed files with 37 additions and 34 deletions

View file

@ -8,6 +8,9 @@ Jump to version:
## 5.2.0 (Unreleased) ## 5.2.0 (Unreleased)
### MLEM.Ui ### MLEM.Ui
Improvements
- Cache TokenizedString inner offsets for non-Left text alignments to improve performance
Fixes Fixes
- Fixed VerticalSpace height parameter being an integer - Fixed VerticalSpace height parameter being an integer

View file

@ -42,6 +42,7 @@ namespace MLEM.Formatting {
public readonly string RawSubstring; public readonly string RawSubstring;
internal RectangleF[] Area; internal RectangleF[] Area;
internal string ModifiedSubstring; internal string ModifiedSubstring;
internal float[] InnerOffsets;
internal Token(Code[] appliedCodes, int index, int rawIndex, string substring, string rawSubstring) { internal Token(Code[] appliedCodes, int index, int rawIndex, string substring, string rawSubstring) {
this.AppliedCodes = appliedCodes; this.AppliedCodes = appliedCodes;

View file

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@ -37,6 +38,7 @@ namespace MLEM.Formatting {
/// </summary> /// </summary>
public readonly Code[] AllCodes; public readonly Code[] AllCodes;
private string modifiedString; private string modifiedString;
private float initialInnerOffset;
internal TokenizedString(GenericFont font, TextAlignment alignment, string rawString, string strg, Token[] tokens) { internal TokenizedString(GenericFont font, TextAlignment alignment, string rawString, string strg, Token[] tokens) {
this.RawString = rawString; this.RawString = rawString;
@ -111,7 +113,7 @@ namespace MLEM.Formatting {
/// <inheritdoc cref="GenericFont.DrawString(SpriteBatch,string,Vector2,Color,float,Vector2,float,SpriteEffects,float)"/> /// <inheritdoc cref="GenericFont.DrawString(SpriteBatch,string,Vector2,Color,float,Vector2,float,SpriteEffects,float)"/>
public void Draw(GameTime time, SpriteBatch batch, Vector2 pos, GenericFont font, Color color, float scale, float depth, TextAlignment alignment = TextAlignment.Left) { public void Draw(GameTime time, SpriteBatch batch, Vector2 pos, GenericFont font, Color color, float scale, float depth, TextAlignment alignment = TextAlignment.Left) {
var innerOffset = new Vector2(this.GetInnerOffsetX(font, 0, 0, scale, alignment), 0); var innerOffset = new Vector2(this.initialInnerOffset * scale, 0);
for (var t = 0; t < this.Tokens.Length; t++) { for (var t = 0; t < this.Tokens.Length; t++) {
var token = this.Tokens[t]; var token = this.Tokens[t];
var drawFont = token.GetFont(font) ?? font; var drawFont = token.GetFont(font) ?? font;
@ -129,7 +131,7 @@ namespace MLEM.Formatting {
} }
// only split at a new line, not between tokens! // only split at a new line, not between tokens!
if (l < token.SplitDisplayString.Length - 1) { if (l < token.SplitDisplayString.Length - 1) {
innerOffset.X = this.GetInnerOffsetX(font, t, l + 1, scale, alignment); innerOffset.X = token.InnerOffsets[l] * scale;
innerOffset.Y += font.LineHeight * scale; innerOffset.Y += font.LineHeight * scale;
} }
} }
@ -172,45 +174,17 @@ namespace MLEM.Formatting {
this.RecalculateTokenData(font, alignment); this.RecalculateTokenData(font, alignment);
} }
private float GetInnerOffsetX(GenericFont font, int tokenIndex, int lineIndex, float scale, TextAlignment alignment) {
if (alignment > TextAlignment.Left) {
var rest = this.GetRestOfLineLength(font, tokenIndex, lineIndex) * scale;
if (alignment == TextAlignment.Center)
rest /= 2;
return -rest;
}
return 0;
}
private float GetRestOfLineLength(GenericFont font, int tokenIndex, int lineIndex) {
var token = this.Tokens[tokenIndex];
var ret = font.MeasureString(token.SplitDisplayString[lineIndex], true).X;
if (lineIndex >= token.SplitDisplayString.Length - 1) {
// the line ends somewhere in or after the next token
for (var i = tokenIndex + 1; i < this.Tokens.Length; i++) {
var other = this.Tokens[i];
if (other.SplitDisplayString.Length > 1) {
// the line ends in this token
ret += font.MeasureString(other.SplitDisplayString[0]).X;
break;
} else {
// the line doesn't end in this token, so add it fully
ret += font.MeasureString(other.DisplayString).X;
}
}
}
return ret;
}
private void RecalculateTokenData(GenericFont font, TextAlignment alignment) { private void RecalculateTokenData(GenericFont font, TextAlignment alignment) {
// split display strings // split display strings
foreach (var token in this.Tokens) foreach (var token in this.Tokens)
token.SplitDisplayString = token.DisplayString.Split('\n'); token.SplitDisplayString = token.DisplayString.Split('\n');
// token areas // token areas
var innerOffset = new Vector2(this.GetInnerOffsetX(font, 0, 0, 1, alignment), 0); this.initialInnerOffset = this.GetInnerOffsetX(font, 0, 0, alignment);
var innerOffset = new Vector2(this.initialInnerOffset, 0);
for (var t = 0; t < this.Tokens.Length; t++) { for (var t = 0; t < this.Tokens.Length; t++) {
var token = this.Tokens[t]; var token = this.Tokens[t];
token.InnerOffsets = new float[token.SplitDisplayString.Length - 1];
var area = new List<RectangleF>(); var area = new List<RectangleF>();
for (var l = 0; l < token.SplitDisplayString.Length; l++) { for (var l = 0; l < token.SplitDisplayString.Length; l++) {
var size = font.MeasureString(token.SplitDisplayString[l]); var size = font.MeasureString(token.SplitDisplayString[l]);
@ -219,7 +193,7 @@ namespace MLEM.Formatting {
area.Add(rect); area.Add(rect);
if (l < token.SplitDisplayString.Length - 1) { if (l < token.SplitDisplayString.Length - 1) {
innerOffset.X = this.GetInnerOffsetX(font, t, l + 1, 1, alignment); innerOffset.X = token.InnerOffsets[l] = this.GetInnerOffsetX(font, t, l + 1, alignment);
innerOffset.Y += font.LineHeight; innerOffset.Y += font.LineHeight;
} else { } else {
innerOffset.X += size.X; innerOffset.X += size.X;
@ -229,5 +203,30 @@ namespace MLEM.Formatting {
} }
} }
private float GetInnerOffsetX(GenericFont font, int tokenIndex, int lineIndex, TextAlignment alignment) {
if (alignment > TextAlignment.Left) {
var token = this.Tokens[tokenIndex];
var restOfLine = font.MeasureString(token.SplitDisplayString[lineIndex], true).X;
if (lineIndex >= token.SplitDisplayString.Length - 1) {
// the line ends somewhere in or after the next token
for (var i = tokenIndex + 1; i < this.Tokens.Length; i++) {
var other = this.Tokens[i];
if (other.SplitDisplayString.Length > 1) {
// the line ends in this token
restOfLine += font.MeasureString(other.SplitDisplayString[0]).X;
break;
} else {
// the line doesn't end in this token, so add it fully
restOfLine += font.MeasureString(other.DisplayString).X;
}
}
}
if (alignment == TextAlignment.Center)
restOfLine /= 2;
return -restOfLine;
}
return 0;
}
} }
} }