From 1c00b428cea4c62f54d28d34ad8aba607ddae54e Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sun, 1 Oct 2017 09:38:03 +1100 Subject: [PATCH] Fix text consisting of only colour codes (no actual chars) behaving differently depending on whether use font was on or off --- ClassicalSharp/2D/Drawing/GdiPlusDrawer2D.cs | 5 +- ClassicalSharp/2D/Drawing/IDrawer2D.TextMC.cs | 17 +++--- ClassicalSharp/2D/Drawing/IDrawer2D.cs | 58 ++++++++++++------- ClassicalSharp/2D/Widgets/ButtonWidget.cs | 2 +- .../Widgets/Chat/AltTextInputWidget.Types.cs | 4 +- .../2D/Widgets/Chat/ChatInputWidget.cs | 2 +- .../Widgets/Chat/TextGroupWidget.Formatter.cs | 7 +-- .../2D/Widgets/Chat/TextGroupWidget.cs | 1 + ClassicalSharp/2D/Widgets/InputWidget.cs | 8 +-- ClassicalSharp/2D/Widgets/TextWidget.cs | 2 +- ClassicalSharp/Entities/Player.cs | 4 +- ClassicalSharp/Network/Protocols/CPE.cs | 2 +- ClassicalSharp/Singleplayer/Server.cs | 4 +- ClassicalSharp/Utils/WrappableStringBuffer.cs | 2 +- Launcher2/LauncherWindow.cs | 2 +- 15 files changed, 66 insertions(+), 54 deletions(-) diff --git a/ClassicalSharp/2D/Drawing/GdiPlusDrawer2D.cs b/ClassicalSharp/2D/Drawing/GdiPlusDrawer2D.cs index 66e393708..c4ed1302a 100644 --- a/ClassicalSharp/2D/Drawing/GdiPlusDrawer2D.cs +++ b/ClassicalSharp/2D/Drawing/GdiPlusDrawer2D.cs @@ -153,11 +153,10 @@ namespace ClassicalSharp { protected override Size MeasureSysSize(ref DrawTextArgs args) { GetTextParts(args.Text); - int count = parts.Count; - if (count == 0) return Size.Empty; + if (EmptyText(args.Text)) return Size.Empty; float width = 0, height = 0; - for (int i = 0; i < count; i++) { + for (int i = 0; i < parts.Count; i++) { SizeF size = measuringGraphics.MeasureString(parts[i].Text, args.Font, Int32.MaxValue, format); height = Math.Max(height, size.Height); width += size.Width; diff --git a/ClassicalSharp/2D/Drawing/IDrawer2D.TextMC.cs b/ClassicalSharp/2D/Drawing/IDrawer2D.TextMC.cs index c42f78cc1..ac700537a 100644 --- a/ClassicalSharp/2D/Drawing/IDrawer2D.TextMC.cs +++ b/ClassicalSharp/2D/Drawing/IDrawer2D.TextMC.cs @@ -74,7 +74,7 @@ namespace ClassicalSharp { } void DrawPart(FastBitmap dst, ref DrawTextArgs args, int x, int y, bool shadowCol) { - FastColour col = Colours['f']; + FastColour col = Cols['f']; if (shadowCol) col = BlackTextShadows ? FastColour.Black : FastColour.Scale(col, 0.25f); FastColour lastCol = col; @@ -87,9 +87,8 @@ namespace ClassicalSharp { for (int i = 0; i < text.Length; i++) { char c = text[i]; - bool isColCode = c == '&' && i < text.Length - 1; - if (isColCode && ValidColour(text[i + 1])) { - col = Colours[text[i + 1]]; + if (c == '&' && ValidColCode(text, i + 1)) { + col = Cols[text[i + 1]]; if (shadowCol) col = BlackTextShadows ? FastColour.Black : FastColour.Scale(col, 0.25f); i++; continue; // Skip over the colour code. @@ -178,9 +177,8 @@ namespace ClassicalSharp { for (int i = 0; i < text.Length; i++) { char c = text[i]; - bool isColCode = c == '&' && i < text.Length - 1; - if (isColCode && ValidColour(text[i + 1])) { - col = Colours[text[i + 1]].ToArgb(); + if (c == '&' && ValidColCode(text, i + 1)) { + col = Cols[text[i + 1]].ToArgb(); i++; continue; // Skip over the colour code. } if (shadowCol) col = FastColour.Black.ToArgb(); @@ -198,15 +196,14 @@ namespace ClassicalSharp { #endif protected Size MeasureBitmappedSize(ref DrawTextArgs args) { - if (String.IsNullOrEmpty(args.Text)) return Size.Empty; + if (EmptyText(args.Text)) return Size.Empty; int textHeight = AdjTextSize(Utils.Floor(args.Font.Size)); Size total = new Size(0, CellSize(textHeight)); int point = Utils.Floor(args.Font.Size); for (int i = 0; i < args.Text.Length; i++) { char c = args.Text[i]; - bool isColCode = c == '&' && i < args.Text.Length - 1; - if (isColCode && ValidColour(args.Text[i + 1])) { + if (c == '&' && ValidColCode(args.Text, i + 1)) { i++; continue; // Skip over the colour code. } diff --git a/ClassicalSharp/2D/Drawing/IDrawer2D.cs b/ClassicalSharp/2D/Drawing/IDrawer2D.cs index 76d2817df..a46214edc 100644 --- a/ClassicalSharp/2D/Drawing/IDrawer2D.cs +++ b/ClassicalSharp/2D/Drawing/IDrawer2D.cs @@ -133,19 +133,19 @@ namespace ClassicalSharp { return Platform.CreateBmp(Utils.NextPowerOf2(size.Width), Utils.NextPowerOf2(size.Height)); } - public FastColour[] Colours = new FastColour[256]; + public static FastColour[] Cols = new FastColour[256]; public IDrawer2D() { InitColours(); } public void InitColours() { - for (int i = 0; i < Colours.Length; i++) - Colours[i] = default(FastColour); + for (int i = 0; i < Cols.Length; i++) + Cols[i] = default(FastColour); for (int i = 0; i <= 9; i++) - Colours['0' + i] = FastColour.GetHexEncodedCol(i, 191, 64); + Cols['0' + i] = FastColour.GetHexEncodedCol(i, 191, 64); for (int i = 10; i <= 15; i++) { - Colours['a' + i - 10] = FastColour.GetHexEncodedCol(i, 191, 64); - Colours['A' + i - 10] = Colours['a' + i - 10]; + Cols['a' + i - 10] = FastColour.GetHexEncodedCol(i, 191, 64); + Cols['A' + i - 10] = Cols['a' + i - 10]; } } @@ -162,9 +162,9 @@ namespace ClassicalSharp { protected void GetTextParts(string value) { parts.Clear(); - if (String.IsNullOrEmpty(value)) { + if (EmptyText(value)) { } else if (value.IndexOf('&') == -1) { - parts.Add(new TextPart(value, Colours['f'])); + parts.Add(new TextPart(value, Cols['f'])); } else { SplitText(value); } @@ -179,12 +179,12 @@ namespace ClassicalSharp { if (partLength > 0) { string part = value.Substring(i, partLength); - parts.Add(new TextPart(part, Colours[code])); + parts.Add(new TextPart(part, Cols[code])); } i += partLength + 1; - if (nextCol >= 0 && nextCol + 1 < value.Length) { - if (!ValidColour(value[nextCol + 1])) { + if (nextCol >= 0) { + if (!ValidColCode(value, nextCol + 1)) { i--; // include character that isn't a valid colour. } else { code = value[nextCol + 1]; @@ -194,29 +194,45 @@ namespace ClassicalSharp { } /// Returns whenever the given character is a valid colour code. - public bool ValidColour(char c) { - return (int)c < 256 && Colours[c].A > 0; + public static bool ValidColCode(string text, int i) { + if (i >= text.Length) return false; + char c = text[i]; + return c < '\xFF' && Cols[c].A > 0; + } + + /// Returns whenever the given character is a valid colour code. + public static bool ValidColCode(char c) { + return c < '\xFF' && Cols[c].A > 0; + } + + public static bool EmptyText(string text) { + if (text == null || text.Length == 0) return true; + + for (int i = 0; i < text.Length; i++) { + if (text[i] != '&') return false; + if (!ValidColCode(text, i + 1)) return false; + i++; // skip colour code + } + return true; } #if !LAUNCHER /// Returns the last valid colour code in the given input, /// or \0 if no valid colour code was found. - public char LastColour(string input, int start) { - if (start >= input.Length) - start = input.Length - 1; + public static char LastCol(string text, int start) { + if (start >= text.Length) + start = text.Length - 1; for (int i = start; i >= 0; i--) { - if (input[i] != '&') continue; - if (i < input.Length - 1 && ValidColour(input[i + 1])) - return input[i + 1]; + if (text[i] != '&') continue; + if (ValidColCode(text, i + 1)) return text[i + 1]; } return '\0'; } - public static bool IsWhiteColour(char c) { + public static bool IsWhiteCol(char c) { return c == '\0' || c == 'f' || c == 'F'; } - public void ReducePadding(ref Texture tex, int point) { ReducePadding(ref tex, point, 4); diff --git a/ClassicalSharp/2D/Widgets/ButtonWidget.cs b/ClassicalSharp/2D/Widgets/ButtonWidget.cs index 6e2bf9b02..4290554ff 100644 --- a/ClassicalSharp/2D/Widgets/ButtonWidget.cs +++ b/ClassicalSharp/2D/Widgets/ButtonWidget.cs @@ -57,7 +57,7 @@ namespace ClassicalSharp.Gui.Widgets { public void SetText(string text) { gfx.DeleteTexture(ref texture); Text = text; - if (String.IsNullOrEmpty(text)) { + if (IDrawer2D.EmptyText(text)) { texture = default(Texture); Width = 0; Height = defaultHeight; } else { diff --git a/ClassicalSharp/2D/Widgets/Chat/AltTextInputWidget.Types.cs b/ClassicalSharp/2D/Widgets/Chat/AltTextInputWidget.Types.cs index 15424cecd..51806aacb 100644 --- a/ClassicalSharp/2D/Widgets/Chat/AltTextInputWidget.Types.cs +++ b/ClassicalSharp/2D/Widgets/Chat/AltTextInputWidget.Types.cs @@ -21,14 +21,14 @@ namespace ClassicalSharp.Gui.Widgets { int count = 0; for (int i = ' '; i <= '~'; i++) { if (i >= 'A' && i <= 'F') continue; - if (game.Drawer2D.Colours[i].A > 0) count++; + if (IDrawer2D.Cols[i].A > 0) count++; } StringBuffer buffer = new StringBuffer(count * 4); int index = 0; for (int i = ' '; i <= '~'; i++) { if (i >= 'A' && i <= 'F') continue; - if (game.Drawer2D.Colours[i].A == 0) continue; + if (IDrawer2D.Cols[i].A == 0) continue; buffer.Append(ref index, '&').Append(ref index, (char)i) .Append(ref index, '%').Append(ref index, (char)i); diff --git a/ClassicalSharp/2D/Widgets/Chat/ChatInputWidget.cs b/ClassicalSharp/2D/Widgets/Chat/ChatInputWidget.cs index 20fec9d37..9819c1690 100644 --- a/ClassicalSharp/2D/Widgets/Chat/ChatInputWidget.cs +++ b/ClassicalSharp/2D/Widgets/Chat/ChatInputWidget.cs @@ -118,7 +118,7 @@ namespace ClassicalSharp.Gui.Widgets { char lastCol = i == 0 ? 'f' : GetLastColour(0, i); // no previous colour on first line // TODO: this needs to be better, in case second/third line starts with a colour code - if (!IDrawer2D.IsWhiteColour(lastCol)) + if (!IDrawer2D.IsWhiteCol(lastCol)) text = "&" + lastCol + text; game.Chat.Send(text, partial); } diff --git a/ClassicalSharp/2D/Widgets/Chat/TextGroupWidget.Formatter.cs b/ClassicalSharp/2D/Widgets/Chat/TextGroupWidget.Formatter.cs index 5af12d79c..81e3e4f61 100644 --- a/ClassicalSharp/2D/Widgets/Chat/TextGroupWidget.Formatter.cs +++ b/ClassicalSharp/2D/Widgets/Chat/TextGroupWidget.Formatter.cs @@ -14,7 +14,7 @@ namespace ClassicalSharp.Gui.Widgets { linkData[index] = default(LinkData); LinkFlags prevFlags = index > 0 ? linkData[index - 1].flags : 0; - if (!String.IsNullOrEmpty(text)) { + if (!IDrawer2D.EmptyText(text)) { Texture tex = NextToken(text, 0, ref prevFlags) == -1 ? DrawSimple(ref args) : DrawAdvanced(ref args, index, text); game.Drawer2D.ReducePadding(ref tex, Utils.Floor(args.Font.Size), 3); @@ -122,9 +122,8 @@ namespace ClassicalSharp.Gui.Widgets { // We may split up a line into say %e // url and word both need to have %e at the start. - if (lastCol >= 0 && lastCol < line.Length - 1) { - if (game.Drawer2D.ValidColour(line[lastCol + 1])) - part = "&" + line[lastCol + 1] + part; + if (lastCol >= 0 && IDrawer2D.ValidColCode(line,lastCol + 1)) { + part = "&" + line[lastCol + 1] + part; } return part; } diff --git a/ClassicalSharp/2D/Widgets/Chat/TextGroupWidget.cs b/ClassicalSharp/2D/Widgets/Chat/TextGroupWidget.cs index 21512aaf9..8650f5239 100644 --- a/ClassicalSharp/2D/Widgets/Chat/TextGroupWidget.cs +++ b/ClassicalSharp/2D/Widgets/Chat/TextGroupWidget.cs @@ -93,6 +93,7 @@ namespace ClassicalSharp.Gui.Widgets { public int GetUsedHeight() { int height = 0, i = 0; + for (i = 0; i < Textures.Length; i++) { if (Textures[i].IsValid) break; } diff --git a/ClassicalSharp/2D/Widgets/InputWidget.cs b/ClassicalSharp/2D/Widgets/InputWidget.cs index 9a4f1fc3e..4ef3cd813 100644 --- a/ClassicalSharp/2D/Widgets/InputWidget.cs +++ b/ClassicalSharp/2D/Widgets/InputWidget.cs @@ -145,7 +145,7 @@ namespace ClassicalSharp.Gui.Widgets { // Update the colour of the caret char code = GetLastColour(caretCol, caretRow); - if (code != '\0') caretColour = drawer.Colours[code]; + if (code != '\0') caretColour = IDrawer2D.Cols[code]; } protected void RenderCaret(double delta) { @@ -182,7 +182,7 @@ namespace ClassicalSharp.Gui.Widgets { if (lines[i] == null) break; args.Text = lines[i]; char lastCol = GetLastColour(0, i); - if (!IDrawer2D.IsWhiteColour(lastCol)) + if (!IDrawer2D.IsWhiteCol(lastCol)) args.Text = "&" + lastCol + args.Text; int offset = i == 0 ? prefixWidth : 0; @@ -203,7 +203,7 @@ namespace ClassicalSharp.Gui.Widgets { IDrawer2D drawer = game.Drawer2D; for (int y = indexY; y >= 0; y--) { string part = lines[y]; - char code = drawer.LastColour(part, x); + char code = IDrawer2D.LastCol(part, x); if (code != '\0') return code; if (y > 0) x = lines[y - 1].Length; } @@ -354,7 +354,7 @@ namespace ClassicalSharp.Gui.Widgets { bool CheckColour(int index) { if (index < 0) return false; char code = Text.value[index], col = Text.value[index + 1]; - return (code == '%' || code == '&') && game.Drawer2D.ValidColour(col); + return (code == '%' || code == '&') && IDrawer2D.ValidColCode(col); } void DeleteKey() { diff --git a/ClassicalSharp/2D/Widgets/TextWidget.cs b/ClassicalSharp/2D/Widgets/TextWidget.cs index 4f9492d52..3ccb8375d 100644 --- a/ClassicalSharp/2D/Widgets/TextWidget.cs +++ b/ClassicalSharp/2D/Widgets/TextWidget.cs @@ -46,7 +46,7 @@ namespace ClassicalSharp.Gui.Widgets { public void SetText(string text) { gfx.DeleteTexture(ref texture); - if (String.IsNullOrEmpty(text)) { + if (IDrawer2D.EmptyText(text)) { texture = new Texture(); Width = 0; Height = defaultHeight; } else { diff --git a/ClassicalSharp/Entities/Player.cs b/ClassicalSharp/Entities/Player.cs index 0008e3e68..5c3000da6 100644 --- a/ClassicalSharp/Entities/Player.cs +++ b/ClassicalSharp/Entities/Player.cs @@ -62,9 +62,9 @@ namespace ClassicalSharp.Entities { { drawer.SetBitmap(bmp); args.Text = "&\xFF" + Utils.StripColours(args.Text); - game.Drawer2D.Colours['\xFF'] = new FastColour(80, 80, 80); + IDrawer2D.Cols['\xFF'] = new FastColour(80, 80, 80); game.Drawer2D.DrawText(ref args, 3, 3); - game.Drawer2D.Colours['\xFF'] = default(FastColour); + IDrawer2D.Cols['\xFF'] = default(FastColour); args.Text = DisplayName; game.Drawer2D.DrawText(ref args, 0, 0); diff --git a/ClassicalSharp/Network/Protocols/CPE.cs b/ClassicalSharp/Network/Protocols/CPE.cs index d5dfe5f06..70c3b070d 100644 --- a/ClassicalSharp/Network/Protocols/CPE.cs +++ b/ClassicalSharp/Network/Protocols/CPE.cs @@ -313,7 +313,7 @@ namespace ClassicalSharp.Network.Protocols { if (code <= ' ' || code > '~') return; // Control chars, space, extended chars cannot be used if (code == '%' || code == '&') return; // colour code signifiers cannot be used - game.Drawer2D.Colours[code] = col; + IDrawer2D.Cols[code] = col; game.Events.RaiseColourCodeChanged((char)code); } diff --git a/ClassicalSharp/Singleplayer/Server.cs b/ClassicalSharp/Singleplayer/Server.cs index d4950fd8e..6be4a4592 100644 --- a/ClassicalSharp/Singleplayer/Server.cs +++ b/ClassicalSharp/Singleplayer/Server.cs @@ -51,10 +51,10 @@ namespace ClassicalSharp.Singleplayer { void AddChat(string text) { text = text.TrimEnd().Replace('%', '&'); - if (!IDrawer2D.IsWhiteColour(lastCol)) + if (!IDrawer2D.IsWhiteCol(lastCol)) text = "&" + lastCol + text; - char col = game.Drawer2D.LastColour(text, text.Length); + char col = IDrawer2D.LastCol(text, text.Length); if (col != '\0') lastCol = col; game.Chat.Add(text, MessageType.Normal); } diff --git a/ClassicalSharp/Utils/WrappableStringBuffer.cs b/ClassicalSharp/Utils/WrappableStringBuffer.cs index eb091397a..578da4ff3 100644 --- a/ClassicalSharp/Utils/WrappableStringBuffer.cs +++ b/ClassicalSharp/Utils/WrappableStringBuffer.cs @@ -65,7 +65,7 @@ namespace ClassicalSharp { } // convert %0-f to &0-f for colour preview. for (int i = 0; i < totalChars - 1; i++) { - if (value[i] == '%' && drawer.ValidColour(value[i + 1])) + if (value[i] == '%' && IDrawer2D.ValidColCode(value[i + 1])) value[i] = '&'; } diff --git a/Launcher2/LauncherWindow.cs b/Launcher2/LauncherWindow.cs index 23ca2fb2b..e3d9e69cb 100644 --- a/Launcher2/LauncherWindow.cs +++ b/Launcher2/LauncherWindow.cs @@ -94,7 +94,7 @@ namespace Launcher { platformDrawer = new OSXPlatformDrawer(); } - Drawer.Colours['g'] = new FastColour(125, 125, 125); + IDrawer2D.Cols['g'] = new FastColour(125, 125, 125); } void LoadFont() {