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) {
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;

View File

@ -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.
}

View File

@ -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 {
}
/// <summary> Returns whenever the given character is a valid colour code. </summary>
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;
}
/// <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
/// <summary> Returns the last valid colour code in the given input,
/// or \0 if no valid colour code was found. </summary>
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);

View File

@ -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 {

View File

@ -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);

View File

@ -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);
}

View File

@ -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<word><url>
// 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;
}

View File

@ -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;
}

View File

@ -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() {

View File

@ -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 {

View File

@ -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);

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; // colour code signifiers cannot be used
game.Drawer2D.Colours[code] = col;
IDrawer2D.Cols[code] = col;
game.Events.RaiseColourCodeChanged((char)code);
}

View File

@ -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);
}

View File

@ -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] = '&';
}

View File

@ -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() {