Mojira Archive
MC-30217

All text fields can cut off the last few characters / Phantom selection highlighting appears at the end of text fields with some texts

The bug

All text fields can cut off the last few characters and display them incorrectly, see for example command_block.png.

How to reproduce

  1. Paste (or write) the following text in chat or in a command block
    iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii_
    
  2. 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);
    }
}