aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/embedding/java/embedding/ExampleFO2JPSPrint.java143
-rw-r--r--src/java/org/apache/fop/render/java2d/Java2DRenderer.java30
-rw-r--r--src/java/org/apache/fop/render/print/PageableRenderer.java214
-rw-r--r--src/java/org/apache/fop/render/print/PrintRenderer.java176
4 files changed, 382 insertions, 181 deletions
diff --git a/examples/embedding/java/embedding/ExampleFO2JPSPrint.java b/examples/embedding/java/embedding/ExampleFO2JPSPrint.java
new file mode 100644
index 000000000..a67e2bdad
--- /dev/null
+++ b/examples/embedding/java/embedding/ExampleFO2JPSPrint.java
@@ -0,0 +1,143 @@
+/*
+ * 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;
+
+// Java
+import java.io.File;
+import java.io.IOException;
+
+import javax.print.Doc;
+import javax.print.DocFlavor;
+import javax.print.DocPrintJob;
+import javax.print.PrintException;
+import javax.print.PrintService;
+import javax.print.PrintServiceLookup;
+import javax.print.ServiceUI;
+import javax.print.SimpleDoc;
+import javax.print.attribute.HashPrintRequestAttributeSet;
+import javax.print.attribute.PrintRequestAttributeSet;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.sax.SAXResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.Fop;
+import org.apache.fop.apps.FopFactory;
+import org.apache.fop.render.print.PageableRenderer;
+
+/**
+ * This class demonstrates printing an FO file using JPS (Java Printing System).
+ */
+public class ExampleFO2JPSPrint {
+
+ // configure fopFactory as desired
+ private FopFactory fopFactory = FopFactory.newInstance();
+
+ private DocPrintJob createDocPrintJob() {
+ PrintService[] services = PrintServiceLookup.lookupPrintServices(
+ DocFlavor.SERVICE_FORMATTED.PAGEABLE, null);
+ PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();
+ PrintService printService = ServiceUI.printDialog(null, 50, 50,
+ services, services[0], null, attributes);
+ if (printService != null) {
+ return printService.createPrintJob();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Prints an FO file using JPS.
+ * @param fo the FO file
+ * @throws IOException In case of an I/O problem
+ * @throws FOPException In case of a FOP problem
+ * @throws TransformerException In case of a problem during XSLT processing
+ * @throws PrintException If an error occurs while printing
+ */
+ public void printFO(File fo)
+ throws IOException, FOPException, TransformerException, PrintException {
+
+ //Set up DocPrintJob instance
+ DocPrintJob printJob = createDocPrintJob();
+
+ //Set up a custom user agent so we can supply our own renderer instance
+ FOUserAgent userAgent = fopFactory.newFOUserAgent();
+
+ PageableRenderer renderer = new PageableRenderer();
+ renderer.setUserAgent(userAgent);
+ userAgent.setRendererOverride(renderer);
+
+ // Construct FOP with desired output format
+ Fop fop = fopFactory.newFop(userAgent);
+
+ // Setup JAXP using identity transformer
+ TransformerFactory factory = TransformerFactory.newInstance();
+ Transformer transformer = factory.newTransformer(); // identity transformer
+
+ // Setup input stream
+ Source src = new StreamSource(fo);
+
+ // Resulting SAX events (the generated FO) must be piped through to FOP
+ Result res = new SAXResult(fop.getDefaultHandler());
+
+ // Start XSLT transformation and FOP processing
+ transformer.transform(src, res);
+
+ Doc doc = new SimpleDoc(renderer, DocFlavor.SERVICE_FORMATTED.PAGEABLE, null);
+ printJob.print(doc, null);
+ }
+
+ /**
+ * Main method.
+ * @param args command-line arguments
+ */
+ public static void main(String[] args) {
+ try {
+ System.out.println("FOP ExampleFO2JPSPrint\n");
+ System.out.println("Preparing...");
+
+ //Setup directories
+ File baseDir = new File(".");
+ File outDir = new File(baseDir, "out");
+ outDir.mkdirs();
+
+ //Setup input and output files
+ File fofile = new File(baseDir, "xml/fo/helloworld.fo");
+
+ System.out.println("Input: XSL-FO (" + fofile + ")");
+ System.out.println("Output: JPS (Java Printing System)");
+ System.out.println();
+ System.out.println("Transforming...");
+
+ ExampleFO2JPSPrint app = new ExampleFO2JPSPrint();
+ app.printFO(fofile);
+
+ System.out.println("Success!");
+ } catch (Exception e) {
+ e.printStackTrace(System.err);
+ System.exit(-1);
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/render/java2d/Java2DRenderer.java b/src/java/org/apache/fop/render/java2d/Java2DRenderer.java
index 1f3194949..db8ed6250 100644
--- a/src/java/org/apache/fop/render/java2d/Java2DRenderer.java
+++ b/src/java/org/apache/fop/render/java2d/Java2DRenderer.java
@@ -198,6 +198,7 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem
/** {@inheritDoc} */
public void startRenderer(OutputStream out) throws IOException {
+ super.startRenderer(out);
// do nothing by default
}
@@ -232,7 +233,9 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem
}
/**
+ * Returns the number of pages available. This method is also part of the Pageable interface.
* @return The 0-based total number of rendered pages
+ * @see java.awt.print.Pageable
*/
public int getNumberOfPages() {
return pageViewportList.size();
@@ -250,7 +253,7 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem
/**
* This method override only stores the PageViewport in a List. No actual
* rendering is performed here. A renderer override renderPage() to get the
- * freshly produced PageViewport, and rendere them on the fly (producing the
+ * freshly produced PageViewport, and render them on the fly (producing the
* desired BufferedImages by calling getPageImage(), which lazily starts the
* rendering process).
*
@@ -260,12 +263,23 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem
* @see org.apache.fop.render.Renderer
*/
public void renderPage(PageViewport pageViewport) throws IOException {
- // TODO clone?
- pageViewportList.add(pageViewport.clone());
+ rememberPage((PageViewport)pageViewport.clone());
+ //The clone() call is necessary as we store the page for later. Otherwise, the
+ //RenderPagesModel calls PageViewport.clear() to release memory as early as possible.
currentPageNumber++;
}
/**
+ * Stores the pageViewport in a list of page viewports so they can be rendered later.
+ * Subclasses can override this method to filter pages, for example.
+ * @param pageViewport the page viewport
+ */
+ protected void rememberPage(PageViewport pageViewport) {
+ assert pageViewport.getPageIndex() >= 0;
+ pageViewportList.add(pageViewport);
+ }
+
+ /**
* Generates a desired page from the renderer's page viewport list.
*
* @param pageViewport the PageViewport to be rendered
@@ -362,17 +376,17 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem
/**
* Returns a page viewport.
- * @param pageNum the page number
+ * @param pageIndex the page index (zero-based)
* @return the requested PageViewport instance
* @exception FOPException If the page is out of range.
*/
- public PageViewport getPageViewport(int pageNum) throws FOPException {
- if (pageNum < 0 || pageNum >= pageViewportList.size()) {
- throw new FOPException("Requested page number is out of range: " + pageNum
+ public PageViewport getPageViewport(int pageIndex) throws FOPException {
+ if (pageIndex < 0 || pageIndex >= pageViewportList.size()) {
+ throw new FOPException("Requested page number is out of range: " + pageIndex
+ "; only " + pageViewportList.size()
+ " page(s) available.");
}
- return (PageViewport) pageViewportList.get(pageNum);
+ return (PageViewport) pageViewportList.get(pageIndex);
}
/**
diff --git a/src/java/org/apache/fop/render/print/PageableRenderer.java b/src/java/org/apache/fop/render/print/PageableRenderer.java
new file mode 100644
index 000000000..947708cef
--- /dev/null
+++ b/src/java/org/apache/fop/render/print/PageableRenderer.java
@@ -0,0 +1,214 @@
+/*
+ * 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.render.print;
+
+import java.awt.geom.Rectangle2D;
+import java.awt.print.PageFormat;
+import java.awt.print.Pageable;
+import java.awt.print.Paper;
+import java.awt.print.Printable;
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.area.PageViewport;
+import org.apache.fop.render.java2d.Java2DRenderer;
+
+/**
+ * Renderer that prints through java.awt.PrintJob.
+ * The actual printing is handled by Java2DRenderer
+ * since both PrintRenderer and AWTRenderer need to
+ * support printing.
+ */
+public class PageableRenderer extends Java2DRenderer implements Pageable {
+
+ /**
+ * Printing parameter: the pages to be printed (all, even or odd),
+ * datatype: the strings "all", "even" or "odd" or one of PagesMode.*
+ */
+ public static final String PAGES_MODE = "even-odd";
+
+ /**
+ * Printing parameter: the page number (1-based) of the first page to be printed,
+ * datatype: a positive Integer
+ */
+ public static final String START_PAGE = "start-page";
+
+ /**
+ * Printing parameter: the page number (1-based) of the last page to be printed,
+ * datatype: a positive Integer
+ */
+ public static final String END_PAGE = "end-page";
+
+
+ /** first valid page number (1-based) */
+ protected int startNumber = 0;
+ /** last valid page number (1-based) */
+ protected int endNumber = -1;
+
+ /** indicates which pages are valid: odd, even or all */
+ protected PagesMode mode = PagesMode.ALL;
+
+ private PageFilter pageFilter;
+
+ /**
+ * Creates a new PageableRenderer.
+ */
+ public PageableRenderer() {
+ }
+
+ /** {@inheritDoc} */
+ public void setUserAgent(FOUserAgent agent) {
+ super.setUserAgent(agent);
+
+ Map rendererOptions = agent.getRendererOptions();
+ processOptions(rendererOptions);
+ this.pageFilter = new DefaultPageFilter();
+ }
+
+ private void processOptions(Map rendererOptions) {
+ Object o = rendererOptions.get(PageableRenderer.PAGES_MODE);
+ if (o != null) {
+ if (o instanceof PagesMode) {
+ this.mode = (PagesMode)o;
+ } else if (o instanceof String) {
+ this.mode = PagesMode.byName((String)o);
+ } else {
+ throw new IllegalArgumentException(
+ "Renderer option " + PageableRenderer.PAGES_MODE
+ + " must be an 'all', 'even', 'odd' or a PagesMode instance.");
+ }
+ }
+
+ o = rendererOptions.get(PageableRenderer.START_PAGE);
+ if (o != null) {
+ this.startNumber = getPositiveInteger(o);
+ }
+ o = rendererOptions.get(PageableRenderer.END_PAGE);
+ if (o != null) {
+ this.endNumber = getPositiveInteger(o);
+ }
+ if (this.endNumber >= 0 && this.endNumber < this.endNumber) {
+ this.endNumber = this.startNumber;
+ }
+ }
+
+ /**
+ * Converts an object into a positive integer value if possible. The method throws an
+ * {@link IllegalArgumentException} if the value is invalid.
+ * @param o the object to be converted
+ * @return the positive integer
+ */
+ protected int getPositiveInteger(Object o) {
+ if (o instanceof Integer) {
+ Integer i = (Integer)o;
+ if (i.intValue() < 1) {
+ throw new IllegalArgumentException(
+ "Value must be a positive Integer");
+ }
+ return i.intValue();
+ } else if (o instanceof String) {
+ return Integer.parseInt((String)o);
+ } else {
+ throw new IllegalArgumentException(
+ "Value must be a positive integer");
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void stopRenderer() throws IOException {
+ super.stopRenderer();
+
+ if (endNumber == -1) {
+ // was not set on command line
+ endNumber = getNumberOfPages();
+ }
+ }
+
+ /** {@inheritDoc} */
+ protected void rememberPage(PageViewport pageViewport) {
+ if (this.pageFilter.isValid(pageViewport)) {
+ super.rememberPage(pageViewport);
+ }
+ }
+
+ private interface PageFilter {
+ boolean isValid(PageViewport page);
+ }
+
+ private class DefaultPageFilter implements PageFilter {
+
+ public boolean isValid(PageViewport page) {
+ int pageNum = page.getPageIndex() + 1;
+ assert pageNum >= 0;
+ if (pageNum < startNumber || (endNumber >= 0 && pageNum > endNumber)) {
+ return false;
+ } else if (mode != PagesMode.ALL) {
+ if (mode == PagesMode.EVEN && (pageNum % 2 != 0)) {
+ return false;
+ } else if (mode == PagesMode.ODD && (pageNum % 2 == 0)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ /** {@inheritDoc} */
+ public PageFormat getPageFormat(int pageIndex)
+ throws IndexOutOfBoundsException {
+ try {
+ if (pageIndex >= getNumberOfPages()) {
+ return null;
+ }
+
+ PageFormat pageFormat = new PageFormat();
+
+ Paper paper = new Paper();
+
+ Rectangle2D dim = getPageViewport(pageIndex).getViewArea();
+ double width = dim.getWidth();
+ double height = dim.getHeight();
+
+ // if the width is greater than the height assume landscape mode
+ // and swap the width and height values in the paper format
+ if (width > height) {
+ paper.setImageableArea(0, 0, height / 1000d, width / 1000d);
+ paper.setSize(height / 1000d, width / 1000d);
+ pageFormat.setOrientation(PageFormat.LANDSCAPE);
+ } else {
+ paper.setImageableArea(0, 0, width / 1000d, height / 1000d);
+ paper.setSize(width / 1000d, height / 1000d);
+ pageFormat.setOrientation(PageFormat.PORTRAIT);
+ }
+ pageFormat.setPaper(paper);
+ return pageFormat;
+ } catch (FOPException fopEx) {
+ throw new IndexOutOfBoundsException(fopEx.getMessage());
+ }
+ }
+
+ /** {@inheritDoc} */
+ public Printable getPrintable(int pageIndex)
+ throws IndexOutOfBoundsException {
+ return this;
+ }
+}
diff --git a/src/java/org/apache/fop/render/print/PrintRenderer.java b/src/java/org/apache/fop/render/print/PrintRenderer.java
index 2774b5373..888776ecb 100644
--- a/src/java/org/apache/fop/render/print/PrintRenderer.java
+++ b/src/java/org/apache/fop/render/print/PrintRenderer.java
@@ -19,20 +19,12 @@
package org.apache.fop.render.print;
-import java.awt.geom.Rectangle2D;
-import java.awt.print.PageFormat;
-import java.awt.print.Pageable;
-import java.awt.print.Paper;
-import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.IOException;
import java.util.Map;
-import java.util.Vector;
-import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
-import org.apache.fop.render.java2d.Java2DRenderer;
/**
* Renderer that prints through java.awt.PrintJob.
@@ -40,7 +32,7 @@ import org.apache.fop.render.java2d.Java2DRenderer;
* since both PrintRenderer and AWTRenderer need to
* support printing.
*/
-public class PrintRenderer extends Java2DRenderer implements Pageable {
+public class PrintRenderer extends PageableRenderer {
/**
* Printing parameter: the preconfigured PrinterJob to use,
@@ -49,45 +41,21 @@ public class PrintRenderer extends Java2DRenderer implements Pageable {
public static final String PRINTER_JOB = "printerjob";
/**
- * Printing parameter: the pages to be printed (all, even or odd),
- * datatype: the strings "all", "even" or "odd" or one of PagesMode.*
- */
- public static final String PAGES_MODE = "even-odd";
-
- /**
- * Printing parameter: the page number (1-based) of the first page to be printed,
- * datatype: a positive Integer
- */
- public static final String START_PAGE = "start-page";
-
- /**
- * Printing parameter: the page number (1-based) of the last page to be printed,
- * datatype: a positive Integer
- */
- public static final String END_PAGE = "end-page";
-
- /**
* Printing parameter: the number of copies of the document to be printed,
* datatype: a positive Integer
*/
public static final String COPIES = "copies";
- private int startNumber = 0;
- private int endNumber = -1;
-
- private PagesMode mode = PagesMode.ALL;
-
private int copies = 1;
private PrinterJob printerJob;
/**
- * Creates a new PrintRenderer with the options set from system properties if a custom
+ * Creates a new PrintRenderer with the options set through the renderer options if a custom
* PrinterJob is not given in FOUserAgent's renderer options.
*/
public PrintRenderer() {
- setupFromSystemProperties();
}
/**
@@ -117,18 +85,6 @@ public class PrintRenderer extends Java2DRenderer implements Pageable {
}
}
- private void setupFromSystemProperties() {
- //TODO Remove me! This is not a beautiful way to do this.
- // read from command-line options
- copies = getIntProperty("copies", 1);
- startNumber = getIntProperty("start", 1);
- endNumber = getIntProperty("end", -1);
- String str = System.getProperty("even");
- if (str != null) {
- mode = Boolean.valueOf(str).booleanValue() ? PagesMode.EVEN : PagesMode.ODD;
- }
- }
-
/** {@inheritDoc} */
public void setUserAgent(FOUserAgent agent) {
super.setUserAgent(agent);
@@ -146,53 +102,13 @@ public class PrintRenderer extends Java2DRenderer implements Pageable {
printerJob = (PrinterJob)printerJobO;
printerJob.setPageable(this);
}
- Object o = rendererOptions.get(PrintRenderer.PAGES_MODE);
- if (o != null) {
- if (o instanceof PagesMode) {
- this.mode = (PagesMode)o;
- } else if (o instanceof String) {
- this.mode = PagesMode.byName((String)o);
- } else {
- throw new IllegalArgumentException(
- "Renderer option " + PrintRenderer.PAGES_MODE
- + " must be an 'all', 'even', 'odd' or a PagesMode instance.");
- }
- }
-
- o = rendererOptions.get(PrintRenderer.START_PAGE);
- if (o != null) {
- this.startNumber = getPositiveInteger(o);
- }
- o = rendererOptions.get(PrintRenderer.END_PAGE);
- if (o != null) {
- this.endNumber = getPositiveInteger(o);
- }
- if (this.endNumber >= 0 && this.endNumber < this.endNumber) {
- this.endNumber = this.startNumber;
- }
- o = rendererOptions.get(PrintRenderer.COPIES);
+ Object o = rendererOptions.get(PrintRenderer.COPIES);
if (o != null) {
this.copies = getPositiveInteger(o);
}
initializePrinterJob();
}
- private int getPositiveInteger(Object o) {
- if (o instanceof Integer) {
- Integer i = (Integer)o;
- if (i.intValue() < 1) {
- throw new IllegalArgumentException(
- "Value must be a positive Integer");
- }
- return i.intValue();
- } else if (o instanceof String) {
- return Integer.parseInt((String)o);
- } else {
- throw new IllegalArgumentException(
- "Value must be a positive integer");
- }
- }
-
/** @return the PrinterJob instance that this renderer prints to */
public PrinterJob getPrinterJob() {
return this.printerJob;
@@ -228,17 +144,6 @@ public class PrintRenderer extends Java2DRenderer implements Pageable {
public void stopRenderer() throws IOException {
super.stopRenderer();
- if (endNumber == -1) {
- // was not set on command line
- endNumber = getNumberOfPages();
- }
-
- Vector numbers = getInvalidPageNumbers();
- for (int i = numbers.size() - 1; i > -1; i--) {
- int page = ((Integer)numbers.elementAt(i)).intValue();
- pageViewportList.remove(page - 1);
- }
-
try {
printerJob.print();
} catch (PrinterException e) {
@@ -249,79 +154,4 @@ public class PrintRenderer extends Java2DRenderer implements Pageable {
clearViewportList();
}
- private static int getIntProperty(String name, int def) {
- String propValue = System.getProperty(name);
- if (propValue != null) {
- try {
- return Integer.parseInt(propValue);
- } catch (Exception e) {
- return def;
- }
- } else {
- return def;
- }
- }
-
- private Vector getInvalidPageNumbers() {
- Vector vec = new Vector();
- int max = getNumberOfPages();
- boolean isValid;
- for (int i = 1; i <= max; i++) {
- isValid = true;
- if (i < startNumber || i > endNumber) {
- isValid = false;
- } else if (mode != PagesMode.ALL) {
- if (mode == PagesMode.EVEN && (i % 2 != 0)) {
- isValid = false;
- } else if (mode == PagesMode.ODD && (i % 2 == 0)) {
- isValid = false;
- }
- }
-
- if (!isValid) {
- vec.add(new Integer(i));
- }
- }
- return vec;
- }
-
- /** {@inheritDoc} */
- public PageFormat getPageFormat(int pageIndex)
- throws IndexOutOfBoundsException {
- try {
- if (pageIndex >= getNumberOfPages()) {
- return null;
- }
-
- PageFormat pageFormat = new PageFormat();
-
- Paper paper = new Paper();
-
- Rectangle2D dim = getPageViewport(pageIndex).getViewArea();
- double width = dim.getWidth();
- double height = dim.getHeight();
-
- // if the width is greater than the height assume lanscape mode
- // and swap the width and height values in the paper format
- if (width > height) {
- paper.setImageableArea(0, 0, height / 1000d, width / 1000d);
- paper.setSize(height / 1000d, width / 1000d);
- pageFormat.setOrientation(PageFormat.LANDSCAPE);
- } else {
- paper.setImageableArea(0, 0, width / 1000d, height / 1000d);
- paper.setSize(width / 1000d, height / 1000d);
- pageFormat.setOrientation(PageFormat.PORTRAIT);
- }
- pageFormat.setPaper(paper);
- return pageFormat;
- } catch (FOPException fopEx) {
- throw new IndexOutOfBoundsException(fopEx.getMessage());
- }
- }
-
- /** {@inheritDoc} */
- public Printable getPrintable(int pageIndex)
- throws IndexOutOfBoundsException {
- return this;
- }
}