Fix text consisting of only colour codes (no actual chars) behaving differently depending on whether use font was on or off

This commit is contained in:
UnknownShadow200 2017-10-01 09:38:03 +11:00
parent ee7fe69d40
commit 1c00b428ce
15 changed files with 66 additions and 54 deletions

View File

@ -153,11 +153,10 @@ namespace ClassicalSharp {
protected override Size MeasureSysSize(ref DrawTextArgs args) { protected override Size MeasureSysSize(ref DrawTextArgs args) {
GetTextParts(args.Text); GetTextParts(args.Text);
int count = parts.Count; if (EmptyText(args.Text)) return Size.Empty;
if (count == 0) return Size.Empty;
float width = 0, height = 0; 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); SizeF size = measuringGraphics.MeasureString(parts[i].Text, args.Font, Int32.MaxValue, format);
height = Math.Max(height, size.Height); height = Math.Max(height, size.Height);
width += size.Width; width += size.Width;

View File

@ -74,7 +74,7 @@ namespace ClassicalSharp {
} }
void DrawPart(FastBitmap dst, ref DrawTextArgs args, int x, int y, bool shadowCol) { void DrawPart(FastBitmap dst, ref DrawTextArgs args, int x, int y, bool shadowCol) {
FastColour col = Colours['f']; FastColour col = Cols['f'];
if (shadowCol) if (shadowCol)
col = BlackTextShadows ? FastColour.Black : FastColour.Scale(col, 0.25f); col = BlackTextShadows ? FastColour.Black : FastColour.Scale(col, 0.25f);
FastColour lastCol = col; FastColour lastCol = col;
@ -87,9 +87,8 @@ namespace ClassicalSharp {
for (int i = 0; i < text.Length; i++) { for (int i = 0; i < text.Length; i++) {
char c = text[i]; char c = text[i];
bool isColCode = c == '&' && i < text.Length - 1; if (c == '&' && ValidColCode(text, i + 1)) {
if (isColCode && ValidColour(text[i + 1])) { col = Cols[text[i + 1]];
col = Colours[text[i + 1]];
if (shadowCol) if (shadowCol)
col = BlackTextShadows ? FastColour.Black : FastColour.Scale(col, 0.25f); col = BlackTextShadows ? FastColour.Black : FastColour.Scale(col, 0.25f);
i++; continue; // Skip over the colour code. i++; continue; // Skip over the colour code.
@ -178,9 +177,8 @@ namespace ClassicalSharp {
for (int i = 0; i < text.Length; i++) { for (int i = 0; i < text.Length; i++) {
char c = text[i]; char c = text[i];
bool isColCode = c == '&' && i < text.Length - 1; if (c == '&' && ValidColCode(text, i + 1)) {
if (isColCode && ValidColour(text[i + 1])) { col = Cols[text[i + 1]].ToArgb();
col = Colours[text[i + 1]].ToArgb();
i++; continue; // Skip over the colour code. i++; continue; // Skip over the colour code.
} }
if (shadowCol) col = FastColour.Black.ToArgb(); if (shadowCol) col = FastColour.Black.ToArgb();
@ -198,15 +196,14 @@ namespace ClassicalSharp {
#endif #endif
protected Size MeasureBitmappedSize(ref DrawTextArgs args) { 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)); int textHeight = AdjTextSize(Utils.Floor(args.Font.Size));
Size total = new Size(0, CellSize(textHeight)); Size total = new Size(0, CellSize(textHeight));
int point = Utils.Floor(args.Font.Size); int point = Utils.Floor(args.Font.Size);
for (int i = 0; i < args.Text.Length; i++) { for (int i = 0; i < args.Text.Length; i++) {
char c = args.Text[i]; char c = args.Text[i];
bool isColCode = c == '&' && i < args.Text.Length - 1; if (c == '&' && ValidColCode(args.Text, i + 1)) {
if (isColCode && ValidColour(args.Text[i + 1])) {
i++; continue; // Skip over the colour code. i++; continue; // Skip over the colour code.
} }

View File

@ -133,19 +133,19 @@ namespace ClassicalSharp {
return Platform.CreateBmp(Utils.NextPowerOf2(size.Width), Utils.NextPowerOf2(size.Height)); 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 IDrawer2D() { InitColours(); }
public void InitColours() { public void InitColours() {
for (int i = 0; i < Colours.Length; i++) for (int i = 0; i < Cols.Length; i++)
Colours[i] = default(FastColour); Cols[i] = default(FastColour);
for (int i = 0; i <= 9; i++) 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++) { for (int i = 10; i <= 15; i++) {
Colours['a' + i - 10] = FastColour.GetHexEncodedCol(i, 191, 64); Cols['a' + i - 10] = FastColour.GetHexEncodedCol(i, 191, 64);
Colours['A' + i - 10] = Colours['a' + i - 10]; Cols['A' + i - 10] = Cols['a' + i - 10];
} }
} }
@ -162,9 +162,9 @@ namespace ClassicalSharp {
protected void GetTextParts(string value) { protected void GetTextParts(string value) {
parts.Clear(); parts.Clear();
if (String.IsNullOrEmpty(value)) { if (EmptyText(value)) {
} else if (value.IndexOf('&') == -1) { } else if (value.IndexOf('&') == -1) {
parts.Add(new TextPart(value, Colours['f'])); parts.Add(new TextPart(value, Cols['f']));
} else { } else {
SplitText(value); SplitText(value);
} }
@ -179,12 +179,12 @@ namespace ClassicalSharp {
if (partLength > 0) { if (partLength > 0) {
string part = value.Substring(i, partLength); string part = value.Substring(i, partLength);
parts.Add(new TextPart(part, Colours[code])); parts.Add(new TextPart(part, Cols[code]));
} }
i += partLength + 1; i += partLength + 1;
if (nextCol >= 0 && nextCol + 1 < value.Length) { if (nextCol >= 0) {
if (!ValidColour(value[nextCol + 1])) { if (!ValidColCode(value, nextCol + 1)) {
i--; // include character that isn't a valid colour. i--; // include character that isn't a valid colour.
} else { } else {
code = value[nextCol + 1]; code = value[nextCol + 1];
@ -194,29 +194,45 @@ namespace ClassicalSharp {
} }
/// <summary> Returns whenever the given character is a valid colour code. </summary> /// <summary> Returns whenever the given character is a valid colour code. </summary>
public bool ValidColour(char c) { public static bool ValidColCode(string text, int i) {
return (int)c < 256 && Colours[c].A > 0; if (i >= text.Length) return false;
char c = text[i];
return c < '\xFF' && Cols[c].A > 0;
}
/// <summary> Returns whenever the given character is a valid colour code. </summary>
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 #if !LAUNCHER
/// <summary> Returns the last valid colour code in the given input, /// <summary> Returns the last valid colour code in the given input,
/// or \0 if no valid colour code was found. </summary> /// or \0 if no valid colour code was found. </summary>
public char LastColour(string input, int start) { public static char LastCol(string text, int start) {
if (start >= input.Length) if (start >= text.Length)
start = input.Length - 1; start = text.Length - 1;
for (int i = start; i >= 0; i--) { for (int i = start; i >= 0; i--) {
if (input[i] != '&') continue; if (text[i] != '&') continue;
if (i < input.Length - 1 && ValidColour(input[i + 1])) if (ValidColCode(text, i + 1)) return text[i + 1];
return input[i + 1];
} }
return '\0'; return '\0';
} }
public static bool IsWhiteColour(char c) { public static bool IsWhiteCol(char c) {
return c == '\0' || c == 'f' || c == 'F'; return c == '\0' || c == 'f' || c == 'F';
} }
public void ReducePadding(ref Texture tex, int point) { public void ReducePadding(ref Texture tex, int point) {
ReducePadding(ref tex, point, 4); ReducePadding(ref tex, point, 4);

View File

@ -57,7 +57,7 @@ namespace ClassicalSharp.Gui.Widgets {
public void SetText(string text) { public void SetText(string text) {
gfx.DeleteTexture(ref texture); gfx.DeleteTexture(ref texture);
Text = text; Text = text;
if (String.IsNullOrEmpty(text)) { if (IDrawer2D.EmptyText(text)) {
texture = default(Texture); texture = default(Texture);
Width = 0; Height = defaultHeight; Width = 0; Height = defaultHeight;
} else { } else {

View File

@ -21,14 +21,14 @@ namespace ClassicalSharp.Gui.Widgets {
int count = 0; int count = 0;
for (int i = ' '; i <= '~'; i++) { for (int i = ' '; i <= '~'; i++) {
if (i >= 'A' && i <= 'F') continue; 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); StringBuffer buffer = new StringBuffer(count * 4);
int index = 0; int index = 0;
for (int i = ' '; i <= '~'; i++) { for (int i = ' '; i <= '~'; i++) {
if (i >= 'A' && i <= 'F') continue; 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) buffer.Append(ref index, '&').Append(ref index, (char)i)
.Append(ref index, '%').Append(ref index, (char)i); .Append(ref index, '%').Append(ref index, (char)i);

View File

@ -118,7 +118,7 @@ namespace ClassicalSharp.Gui.Widgets {
char lastCol = i == 0 ? 'f' : GetLastColour(0, i); // no previous colour on first line 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 // 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; text = "&" + lastCol + text;
game.Chat.Send(text, partial); game.Chat.Send(text, partial);
} }

View File

@ -14,7 +14,7 @@ namespace ClassicalSharp.Gui.Widgets {
linkData[index] = default(LinkData); linkData[index] = default(LinkData);
LinkFlags prevFlags = index > 0 ? linkData[index - 1].flags : 0; 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) : Texture tex = NextToken(text, 0, ref prevFlags) == -1 ? DrawSimple(ref args) :
DrawAdvanced(ref args, index, text); DrawAdvanced(ref args, index, text);
game.Drawer2D.ReducePadding(ref tex, Utils.Floor(args.Font.Size), 3); 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<word><url> // We may split up a line into say %e<word><url>
// url and word both need to have %e at the start. // url and word both need to have %e at the start.
if (lastCol >= 0 && lastCol < line.Length - 1) { if (lastCol >= 0 && IDrawer2D.ValidColCode(line,lastCol + 1)) {
if (game.Drawer2D.ValidColour(line[lastCol + 1])) part = "&" + line[lastCol + 1] + part;
part = "&" + line[lastCol + 1] + part;
} }
return part; return part;
} }

View File

@ -93,6 +93,7 @@ namespace ClassicalSharp.Gui.Widgets {
public int GetUsedHeight() { public int GetUsedHeight() {
int height = 0, i = 0; int height = 0, i = 0;
for (i = 0; i < Textures.Length; i++) { for (i = 0; i < Textures.Length; i++) {
if (Textures[i].IsValid) break; if (Textures[i].IsValid) break;
} }

View File

@ -145,7 +145,7 @@ namespace ClassicalSharp.Gui.Widgets {
// Update the colour of the caret // Update the colour of the caret
char code = GetLastColour(caretCol, caretRow); char code = GetLastColour(caretCol, caretRow);
if (code != '\0') caretColour = drawer.Colours[code]; if (code != '\0') caretColour = IDrawer2D.Cols[code];
} }
protected void RenderCaret(double delta) { protected void RenderCaret(double delta) {
@ -182,7 +182,7 @@ namespace ClassicalSharp.Gui.Widgets {
if (lines[i] == null) break; if (lines[i] == null) break;
args.Text = lines[i]; args.Text = lines[i];
char lastCol = GetLastColour(0, i); char lastCol = GetLastColour(0, i);
if (!IDrawer2D.IsWhiteColour(lastCol)) if (!IDrawer2D.IsWhiteCol(lastCol))
args.Text = "&" + lastCol + args.Text; args.Text = "&" + lastCol + args.Text;
int offset = i == 0 ? prefixWidth : 0; int offset = i == 0 ? prefixWidth : 0;
@ -203,7 +203,7 @@ namespace ClassicalSharp.Gui.Widgets {
IDrawer2D drawer = game.Drawer2D; IDrawer2D drawer = game.Drawer2D;
for (int y = indexY; y >= 0; y--) { for (int y = indexY; y >= 0; y--) {
string part = lines[y]; string part = lines[y];
char code = drawer.LastColour(part, x); char code = IDrawer2D.LastCol(part, x);
if (code != '\0') return code; if (code != '\0') return code;
if (y > 0) x = lines[y - 1].Length; if (y > 0) x = lines[y - 1].Length;
} }
@ -354,7 +354,7 @@ namespace ClassicalSharp.Gui.Widgets {
bool CheckColour(int index) { bool CheckColour(int index) {
if (index < 0) return false; if (index < 0) return false;
char code = Text.value[index], col = Text.value[index + 1]; 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() { void DeleteKey() {

View File

@ -46,7 +46,7 @@ namespace ClassicalSharp.Gui.Widgets {
public void SetText(string text) { public void SetText(string text) {
gfx.DeleteTexture(ref texture); gfx.DeleteTexture(ref texture);
if (String.IsNullOrEmpty(text)) { if (IDrawer2D.EmptyText(text)) {
texture = new Texture(); texture = new Texture();
Width = 0; Height = defaultHeight; Width = 0; Height = defaultHeight;
} else { } else {

View File

@ -62,9 +62,9 @@ namespace ClassicalSharp.Entities {
{ {
drawer.SetBitmap(bmp); drawer.SetBitmap(bmp);
args.Text = "&\xFF" + Utils.StripColours(args.Text); 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.DrawText(ref args, 3, 3);
game.Drawer2D.Colours['\xFF'] = default(FastColour); IDrawer2D.Cols['\xFF'] = default(FastColour);
args.Text = DisplayName; args.Text = DisplayName;
game.Drawer2D.DrawText(ref args, 0, 0); game.Drawer2D.DrawText(ref args, 0, 0);

View File

@ -313,7 +313,7 @@ namespace ClassicalSharp.Network.Protocols {
if (code <= ' ' || code > '~') return; // Control chars, space, extended chars cannot be used if (code <= ' ' || code > '~') return; // Control chars, space, extended chars cannot be used
if (code == '%' || code == '&') return; // colour code signifiers 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); game.Events.RaiseColourCodeChanged((char)code);
} }

View File

@ -51,10 +51,10 @@ namespace ClassicalSharp.Singleplayer {
void AddChat(string text) { void AddChat(string text) {
text = text.TrimEnd().Replace('%', '&'); text = text.TrimEnd().Replace('%', '&');
if (!IDrawer2D.IsWhiteColour(lastCol)) if (!IDrawer2D.IsWhiteCol(lastCol))
text = "&" + lastCol + text; text = "&" + lastCol + text;
char col = game.Drawer2D.LastColour(text, text.Length); char col = IDrawer2D.LastCol(text, text.Length);
if (col != '\0') lastCol = col; if (col != '\0') lastCol = col;
game.Chat.Add(text, MessageType.Normal); game.Chat.Add(text, MessageType.Normal);
} }

View File

@ -65,7 +65,7 @@ namespace ClassicalSharp {
} }
// convert %0-f to &0-f for colour preview. // convert %0-f to &0-f for colour preview.
for (int i = 0; i < totalChars - 1; i++) { 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] = '&'; value[i] = '&';
} }

View File

@ -94,7 +94,7 @@ namespace Launcher {
platformDrawer = new OSXPlatformDrawer(); platformDrawer = new OSXPlatformDrawer();
} }
Drawer.Colours['g'] = new FastColour(125, 125, 125); IDrawer2D.Cols['g'] = new FastColour(125, 125, 125);
} }
void LoadFont() { void LoadFont() {