Using java2d user space measurements with TextLayout and LineBreakMeasurer
- by Andrew Wheeler
I have a java2d image defined in user space (mm) to print an identity card. The transformation to pixels is by using an AffineTransform for the required DPI (Screen or print).
I want to wrap text across several lines but the the TextLayout does not respect user space co-ordinates.
private void drawParagraph(Graphics2D g2d, Rectangle2D area, String text) {
LineBreakMeasurer lineMeasurer;
AttributedString string = new AttributedString(text);
AttributedCharacterIterator paragraph = string.getIterator();
int paragraphStart = paragraph.getBeginIndex();
int paragraphEnd = paragraph.getEndIndex();
FontRenderContext frc = g2d.getFontRenderContext();
lineMeasurer = new LineBreakMeasurer(paragraph, frc);
float breakWidth = (float)area.getWidth();
float drawPosY = (float)area.getY();
float drawPosX = (float)area.getX();
lineMeasurer.setPosition(paragraphStart);
while (lineMeasurer.getPosition() < paragraphEnd) {
TextLayout layout = lineMeasurer.nextLayout(breakWidth);
drawPosY += layout.getAscent();
layout.draw(g2d, drawPosX, drawPosY);
drawPosY += layout.getDescent() + layout.getLeading();
}
}
The above code determines font metrics using user space sizing of the Font and thus turn out rather large. The font size is calculated as best vertical fit for the number of lines in an area with the calculation as below. E.g.
attr.put(TextAttribute.SIZE, (geTextArea().getHeight() / noOfLines - LINE_SPACING) );
When using
g2d.drawString("Some text to display", x, y);
the font size appears correct.
Does anyone have a better way of doing text layout in user space co-ords?