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

Incorrect FontMetrics.stringWidth() in PrintGraphics

    XMLWordPrintable

    Details

    • Subcomponent:
    • Resolved In Build:
      07
    • CPU:
      x86, sparc
    • OS:
      solaris_7, windows_95, windows_nt

      Description

      Name: wl91122 Date: 08/19/99

      FontMetrics returns incorrect stringWidth() for PLAIN font
      in PrintGraphics context on WinNT4/JDK1.1.8. The sample
      code below attempts to print a right justified string in
      both PLAIN and BOLD font styles. The BOLD font justifies
      correcty, but the PLAIN font does not. This problem does
      not occur on Solaris with either JDK1.1.7 or JDK1.1.8

      Sample output:

      WinNT/JDK1.1.8
      Dimensions: java.awt.Dimension[width=612,height=792]
      Resolution: 72
      Plain: 58
      Bold: 59

      Solaris/JDK1.1.8
      Dimensions: java.awt.Dimension[width=612,height=792]
      Resolution: 72
      Plain: 55
      Bold: 59

      See also 4244848 which was classified 'not reproducible'
      due to a lack of detail in the bug submission and sample
      code.

      My printed output in each case was created on the
      same network printer. The Solaris runs were properly
      right justified. The strings were misaligned in WinNT.

      Note that on WinNT the Plain and Bold string widths are not
      exactly the same as claimed in bug 4244848, but the single pixel
      difference would translate to 1/72 of an inch. This would barely
      be visible to the naked eye. The printed page (I'll fax my samples
      if you wish) shows a measurable difference of at least 1/16 inch.

      After further work with this problem, it appears the the culprit
      may be the metrics for the space character (0x20). The charWidth
      returned by FontMetrics is suspiciously small. If I were you, I'd
      look there first.

      ======================================================================

      import java.awt.*;
      import java.util.Properties;

      public class StringWidth extends Frame {

        public StringWidth() {
          Font plain = new Font("Dialog", Font.PLAIN, 10);
          Font bold = new Font("Dialog", Font.BOLD, 10);
          Properties props = new Properties();
          int x, y;

          // we must have visible Frame context for PrintDialog in Solaris
          setSize(400, 300);
          setVisible(true);

          PrintJob pj = getToolkit().getPrintJob(this, "", props);
          Graphics pg = pj.getGraphics();

          String test = "Hello World!";

          FontMetrics plainFm = pg.getFontMetrics(plain);
          FontMetrics boldFm = pg.getFontMetrics(bold);
          Dimension size = pj.getPageDimension();

          System.out.println("Dimensions: " + size);
          System.out.println("Resolution: " + pj.getPageResolution());
          System.out.println("Plain: " + plainFm.stringWidth(test));
          System.out.println("Bold: " + boldFm.stringWidth(test));

          // now right justify on the printed page
          int center = size.width/2;
          y = 50;
          x = center - plainFm.stringWidth(test);
          pg.setFont(plain);
          pg.drawString(test, x, y);

          y += boldFm.getHeight();
          x = center - boldFm.stringWidth(test);
          pg.setFont(bold);
          pg.drawString(test, x, y);

          // draw a line to show where right justification should be
          y += boldFm.getDescent() + 2;
          pg.drawLine(center, 0, center, y);

          pg.dispose();
          pj.end();
          setVisible(false);
          System.exit(0);
        }

        public static void main(String[] args) {
          new StringWidth();
        }

      }
      (Review ID: 94135)
      ======================================================================

      Name: mc57594 Date: 01/06/2000


      java version "1.2.2"
      Classic VM (build JDK-1.2.2-001, native threads, symcjit)


      The stringWidth() method for FontMetrics returns incorrect values when applied
      to a Graphics object obtained from a PrintJob. For 10 point fonts, the value
      returned is too large, while for 8 point it is too small. The following code
      demonstrates the problem:

      ----------BEGIN CODE-----------

      import java.awt.*;
      import java.awt.event.*;
      import java.awt.geom.*;
      import javax.swing.*;
      import java.util.Properties;

      public class FontMetricsBug extends JApplet
      {
      private static final int OFFSET = 15;
      String s = "This is a long string which gets its width mis-reported by
      FontMetrics.stringWidth() when it's being printed.";

      Font f = new Font("SansSerif", Font.PLAIN, 10); // This overreports the
      width
      // Font f = new Font("SansSerif", Font.PLAIN, 8); // This underreports the
      width

      public void init()
      {
      JFrame f = new JFrame("FontMetricsBug");
              f.addWindowListener(new WindowAdapter() {
                  public void windowClosing(WindowEvent e) {System.exit(0);}
              });

      f.getContentPane().add("Center", this);
              f.pack();
              f.setSize(new Dimension(700,80));
              f.show();

      setBackground(Color.white);
      setForeground(Color.black);
              Properties printProperties = new Properties();
      PrintJob printJob = this.getToolkit().getPrintJob( f,
              
      "Print Test",
              
      printProperties );
              if (printJob != null) {
              Graphics g = printJob.getGraphics();
              g = printJob.getGraphics();
      draw(g);
      g.dispose();
      printJob.end();
              }
      }

          public void paint(Graphics g) {
           draw(g);
          }


      public void draw(Graphics g) {
      g.setColor(Color.black);
      g.setFont(f);
              FontMetrics fm = g.getFontMetrics();
              g.drawString(s, OFFSET, fm.getHeight() + OFFSET);
              g.setColor(Color.red);
              //Draw red bars around the text where FontMetrics thinks the borders are
              g.drawLine(OFFSET, OFFSET, OFFSET, OFFSET+fm.getHeight());
              int length = fm.stringWidth(s);
              g.drawLine(OFFSET+length, OFFSET, OFFSET+length, OFFSET+fm.getHeight());
              
          }


          public static void main(String s[]) {
              JApplet applet = new FontMetricsBug();
              applet.init();
          }
      }

      ----------END CODE-----------

      The window displayed has red lines at either end of the string, in exactly the
      right place. When it is printed, however, the line on the right is either too
      far away (in the case of the 10 point font) or too close (for the 8 point font)
      to the other line. This occurs on HP Laserjet 4000 and 4M printers (at least -
      I haven't tested any others).
      (Review ID: 99070)
      ======================================================================

        Attachments

          Activity

            People

            Assignee:
            ssisunw Ssi Ssi (Inactive)
            Reporter:
            wleesunw William Lee (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: