Font.java
net.minecraft.client.gui.Font
信息
- 全限定名:net.minecraft.client.gui.Font
- 类型:public class
- 包:net.minecraft.client.gui
- 源码路径:src/main/java/net/minecraft/client/gui/Font.java
- 起始行号:L36
- 职责:
TODO
字段/常量
-
EFFECT_DEPTH- 类型:
float - 修饰符:
private static final - 源码定位:
L37 - 说明:
TODO
- 类型:
-
OVER_EFFECT_DEPTH- 类型:
float - 修饰符:
private static final - 源码定位:
L38 - 说明:
TODO
- 类型:
-
UNDER_EFFECT_DEPTH- 类型:
float - 修饰符:
private static final - 源码定位:
L39 - 说明:
TODO
- 类型:
-
SHADOW_DEPTH- 类型:
float - 修饰符:
public static final - 源码定位:
L40 - 说明:
TODO
- 类型:
-
lineHeight- 类型:
int - 修饰符:
public final - 源码定位:
L41 - 说明:
TODO
- 类型:
-
random- 类型:
RandomSource - 修饰符:
private final - 源码定位:
L42 - 说明:
TODO
- 类型:
-
provider- 类型:
Font.Provider - 修饰符:
private final - 源码定位:
L43 - 说明:
TODO
- 类型:
-
splitter- 类型:
StringSplitter - 修饰符:
private final - 源码定位:
L44 - 说明:
TODO
- 类型:
内部类/嵌套类型
-
net.minecraft.client.gui.Font.DisplayMode- 类型:
enum - 修饰符:
public static - 源码定位:
L221 - 说明:
TODO
- 类型:
-
net.minecraft.client.gui.Font.GlyphVisitor- 类型:
interface - 修饰符:
public - 源码定位:
L228 - 说明:
TODO
- 类型:
-
net.minecraft.client.gui.Font.PreparedText- 类型:
interface - 修饰符:
public - 源码定位:
L259 - 说明:
TODO
- 类型:
-
net.minecraft.client.gui.Font.PreparedTextBuilder- 类型:
class - 修饰符:
private - 源码定位:
L266 - 说明:
TODO
- 类型:
-
net.minecraft.client.gui.Font.Provider- 类型:
interface - 修饰符:
public - 源码定位:
L458 - 说明:
TODO
- 类型:
构造器
public Font(Font.Provider provider) @ L46
- 构造器名:Font
- 源码定位:L46
- 修饰符:public
参数:
- provider: Font.Provider
说明:
TODO
方法
下面的方法块按源码顺序生成。
private GlyphSource getGlyphSource(FontDescription fontLocation) @ L51
- 方法名:getGlyphSource
- 源码定位:L51
- 返回类型:GlyphSource
- 修饰符:private
参数:
- fontLocation: FontDescription
说明:
TODO
public String bidirectionalShaping(String text) @ L55
- 方法名:bidirectionalShaping
- 源码定位:L55
- 返回类型:String
- 修饰符:public
参数:
- text: String
说明:
TODO
public void drawInBatch(String str, float x, float y, int color, boolean dropShadow, Matrix4fc pose, MultiBufferSource bufferSource, Font.DisplayMode displayMode, int backgroundColor, int packedLightCoords) @ L65
- 方法名:drawInBatch
- 源码定位:L65
- 返回类型:void
- 修饰符:public
参数:
- str: String
- x: float
- y: float
- color: int
- dropShadow: boolean
- pose: Matrix4fc
- bufferSource: MultiBufferSource
- displayMode: Font.DisplayMode
- backgroundColor: int
- packedLightCoords: int
说明:
TODO
public void drawInBatch(Component str, float x, float y, int color, boolean dropShadow, Matrix4fc pose, MultiBufferSource bufferSource, Font.DisplayMode displayMode, int backgroundColor, int packedLightCoords) @ L81
- 方法名:drawInBatch
- 源码定位:L81
- 返回类型:void
- 修饰符:public
参数:
- str: Component
- x: float
- y: float
- color: int
- dropShadow: boolean
- pose: Matrix4fc
- bufferSource: MultiBufferSource
- displayMode: Font.DisplayMode
- backgroundColor: int
- packedLightCoords: int
说明:
TODO
public void drawInBatch(FormattedCharSequence str, float x, float y, int color, boolean dropShadow, Matrix4fc pose, MultiBufferSource bufferSource, Font.DisplayMode displayMode, int backgroundColor, int packedLightCoords) @ L97
- 方法名:drawInBatch
- 源码定位:L97
- 返回类型:void
- 修饰符:public
参数:
- str: FormattedCharSequence
- x: float
- y: float
- color: int
- dropShadow: boolean
- pose: Matrix4fc
- bufferSource: MultiBufferSource
- displayMode: Font.DisplayMode
- backgroundColor: int
- packedLightCoords: int
说明:
TODO
public void drawInBatch8xOutline(FormattedCharSequence str, float x, float y, int color, int outlineColor, Matrix4fc pose, MultiBufferSource bufferSource, int packedLightCoords) @ L113
- 方法名:drawInBatch8xOutline
- 源码定位:L113
- 返回类型:void
- 修饰符:public
参数:
- str: FormattedCharSequence
- x: float
- y: float
- color: int
- outlineColor: int
- pose: Matrix4fc
- bufferSource: MultiBufferSource
- packedLightCoords: int
说明:
TODO
private BakedGlyph getGlyph(int codepoint, Style style) @ L147
- 方法名:getGlyph
- 源码定位:L147
- 返回类型:BakedGlyph
- 修饰符:private
参数:
- codepoint: int
- style: Style
说明:
TODO
public Font.PreparedText prepareText(String text, float x, float y, int originalColor, boolean drawShadow, int backgroundColor) @ L158
- 方法名:prepareText
- 源码定位:L158
- 返回类型:Font.PreparedText
- 修饰符:public
参数:
- text: String
- x: float
- y: float
- originalColor: int
- drawShadow: boolean
- backgroundColor: int
说明:
TODO
public Font.PreparedText prepareText(FormattedCharSequence text, float x, float y, int originalColor, boolean drawShadow, boolean includeEmpty, int backgroundColor) @ L168
- 方法名:prepareText
- 源码定位:L168
- 返回类型:Font.PreparedText
- 修饰符:public
参数:
- text: FormattedCharSequence
- x: float
- y: float
- originalColor: int
- drawShadow: boolean
- includeEmpty: boolean
- backgroundColor: int
说明:
TODO
public int width(String str) @ L176
- 方法名:width
- 源码定位:L176
- 返回类型:int
- 修饰符:public
参数:
- str: String
说明:
TODO
public int width(FormattedText text) @ L180
- 方法名:width
- 源码定位:L180
- 返回类型:int
- 修饰符:public
参数:
- text: FormattedText
说明:
TODO
public int width(FormattedCharSequence text) @ L184
- 方法名:width
- 源码定位:L184
- 返回类型:int
- 修饰符:public
参数:
- text: FormattedCharSequence
说明:
TODO
public String plainSubstrByWidth(String str, int width, boolean reverse) @ L188
- 方法名:plainSubstrByWidth
- 源码定位:L188
- 返回类型:String
- 修饰符:public
参数:
- str: String
- width: int
- reverse: boolean
说明:
TODO
public String plainSubstrByWidth(String str, int width) @ L192
- 方法名:plainSubstrByWidth
- 源码定位:L192
- 返回类型:String
- 修饰符:public
参数:
- str: String
- width: int
说明:
TODO
public FormattedText substrByWidth(FormattedText text, int width) @ L196
- 方法名:substrByWidth
- 源码定位:L196
- 返回类型:FormattedText
- 修饰符:public
参数:
- text: FormattedText
- width: int
说明:
TODO
public int wordWrapHeight(FormattedText input, int textWidth) @ L200
- 方法名:wordWrapHeight
- 源码定位:L200
- 返回类型:int
- 修饰符:public
参数:
- input: FormattedText
- textWidth: int
说明:
TODO
public List<FormattedCharSequence> split(FormattedText input, int maxWidth) @ L204
- 方法名:split
- 源码定位:L204
- 返回类型:List
- 修饰符:public
参数:
- input: FormattedText
- maxWidth: int
说明:
TODO
public List<FormattedText> splitIgnoringLanguage(FormattedText input, int maxWidth) @ L208
- 方法名:splitIgnoringLanguage
- 源码定位:L208
- 返回类型:List
- 修饰符:public
参数:
- input: FormattedText
- maxWidth: int
说明:
TODO
public boolean isBidirectional() @ L212
- 方法名:isBidirectional
- 源码定位:L212
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public StringSplitter getSplitter() @ L216
- 方法名:getSplitter
- 源码定位:L216
- 返回类型:StringSplitter
- 修饰符:public
参数:
- 无
说明:
TODO
代码
@OnlyIn(Dist.CLIENT)
public class Font {
private static final float EFFECT_DEPTH = 0.01F;
private static final float OVER_EFFECT_DEPTH = 0.01F;
private static final float UNDER_EFFECT_DEPTH = -0.01F;
public static final float SHADOW_DEPTH = 0.03F;
public final int lineHeight = 9;
private final RandomSource random = RandomSource.create();
private final Font.Provider provider;
private final StringSplitter splitter;
public Font(Font.Provider provider) {
this.provider = provider;
this.splitter = new StringSplitter((codepoint, style) -> this.getGlyphSource(style.getFont()).getGlyph(codepoint).info().getAdvance(style.isBold()));
}
private GlyphSource getGlyphSource(FontDescription fontLocation) {
return this.provider.glyphs(fontLocation);
}
public String bidirectionalShaping(String text) {
try {
Bidi bidi = new Bidi(new ArabicShaping(8).shape(text), 127);
bidi.setReorderingMode(0);
return bidi.writeReordered(2);
} catch (ArabicShapingException var3) {
return text;
}
}
public void drawInBatch(
String str,
float x,
float y,
int color,
boolean dropShadow,
Matrix4fc pose,
MultiBufferSource bufferSource,
Font.DisplayMode displayMode,
int backgroundColor,
int packedLightCoords
) {
Font.PreparedText preparedText = this.prepareText(str, x, y, color, dropShadow, backgroundColor);
preparedText.visit(Font.GlyphVisitor.forMultiBufferSource(bufferSource, pose, displayMode, packedLightCoords));
}
public void drawInBatch(
Component str,
float x,
float y,
int color,
boolean dropShadow,
Matrix4fc pose,
MultiBufferSource bufferSource,
Font.DisplayMode displayMode,
int backgroundColor,
int packedLightCoords
) {
Font.PreparedText preparedText = this.prepareText(str.getVisualOrderText(), x, y, color, dropShadow, false, backgroundColor);
preparedText.visit(Font.GlyphVisitor.forMultiBufferSource(bufferSource, pose, displayMode, packedLightCoords));
}
public void drawInBatch(
FormattedCharSequence str,
float x,
float y,
int color,
boolean dropShadow,
Matrix4fc pose,
MultiBufferSource bufferSource,
Font.DisplayMode displayMode,
int backgroundColor,
int packedLightCoords
) {
Font.PreparedText preparedText = this.prepareText(str, x, y, color, dropShadow, false, backgroundColor);
preparedText.visit(Font.GlyphVisitor.forMultiBufferSource(bufferSource, pose, displayMode, packedLightCoords));
}
public void drawInBatch8xOutline(
FormattedCharSequence str, float x, float y, int color, int outlineColor, Matrix4fc pose, MultiBufferSource bufferSource, int packedLightCoords
) {
Font.PreparedTextBuilder outlineOutput = new Font.PreparedTextBuilder(0.0F, 0.0F, outlineColor, false, false);
for (int xo = -1; xo <= 1; xo++) {
for (int yo = -1; yo <= 1; yo++) {
if (xo != 0 || yo != 0) {
float[] startX = new float[]{x};
int finalXo = xo;
int finalYo = yo;
str.accept((position, style, codepoint) -> {
boolean bold = style.isBold();
BakedGlyph glyph = this.getGlyph(codepoint, style);
outlineOutput.x = startX[0] + finalXo * glyph.info().getShadowOffset();
outlineOutput.y = y + finalYo * glyph.info().getShadowOffset();
startX[0] += glyph.info().getAdvance(bold);
return outlineOutput.accept(position, style.withColor(outlineColor), glyph);
});
}
}
}
Font.GlyphVisitor outlineGlyphVisitor = Font.GlyphVisitor.forMultiBufferSource(bufferSource, pose, Font.DisplayMode.NORMAL, packedLightCoords);
for (TextRenderable.Styled glyphInstance : outlineOutput.glyphs) {
outlineGlyphVisitor.acceptGlyph(glyphInstance);
}
Font.PreparedTextBuilder primaryOutput = new Font.PreparedTextBuilder(x, y, color, false, true);
str.accept(primaryOutput);
primaryOutput.visit(Font.GlyphVisitor.forMultiBufferSource(bufferSource, pose, Font.DisplayMode.POLYGON_OFFSET, packedLightCoords));
}
private BakedGlyph getGlyph(int codepoint, Style style) {
GlyphSource glyphSource = this.getGlyphSource(style.getFont());
BakedGlyph glyph = glyphSource.getGlyph(codepoint);
if (style.isObfuscated() && codepoint != 32) {
int targetWidth = Mth.ceil(glyph.info().getAdvance(false));
glyph = glyphSource.getRandomGlyph(this.random, targetWidth);
}
return glyph;
}
public Font.PreparedText prepareText(String text, float x, float y, int originalColor, boolean drawShadow, int backgroundColor) {
if (this.isBidirectional()) {
text = this.bidirectionalShaping(text);
}
Font.PreparedTextBuilder output = new Font.PreparedTextBuilder(x, y, originalColor, backgroundColor, drawShadow, false);
StringDecomposer.iterateFormatted(text, Style.EMPTY, output);
return output;
}
public Font.PreparedText prepareText(
FormattedCharSequence text, float x, float y, int originalColor, boolean drawShadow, boolean includeEmpty, int backgroundColor
) {
Font.PreparedTextBuilder builder = new Font.PreparedTextBuilder(x, y, originalColor, backgroundColor, drawShadow, includeEmpty);
text.accept(builder);
return builder;
}
public int width(String str) {
return Mth.ceil(this.splitter.stringWidth(str));
}
public int width(FormattedText text) {
return Mth.ceil(this.splitter.stringWidth(text));
}
public int width(FormattedCharSequence text) {
return Mth.ceil(this.splitter.stringWidth(text));
}
public String plainSubstrByWidth(String str, int width, boolean reverse) {
return reverse ? this.splitter.plainTailByWidth(str, width, Style.EMPTY) : this.splitter.plainHeadByWidth(str, width, Style.EMPTY);
}
public String plainSubstrByWidth(String str, int width) {
return this.splitter.plainHeadByWidth(str, width, Style.EMPTY);
}
public FormattedText substrByWidth(FormattedText text, int width) {
return this.splitter.headByWidth(text, width, Style.EMPTY);
}
public int wordWrapHeight(FormattedText input, int textWidth) {
return 9 * this.splitter.splitLines(input, textWidth, Style.EMPTY).size();
}
public List<FormattedCharSequence> split(FormattedText input, int maxWidth) {
return Language.getInstance().getVisualOrder(this.splitter.splitLines(input, maxWidth, Style.EMPTY));
}
public List<FormattedText> splitIgnoringLanguage(FormattedText input, int maxWidth) {
return this.splitter.splitLines(input, maxWidth, Style.EMPTY);
}
public boolean isBidirectional() {
return Language.getInstance().isDefaultRightToLeft();
}
public StringSplitter getSplitter() {
return this.splitter;
}
@OnlyIn(Dist.CLIENT)
public static enum DisplayMode {
NORMAL,
SEE_THROUGH,
POLYGON_OFFSET;
}
@OnlyIn(Dist.CLIENT)
public interface GlyphVisitor {
static Font.GlyphVisitor forMultiBufferSource(MultiBufferSource bufferSource, Matrix4fc pose, Font.DisplayMode displayMode, int lightCoords) {
return new Font.GlyphVisitor() {
@Override
public void acceptGlyph(TextRenderable.Styled glyph) {
this.render(glyph);
}
@Override
public void acceptEffect(TextRenderable effect) {
this.render(effect);
}
private void render(TextRenderable glyph) {
VertexConsumer buffer = bufferSource.getBuffer(glyph.renderType(displayMode));
glyph.render(pose, buffer, lightCoords, false);
}
};
}
default void acceptGlyph(TextRenderable.Styled glyph) {
}
default void acceptEffect(TextRenderable effect) {
}
default void acceptEmptyArea(EmptyArea empty) {
}
}
@OnlyIn(Dist.CLIENT)
public interface PreparedText {
void visit(Font.GlyphVisitor visitor);
@Nullable ScreenRectangle bounds();
}
@OnlyIn(Dist.CLIENT)
private class PreparedTextBuilder implements Font.PreparedText, FormattedCharSink {
private final boolean drawShadow;
private final int color;
private final int backgroundColor;
private final boolean includeEmpty;
private float x;
private float y;
private float left;
private float top;
private float right;
private float bottom;
private float backgroundLeft;
private float backgroundTop;
private float backgroundRight;
private float backgroundBottom;
private final List<TextRenderable.Styled> glyphs;
private @Nullable List<TextRenderable> effects;
private @Nullable List<EmptyArea> emptyAreas;
public PreparedTextBuilder(float x, float y, int color, boolean drawShadow, boolean includeEmpty) {
this(x, y, color, 0, drawShadow, includeEmpty);
}
public PreparedTextBuilder(float x, float y, int color, int backgroundColor, boolean drawShadow, boolean includeEmpty) {
Objects.requireNonNull(Font.this);
super();
this.left = Float.MAX_VALUE;
this.top = Float.MAX_VALUE;
this.right = -Float.MAX_VALUE;
this.bottom = -Float.MAX_VALUE;
this.backgroundLeft = Float.MAX_VALUE;
this.backgroundTop = Float.MAX_VALUE;
this.backgroundRight = -Float.MAX_VALUE;
this.backgroundBottom = -Float.MAX_VALUE;
this.glyphs = new ArrayList<>();
this.x = x;
this.y = y;
this.drawShadow = drawShadow;
this.color = color;
this.backgroundColor = backgroundColor;
this.includeEmpty = includeEmpty;
this.markBackground(x, y, 0.0F);
}
private void markSize(float left, float top, float right, float bottom) {
this.left = Math.min(this.left, left);
this.top = Math.min(this.top, top);
this.right = Math.max(this.right, right);
this.bottom = Math.max(this.bottom, bottom);
}
private void markBackground(float x, float y, float advance) {
if (ARGB.alpha(this.backgroundColor) != 0) {
this.backgroundLeft = Math.min(this.backgroundLeft, x - 1.0F);
this.backgroundTop = Math.min(this.backgroundTop, y - 1.0F);
this.backgroundRight = Math.max(this.backgroundRight, x + advance);
this.backgroundBottom = Math.max(this.backgroundBottom, y + 9.0F);
this.markSize(this.backgroundLeft, this.backgroundTop, this.backgroundRight, this.backgroundBottom);
}
}
private void addGlyph(TextRenderable.Styled instance) {
this.glyphs.add(instance);
this.markSize(instance.left(), instance.top(), instance.right(), instance.bottom());
}
private void addEffect(TextRenderable effect) {
if (this.effects == null) {
this.effects = new ArrayList<>();
}
this.effects.add(effect);
this.markSize(effect.left(), effect.top(), effect.right(), effect.bottom());
}
private void addEmptyGlyph(EmptyArea empty) {
if (this.emptyAreas == null) {
this.emptyAreas = new ArrayList<>();
}
this.emptyAreas.add(empty);
}
@Override
public boolean accept(int position, Style style, int c) {
BakedGlyph glyph = Font.this.getGlyph(c, style);
return this.accept(position, style, glyph);
}
public boolean accept(int position, Style style, BakedGlyph glyph) {
GlyphInfo glyphInfo = glyph.info();
boolean bold = style.isBold();
TextColor styleColor = style.getColor();
int textColor = this.getTextColor(styleColor);
int shadowColor = this.getShadowColor(style, textColor);
float advance = glyphInfo.getAdvance(bold);
float effectX0 = position == 0 ? this.x - 1.0F : this.x;
float shadowOffset = glyphInfo.getShadowOffset();
float boldOffset = bold ? glyphInfo.getBoldOffset() : 0.0F;
TextRenderable.Styled instance = glyph.createGlyph(this.x, this.y, textColor, shadowColor, style, boldOffset, shadowOffset);
if (instance != null) {
this.addGlyph(instance);
} else if (this.includeEmpty) {
this.addEmptyGlyph(new EmptyArea(this.x, this.y, advance, 7.0F, 9.0F, style));
}
this.markBackground(this.x, this.y, advance);
if (style.isStrikethrough()) {
this.addEffect(
Font.this.provider
.effect()
.createEffect(effectX0, this.y + 4.5F - 1.0F, this.x + advance, this.y + 4.5F, 0.01F, textColor, shadowColor, shadowOffset)
);
}
if (style.isUnderlined()) {
this.addEffect(
Font.this.provider
.effect()
.createEffect(effectX0, this.y + 9.0F - 1.0F, this.x + advance, this.y + 9.0F, 0.01F, textColor, shadowColor, shadowOffset)
);
}
this.x += advance;
return true;
}
@Override
public void visit(Font.GlyphVisitor visitor) {
if (ARGB.alpha(this.backgroundColor) != 0) {
visitor.acceptEffect(
Font.this.provider
.effect()
.createEffect(
this.backgroundLeft, this.backgroundTop, this.backgroundRight, this.backgroundBottom, -0.01F, this.backgroundColor, 0, 0.0F
)
);
}
for (TextRenderable.Styled glyph : this.glyphs) {
visitor.acceptGlyph(glyph);
}
if (this.effects != null) {
for (TextRenderable effect : this.effects) {
visitor.acceptEffect(effect);
}
}
if (this.emptyAreas != null) {
for (EmptyArea emptyArea : this.emptyAreas) {
visitor.acceptEmptyArea(emptyArea);
}
}
}
private int getTextColor(@Nullable TextColor textColor) {
if (textColor != null) {
int alpha = ARGB.alpha(this.color);
int rgb = textColor.getValue();
return ARGB.color(alpha, rgb);
} else {
return this.color;
}
}
private int getShadowColor(Style style, int textColor) {
Integer shadow = style.getShadowColor();
if (shadow != null) {
float textAlpha = ARGB.alphaFloat(textColor);
float shadowAlpha = ARGB.alphaFloat(shadow);
return textAlpha != 1.0F ? ARGB.color(ARGB.as8BitChannel(textAlpha * shadowAlpha), shadow) : shadow;
} else {
return this.drawShadow ? ARGB.scaleRGB(textColor, 0.25F) : 0;
}
}
@Override
public @Nullable ScreenRectangle bounds() {
if (!(this.left >= this.right) && !(this.top >= this.bottom)) {
int left = Mth.floor(this.left);
int top = Mth.floor(this.top);
int right = Mth.ceil(this.right);
int bottom = Mth.ceil(this.bottom);
return new ScreenRectangle(left, top, right - left, bottom - top);
} else {
return null;
}
}
}
@OnlyIn(Dist.CLIENT)
public interface Provider {
GlyphSource glyphs(FontDescription font);
EffectGlyph effect();
}
}引用的其他类
-
- 引用位置:
字段/构造调用/返回值 - 关联成员:
StringSplitter()
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
EmptyArea()
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
ScreenRectangle()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Language.getInstance()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数/返回值
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
ARGB.alpha(), ARGB.alphaFloat(), ARGB.as8BitChannel(), ARGB.color(), ARGB.scaleRGB()
- 引用位置:
-
- 引用位置:
参数/返回值
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Mth.ceil(), Mth.floor()
- 引用位置:
-
- 引用位置:
字段/方法调用 - 关联成员:
RandomSource.create()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
StringDecomposer.iterateFormatted()
- 引用位置: