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

Rotated big fonts seems to be placed in wrong position (deriveFont, drawString)

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P4 P4
    • None
    • 6
    • client-libs
    • 2d
    • Cause Known
    • b53
    • 6
    • x86
    • windows_xp

      FULL PRODUCT VERSION :
      java version "1.6.0_01"
      Java(TM) SE Runtime Environment (build 1.6.0_01-b06)
      Java HotSpot(TM) Client VM (build 1.6.0_01-b06, mixed mode, sharing)

      ADDITIONAL OS VERSION INFORMATION :
      Windows XP Professional (32 bits)

      EXTRA RELEVANT SYSTEM CONFIGURATION :
      Intel Core 2 Duo E6600
      2 GBytes DDR2 RAM

      A DESCRIPTION OF THE PROBLEM :
      To reproduce this bug you have to create a rotated font with size > 100:
      double rads = (45.0 * Math.PI) / 180.0;
      AffineTransform transform = new AffineTransform();
      transform.rotate(Math.PI * 2.0 - rads);
      return font.deriveFont(transform);

      Original font must be a font with size > 100. Then you can try to draw some text with drawString (first setFont and then drawString). The text seems to be translated incorrectly. If size is <= 100 all seems to be ok.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      The test program is a simple
      JFrame based application drawing a text named "Text" (sic) centered in main
      window. The first time you execute this program text is not rotated and it
      have a size of 100 (new Font("Arial", Font.PLAIN, 100)).
      Every time you clic in window with left mouse button (BUTTON1) text rotates
      1 degree. All works fine for 360 degrees.
      However, you can change the text size to 101 clicking in window with right
      mouse button (BUTTON3), in fact, clicking right mouse button in window
      alternates between 100 and 101 font size). As you see, with a size of 101
      expected behavior is not obtained behavior. When rotation is done with a
      font size of 101 text is not located in right place, or expected place, that
      is, in center of window.
      If you want to restore degrees to 0 you only must exit the mouse from
      window.
      Its possible to increment the speed of rotation by clicking the center mouse
      button (BUTTON2) in order to rotate text faster.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      /*
       * Main.java
       *
       * Created on 1 de junio de 2007, 8:51
       *
       * To change this template, choose Tools | Template Manager
       * and open the template in the editor.
       */

      package bugsun;

      import java.awt.*;
      import java.awt.event.*;
      import java.awt.font.*;
      import java.awt.geom.*;
      import javax.swing.*;

      /**
       *
       * @author ismael.flores
       */
      public class Main extends JFrame implements MouseListener {
          
          public class JTextControl extends JLabel
          {
              
              private Font f1 = null;
              private Font f2 = null;
              private double degrees = 0;
              private double dstep = 1;
              private int size = 100;

              /** Creates a new instance of JTextControl */
              public JTextControl() {
                  super();
                  f1 = new Font("Arial", Font.PLAIN, size);
                  f2 = transformFont(f1, degrees);
                  setFont(f2);
              }

              public JTextControl(String text) {
                  super(text);
                  f1 = new Font("Arial", Font.PLAIN, size);
                  f2 = transformFont(f1, degrees);
                  setFont(f2);
              }
              
              private Font transformFont(Font font, double orientation) {
                  if (orientation == 0.0)
                      return font;
                  double rads = (orientation * Math.PI) / 180.0;
                  AffineTransform transform = new AffineTransform();
                  transform.rotate(Math.PI * 2.0 - rads);
                  return font.deriveFont(transform);
              }
              
              public void reset() {
                  size = 100;
                  degrees = 0;
                  f1 = new Font("Arial", Font.PLAIN, size);
                  f2 = transformFont(f1, degrees);
                  setFont(f2);
              }
              
              public void changeSize() {
                  size = (size == 100) ? 101 : 100;
                  f1 = new Font("Arial", Font.PLAIN, size);
                  f2 = transformFont(f1, degrees);
                  setFont(f2);
              }
              
              public void addDegree() {
                  degrees += dstep;
                  while (degrees > 360)
                      degrees -= 360;
                  f2 = transformFont(f1, degrees);
                  setFont(f2);
              }
              
              public void changeStep() {
                  dstep = dstep + 1;
                  if (dstep == 10)
                      dstep = 1;
              }
              
              public void drawText(Graphics2D g2, String text, Rectangle2D cr, int
      horizontalAlignment, int verticalAlignment, boolean antialiasing) {
                  if (antialiasing)
                      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
      RenderingHints.VALUE_ANTIALIAS_ON);
                  FontMetrics fm = g2.getFontMetrics();
                  FontRenderContext frc = g2.getFontRenderContext();
                  double y = 0.0;
                  double x = 0.0;
                  TextLayout layout = new TextLayout(text, g2.getFont(), frc);
                  Rectangle2D r = layout.getBounds();
                  double w = r.getWidth();
                  double h = r.getHeight();
                  y = (cr.getHeight() - h) / 2.0;
                  y -= Math.floor(r.getY());

                  x = (cr.getWidth() - w) / 2.0;
                  x -= Math.floor(r.getX());
                  g2.drawString(text, (int)Math.round(x), (int)Math.round(y));
              }

              public void paintComponent(Graphics g) {
                  Rectangle2D cr = getBounds();
                  if (cr == null || getText() == null)
                      return;

                  setForeground(Color.RED);
                  drawText((Graphics2D)g, getText(), cr, getHorizontalAlignment(),
      getVerticalAlignment(), true);
              }
          }
          
          private JTextControl textControl = new JTextControl("Text");
          
          /** Creates a new instance of Main */
          public Main() {
              setLayout(new BorderLayout());
              getContentPane().add(textControl, BorderLayout.CENTER);
              addMouseListener(this);
          }
          
          /**
           * @param args the command line arguments
           */
          public static void main(String[] args) {
              // TODO code application logic here
              Main mainWindow = new Main();
      // Create a new object.
              mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      // Exit program on close
              mainWindow.pack();
      // Arrange the components.
              mainWindow.setBounds(50, 50, 400, 300); // Default dimensions of
      main window
              mainWindow.setVisible(true);
      // Make the window visible.
          }

          public void mouseClicked(MouseEvent e) {
              if (e.getButton() == e.BUTTON1)
                  textControl.addDegree();
              else if (e.getButton() == e.BUTTON3)
                  textControl.changeSize();
              else
                  textControl.changeStep();
              doLayout();
          }

          public void mousePressed(MouseEvent e) { }

          public void mouseReleased(MouseEvent e) { }

          public void mouseEntered(MouseEvent e) { }

          public void mouseExited(MouseEvent e) {
              textControl.reset();
              doLayout();
          }
      }
      ---------- END SOURCE ----------

            dgredler Daniel Gredler
            ndcosta Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: