mojira.dev

+merlan #flirora

Assigned

No issues.

Reported

MC-300856 I-beam cursor in book signing screen has wrong color Fixed MC-267578 Messages in chat HUD do not rewrap on font reload Duplicate MC-265929 Ctrl+Backspacing a word with non-BMP characters in an edit box deletes additional characters Fixed MC-265927 Edit box length restrictions can result in unpaired surrogate characters Fixed MC-262185 Partially transparent pixels in font glyphs appear more opaque than they should in the tooltip Fixed MC-84025 root.gameRenderer.level.entities.entityOutlines performance Incomplete MC-16430 Section sign appears incorrectly in language packs Won't Fix MC-15837 World unopenable Duplicate MC-15833 Player data on world erased Duplicate MC-15348 SSP uses English command guides instead of those of the language pack Fixed MC-15102 Connecting to servers gives End of Stream message if using certain language packs. Invalid MCL-196 Version list does not show Fixed MC-10426 Custom fonts do not display properly Won't Fix MC-10022 Mobs sometimes appear black Duplicate MC-9971 Can join 13w06a servers Works As Intended MC-9514 Lighting ignores ceiling Duplicate MC-9053 Unexpected Crash Duplicate MC-8067 Sharpness-enchanted swords degrade more quickly Cannot Reproduce MC-7163 Death messages not translated Duplicate

Comments

I also experience this issue.

GPU info:

	Graphics card #0 name: Lucienne
	Graphics card #0 vendor: Advanced Micro Devices, Inc. [AMD/ATI] (0x1002)
	Graphics card #0 VRAM (MiB): 258.00
	Graphics card #0 deviceId: 0x164c
	Graphics card #0 versionInfo: unknown

However, if I use a glow ink sac (but no dye), only the glow is visible:

[media: 2025-05-02_02.19.05.png]

Code analysis

The fragment shader for the text_intensity render type uses the rendertype_text_intensity shader program, whose fragment shader looks like this:

#version 150

#moj_import <fog.glsl>

uniform sampler2D Sampler0;

uniform vec4 ColorModulator;
uniform float FogStart;
uniform float FogEnd;
uniform vec4 FogColor;

in float vertexDistance;
in vec4 vertexColor;
in vec2 texCoord0;

out vec4 fragColor;

void main() {
    vec4 color = texture(Sampler0, texCoord0).rrrr * vertexColor * ColorModulator;
    if (color.a < 0.1) {
        discard;
    }
    fragColor = linear_fog(color, vertexDistance, FogStart, FogEnd, FogColor);
}

The intensity channel of the texture controls not only the alpha channel of the fragment but also its red, green, and blue channels. The render program JSON, on the other hand, assumes that the color output of the fragment shader uses non-premultiplied alpha.

This issue can be fixed by making the texture intensity affect only the alpha channel of the fragment:

vec4 color = vec4(vec3(1.0), texture(Sampler0, texCoord0).r) * vertexColor;

Alternatively, the blend parameters in the shader program JSON could be modified to assume alpha premultiplication:

"blend": {
        "func": "add",
        "srcrgb": "1",
        "dstrgb": "1-srcalpha"
    },

> Minecraft versions before 1.15 were fine.

That’s not true – I’ve attached a screenshot from 1.10.2 that also shows this issue.

Code analysis (23w18a)

Yarn names are used here: 23w18a+build.1 for 23w18a. The decompiled code shown below has been generated using Fabric’s fork of CFR.

Minecraft’s text rendering is basic and fails to handle complex scripts properly. In TextRenderer (with constants manually unfolded):

public String mirror(String text) {
        try {
            Bidi bidi = new Bidi(new ArabicShaping(ArabicShaping.LETTERS_SHAPE).shape(text), Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
            bidi.setReorderingMode(Bidi.REORDER_DEFAULT);
            return bidi.writeReordered(Bidi.DO_MIRRORING);
        } catch (ArabicShapingException arabicShapingException) {
            return text;
        }
    }
    
    // ...
    
    private int drawInternal(String text, float x, float y, int color, boolean shadow, Matrix4f matrix, VertexConsumerProvider vertexConsumers, TextLayerType layerType, int backgroundColor, int light, boolean mirror) {
        if (mirror) {
            text = this.mirror(text);
        }
        color = TextRenderer.tweakTransparency(color);
        Matrix4f matrix4f = new Matrix4f(matrix);
        if (shadow) {
            this.drawLayer(text, x, y, color, true, matrix, vertexConsumers, layerType, backgroundColor, light);
            matrix4f.translate(FORWARD_SHIFT);
        }
        x = this.drawLayer(text, x, y, color, false, matrix4f, vertexConsumers, layerType, backgroundColor, light);
        return (int)x + (shadow ? 1 : 0);
    }

TextRenderer#mirror uses ICU4J’s ArabicShaping to replace Arabic-script codepoints with their equivalent presentation forms. It then reorders the characters in the string to visual order. The resulting string is displayed from left to right, rendering each character individually.

Unfortunately, ArabicShaping does not reshape letters specific to languages other than Arabic, and there are many other scripts that cannot be shaped in this manner. Properly fixing this issue would require using a full-featured text shaping library and using a font format that supports shaping features.

I’ve attached a sample resource pack. You should be able to reproduce this bug by reloading resources several times with this pack loaded.

Code analysis (23w18a)

Yarn names are used here: 23w18+build.1 for 23w18a. The decompiled code shown below has been generated using Fabric’s fork of CFR.

FontManager#reload has this chunk of code, closing each loaded font storage, then closing each font:

this.fontStorages.values().forEach(FontStorage::close);
        this.fontStorages.clear();
        this.fonts.forEach(Font::close);
        this.fonts.clear();

Looking at {{FontStorage}}’s code, we find the following:

@Override
    public void close() {
        this.closeFonts();
        this.closeGlyphAtlases();
    }

    private void closeFonts() {
        for (Font font : this.fonts) {
            font.close();
        }
        this.fonts.clear();
    }

    private void closeGlyphAtlases() {
        for (GlyphAtlasTexture glyphAtlasTexture : this.glyphAtlases) {
            glyphAtlasTexture.close();
        }
        this.glyphAtlases.clear();
    }

The problem is that the font storage objects in FontManager#fontStorages refer to the same fonts as the ones in FontManager#fonts. This causes some fonts to be closed more than once. BitmapFont}}’s implementation of {{Font#close protects against multiple calls, but TrueTypeFont}}’s implementation does not – calling {{close more than once on a TrueTypeFont causes a double free, resulting in a JVM crash.

Likewise, FontManager#close also causes the same type of double free.

A possible solution would be to have FontStorage not be responsible for closing its fonts. Alternatively, each subclass of Font could protect against multiple closes, but this is a hacky solution in my opinion.

I can confirm that this issue has been fixed in 23w18a, as it has the same underlying cause as MC-262003.

Are you getting FPS drops too?

Also, Minecraft gets a similar display issue when I switch resource packs or the game crashes. The workaround has something to do with killing the right javaw.exe processes, but it's too random to perform reliably.

It would be better to make book editing on one contiguous page, so inserting or deleting something on one page doesn't take effort on the following pages.

Could you please post your computer specs?

At first, I didn't know where all the worlds went!

Confirmed for 13w21a for the dev language pack, but not the publication one. If I've done my C right, then the publication pack should be identical to the dev pack, except that the default translations are removed.

Doibg so would assume that the resolution for each character would be at most 256 pixels.

The console freezes, so here's a screenshot.

The game returns me to the title screen, without loading the world. And it didn't crash at all.

By the way, did some data in player.dat get erased?