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

Fonts antialiasing artifacts appear when using translucent composited images

    XMLWordPrintable

Details

    • Bug
    • Resolution: Duplicate
    • P3
    • 9
    • 7, 8, 9
    • client-libs
    • 2d
    • windows_7

    Description

      FULL PRODUCT VERSION :
      JDK 7u21

      ADDITIONAL OS VERSION INFORMATION :
      Windows 7 64bit

      A DESCRIPTION OF THE PROBLEM :
      When you draw a string onto a translucent buffered image and then blit the image onto a transparent window, the antialiasing of the fonts doesn't blend from the font color to the translucent background color. In our application, we need to write to an intermediate buffered image, because we need to animate the content of the window.

      This works well with Java 6. And is therefore a regression.

      REGRESSION. Last worked in version 6u45

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the provided code and put the transparent window over a dark background.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The antialiasing of the first line of the provided example should blend to the transparent background color.

      ACTUAL -
      The pixels blend from the opaque font color to the OPAQUE background color of the even thoug the background color is translucent.

      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.font.FontRenderContext;
      import java.awt.font.TextLayout;
      import java.awt.geom.AffineTransform;
      import java.awt.geom.Rectangle2D;
      import java.awt.image.BufferedImage;
      import java.awt.image.ColorModel;
      import sun.font.GlyphList;
      import sun.java2d.SunGraphics2D;
      import sun.java2d.loops.FontInfo;

      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, 0, 0, 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.setStroke(new BasicStroke(1f));
                          Font font = getFont().deriveFont(40f);
                          big.setFont(font);
                          big.drawString( " paintComponent:image:drawString " , 10, 30);

                          big.setColor(Color.BLACK);
                          FontRenderContext frc = big.getFontRenderContext();
                          TextLayout textLayout = new TextLayout( " Outline " , font, frc);
      // textLayout.draw(big, 10, 120);
                          Rectangle2D textBounds = textLayout.getBounds();

                          Shape shapeOutline = textLayout.getOutline(AffineTransform.getTranslateInstance(10 - textBounds.getX(), 120 - textBounds.getY()));
                          big.fill(shapeOutline);

                          SunGraphics2D sg = (SunGraphics2D) big;
                          FontInfo info = sg.getFontInfo();
                          GlyphList gl = GlyphList.getInstance();
                          if (gl.setFromString(info, " String " , 10, 110)) {
                              // Native call
      // sg.loops.drawGlyphListAALoop.DrawGlyphListAA(sg, sg.surfaceData, gl);
      // sg.loops.drawGlyphListLoop.DrawGlyphList(sg, sg.surfaceData, gl);
      // sg.loops.drawGlyphListLCDLoop.DrawGlyphListLCD(sg, sg.surfaceData, gl);
                              gl.dispose();
                          }

                          big.dispose();

                          Graphics2D g2d = (Graphics2D) g.create();
                          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);
                          g2d.dispose();
                          super.paintComponent(g);
                      }
                  }
              };

              panel.setLayout(new BorderLayout());
              panel.add(new JLabel( " hey " ), BorderLayout.CENTER);
              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 ----------

      Attachments

        Issue Links

          Activity

            People

              psadhukhan Prasanta Sadhukhan
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: