Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8217509

Broken fontmetrics when printing Text using background with alpha channel

    Details

    • Subcomponent:
    • Introduced In Version:
      11
    • CPU:
      x86_64
    • OS:
      generic

      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


        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                pnarayanaswa Praveen Narayanaswamy
                Reporter:
                webbuggrp Webbug Group
              • Votes:
                0 Vote for this issue
                Watchers:
                6 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: