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

Font rendering anti-aliasing in translucent BufferedImages broken

    XMLWordPrintable

    Details

    • Subcomponent:
      2d
    • CPU:
      sparc
    • OS:
      solaris_10, windows_7

      Backports

        Description

        FULL PRODUCT VERSION :
        java 1.7_7

        ADDITIONAL OS VERSION INFORMATION :
        Microsoft Windows [Version 6.1.7601]

        A DESCRIPTION OF THE PROBLEM :
        On Java 7, pixel translucency has regressed comparing to Java 6.

        When you try to draw strings in a translucent BufferedImage, instead of using the alpha values of the background the anti-aliasing uses the opaque color value of the background. This makes anti-aliasing artifacts appear around the text.

        This never occured with Java 6, which renders the properly the fonts when using intermediate buffered images and alpha compositing.



        REGRESSION. Last worked in version 6u31

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        Compile the provided sample code and put the window on dark background. You will see the labels:
        * paintComponent:image:drawStringproperly rendered

        This sample shows two different approaches, once in paint() and once in paintComponent():
        1) write into a buffered image and blit it on the graphics context
        2) write directly to the graphics context

        The rendering changes by using Using -Dsun.java2d.noddraw=true or false, which makes me think of a pipeline rendering issue. -Dsun.java2d.d3d also affects the rendering.

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        There should be no " white " artifacts

        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        package misc;

        import java.awt.*;
        import javax.swing.*;
        import static java.awt.GraphicsDevice.WindowTranslucency.*;
        import java.awt.event.MouseAdapter;
        import java.awt.event.MouseEvent;
        import java.awt.image.BufferedImage;
        import java.awt.image.ColorModel;

        public class TranslucentFontWindowDemo extends JFrame {

            public TranslucentFontWindowDemo() {
                super( " TranslucentFontWindowDemo " );
                setUndecorated(true);
                setBackground(new Color(0, 0, 0, 0));
                setSize(new Dimension(700, 300));
                setLocationRelativeTo(null);
                setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                JPanel panel = new JPanel() {
                    @Override
                    protected void paintComponent(Graphics g) {
                        int w = getWidth();
                        int h = getHeight();
                        if (g instanceof Graphics2D) {

                            BufferedImage bi = getGraphicsConfiguration().createCompatibleImage(w, h, Transparency.TRANSLUCENT);
                            Graphics2D big = (Graphics2D) bi.createGraphics();
                            big.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                            big.setColor(new Color (255,255,255,50));
                            big.fillRoundRect(0, 0, getWidth(), getHeight(), 30, 30);
                            big.setColor(Color.BLACK);
                            big.setStroke(new BasicStroke(1.5f));
                            big.drawLine(0, 0, w, h);
                            big.setFont(getFont().deriveFont(40f));
                            big.drawString( " paintComponent:image:drawString " , 10, 30);
                            big.dispose();

                            Graphics2D g2d = (Graphics2D) g;
                            super.paintComponent(g);
                            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                            g2d.drawImage(bi, 0, 0, null);
                            g2d.setColor(Color.BLACK);
                            g2d.setFont(getFont().deriveFont(40f));
                            g2d.drawString( " paintComponent:drawString " , 10, 70);
                        }
                    }
                };

                panel.setOpaque(false);
                setLayout(new BorderLayout());
                setContentPane(panel);

                MouseAdapter mouseAdapter = new MouseAdapter() {

                    Point start = null;

                    @Override
                    public void mousePressed(MouseEvent e) {
                        this.start = e.getLocationOnScreen();
                    }

                    @Override
                    public void mouseDragged(MouseEvent e) {
                        if (this.start != null) {
                            Point end = e.getLocationOnScreen();
                            if (!end.equals(this.start)) {
                                int deltaX = end.x - this.start.x;
                                int deltaY = end.y - this.start.y;
                                Point dialogLocation = getLocation();
                                Point newLocation = new Point(dialogLocation.x + deltaX, dialogLocation.y + deltaY);
                                setLocation(newLocation);
                                this.start = end;
                            }
                        }
                    }

                    @Override
                    public void mouseReleased(MouseEvent e) {
                        this.start = null;
                    }
                };

                addMouseListener(mouseAdapter);
                addMouseMotionListener(mouseAdapter);
            }

            public static void main(String[] args) {
                ColorModel cm = ColorModel.getRGBdefault();
                switch (cm.getTransparency()) {
                    case Transparency.BITMASK:
                        System.err.println( " Color model supports: BITMASK " );
                        break;
                    case Transparency.OPAQUE:
                        System.err.println( " Color model supports: OPAQUE " );
                        break;
                    case Transparency.TRANSLUCENT:
                        System.err.println( " Color model supports: TRANSLUCENT " );
                        break;
                }

                // Determine what the GraphicsDevice can support.
                GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
                GraphicsDevice gd = ge.getDefaultScreenDevice();
                boolean isPerPixelTranslucencySupported = gd.isWindowTranslucencySupported(PERPIXEL_TRANSLUCENT);

                //If translucent windows aren't supported, exit.
                if (!isPerPixelTranslucencySupported) {
                    System.out.println( " Per-pixel translucency is not supported " );
                    System.exit(0);
                }

                // Create the GUI on the event-dispatching thread
                SwingUtilities.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        TranslucentFontWindowDemo gtw = new TranslucentFontWindowDemo();

                        // Display the window.
                        gtw.setUndecorated(true);
                        gtw.setVisible(true);
                    }
                });
            }
        }
        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        Use Java 6, but on Windows 7 x64 there are other issues with this JVM.

          Attachments

            Issue Links

              Activity

                People

                Assignee:
                pnarayanan Prahalad Kumar Narayanan (Inactive)
                Reporter:
                webbuggrp Webbug Group
                Votes:
                0 Vote for this issue
                Watchers:
                7 Start watching this issue

                  Dates

                  Created:
                  Updated:
                  Resolved: