Uploaded image for project: 'Minecraft: Java Edition'
  1. Minecraft: Java Edition
  2. MC-262185

Partially transparent pixels in font glyphs appear more opaque than they should in the tooltip

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • 23w18a
    • 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

      1. Install and enable the attached resource pack – this sets lowercase ASCII letters to be partially transparent
      2. 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();
          }
      

        1. tooltip_1.19.4.png
          702 kB
          +merlan #flirora
        2. tooltip_23w17a.png
          449 kB
          +merlan #flirora

            Unassigned Unassigned
            fluffy8x +merlan #flirora
            Votes:
            3 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              CHK: