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

Fonts with embedded bitmaps are not always rotated

    Details

    • Subcomponent:
      2d
    • Introduced In Version:
      11
    • Resolved In Build:
      b19
    • CPU:
      x86_64
    • OS:
      windows_10

      Backports

        Description

        A DESCRIPTION OF THE PROBLEM :
        Our application programs are rendering rotated string images using Graphics2D#rotate() method.
        Running these applications with Java 11, the bounding box of text is properly rotated but each characters included in the string are not rotated and inproperly layouted, so we can't read the text from displayed rendering image.
        In addition, the situation seems to be different depending on the font used. With Japanese fonts installed in Windows, this problem is always occured.

        REGRESSION : Last worked in version 11

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        1. Compile attached source code.
        2. Change the rotating degrees using JSlider on the north of the JFrame.

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        We expect the same rendering with Java 8, 9, 10. With older versions from 11, the whole rendering image of text are properly rotated.
        ACTUAL -
        The bounding box of text is properly rotated but each characters included in the string are not rotated and inproperly layouted, so we can't read the text from displayed rendering image.

        ---------- BEGIN SOURCE ----------
        import java.awt.BorderLayout;
        import java.awt.Color;
        import java.awt.Dimension;
        import java.awt.Font;
        import java.awt.FontMetrics;
        import java.awt.Graphics;
        import java.awt.Graphics2D;
        import java.awt.geom.AffineTransform;

        import javax.swing.JComponent;
        import javax.swing.JFrame;
        import javax.swing.JLabel;
        import javax.swing.JPanel;
        import javax.swing.JSlider;
        import javax.swing.SwingUtilities;
        import javax.swing.UIManager;
        import javax.swing.WindowConstants;
        import javax.swing.event.ChangeEvent;
        import javax.swing.event.ChangeListener;

        public class DrawRotateText {

        private static final String TEXT =
        "OS[" + System.getProperty("os.name") +
        "], Java[" +
        System.getProperty("java.version") +
        "], text[テキスト回転]";

        private static final Color BACKGROUND_COLOR = Color.white;
        private static final Color LINE_COLOR = new Color(0,0,255,60);

        public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
        public void run() {
        try {
        // set Windows Look & Feel
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }
        catch(Exception ex) {
        ex.printStackTrace();
        }
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

        JPanel content = new JPanel();
        content.setLayout(new BorderLayout());

        final MyComponent comp = new MyComponent();
        // final MyLabel comp = new MyLabel();
        content.add(comp, BorderLayout.CENTER);

        JSlider slider = new JSlider();
        slider.setMinimum(0);
        slider.setMaximum(360);
        slider.setValue(0);
        slider.addChangeListener(new ChangeListener() {
        public void stateChanged(ChangeEvent e) {
        comp.setDegree(slider.getValue());
        }
        });
        content.add(slider, BorderLayout.NORTH);

        comp.setPreferredSize(new Dimension(500,500));
        frame.setContentPane(content);
        frame.pack();
        frame.setVisible(true);
        }
        });
        }

        public static class MyComponent extends JComponent {
        private int degree;

        public void setDegree(int degree) {
        this.degree = degree;
        repaint();
        }
        public int getDegree() {
        return this.degree;
        }
        public void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D)g.create();
        g2d.setColor(BACKGROUND_COLOR);
        g2d.fillRect(0, 0, getWidth(), getHeight());
        g2d.setColor(getForeground());
        Font font = getFont();
        FontMetrics fm = getFontMetrics(font);
        g2d.drawString(font2string(font), 0, getHeight()-(fm.getDescent()+fm.getLeading()));
        g2d.setColor(LINE_COLOR);
        g2d.drawLine(0, getHeight()/2, getWidth(), getHeight()/2);
        g2d.drawLine(getWidth()/2, 0, getWidth()/2, getHeight());
        double theta = (2 * Math.PI * degree) / 360;
        g2d.rotate(theta, getWidth()/2, getHeight()/2);
        g2d.setColor(getForeground());
        g2d.drawString(TEXT, (getWidth()-fm.stringWidth(TEXT))/2, (getHeight()+fm.getAscent())/2);
        g2d.dispose();
        }
        }

        public static class MyLabel extends JLabel {
        private int degree;

        public MyLabel() {
        setHorizontalAlignment(CENTER);
        setVerticalAlignment(CENTER);
        setText(TEXT);
        }
        public void setDegree(int degree) {
        this.degree = degree;
        repaint();
        }
        public int getDegree() {
        return this.degree;
        }
        public void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D)g.create();
        g2d.setColor(BACKGROUND_COLOR);
        g2d.fillRect(0, 0, getWidth(), getHeight());
        g2d.setColor(getForeground());
        Font font = getFont();
        FontMetrics fm = getFontMetrics(font);
        g2d.drawString(font2string(font), 0, getHeight()-(fm.getDescent()+fm.getLeading()));
        g2d.setColor(LINE_COLOR);
        g2d.drawLine(0, getHeight()/2, getWidth(), getHeight()/2);
        g2d.drawLine(getWidth()/2, 0, getWidth()/2, getHeight());
        double theta = (2 * Math.PI * degree) / 360;
        g2d.rotate(theta, getWidth()/2, getHeight()/2);
        g2d.setColor(getForeground());
        super.paintComponent(g2d);
        g2d.dispose();
        }
        }

        private static String font2string(Font font) {
        StringBuilder sb = new StringBuilder();
        sb.append("Font[family=");
        sb.append(font.getFamily());
        sb.append(",name=");
        sb.append(font.getFontName());
        sb.append(",style=");
        if(font.isBold() && font.isItalic()) {
        sb.append("bold+italic");
        } else if(font.isBold()) {
        sb.append("bold");
        } else if(font.isItalic()) {
        sb.append("italic");
        } else {
        sb.append("plain");
        }
        sb.append(",size=");
        sb.append(font.getSize());
        sb.append("]");
        return sb.toString();
        }

        }

        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        No workaround

        FREQUENCY : always


          Attachments

          1. 11-results.JPG
            11-results.JPG
            27 kB
          2. 8u172-results.JPG
            8u172-results.JPG
            20 kB
          3. 9-results.JPG
            9-results.JPG
            27 kB
          4. DrawRotateText.java
            4 kB

            Issue Links

              Activity

                People

                • Assignee:
                  prr Philip Race
                  Reporter:
                  webbuggrp Webbug Group
                • Votes:
                  0 Vote for this issue
                  Watchers:
                  5 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved: