File size: 4,790 Bytes
d46f4a3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package net.minecraft.client.gui.font;

import com.mojang.blaze3d.font.SheetGlyphInfo;
import com.mojang.blaze3d.platform.NativeImage;
import com.mojang.blaze3d.platform.TextureUtil;
import java.nio.file.Path;
import javax.annotation.Nullable;
import net.minecraft.client.gui.font.glyphs.BakedGlyph;
import net.minecraft.client.renderer.texture.AbstractTexture;
import net.minecraft.client.renderer.texture.Dumpable;
import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;

@OnlyIn(Dist.CLIENT)
public class FontTexture extends AbstractTexture implements Dumpable {
    private static final int SIZE = 256;
    private final GlyphRenderTypes renderTypes;
    private final boolean colored;
    private final FontTexture.Node root;

    public FontTexture(GlyphRenderTypes p_285000_, boolean p_285085_) {
        this.colored = p_285085_;
        this.root = new FontTexture.Node(0, 0, 256, 256);
        TextureUtil.prepareImage(p_285085_ ? NativeImage.InternalGlFormat.RGBA : NativeImage.InternalGlFormat.RED, this.getId(), 256, 256);
        this.setFilter(false, false);
        this.renderTypes = p_285000_;
    }

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

    @Nullable
    public BakedGlyph add(SheetGlyphInfo p_232569_) {
        if (p_232569_.isColored() != this.colored) {
            return null;
        } else {
            FontTexture.Node fonttexture$node = this.root.insert(p_232569_);
            if (fonttexture$node != null) {
                this.bind();
                p_232569_.upload(fonttexture$node.x, fonttexture$node.y);
                float f = 256.0F;
                float f1 = 256.0F;
                float f2 = 0.01F;
                return new BakedGlyph(
                    this.renderTypes,
                    ((float)fonttexture$node.x + 0.01F) / 256.0F,
                    ((float)fonttexture$node.x - 0.01F + (float)p_232569_.getPixelWidth()) / 256.0F,
                    ((float)fonttexture$node.y + 0.01F) / 256.0F,
                    ((float)fonttexture$node.y - 0.01F + (float)p_232569_.getPixelHeight()) / 256.0F,
                    p_232569_.getLeft(),
                    p_232569_.getRight(),
                    p_232569_.getTop(),
                    p_232569_.getBottom()
                );
            } else {
                return null;
            }
        }
    }

    @Override
    public void dumpContents(ResourceLocation p_285121_, Path p_285511_) {
        String s = p_285121_.toDebugFileName();
        TextureUtil.writeAsPNG(p_285511_, s, this.getId(), 0, 256, 256, p_285145_ -> (p_285145_ & 0xFF000000) == 0 ? -16777216 : p_285145_);
    }

    @OnlyIn(Dist.CLIENT)
    static class Node {
        final int x;
        final int y;
        private final int width;
        private final int height;
        @Nullable
        private FontTexture.Node left;
        @Nullable
        private FontTexture.Node right;
        private boolean occupied;

        Node(int p_95113_, int p_95114_, int p_95115_, int p_95116_) {
            this.x = p_95113_;
            this.y = p_95114_;
            this.width = p_95115_;
            this.height = p_95116_;
        }

        @Nullable
        FontTexture.Node insert(SheetGlyphInfo p_232571_) {
            if (this.left != null && this.right != null) {
                FontTexture.Node fonttexture$node = this.left.insert(p_232571_);
                if (fonttexture$node == null) {
                    fonttexture$node = this.right.insert(p_232571_);
                }

                return fonttexture$node;
            } else if (this.occupied) {
                return null;
            } else {
                int i = p_232571_.getPixelWidth();
                int j = p_232571_.getPixelHeight();
                if (i > this.width || j > this.height) {
                    return null;
                } else if (i == this.width && j == this.height) {
                    this.occupied = true;
                    return this;
                } else {
                    int k = this.width - i;
                    int l = this.height - j;
                    if (k > l) {
                        this.left = new FontTexture.Node(this.x, this.y, i, this.height);
                        this.right = new FontTexture.Node(this.x + i + 1, this.y, this.width - i - 1, this.height);
                    } else {
                        this.left = new FontTexture.Node(this.x, this.y, this.width, j);
                        this.right = new FontTexture.Node(this.x, this.y + j + 1, this.width, this.height - j - 1);
                    }

                    return this.left.insert(p_232571_);
                }
            }
        }
    }
}