JDK-8217509 : Broken fontmetrics when printing Text using background with alpha channel
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 11
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic
  • CPU: x86_64
  • Submitted: 2019-01-16
  • Updated: 2020-09-17
  • Resolved: 2020-09-17
Related Reports
Duplicate :  
Description
ADDITIONAL SYSTEM INFORMATION :
Can be reproduced at least in Windows 64-bit and in Linux 64-bit
Can be reproduced at least in Java 10.0.2 and in Java 11.0.2
Can NOT be reproduced in Java 8

A DESCRIPTION OF THE PROBLEM :
When drawing text using background with alpha channel fontmetrics return invalid values, for example getStringBounds returns a zero rectangle and getAscent returns a negative value. So most applications will print such strings at wrong locations. Problem only occurs when printing, not when drawing in a panel.
JTable.print() is also broken when used with Nimbus L&F - I suppose this is the same problem

REGRESSION : Last worked in version 8u201

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run class SwingTextPrintBugFrame2 from test case in Java 10.0.2 or java 11.0.2



EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Java version number should be shown as text 3 times side by side in JFrame and on printout
ACTUAL -
Java version number is shown as text 3 times side by side in JFrame but NOT on printout: printout is broken

---------- BEGIN SOURCE ----------
package bugs.swing_text_print;

import java.awt.*;
import java.awt.font.*;
import java.awt.geom.AffineTransform;
import java.awt.print.*;
import java.util.*;
import javax.swing.*;

/**
 *
 * @author werner
 */
public class SwingTextPrintBugFrame2 extends JFrame
{
  private final String TEXT =
    "* " +System.getProperty("java.version")+" *";

  private javax.swing.JButton btPrint;
  
  /**
   * Creates new form SwingTextPrintBugFrame
   */
  public SwingTextPrintBugFrame2()
  {
    initComponents();
    final JPanel pMain =
      new JPanel()
      {
        @Override
        public void paint(final Graphics g)
        {
          super.paint(g);
          drawText((Graphics2D)g);
        }
      };
    pMain.setPreferredSize(new Dimension(360,100));
    getContentPane().add(pMain);
    pack();
  }
  
  private void initComponents()
  {

    btPrint = new javax.swing.JButton();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    btPrint.setText("Print");
    btPrint.addActionListener(new java.awt.event.ActionListener()
    {
      public void actionPerformed(java.awt.event.ActionEvent evt)
      {
        onPrint(evt);
      }
    });
    getContentPane().add(btPrint, java.awt.BorderLayout.PAGE_END);

    pack();
  }  
  private void drawText(final Graphics2D g2)
  {
    final Map<java.text.AttributedCharacterIterator.Attribute,Object>
      fontMap  = new HashMap<>();
    fontMap.put(TextAttribute.FAMILY,"SansSerif");
    fontMap.put(TextAttribute.SIZE,17F+2F/3F);
    fontMap.put(TextAttribute.FOREGROUND,Color.BLACK);
    fontMap.put(TextAttribute.WEIGHT,TextAttribute.WEIGHT_BOLD);

    //setRenderingHints(g2);
    int baseX = 10, baseY = 50;
    for (int i=0;i<3;i++)
    {
      if (i==2)     // Bug only occurs if Text has background WITH ALPHA!
        fontMap.put(TextAttribute.BACKGROUND, new Color(0,0,255,64)); 
      final Font font = new Font(fontMap);
      final FontMetrics fontMetrics = g2.getFontMetrics(font);
      final Rectangle rect =
        fontMetrics.getStringBounds(TEXT, g2).getBounds();
      System.out.println("***** "+rect+" / "+fontMetrics.getAscent());
      final int
        ascent = fontMetrics.getAscent(), // Bug: ascent gets negative!
        width= rect.width;                // Bug: width gets zero!
      final TextLayout textLayout =
        new TextLayout(TEXT, font, fontMetrics.getFontRenderContext());
      textLayout.getBounds();
      
      textLayout.draw(g2, baseX, baseY+ascent);
      g2.drawRect(baseX, baseY, rect.width, rect.height);
      
      baseX += width+10;
    }
  }
  
  private Printable getPrintable()
  {
    return new Printable()
    {
      @Override
      public int print(Graphics graphics, PageFormat pageFormat, int pageIndex)
        throws PrinterException
      {
        final Graphics2D g2 = (Graphics2D)graphics;
        final AffineTransform at = g2.getTransform();
        at.translate((int)pageFormat.getImageableX(), (int)pageFormat.getImageableY());
        //at.scale(0.7, 0.7);
        g2.setTransform(at);
        drawText(g2);
        return pageIndex==0 ? Printable.PAGE_EXISTS : Printable.NO_SUCH_PAGE;
      }
    };
  }
  
  private void onPrint(java.awt.event.ActionEvent evt)                         
  {                             
    final PrinterJob pj = PrinterJob.getPrinterJob();
    if (!pj.printDialog())
      return;
    pj.setPrintable(getPrintable(), pj.defaultPage());
    try
    {
      pj.print();
    }
    catch (final Exception ex)
    {
      ex.printStackTrace();
    }
  }                        
  
  public static void main(String[] args)
  {
      java.awt.EventQueue.invokeLater(new Runnable()
    {
      @Override
      public void run()
      {
        new SwingTextPrintBugFrame2().setVisible(true);
      }
    });
    
  }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
None known

FREQUENCY : always



Comments
This is fixed as of jdk12 b23 by JDK-8139178. Closing as a dup.
17-09-2020

So we reproduced this on earlier releases and then it stopped reproducing. Closing it out as fixed and not reproducible are both wrong. The correct thing is to idenify what fixed it and close it as a dup.
17-09-2020

As the issue is fixed in b10-11.0.5 Closing this issue.
14-08-2020

Verifying the test case in Windows 10 and Ubuntu 18.04 + JDK 11.0.8 Test Result: ========= 11.0.8: PASS, attached output(SwingTextPrintBugFrame2_TestPrint_jdk_11_0_8.pdf)
12-08-2020

[~pnarayanaswa] Can you please check whether this is reproducible in 11.0.8?
11-08-2020

Additional Information from submitter: Referring to your comment: Reported problem for Java 11.0.2 for Windows 10 64 Bit and Linux 64 Bit Can confirm problem is not present in Java 12 EA BUT Problem IS DEFINITELY PRESENT in Java 10.0.2, reproduced it on Windows 10 64 Bit and on Linux 64 Bit So "regression in Java 10.0.2" is NOT correct
23-01-2019

Reported as regression in JDK 10.0.2, drawing text using background with alpha channel fontmetrics return invalid values. Checked this for reported JDK version and could confirm the issue. Results: ========= 8u201: Pass 9: Pass 10.0.2: Pass 11: Fail 11.0.2: Fail 12 ea b28: Pass 13 ea b04: Pass When checked with Windows 10 (64-bit), the issue does not occur with JDK 10.0.2 and it has failed in JDK 11 and 11.0.2, however seems fixed in JDK 12 ea build. Written back to the submitter requesting additional information including status with 12 ea build and 10.0.2. To verify, run the attached test case with respective JDK versions.
22-01-2019