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

FontMetrics.stringWidth incorrect for multi-byte characters print

XMLWordPrintable

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

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

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows XP [Version 5.1.2600]

      EXTRA RELEVANT SYSTEM CONFIGURATION :
      Windows XP Japanese
      (I do not investigate other national language version.)

      A DESCRIPTION OF THE PROBLEM :
      When I print a multi-byte character less than 7-point, a real print result is different from FontMetrics.stringWidth().

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Windows XP SP3 Professional (Japanese)
      Execute sample code
      select "File" -> "Print"

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The length of the underline almost accords with printed character string.
      ACTUAL -
      The length of the underline does not accord with character string printed by a font size.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      package sample;

      import java.awt.Font;
      import java.awt.FontMetrics;
      import java.awt.Graphics;
      import java.awt.JobAttributes;
      import java.awt.PageAttributes;
      import java.awt.PrintJob;
      import java.awt.Toolkit;
      import java.awt.event.ActionEvent;
      import java.awt.event.ActionListener;

      import javax.swing.JFrame;
      import javax.swing.JMenu;
      import javax.swing.JMenuBar;
      import javax.swing.JMenuItem;
      import javax.swing.SwingUtilities;

      public class SamplePrint extends JFrame implements ActionListener, Runnable {

          static final int OFFSET_X = 30;
          static final int OFFSET_Y = 30;
          static final int X2 = 50;
          static final int BETWEEN_LINES = 10;

          /**
           * @param args
           */
          public static void main(String[] args) {
              SwingUtilities.invokeLater(new SamplePrint());
          }

          public void run() {
              setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              JMenuBar mb = new JMenuBar();
              JMenu menu = new JMenu("File");
              JMenuItem item = new JMenuItem("Print");
              item.addActionListener(this);
              menu.add(item);
              mb.add(menu);
              setJMenuBar(mb);
              setSize(150, 150);
              setVisible(true);
          }

          public void actionPerformed(ActionEvent e) {
              String title = "PrintJob";

              JobAttributes job = new JobAttributes();
              PageAttributes page = new PageAttributes();
              page.setOrientationRequested(3); // portrait
              page.setMedia(PageAttributes.MediaType.A4);

              // show dialog
              PrintJob printJob = Toolkit.getDefaultToolkit().getPrintJob(this,
                      title, job, page);

              //
              Graphics g = printJob.getGraphics();

              // java version print
              Font titleFont = new Font("Monospaced", Font.PLAIN, 7);
              g.setFont(titleFont);
              g.drawString("size width " + System.getProperty("java.vm.name")
                      + " " + System.getProperty("java.version"), OFFSET_X, OFFSET_Y);

              Font basefont = new Font("Monospaced", Font.PLAIN, 1);
              for (int i = 0; i < 61; i++) {
                  String tmp = "\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18\uff19\uff10";
                  String str = tmp + tmp + tmp + tmp + tmp + tmp + tmp;

                  float fontSize = ((float) (i + 10)) / 10;
                  Font font = basefont.deriveFont(fontSize);
                  g.setFont(font);
                  FontMetrics fm = g.getFontMetrics();
                  // System.err.println(fm);
                  int width = fm.stringWidth(str);
                  int y = (i + 1) * BETWEEN_LINES + OFFSET_Y;

                  g.drawString(str, OFFSET_X + X2, y);
                  g.drawLine(OFFSET_X + X2, y, OFFSET_X + X2 + width, y);

                  g.setFont(titleFont);
                  g.drawString("" + fontSize + " " + width, OFFSET_X, y);
              }
              printJob.end();
          }
      }

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

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

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: