]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Restored PDFDocumentGraphics2D functionality.
authorJeremias Maerki <jeremias@apache.org>
Sat, 15 Oct 2011 10:32:15 +0000 (10:32 +0000)
committerJeremias Maerki <jeremias@apache.org>
Sat, 15 Oct 2011 10:32:15 +0000 (10:32 +0000)
Bugfix: NPE after PDFDocumentGraphics2D.create() due to missing font setup and other missing initializations.
Bugfix: Properly handle state in PDFGraphics2D.drawString().
Added an example class demonstrating the use of PDFDocumentGraphics2D.

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1183620 13f79535-47bb-0310-9956-ffa450edef68

examples/embedding/java/embedding/ExampleJava2D2PDF.java [new file with mode: 0644]
src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java
src/java/org/apache/fop/svg/PDFGraphics2D.java
status.xml
test/java/org/apache/fop/UtilityCodeTestSuite.java
test/java/org/apache/fop/pdf/PDFDocumentGraphics2DTestCase.java [new file with mode: 0644]

diff --git a/examples/embedding/java/embedding/ExampleJava2D2PDF.java b/examples/embedding/java/embedding/ExampleJava2D2PDF.java
new file mode 100644 (file)
index 0000000..ff98071
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package embedding;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.StringReader;
+
+import javax.swing.JEditorPane;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.configuration.DefaultConfiguration;
+import org.apache.commons.io.IOUtils;
+
+import org.apache.xmlgraphics.util.UnitConv;
+
+import org.apache.fop.svg.PDFDocumentGraphics2D;
+import org.apache.fop.svg.PDFDocumentGraphics2DConfigurator;
+
+/**
+ * This example class demonstrates the use of {@link PDFDocumentGraphics2D} that can be
+ * used to create a PDF file from Java2D graphics (using the {@link Graphics2D} API).
+ */
+public class ExampleJava2D2PDF {
+
+    private Configuration createAutoFontsConfiguration() {
+        //Create a default configuration using auto-detection of fonts.
+        //This can be a bit slow but covers most use cases.
+        DefaultConfiguration c = new DefaultConfiguration("cfg");
+        DefaultConfiguration fonts = new DefaultConfiguration("fonts");
+        c.addChild(fonts);
+        DefaultConfiguration autodetect = new DefaultConfiguration("auto-detect");
+        fonts.addChild(autodetect);
+        return c;
+
+        /* You can also load the configuration from a file:
+        DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder();
+        return cfgBuilder.buildFromFile(configFile);
+        */
+    }
+
+    private void configure(PDFDocumentGraphics2D g2d, Configuration cfg)
+                throws ConfigurationException {
+
+        PDFDocumentGraphics2DConfigurator configurator = new PDFDocumentGraphics2DConfigurator();
+        configurator.configure(g2d, cfg);
+    }
+
+    /**
+     * Creates a PDF file. The contents are painted using a Graphics2D implementation that
+     * generates an PDF file.
+     * @param outputFile the target file
+     * @throws IOException In case of an I/O error
+     * @throws ConfigurationException if an error occurs configuring the PDF output
+     */
+    public void generatePDF(File outputFile) throws IOException, ConfigurationException {
+        OutputStream out = new java.io.FileOutputStream(outputFile);
+        out = new java.io.BufferedOutputStream(out);
+        try {
+
+            //Instantiate the PDFDocumentGraphics2D instance
+            PDFDocumentGraphics2D g2d = new PDFDocumentGraphics2D(false);
+            g2d.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());
+
+            //Configure the G2D with the necessary fonts
+            configure(g2d, createAutoFontsConfiguration());
+
+            //Set up the document size
+            Dimension pageSize = new Dimension(
+                    (int)Math.ceil(UnitConv.mm2pt(210)),
+                    (int)Math.ceil(UnitConv.mm2pt(297))); //page size A4 (in pt)
+            g2d.setupDocument(out, pageSize.width, pageSize.height);
+            g2d.translate(144, 72); //Establish some page borders
+
+            //A few rectangles rotated and with different color
+            Graphics2D copy = (Graphics2D)g2d.create();
+            int c = 12;
+            for (int i = 0; i < c; i++) {
+                float f = ((i + 1) / (float)c);
+                Color col = new Color(0.0f, 1 - f, 0.0f);
+                copy.setColor(col);
+                copy.fillRect(70, 90, 50, 50);
+                copy.rotate(-2 * Math.PI / c, 70, 90);
+            }
+            copy.dispose();
+
+            //Some text
+            g2d.rotate(-0.25);
+            g2d.setColor(Color.RED);
+            g2d.setFont(new Font("sans-serif", Font.PLAIN, 36));
+            g2d.drawString("Hello world!", 140, 140);
+            g2d.setColor(Color.RED.darker());
+            g2d.setFont(new Font("serif", Font.PLAIN, 36));
+            g2d.drawString("Hello world!", 140, 180);
+
+            g2d.nextPage();
+
+            //Demonstrate painting rich text
+            String someHTML = "<html><body style=\"font-family:Verdana\">"
+                + "<p>Welcome to <b>page 2!</b></p>"
+                + "<h2>PDFDocumentGraphics2D Demonstration</h2>"
+                + "<p>We can <i>easily</i> paint some HTML here!</p>"
+                + "<p style=\"color:green;\">"
+                + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin accumsan"
+                + " condimentum ullamcorper. Sed varius quam id arcu fermentum luctus. Praesent"
+                + " nisi ligula, cursus sed vestibulum vel, sodales sed lectus.</p>"
+                + "</body></html>";
+            JEditorPane htmlComp = new JEditorPane();
+            htmlComp.setContentType("text/html");
+            htmlComp.read(new StringReader(someHTML), null);
+            htmlComp.setSize(new Dimension(pageSize.width - 72, pageSize.height - 72));
+            //htmlComp.setBackground(Color.ORANGE);
+            htmlComp.validate();
+            htmlComp.printAll(g2d);
+
+            //Cleanup
+            g2d.finish();
+        } finally {
+            IOUtils.closeQuietly(out);
+        }
+    }
+
+    /**
+     * Main method.
+     * @param args command-line arguments
+     */
+    public static void main(String[] args) {
+        try {
+            System.out.println("FOP " + ExampleJava2D2PDF.class.getSimpleName() + "\n");
+            System.out.println("Preparing...");
+
+            //Setup directories
+            File baseDir = new File(".");
+            File outDir = new File(baseDir, "out");
+            if (!outDir.isDirectory()) {
+                if (!outDir.mkdirs()) {
+                    throw new IOException("Could not create output directory: " + outDir);
+                }
+            }
+
+            //Setup output file
+            File pdffile = new File(outDir, "ResultJava2D2PDF.pdf");
+
+            System.out.println("Output: PDF (" + pdffile + ")");
+            System.out.println();
+            System.out.println("Generating...");
+
+            ExampleJava2D2PDF app = new ExampleJava2D2PDF();
+            app.generatePDF(pdffile);
+
+            System.out.println("Success!");
+        } catch (Throwable t) {
+            t.printStackTrace(System.err);
+            System.exit(-1);
+        }
+    }
+}
index 829d8972d6f49a125d45e0abbb16af3a09281769..f8f14cca28a7fd921dbca3ccbb31b5c62a32d9de 100644 (file)
@@ -276,6 +276,7 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D {
     }
 
     /** {@inheritDoc} */
+    @Override
     protected void preparePainting() {
         if (pdfContext.isPagePending()) {
             return;
@@ -391,7 +392,9 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D {
      * @return     a new graphics context that is a copy of
      * this graphics context.
      */
+    @Override
     public Graphics create() {
+        preparePainting();
         return new PDFDocumentGraphics2D(this);
     }
 
@@ -403,6 +406,7 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D {
      * @param x the x position
      * @param y the y position
      */
+    @Override
     public void drawString(String s, float x, float y) {
         if (super.textAsShapes) {
             Font font = super.getFont();
index 4ae8e72d7f6b604a6d7d945441cb9b1b4dc89c2d..0d25e166c7ece47c6c36f1b96d5f466b4cf03b33 100644 (file)
@@ -751,10 +751,14 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand
         }
 
         boolean doWrite = false;
-        if (fill && paintingState.setBackColor(col)) {
-            doWrite = true;
-        } else if (paintingState.setColor(col)) {
-            doWrite = true;
+        if (fill) {
+            if (paintingState.setBackColor(col)) {
+                doWrite = true;
+            }
+        } else {
+            if (paintingState.setColor(col)) {
+                doWrite = true;
+            }
         }
         if (doWrite) {
             StringBuffer sb = new StringBuffer();
@@ -1327,7 +1331,7 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand
         }
         updateCurrentFont(fontState);
 
-        currentStream.write("q\n");
+        saveGraphicsState();
 
         Color c = getColor();
         applyColor(c, true);
@@ -1402,7 +1406,7 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand
 
         currentStream.write("] TJ\n");
         currentStream.write("ET\n");
-        currentStream.write("Q\n");
+        restoreGraphicsState();
     }
 
     /**
index 117594b79dbd93b426b47b79176b1c0290ff6463..891b62496751b30cb1aa04f0e199001cd597bcf0 100644 (file)
@@ -60,6 +60,9 @@
       documents. Example: the fix of marks layering will be such a case when it's done.
     -->
     <release version="FOP Trunk" date="TBD">
+      <action context="Renderers" dev="JM" type="add">
+        Various bugfixes to make PDFDocumentGraphics2D operational again.
+      </action>
       <action context="Code" dev="PH" type="add" fixes-bug="51962" due-to="Mehdi Houshmand">
         Bugfix for when the last simple-page-master referenced in a page-sequence-master is not
         chosen when force-page-count=odd.
index 37826954e266472958c8fb8a3e7665c626e495d4..442d63f5b298408452a6292a7f21bc3eb2d820d2 100644 (file)
@@ -25,6 +25,7 @@ import org.junit.runners.Suite.SuiteClasses;
 
 import org.apache.fop.events.BasicEventTestCase;
 import org.apache.fop.pdf.FileIDGeneratorTestCase;
+import org.apache.fop.pdf.PDFDocumentGraphics2DTestCase;
 import org.apache.fop.pdf.PDFEncryptionJCETestCase;
 import org.apache.fop.pdf.PDFFactoryTestCase;
 import org.apache.fop.pdf.PDFObjectTestCase;
@@ -51,7 +52,8 @@ import org.apache.fop.util.XMLResourceBundleTestCase;
     FileIDGeneratorTestCase.class,
     PDFFactoryTestCase.class,
     PDFEncryptionJCETestCase.class,
-    BitmapImageUtilTestCase.class
+    BitmapImageUtilTestCase.class,
+    PDFDocumentGraphics2DTestCase.class
 })
 public class UtilityCodeTestSuite {
 }
diff --git a/test/java/org/apache/fop/pdf/PDFDocumentGraphics2DTestCase.java b/test/java/org/apache/fop/pdf/PDFDocumentGraphics2DTestCase.java
new file mode 100644 (file)
index 0000000..c7eff50
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.pdf;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.Graphics2D;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+import org.apache.commons.io.output.ByteArrayOutputStream;
+
+import org.apache.xmlgraphics.util.UnitConv;
+
+import org.apache.fop.svg.PDFDocumentGraphics2D;
+
+/**
+ * Tests for {@link PDFDocumentGraphics2D}.
+ */
+public class PDFDocumentGraphics2DTestCase {
+
+    /**
+     * Does a smoke test on PDFDocumentGraphics2D making sure that nobody accidentally broke
+     * anything serious. It does not check the correctness of the produced PDF.
+     * @throws Exception if an error occurs
+     */
+    @Test
+    public void smokeTest() throws Exception {
+        ByteArrayOutputStream baout = new ByteArrayOutputStream();
+        PDFDocumentGraphics2D g2d = new PDFDocumentGraphics2D(false);
+        g2d.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());
+
+        //Set up the document size
+        Dimension pageSize = new Dimension(
+                (int)Math.ceil(UnitConv.mm2pt(210)),
+                (int)Math.ceil(UnitConv.mm2pt(297))); //page size A4 (in pt)
+        g2d.setupDocument(baout, pageSize.width, pageSize.height);
+
+        //A few rectangles rotated and with different color
+        Graphics2D copy = (Graphics2D)g2d.create();
+        int c = 12;
+        for (int i = 0; i < c; i++) {
+            float f = ((i + 1) / (float)c);
+            Color col = new Color(0.0f, 1 - f, 0.0f);
+            copy.setColor(col);
+            copy.fillRect(70, 90, 50, 50);
+            copy.rotate(-2 * Math.PI / c, 70, 90);
+        }
+        copy.dispose();
+
+        //Some text
+        g2d.rotate(-0.25);
+        g2d.setColor(Color.RED);
+        g2d.setFont(new Font("sans-serif", Font.PLAIN, 36));
+        g2d.drawString("Hello world!", 140, 140);
+        g2d.setColor(Color.RED.darker());
+        g2d.setFont(new Font("serif", Font.PLAIN, 36));
+        g2d.drawString("Hello world!", 140, 180);
+
+        g2d.nextPage(); //Move to next page
+
+        g2d.setFont(new Font("sans-serif", Font.PLAIN, 36));
+        g2d.drawString("Welcome to page 2!", 140, 140);
+
+        //Cleanup
+        g2d.finish();
+
+        String pdfString = baout.toString("ISO-8859-1");
+        Assert.assertEquals("%%EOF not found",
+                pdfString.substring(pdfString.length() - 6), "%%EOF\n");
+    }
+
+}