3

Which Font API of Java returns the right width? We use currently

font.getStringBounds( "the string", frc ).getWidth();

This return the right values on images and display. But it is wrong on printing with Java SE 6. With Java 7 all is correct. The difference is very small. But we lost one "i" at end of a line. We receive on printing exact the same values. But the text need more space on a printing graphics.

We use anti alias and fractional metrics.

I know there are different API. But what is the recommended API?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Horcrux7
  • 23,758
  • 21
  • 98
  • 156

3 Answers3

1

Do you have a Graphics object to the printer? What does in that case happen if you test this code? It's what I'm using to measure width:

/*
Graphics2D g
Font currentFont
String stringToMeasure
*/
FontMetrics currentFontMetrics = g.getFontMetrics(currentFont);
Rectangle2D stringBounds = currentFontMetrics.getStringBounds(stringToMeasure, g);
double width = stringBounds.getWidth();
Kaj
  • 10,862
  • 2
  • 33
  • 27
0

Java rounds all font metrics by default, because it assumes you are attempting to render to a screen, what you need to extend FontRenderContext and turn on FractionalMetricsHint as shown below. Then, use that to pass in a font render context.

import java.awt.RenderingHints;
import java.awt.font.FontRenderContext;
import java.awt.geom.AffineTransform;

public class MyFontRenderContext extends FontRenderContext {

public MyFontRenderContext()
{

}
@Override
public AffineTransform getTransform()
{
    return new AffineTransform();
}

/* (non-Javadoc)
 * @see java.awt.font.FontRenderContext#usesFractionalMetrics()
 */
@Override
public boolean usesFractionalMetrics()
{
    return true;
}

/* (non-Javadoc)
 * @see java.awt.font.FontRenderContext#getFractionalMetricsHint()
 */
@Override
public Object getFractionalMetricsHint()
{
    // TODO Auto-generated method stub
    return RenderingHints.VALUE_FRACTIONALMETRICS_ON;
}

/* (non-Javadoc)
 * @see java.awt.font.FontRenderContext#getAntiAliasingHint()
 */
@Override
public Object getAntiAliasingHint()
{
    return RenderingHints.VALUE_ANTIALIAS_ON;
}

/* (non-Javadoc)
 * @see java.awt.font.FontRenderContext#isAntiAliased()
 */
@Override
public boolean isAntiAliased()
{
    return true;
}

}

import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.image.BufferedImage;

public class FontMetricsReader
{
public static void main(String[] args)
{
    Font f = new Font("Frutiger55Roman", java.awt.Font.PLAIN, 6);
    BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
    Graphics g = img.getGraphics();
    FontMetrics metrics = g.getFontMetrics(f);

    String str = "The quick brown fox jumps over the lazy dog";

    System.out.println("Rounded text width = " + metrics.stringWidth(str));

    System.out.println("Accurate text width = " + f.getStringBounds(str, new MyFontRenderContext()).getWidth());
}

}
mtanzania
  • 125
  • 2
  • 12
0

TextLayout is probably the most versatile approach. Some related examples may be found among the questions and answers here:

Java2D Graphics anti-aliased.

How to calculate the number of rows (and columns in each row) a text takes in a JTextArea?

Ideal method to truncate a string with ellipsis.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045