Hi All, I'm investigating a bug report from a JFreeChart user who is having trouble with text alignment in a PDF file created using JFreeChart and iText. The output is OK on Windows but not quite correct on Linux. I believe the problem is due to an incorrect result from the getStringBounds(...) method in iText's PdfGraphics2D class. I've reproduced the bug using a small application that doesn't depend on JFreeChart, and generates the following output (the problem can be seen by comparing the positions of the text labels at the bottom right of each generated document):
http://www.jfree.org/jfreechart/winXP-itext-1-01.pdf http://www.jfree.org/jfreechart/linux-itext-1-01.pdf Here is the source code for creating the test files above: import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.font.FontRenderContext; import java.awt.font.LineMetrics; import java.awt.geom.Rectangle2D; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.Rectangle; import com.lowagie.text.pdf.DefaultFontMapper; import com.lowagie.text.pdf.FontMapper; import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.PdfTemplate; import com.lowagie.text.pdf.PdfWriter; /** * A test for the font measurements in iText. */ public class Test { public static void saveOutputAsPDF( File file, OutputGenerator outputGenerator, int width, int height, FontMapper mapper) throws IOException { OutputStream out = new BufferedOutputStream(new FileOutputStream(file)); writeOutputAsPDF(out, outputGenerator, width, height, mapper); out.close(); } public static void writeOutputAsPDF( OutputStream out, OutputGenerator outputGenerator, int width, int height, FontMapper mapper) throws IOException { Rectangle pagesize = new Rectangle(width, height); Document document = new Document(pagesize, 50, 50, 50, 50); try { PdfWriter writer = PdfWriter.getInstance(document, out); document.open(); PdfContentByte cb = writer.getDirectContent(); PdfTemplate tp = cb.createTemplate(width, height); Graphics2D g2 = tp.createGraphics(width, height, mapper); Rectangle2D r2D = new Rectangle2D.Double(0, 0, width, height); outputGenerator.draw(g2, r2D); g2.dispose(); cb.addTemplate(tp, 0, 0); } catch (DocumentException de) { System.err.println(de.getMessage()); } document.close(); } public static void main(String[] args) { try { OutputGenerator drawable = new OutputGenerator("iText-1.01", "SuSE Linux 8.2", "Bottom-Right"); String f = System.getProperty("user.home") + "/linux-itext-1-01.pdf"; System.out.println("Filename = " + f); File file = new File(f); saveOutputAsPDF(file, drawable, 100, 72, new DefaultFontMapper()); } catch (IOException e) { System.out.println(e.getMessage()); } } } class OutputGenerator { private String topLeftStr; private String centerStr; private String bottomRightStr; public OutputGenerator(String topLeftStr, String centerStr, String bottomRightStr) { this.topLeftStr = topLeftStr; this.centerStr = centerStr; this.bottomRightStr = bottomRightStr; } public void draw(Graphics2D g2, Rectangle2D area) { // draw an outline... g2.setPaint(Color.red); g2.draw(area); // create/get font information... Font font = new Font("Serif", Font.PLAIN, 12); g2.setFont(font); FontRenderContext frc = g2.getFontRenderContext(); // write some text at the top left of the rectangle LineMetrics lineMetrics = font.getLineMetrics(this.topLeftStr, frc); Rectangle2D bounds = font.getStringBounds(this.topLeftStr, frc); double x = area.getMinX(); double y = area.getMinY() + bounds.getHeight() - lineMetrics.getLeading() - lineMetrics.getDescent(); g2.drawString(this.topLeftStr, (float) x, (float) y); // write some text in the middle of the rectangle bounds = font.getStringBounds(this.centerStr, frc); x = area.getCenterX() - (bounds.getWidth() / 2.0); y = area.getCenterY() + (bounds.getHeight() / 2.0); g2.drawString(this.centerStr, (float) x, (float) y); // write some text at the bottom right of the rectangle bounds = font.getStringBounds(this.bottomRightStr, frc); x = area.getMaxX() - bounds.getWidth(); y = area.getMaxY() - lineMetrics.getDescent() - lineMetrics.getLeading(); g2.drawString(this.bottomRightStr, (float) x, (float) y); } } If there is any more information I can supply, let me know. I'm going to start looking through the iText source code now, but thought I'd report what I had so far. If anyone knows of a workaround (using only Graphics2D) then that would be very helpful. Regards, Dave Gilbert JFreeChart Project Leader P.S. The developer that reported the bug to me has created some fantastic looking reports, so thanks for all the work on the PdfGraphics2D class which makes it possible to use JFreeChart with iText! ------------------------------------------------------- This SF.net email is sponsored by: The SF.net Donation Program. Do you like what SourceForge.net is doing for the Open Source Community? Make a contribution, and help us add new features and functionality. Click here: http://sourceforge.net/donate/ _______________________________________________ iText-questions mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/itext-questions