0 Replies Latest reply: Apr 25, 2011 2:51 PM by 800188 RSS

    Rotated Text and Antialiasing on Windows

    800188
      Hello all I hope you can help me with this problem,

      I am creating an application that uses rotated text, i've been developing this application in Mac OS X and have had no problem with jagged edges on text as it seems Mac OS automatically antialiases text without using any rendering hints. However on Windows platforms I noticed the text appeared very jagged especially when rotated anywhere from five degrees up. I thought I could solve this problem by applying rendering hints specifying antialiasing on and text antialiasing on. This did help however it only appears smooth when the text is very large around 90-100pts and goes back to appearing jagged when below this size even with these rendering hints applied.

      I have developed a simple application that you can run that rotates a letter seven degrees and loops through the font sizes of 20 - 120. You should notice that at font sizes around 100-120 the letter appears way smoother then at font sizes around 80 and below.

      I have also uploaded an image comparing the letter D antialiased and rotated 7 degrees on both Mac OS and Windows you can see on the left (Mac OS) the letter appears smoother then then the letter on the right (Windows 7). It appears the letter on the right is still being antialiased but not as effectively as the letter on the left. Is there a way to fix this problem? The antialiased text on Windows 7 really doesn't appear all that smooth compared to Mac OS. In fact if I didn't know that I was explicitly telling it to use antialiasing it would be hard for me to tell it was antialiasing at all.

      The photo comparing antialiasing on Mac OS and Windows 7 can be found here: http://doodletype.com/Antialiasing/jagged.png

      The source code for my example:
      /*
       * To change this template, choose Tools | Templates
       * and open the template in the editor.
       */
      
      package smoothtext;
      
      
      import java.awt.*;
      import javax.swing.*;
      import javax.swing.Action.*;
      import com.sun.awt.AWTUtilities.*;
      import java.awt.Rectangle;
      import java.awt.font.*;
      
      
      public class SmoothText {
      
          /**
           * @param args the command line arguments
           */
      
          public static void main(String[] args) {
              SwingUtilities.invokeLater( new Runnable() {
                  public void run() {
                      try {
                          UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                      } catch(Exception err) {
                          System.out.println(err);
                      }
                      new SmoothText();
                  }
              });
          }
      
      
          int offset = 1;
          Font font = new Font("Arial", Font.PLAIN, 20);
          PaintSurface canvas = new PaintSurface();
          JFrame frame = new JFrame("Smooth Text");
          
          public SmoothText() {
      
              frame.setSize(500,500);
              frame.setLocationRelativeTo(null);
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      
              frame.add(canvas);
              frame.setVisible(true);
      
              new Thread(new AnimationThread()).start();
          }
      
          class AnimationThread implements Runnable {
      
              public void run() {
      
                  while(true) {
                      try {
                          Thread.sleep(30);
                      } catch(InterruptedException err) {
                          //handle interrupted exception
                      }
      
                      if(font.getSize()>120) {
                          offset = -1;
                      } else if(font.getSize()<20) {
                          offset = 1;
                      }
                      font = new Font(font.getFamily(), font.getStyle(), font.getSize()+offset);
                      canvas.repaint();
                  }
              }
          }
      
          class PaintSurface extends JComponent {
      
              @Override
              public void paintComponent(Graphics g) {
      
                  super.paintComponent(g);
      
                  Graphics2D g2 = (Graphics2D)g;
                  g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                  //This probably isn't necissary when I already specifed antialiasing on.
                  g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
      
                  g2.setColor(Color.red);
                  g2.drawString("Font Size: "+font.getSize(), 20, 20);
                  g2.setColor(Color.black);
                  
                  g2.setFont(font);
                  TextLayout layout = new TextLayout("D", font, g2.getFontRenderContext());
                  Rectangle bounds = layout.getPixelBounds(null, 0, 0);
      
                  g2.rotate(Math.toRadians(7), (getWidth()/2 - bounds.width/2)+bounds.width/2, ((getHeight()/2 - bounds.height/2)-(int)bounds.getY())+bounds.height/2);
                  g2.drawString("D", getWidth()/2 - bounds.width/2, (getHeight()/2 - bounds.height/2)-(int)bounds.getY());
              }
          }
      }
      I've only tested this on Windows 7 so this "problem" may only occur on Windows 7 but let me know if you see the same thing and any help with solving this problem would be great.

      Thank you :)