Какой API возвращает правильную ширину шрифта в Java?

Какой API шрифтов Java возвращает правильную ширину? Мы используем в настоящее время

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

Это возвращает правильные значения для изображений и отображения. Но при печати с Java SE 6 это неправильно. С Java 7 все правильно. Разница очень мала. Но мы потеряли одну "i" в конце строки. Мы получаем на печать точно такие же значения. А вот тексту нужно больше места на печатной графике.

Мы используем сглаживание и дробные метрики.

Я знаю, что есть разные API. Но какой рекомендуемый API?


person Horcrux7    schedule 27.05.2011    source источник


Ответы (3)


У вас есть объект Graphics для принтера? Что в таком случае произойдет, если вы протестируете этот код? Это то, что я использую для измерения ширины:

/*
Graphics2D g
Font currentFont
String stringToMeasure
*/
FontMetrics currentFontMetrics = g.getFontMetrics(currentFont);
Rectangle2D stringBounds = currentFontMetrics.getStringBounds(stringToMeasure, g);
double width = stringBounds.getWidth();
person Kaj    schedule 27.05.2011
comment
Он возвращает точно такое же значение. - person Horcrux7; 06.06.2011
comment
облом, а вы использовали графический объект для принтера? - person Kaj; 06.06.2011
comment
Да, конечно, я использую графику принтера. Я взломал проблему сейчас. При печати я увеличиваю рассчитанную ширину с коэффициентом 1,005. - person Horcrux7; 07.06.2011

TextLayout, пожалуй, самый универсальный подход. Некоторые связанные примеры можно найти среди вопросов и ответов здесь:

Java2D Graphics со сглаживанием.

Как рассчитать количество строк (и столбцов в каждой строке), которое занимает текст в JTextArea?

Идеальный метод для усечения строки многоточием.

person trashgod    schedule 27.05.2011
comment
new TextLayout(str,font,frc).getAdvance() возвращает точно такое же значение. - person Horcrux7; 06.06.2011

Java по умолчанию округляет все метрики шрифтов, поскольку предполагается, что вы пытаетесь отобразить их на экране, что вам нужно для расширения FontRenderContext и включения FractionalMetricsHint, как показано ниже. Затем используйте это, чтобы передать контекст рендеринга шрифта.

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());
}

}
person mtanzania    schedule 18.12.2012