The bug
All text fields can cut off the last few characters and display them incorrectly, see for example
[media].
How to reproduce
Paste (or write) the following text in chat or in a command block
iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii_
Look at the end of the text field
→ ❌ The last characters are cut off and are displayed incorrectly
Code analysis
The following is based on decompiled version of Minecraft 1.9 using MCP 9.24 beta. All method and class names are the names used in the decompiled version.
The reason why this happens is very likely that the method net.minecraft.client.gui.GuiTextField.setSelectionPos(int)
calls the method net.minecraft.client.gui.FontRenderer.trimStringToWidth(String, int)
without reversing the text of the text field. This is a problem because the text of the textfield should not be trimmed at the end, but instead at the beginning. To prevent the underscore from overflowing over the text field, the width could be reduced by the width of the underscore.
/**
* Sets the position of the selection anchor (i.e. position the selection was started at)
*/
public void setSelectionPos(int p_146199_1_)
{
int i = this.text.length();
if (p_146199_1_ > i)
{
p_146199_1_ = i;
}
if (p_146199_1_ < 0)
{
p_146199_1_ = 0;
}
this.selectionEnd = p_146199_1_;
if (this.fontRendererInstance != null)
{
if (this.lineScrollOffset > i)
{
this.lineScrollOffset = i;
}
// Replaced this
//int j = this.getWidth();
//String s = this.fontRendererInstance.trimStringToWidth(this.text.substring(this.lineScrollOffset), j);
int j = this.getWidth() - this.fontRendererInstance.getCharWidth('_');
String s = this.fontRendererInstance.trimStringToWidth(this.text.substring(this.lineScrollOffset), j, true);
int k = s.length() + this.lineScrollOffset;
if (p_146199_1_ == this.lineScrollOffset)
{
this.lineScrollOffset -= this.fontRendererInstance.trimStringToWidth(this.text, j, true).length();
}
if (p_146199_1_ > k)
{
this.lineScrollOffset += p_146199_1_ - k;
}
else if (p_146199_1_ <= this.lineScrollOffset)
{
this.lineScrollOffset -= this.lineScrollOffset - p_146199_1_;
}
this.lineScrollOffset = MathHelper.clamp_int(this.lineScrollOffset, 0, i);
}
}
Linked issues
is duplicated by 4
relates to 2
Attachments
Comments 20
Related to (if not duplicate) of MC-1237
Please link to this comment in the description
The following is based on decompiled version of Minecraft 1.9 using MCP 9.24 beta. All method and class names are the names used in the decompiled version.
The reason why this happens is very likely that the method net.minecraft.client.gui.GuiTextField.setSelectionPos(int)
calls the method net.minecraft.client.gui.FontRenderer.trimStringToWidth(String, int)
without reversing the text of the text field. This is a problem because the text of the textfield should not be trimmed at the end, but instead at the beginning. To prevent the underscore from overflowing over the text field, the width could be reduced by the width of the underscore.
/**
* Sets the position of the selection anchor (i.e. position the selection was started at)
*/
public void setSelectionPos(int p_146199_1_)
{
int i = this.text.length();
if (p_146199_1_ > i)
{
p_146199_1_ = i;
}
if (p_146199_1_ < 0)
{
p_146199_1_ = 0;
}
this.selectionEnd = p_146199_1_;
if (this.fontRendererInstance != null)
{
if (this.lineScrollOffset > i)
{
this.lineScrollOffset = i;
}
// Replaced this
//int j = this.getWidth();
//String s = this.fontRendererInstance.trimStringToWidth(this.text.substring(this.lineScrollOffset), j);
int j = this.getWidth() - this.fontRendererInstance.getCharWidth('_');
String s = this.fontRendererInstance.trimStringToWidth(this.text.substring(this.lineScrollOffset), j, true);
int k = s.length() + this.lineScrollOffset;
if (p_146199_1_ == this.lineScrollOffset)
{
this.lineScrollOffset -= this.fontRendererInstance.trimStringToWidth(this.text, j, true).length();
}
if (p_146199_1_ > k)
{
this.lineScrollOffset += p_146199_1_ - k;
}
else if (p_146199_1_ <= this.lineScrollOffset)
{
this.lineScrollOffset -= this.lineScrollOffset - p_146199_1_;
}
this.lineScrollOffset = MathHelper.clamp_int(this.lineScrollOffset, 0, i);
}
}
Confirmed, although the characters exist. You just need to go right two characters.