-
Bug
-
Resolution: Fixed
-
23w17a
-
None
-
Operating System: Linux (kernel ver: 6.2.12-arch1-1)
Java: OpenJDK 17.0.7
-
Plausible
-
UI
-
Important
-
Platform
The bug
Partially transparent pixels in glyph textures appear more opaque than usual when appearing in the tooltip.
How to reproduce
- Install and enable the attached resource pack – this sets lowercase ASCII letters to be partially transparent
- Hover over an item to show its tooltip
Intended behavior: The opacity of the affected glyphs in the tooltip is similar to their opacity elsewhere
Actual behavior: The opacity of the affected glyphs is greater in the tooltip than elsewhere
Code analysis
Yarn names are used here: 1.19.4+build.1 for 1.19.4, and 23w17a+build.7 for 23w17a. The decompiled code shown below has been generated using Fabric’s fork of CFR.
The relevant method for drawing the tooltip text is Screen#renderTooltipFromComponents(MatrixStack matrices, List<TooltipComponent> components, int x, int y, TooltipPositioner positioner) for 1.19.4 and DrawContext#drawTooltip(TextRenderer textRenderer, List<TooltipComponent> components, int x, int y, TooltipPositioner positioner) for 23w17a.
Both of these methods draw each line of the tooltip text twice. 1.19.4’s version offsets the second copy of the method by 400 units in the Z-direction, thereby drawing it in front the tooltip background, whereas the first copy is drawn without any Z-offset, thereby drawing it behind the background. In contrast, 23w17a’s version draws both copies of the text with the Z-offset, so that both of them appear in front of the tooltip background. (This analysis is incorrect – matrix4f would have been mutated by the MatrixStack#translate call, so both of the copies would have been drawn with the Z-offset in the 1.19.4 version.)
The 23w17a version has two identical loops that call TooltipComponent#drawText for each tooltip component, where the latter was probably intended to call TooltipComponent#drawItems instead as the 1.19.4 version did.
1.19.4:
private void renderTooltipFromComponents(MatrixStack matrices, List<TooltipComponent> components, int x, int y, TooltipPositioner positioner) { TooltipComponent tooltipComponent2; int r; if (components.isEmpty()) { return; } int i = 0; int j = components.size() == 1 ? -2 : 0; for (TooltipComponent tooltipComponent : components) { int k = tooltipComponent.getWidth(this.textRenderer); if (k > i) { i = k; } j += tooltipComponent.getHeight(); } int l = i; int m = j; Vector2ic vector2ic = positioner.getPosition(this, x, y, l, m); int n = vector2ic.x(); int o = vector2ic.y(); matrices.push(); int p = 400; Tessellator tessellator = Tessellator.getInstance(); BufferBuilder bufferBuilder = tessellator.getBuffer(); RenderSystem.setShader(GameRenderer::getPositionColorProgram); bufferBuilder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR); Matrix4f matrix4f = matrices.peek().getPositionMatrix(); TooltipBackgroundRenderer.render((matrix, builder, startX, startY, endX, endY, z, colorStart, colorEnd) -> DrawableHelper.fillGradient(matrix, builder, startX, startY, endX, endY, z, colorStart, colorEnd), matrix4f, bufferBuilder, n, o, l, m, 400); RenderSystem.enableDepthTest(); RenderSystem.enableBlend(); RenderSystem.defaultBlendFunc(); BufferRenderer.drawWithGlobalProgram(bufferBuilder.end()); VertexConsumerProvider.Immediate immediate = VertexConsumerProvider.immediate(Tessellator.getInstance().getBuffer()); matrices.translate(0.0f, 0.0f, 400.0f); int q = o; for (r = 0; r < components.size(); ++r) { tooltipComponent2 = components.get(r); tooltipComponent2.drawText(this.textRenderer, n, q, matrix4f, immediate); // <- not offset by 400 units in the Z-direction q += tooltipComponent2.getHeight() + (r == 0 ? 2 : 0); } immediate.draw(); q = o; for (r = 0; r < components.size(); ++r) { tooltipComponent2 = components.get(r); tooltipComponent2.drawItems(this.textRenderer, n, q, matrices, this.itemRenderer); // <- offset by 400 units in the Z direction q += tooltipComponent2.getHeight() + (r == 0 ? 2 : 0); } matrices.pop(); }
23w17a:
private void drawTooltip(TextRenderer textRenderer, List<TooltipComponent> components, int x, int y, TooltipPositioner positioner) { TooltipComponent tooltipComponent2; int r; if (components.isEmpty()) { return; } int i = 0; int j = components.size() == 1 ? -2 : 0; for (TooltipComponent tooltipComponent : components) { int k = tooltipComponent.getWidth(textRenderer); if (k > i) { i = k; } j += tooltipComponent.getHeight(); } int l = i; int m = j; Vector2ic vector2ic = positioner.getPosition(this.getScaledWindowWidth(), this.getScaledWindowHeight(), x, y, l, m); int n = vector2ic.x(); int o = vector2ic.y(); this.matrices.push(); int p = 400; TooltipBackgroundRenderer.render(this, n, o, l, m, 400); this.matrices.translate(0.0f, 0.0f, 400.0f); int q = o; for (r = 0; r < components.size(); ++r) { tooltipComponent2 = components.get(r); tooltipComponent2.drawText(textRenderer, n, q, this.matrices.peek().getPositionMatrix(), this.vertexConsumers); // <- offset by 400 units in the Z-direction q += tooltipComponent2.getHeight() + (r == 0 ? 2 : 0); } q = o; for (r = 0; r < components.size(); ++r) { tooltipComponent2 = components.get(r); tooltipComponent2.drawText(textRenderer, n, q, this.matrices.peek().getPositionMatrix(), this.vertexConsumers); // <- offset by 400 units in the Z-direction q += tooltipComponent2.getHeight() + (r == 0 ? 2 : 0); } this.matrices.pop(); }