You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xmlgraphics.apache.org by je...@apache.org on 2007/02/28 17:42:31 UTC

svn commit: r512838 [1/3] - in /xmlgraphics/commons/trunk: examples/java/ps/ src/documentation/content/xdocs/ src/java/org/apache/xmlgraphics/java2d/ps/ src/java/org/apache/xmlgraphics/ps/ src/java/org/apache/xmlgraphics/ps/dsc/ src/java/org/apache/xml...

Author: jeremias
Date: Wed Feb 28 08:42:28 2007
New Revision: 512838

URL: http://svn.apache.org/viewvc?view=rev&rev=512838
Log:
Bugzilla #41582:
Added a PostScript DSC parser as voted on on general@xmlgraphics (grant and IP clearance documents filed and processed).
The PostScript package was extended to include resource tracking. Resources in this context are images or procsets. See the DSC spec for details. This was necessary for handling dependencies within a PostScript file.
Made some method names non-FOP specific.
Deprecated the use of "%%EndPage" DSC comment which is non-standard and strictly speaking illegal. A page is normally ended by a "%%Page", "%%Trailer" or "%%EOF" comment. (See DSCTools.nextPageOrTrailer())
Refined the image writing routines for PostScript images to be able to handle images as PostScript forms.

Added:
    xmlgraphics/commons/trunk/examples/java/ps/
    xmlgraphics/commons/trunk/examples/java/ps/DSCProcessingExample1.java   (with props)
    xmlgraphics/commons/trunk/src/documentation/content/xdocs/postscript.xml   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSProcSet.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCCommentFactory.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCException.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCFilter.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCHandler.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCParser.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCParserConstants.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DefaultDSCHandler.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DefaultNestedDocumentHandler.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/EventRecorder.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/NestedDocumentHandler.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/ResourceTracker.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/events/
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/events/AbstractDSCComment.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/events/AbstractEvent.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/events/AbstractResourcesDSCComment.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/events/DSCAtend.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/events/DSCComment.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentBeginResource.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentDocumentNeededResources.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentDocumentSuppliedResources.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentEndComments.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentEndOfFile.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentLanguageLevel.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentPage.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentPageResources.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/events/DSCCommentPages.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/events/DSCEvent.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/events/DSCHeaderComment.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/events/PostScriptComment.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/events/PostScriptLine.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/events/UnparsedDSCComment.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/events/package.html   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/package.html   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/tools/
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/tools/DSCTools.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/tools/PageExtractor.java   (with props)
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/tools/package.html   (with props)
    xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/ps/
    xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/ps/dsc/
    xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/ps/dsc/events/
    xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/ps/dsc/events/DSCValueParserTestCase.java   (with props)
    xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/ps/dsc/tools/
    xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/ps/dsc/tools/DSCToolsTestCase.java   (with props)
Modified:
    xmlgraphics/commons/trunk/src/documentation/content/xdocs/index.xml
    xmlgraphics/commons/trunk/src/documentation/content/xdocs/site.xml
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/java2d/ps/EPSDocumentGraphics2D.java
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/java2d/ps/PSDocumentGraphics2D.java
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/DSCConstants.java
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSFontUtils.java
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSGenerator.java
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSImageUtils.java
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSProcSets.java
    xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSResource.java
    xmlgraphics/commons/trunk/test/java/org/apache/xmlgraphics/StandardTestSuite.java

Added: xmlgraphics/commons/trunk/examples/java/ps/DSCProcessingExample1.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/examples/java/ps/DSCProcessingExample1.java?view=auto&rev=512838
==============================================================================
--- xmlgraphics/commons/trunk/examples/java/ps/DSCProcessingExample1.java (added)
+++ xmlgraphics/commons/trunk/examples/java/ps/DSCProcessingExample1.java Wed Feb 28 08:42:28 2007
@@ -0,0 +1,101 @@
+/*
+ * 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 ps;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.InputStream;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.xmlgraphics.ps.dsc.DSCException;
+import org.apache.xmlgraphics.ps.dsc.tools.PageExtractor;
+ 
+/**
+ * Demonstrates how the DSC parser can be used to extract a series of pages from a DSC-compliant
+ * PostScript file. For details how this works, please look into the PageExtractor class
+ * where the actual functionality is located. This sample class only calls the code there.
+ */
+public class DSCProcessingExample1 {
+
+    /**
+     * Extracts a series of pages from a DSC-compliant PostScript file.
+     * @param srcFile the source PostScript file
+     * @param tgtFile the target file to write the extracted pages to
+     * @param from the starting page number
+     * @param to the ending page number
+     * @throws IOException In case of an I/O error
+     */
+    public void extractPages(File srcFile, File tgtFile, int from, int to) throws IOException {
+        InputStream in = new java.io.FileInputStream(srcFile);
+        in = new java.io.BufferedInputStream(in);
+        try {
+            OutputStream out = new java.io.FileOutputStream(tgtFile);
+            out = new java.io.BufferedOutputStream(out);
+            try {
+                PageExtractor.extractPages(in, out, from, to);
+            } catch (DSCException e) {
+                throw new RuntimeException(e.getMessage());
+            } finally {
+                IOUtils.closeQuietly(out);
+            }
+        } finally {
+            IOUtils.closeQuietly(in);
+        }
+    }
+    
+    private static void showInfo() {
+        System.out.println(
+                "Call: DSCProcessingExample1 <source-file> <target-file> <from-page> <to-page>");
+    }
+    
+    /**
+     * Command-line interface
+     * @param args command-line arguments
+     */
+    public static void main(String[] args) {
+        try {
+            File srcFile , tgtFile;
+            int from, to;
+            if (args.length >= 4) {
+                srcFile = new File(args[0]);
+                tgtFile = new File(args[1]);
+                from = Integer.parseInt(args[2]);
+                to = Integer.parseInt(args[3]);
+            } else {
+                throw new IllegalArgumentException("Invalid number of parameters!");
+            }
+            if (!srcFile.exists()) {
+                throw new IllegalArgumentException("Source file not found: " + srcFile);
+            }
+            DSCProcessingExample1 app = new DSCProcessingExample1();
+            app.extractPages(srcFile, tgtFile, from, to);
+            System.out.println("File written: " + tgtFile.getCanonicalPath());
+        } catch (IllegalArgumentException iae) {
+            System.err.println(iae.getMessage());
+            showInfo();
+            System.exit(1);
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.exit(-1);
+        }
+    }
+
+}

Propchange: xmlgraphics/commons/trunk/examples/java/ps/DSCProcessingExample1.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: xmlgraphics/commons/trunk/src/documentation/content/xdocs/index.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/documentation/content/xdocs/index.xml?view=diff&rev=512838&r1=512837&r2=512838
==============================================================================
--- xmlgraphics/commons/trunk/src/documentation/content/xdocs/index.xml (original)
+++ xmlgraphics/commons/trunk/src/documentation/content/xdocs/index.xml Wed Feb 28 08:42:28 2007
@@ -81,6 +81,13 @@
           <td>FOP</td>
         </tr>
         <tr>
+          <td>Parser/Processor for DSC-compliant PostScript files (DSC = 
+            <a href="http://partners.adobe.com/public/developer/en/ps/5001.DSC_Spec.pdf">Document Structuring Conventions</a>)
+          </td>
+          <td>org.apache.xmlgraphics.ps.dsc</td>
+          <td>new</td>
+        </tr>
+        <tr>
           <td><a href="http://www.adobe.com/products/xmp/index.html">XMP metadata</a> framework</td>
           <td>org.apache.xmlgraphics.xmp</td>
           <td>new</td>

Added: xmlgraphics/commons/trunk/src/documentation/content/xdocs/postscript.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/documentation/content/xdocs/postscript.xml?view=auto&rev=512838
==============================================================================
--- xmlgraphics/commons/trunk/src/documentation/content/xdocs/postscript.xml (added)
+++ xmlgraphics/commons/trunk/src/documentation/content/xdocs/postscript.xml Wed Feb 28 08:42:28 2007
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN" "http://forrest.apache.org/dtd/document-v20.dtd">
+<document> 
+  <header> 
+    <title>Tools for Adobe PostScript</title> 
+  </header>
+  <body> 
+    <section id="overview">
+      <title>Overview</title>
+      <p>
+        Apache XML Graphics Commons contains various tools for writing and processing Adobe 
+        PostScript files. This includes:
+      </p>
+      <ul>
+        <li>A PostScript generator class which helps writing PostScript files from scratch.</li>
+        <li>Two Graphics2D implementations, one for plain PostScript and one for writing 
+          Encapsulated PostScript (EPS).</li>
+        <li>A DSC-parser/processor: Parse, post-process and change DSC-compliant PostScript files.</li>
+      </ul>
+      <note>
+        We don't currently include a PostScript interpreter though we would love to have one. A
+        Java-based PostScript interpreter to keep an eye on is the one from the
+        <a href="http://foray.sourceforge.net">FOray project</a>.
+      </note>
+    </section>
+    <section id="generator">
+      <title>The PostScript generator</title>
+      <p>
+        The "PSGenerator" class can help writing PostScript files. It deals with things like
+        escaping, saving/tracking/restoring graphics state, writing DSC comments and tracking of
+        DSC resources.        
+      </p>
+      <p>
+        You will rarely interact with the PS generator itself, as it is probably more interesting
+        to generate a PostScript file using Java2D which is described in the following section.
+      </p>
+    </section>
+    <section id="java2d">
+      <title>Java2D: Graphics2D implementation for generating PostScript and EPS</title>
+      <p>
+        We provide two classes (PSDocumentGraphics2D and EPSDocumentGraphics2D) which you can use
+        to generated complete PostScript files using normal Java2D means. The difference between
+        the two classes is that the EPS variant creates a fully compliant Encapsulated
+        PostScript file while the PS variant simply creates a normal DSC-compliant level 2 
+        PostScript file. It depends on your requirement which variant you choose. The PS variant
+        is mostly for printing purposes while the EPS variant is better suited for inclusion in
+        other documents.
+      </p>
+      <section id="creating-eps">
+        <title>Creating an EPS file</title>
+        <p>
+          Creating an EPS file using the Graphics2D implementation is easy. Instantiate
+          EPSDocumentGraphics2D, set a GraphicContext and set up the output document. Here's an
+          example:
+        </p>
+        <source><![CDATA[
+import org.apache.xmlgraphics.java2d.ps.EPSDocumentGraphics2D;
+
+[..]
+
+EPSDocumentGraphics2D g2d = new EPSDocumentGraphics2D(false);
+g2d.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());
+
+//Set up the document size
+g2d.setupDocument(out, 400, 200); //400pt x 200pt
+//out is the OutputStream to write the EPS to
+          
+g2d.drawRect(10, 10, 50, 50); //paint a rectangle using normal Java2D calls
+          
+g2d.finish(); //Wrap up and finalize the EPS file
+        ]]></source>
+        <p>
+          A complete example for generating an EPS files can be found in the 
+          <a href="http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/examples/java/java2d/ps/">"examples" directory</a>
+          in the distribution.
+        </p>
+      </section>
+    </section>
+    <section id="dsc">
+      <title>DSC parser/processor</title>
+      <p>
+        Many PostScript files use special comments to structure a document. This allows manipulation
+        of PostScript files without interpreting them. These special comments are defined in the
+        <a href="http://partners.adobe.com/public/developer/en/ps/5001.DSC_Spec.pdf">Document Structuring Conventions</a>.
+        The code in Commons is designed to work with DSC 3.0. For details on how DSC is used,
+        please take a look at the DSC specification.
+      </p>
+      <p>
+        The DSC support in Commons was primarily developed to implement resource optimization
+        features in <a href="ext:fop">Apache FOP</a>'s PostScript output support. Resources like
+        images which are used repeatedly in a document should not be written to the PostScript
+        file each time it is used. Instead it is written once at the beginning of the file as a 
+        PostScript form. The form is then called whenever the image needs painting. 
+      </p>
+      <p>
+        But the DSC parser could potentially be used for other purposes. The most obvious is
+        extracting a subset of pages from a DSC-compliant file. Assume you want to print only
+        page 45 to 57 of a particular document. There's an example that demonstrates exactly this.
+        Check out the "examples" directory in the distribution. Other potential use cases for the 
+        DSC parser are:
+      </p>
+      <ul>
+        <li>Patching PostScript files, for example, adding OMR marks for automatic packaging</li>
+        <li><a href="http://en.wikipedia.org/wiki/Imposition">Imposition</a> (2-up, n-up, rotation, etc.)</li>
+        <li>EPS graphic extraction</li>
+        <li>Inspecting the page count</li>
+        <li>etc. etc.</li>
+      </ul>
+      <p>
+        The DSC parser (DSCParser) was designed as a pull parser, i.e. you fetch new events from 
+        the parser inspecting them and acting on them as they are found. If you prefer to work 
+        with a push parser, you can pass the DSCParser a DSCHandler implementation and the parser
+        will send you all the events.
+      </p>
+      <p>
+        The best example to understand how to use the DSC parser is the PageExtractor class
+        that implements the page extraction functionality mentioned above.
+      </p>
+      <note>
+        The DSC parser is not considered feature-complete. The basic infrastructure is there but,
+        for example, not all DSC comments are available as concrete Java classes. If you need
+        to extend the DSC parser for your own use cases, please send us your patches.
+      </note>
+    </section>
+  </body>
+</document>

Propchange: xmlgraphics/commons/trunk/src/documentation/content/xdocs/postscript.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/commons/trunk/src/documentation/content/xdocs/postscript.xml
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: xmlgraphics/commons/trunk/src/documentation/content/xdocs/site.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/documentation/content/xdocs/site.xml?view=diff&rev=512838&r1=512837&r2=512838
==============================================================================
--- xmlgraphics/commons/trunk/src/documentation/content/xdocs/site.xml (original)
+++ xmlgraphics/commons/trunk/src/documentation/content/xdocs/site.xml Wed Feb 28 08:42:28 2007
@@ -35,6 +35,9 @@
   <about label="XML Graphics Commons">
     <index label="Overview" href="index.html" description="Overview"/>
     <download label="Download" href="download.html" description="Download"/>
+    <documentation label="Documentation">
+      <postscript label="Tools for Adobe PostScript" href="postscript.html" description="Tools for Adobe PostScript"/>
+    </documentation>
     <information label="Information">
       <mail label="Mailing Lists" href="http://xmlgraphics.apache.org/mail.html" description="Information on Mailing Lists"/>
       <repo label="Code Repositories" href="http://xmlgraphics.apache.org/repo.html" description="Information on Code Repositories"/>

Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/java2d/ps/EPSDocumentGraphics2D.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/java2d/ps/EPSDocumentGraphics2D.java?view=diff&rev=512838&r1=512837&r2=512838
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/java2d/ps/EPSDocumentGraphics2D.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/java2d/ps/EPSDocumentGraphics2D.java Wed Feb 28 08:42:28 2007
@@ -60,7 +60,7 @@
                         + ": EPS Generator for Java2D"});
         gen.writeDSCComment(DSCConstants.CREATION_DATE, 
                     new Object[] {new java.util.Date()});
-        gen.writeDSCComment(DSCConstants.PAGES, new Integer(0));
+        gen.writeDSCComment(DSCConstants.PAGES, DSCConstants.ATEND);
         gen.writeDSCComment(DSCConstants.BBOX, new Object[]
                 {ZERO, ZERO, pagewidth, pageheight});
         gen.writeDSCComment(DSCConstants.LANGUAGE_LEVEL, new Integer(gen.getPSLevel()));
@@ -68,8 +68,8 @@
         
         //Prolog
         gen.writeDSCComment(DSCConstants.BEGIN_PROLOG);
-        PSProcSets.writeFOPStdProcSet(gen);
-        PSProcSets.writeFOPEPSProcSet(gen);
+        PSProcSets.writeStdProcSet(gen);
+        PSProcSets.writeEPSProcSet(gen);
         if (customTextHandler != null) {
             customTextHandler.writeSetup();
         }
@@ -89,8 +89,7 @@
     }
     
     protected void writePageTrailer() throws IOException {
-        gen.writeDSCComment(DSCConstants.PAGE_TRAILER);
-        gen.writeDSCComment(DSCConstants.END_PAGE);
+        //nop, no DSC PageTrailer needed
     }
 
 }

Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/java2d/ps/PSDocumentGraphics2D.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/java2d/ps/PSDocumentGraphics2D.java?view=diff&rev=512838&r1=512837&r2=512838
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/java2d/ps/PSDocumentGraphics2D.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/java2d/ps/PSDocumentGraphics2D.java Wed Feb 28 08:42:28 2007
@@ -24,7 +24,6 @@
 import java.io.IOException;
 
 import org.apache.xmlgraphics.ps.DSCConstants;
-import org.apache.xmlgraphics.ps.PSGenerator;
 import org.apache.xmlgraphics.ps.PSProcSets;
 
 /**
@@ -88,7 +87,7 @@
                         + ": PostScript Generator for Java2D"});
         gen.writeDSCComment(DSCConstants.CREATION_DATE,
                     new Object[] {new java.util.Date()});
-        gen.writeDSCComment(DSCConstants.PAGES, PSGenerator.ATEND);
+        gen.writeDSCComment(DSCConstants.PAGES, DSCConstants.ATEND);
         gen.writeDSCComment(DSCConstants.BBOX, new Object[]
                 {ZERO, ZERO, pagewidth, pageheight});
         gen.writeDSCComment(DSCConstants.END_COMMENTS);
@@ -103,8 +102,8 @@
         
         //Setup
         gen.writeDSCComment(DSCConstants.BEGIN_SETUP);
-        PSProcSets.writeFOPStdProcSet(gen);
-        PSProcSets.writeFOPEPSProcSet(gen);
+        PSProcSets.writeStdProcSet(gen);
+        PSProcSets.writeEPSProcSet(gen);
         if (customTextHandler != null) {
             customTextHandler.writeSetup();
         }
@@ -129,8 +128,6 @@
     
     protected void writePageTrailer() throws IOException {
         gen.writeln("showpage");        
-        gen.writeDSCComment(DSCConstants.PAGE_TRAILER);
-        gen.writeDSCComment(DSCConstants.END_PAGE);
     }
     
     /**

Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/DSCConstants.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/DSCConstants.java?view=diff&rev=512838&r1=512837&r2=512838
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/DSCConstants.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/DSCConstants.java Wed Feb 28 08:42:28 2007
@@ -46,7 +46,7 @@
     public static final String CREATION_DATE     = "CreationDate";
     /** Type of data */
     public static final String DOCUMENT_DATA     = "BoundingBox";
-    /** Use for inidicating an emulator being invoked in the document */
+    /** Use for indicating an emulator being invoked in the document */
     public static final String EMULATION         = "Emulation";
     /** Explicit end of comments */
     public static final String END_COMMENTS      = "EndComments";
@@ -135,7 +135,10 @@
     public static final String PAGE_TRAILER     = "PageTrailer";
     /** Indicates the start of the document trailer */    
     public static final String TRAILER          = "Trailer";
-    /** Indicates the end of a page (NON-STANDARD!) */    
+    /**
+     * Indicates the end of a page (NON-STANDARD!)
+     * @deprecated Shouldn't really use that. Bad idea. "Page" and "Trailer" end a page.
+     */    
     public static final String END_PAGE         = "EndPage";
     /** Indicates the end of the document */    
     public static final String EOF              = "EOF";
@@ -216,4 +219,25 @@
      */
     public static final String PAGE_RESOURCES    = "PageResources";
 
+    // ----==== (atend) indicator ====----
+    
+    /** 
+     * Indicator for the PostScript interpreter that the value is provided 
+     * later in the document (mostly in the %%Trailer section).
+     */
+    public static final Object ATEND = new AtendIndicator();
+
+    /** Used for the ATEND constant. See there. */
+    private static final class AtendIndicator extends Object {
+        
+        private AtendIndicator() {
+            super();
+        }
+        
+        public String toString() {
+            return "(atend)";
+        }
+    }
+
+    
 }

Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSFontUtils.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSFontUtils.java?view=diff&rev=512838&r1=512837&r2=512838
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSFontUtils.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSFontUtils.java Wed Feb 28 08:42:28 2007
@@ -112,5 +112,23 @@
         gen.writeln("] def");
     }
 
+    /**
+     * Redefines the encoding of a font.
+     * @param gen the PostScript generator
+     * @param fontName the font name
+     * @param encoding the new encoding (must be predefined in the PS file)
+     * @throws IOException In case of an I/O problem
+     */
+    public static void redefineFontEncoding(PSGenerator gen, String fontName, String encoding) 
+                throws IOException {
+        gen.writeln("/" + fontName + " findfont");
+        gen.writeln("dup length dict begin");
+        gen.writeln("  {1 index /FID ne {def} {pop pop} ifelse} forall");
+        gen.writeln("  /Encoding " + encoding + " def");
+        gen.writeln("  currentdict");
+        gen.writeln("end");
+        gen.writeln("/" + fontName + " exch definefont pop");
+    }
+
     
 }

Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSGenerator.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSGenerator.java?view=diff&rev=512838&r1=512837&r2=512838
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSGenerator.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSGenerator.java Wed Feb 28 08:42:28 2007
@@ -27,13 +27,13 @@
 import java.text.DecimalFormat;
 import java.text.DecimalFormatSymbols;
 import java.util.Date;
-import java.util.Iterator;
 import java.util.Locale;
-import java.util.Set;
 import java.util.Stack;
 
 import javax.xml.transform.Source;
 
+import org.apache.xmlgraphics.ps.dsc.ResourceTracker;
+
 /**
  * This class is used to output PostScript code to an OutputStream.
  *
@@ -41,17 +41,20 @@
  */
 public class PSGenerator {
 
+    public static final int DEFAULT_LANGUAGE_LEVEL = 3;
+    
     /** 
      * Indicator for the PostScript interpreter that the value is provided 
      * later in the document (mostly in the %%Trailer section).
+     * @deprecated Please use DSCConstants.ATEND. This constant was in the wrong place.
      */
-    public static final AtendIndicator ATEND = new AtendIndicator() {
-    };
+    public static final Object ATEND = DSCConstants.ATEND;
 
     /** Line feed used by PostScript */
     public static final char LF = '\n';
     
     private OutputStream out;
+    private int psLevel = DEFAULT_LANGUAGE_LEVEL;
     private boolean commentsEnabled = true;
     
     private Stack graphicsStateStack = new Stack();
@@ -62,7 +65,10 @@
 
     private StringBuffer tempBuffer = new StringBuffer(256);
 
-    /** @see java.io.FilterOutputStream **/
+    /**
+     * Creates a new instance.
+     * @param out the OutputStream to write the generated PostScript code to
+     */
     public PSGenerator(OutputStream out) {
         this.out = out;
         this.currentState = new PSState();
@@ -79,11 +85,18 @@
 
     /**
      * Returns the selected PostScript level. 
-     * (Hardcoded to level 2 for the moment.)
      * @return the PostScript level
      */
     public int getPSLevel() {
-        return 2; 
+        return this.psLevel; 
+    }
+    
+    /**
+     * Sets the PostScript level that is used to generate the current document.
+     * @param level the PostScript level (currently 1, 2 and 3 are known)
+     */
+    public void setPSLevel(int level) {
+        this.psLevel = level;
     }
     
     /**
@@ -238,6 +251,14 @@
         return convertStringToDSC(text, false);
     }
 
+    /**
+     * Converts a <real> value for use in DSC comments.
+     * @param value the value to convert
+     * @return String The resulting String
+     */
+    public static final String convertRealToDSC(float value) {
+        return Float.toString(value);
+    }
 
     /**
      * Converts text by applying escaping rules established in the DSC specs.
@@ -319,8 +340,8 @@
                 
                 if (params[i] instanceof String) {
                     tempBuffer.append(convertStringToDSC((String)params[i]));
-                } else if (params[i] instanceof AtendIndicator) {
-                    tempBuffer.append("(atend)");
+                } else if (params[i] == DSCConstants.ATEND) {
+                    tempBuffer.append(DSCConstants.ATEND);
                 } else if (params[i] instanceof Double) {
                     tempBuffer.append(df3.format(params[i]));
                 } else if (params[i] instanceof Number) {
@@ -505,96 +526,22 @@
         }
     }
     
-    private Set documentSuppliedResources;
-    private Set documentNeededResources;
-    private Set pageResources;
+    private ResourceTracker resTracker = new ResourceTracker();
     
     /**
-     * Notifies the generator that a new page has been started and that the page resource
-     * set can be cleared.
+     * Resturns the ResourceTracker instance associated with this PSGenerator.
+     * @return the ResourceTracker instance or null if none is assigned
      */
-    public void notifyStartNewPage() {
-        if (pageResources != null) {
-            pageResources.clear();
-        }
+    public ResourceTracker getResourceTracker() {
+        return this.resTracker;
     }
     
     /**
-     * Notifies the generator about the usage of a resource on the current page.
-     * @param res the resource being used
-     * @param needed true if this is a needed resource, false for a supplied resource
+     * Sets the ResourceTracker instance to be associated with this PSGenerator.
+     * @param resTracker the ResourceTracker instance
      */
-    public void notifyResourceUsage(PSResource res, boolean needed) {
-        if (pageResources == null) {
-            pageResources = new java.util.HashSet();
-        }
-        pageResources.add(res);
-        if (needed) {
-            if (documentNeededResources == null) {
-                documentNeededResources = new java.util.HashSet();
-            }
-            documentNeededResources.add(res);
-        } else {
-            if (documentSuppliedResources == null) {
-                documentSuppliedResources = new java.util.HashSet();
-            }
-            documentSuppliedResources.add(res);
-        }
-    }
-
-    /**
-     * Indicates whether a particular resource is supplied, rather than needed.
-     * @param res the resource
-     * @return true if the resource is registered as being supplied.
-     */
-    public boolean isResourceSupplied(PSResource res) {
-        return documentSuppliedResources.contains(res);
-    }
-
-    /**
-     * Writes a DSC comment for the accumulated used resources, either at page level or
-     * at document level.
-     * @param pageLevel true if the DSC comment for the page level should be generated, 
-     *                  false for the document level (in the trailer)
-     * @exception IOException In case of an I/O problem
-     */
-    public void writeResources(boolean pageLevel) throws IOException {
-        if (pageLevel) {
-            writeResourceComment(DSCConstants.PAGE_RESOURCES, pageResources);
-        } else {
-            writeResourceComment(DSCConstants.DOCUMENT_NEEDED_RESOURCES, 
-                    documentNeededResources);
-            writeResourceComment(DSCConstants.DOCUMENT_SUPPLIED_RESOURCES, 
-                    documentSuppliedResources);
-        }
-    }
-    
-    private void writeResourceComment(String name, Set resources) throws IOException {
-        if (resources == null || resources.size() == 0) {
-            return;
-        }
-        tempBuffer.setLength(0);
-        tempBuffer.append("%%");
-        tempBuffer.append(name);
-        tempBuffer.append(" ");
-        boolean first = true;
-        Iterator i = resources.iterator();
-        while (i.hasNext()) {
-            if (!first) {
-                writeln(tempBuffer.toString());
-                tempBuffer.setLength(0);
-                tempBuffer.append("%%+ ");
-            }
-            PSResource res = (PSResource)i.next();
-            tempBuffer.append(res.getResourceSpecification());
-            first = false;
-        }
-        writeln(tempBuffer.toString());
+    public void setResourceTracker(ResourceTracker resTracker) {
+        this.resTracker = resTracker;
     }
     
-    /** Used for the ATEND constant. See there. */
-    private static interface AtendIndicator {
-    }
-
-
 }

Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSImageUtils.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSImageUtils.java?view=diff&rev=512838&r1=512837&r2=512838
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSImageUtils.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSImageUtils.java Wed Feb 28 08:42:28 2007
@@ -43,7 +43,7 @@
      * Writes a bitmap image to the PostScript stream.
      * @param img the bitmap image as a byte array
      * @param imgDim the dimensions of the image
-     * @param imgName the name of the image
+     * @param imgDescription the name of the image
      * @param targetRect the target rectangle to place the image in
      * @param isJPEG true if "img" contains a DCT-encoded images, false if "img" contains the 
      *               decoded bitmap
@@ -52,26 +52,17 @@
      * @throws IOException In case of an I/O exception
      */
     public static void writeImage(byte[] img,
-            Dimension imgDim, String imgName,
+            Dimension imgDim, String imgDescription,
             Rectangle2D targetRect, 
             boolean isJPEG, ColorSpace colorSpace,
             PSGenerator gen) throws IOException {
-        boolean iscolor = colorSpace.getType() != ColorSpace.CS_GRAY;
-
         gen.saveGraphicsState();
         gen.writeln(gen.formatDouble(targetRect.getX()) + " " 
                 + gen.formatDouble(targetRect.getY()) + " translate");
         gen.writeln(gen.formatDouble(targetRect.getWidth()) + " " 
                 + gen.formatDouble(targetRect.getHeight()) + " scale");
 
-        gen.commentln("%FOPBeginBitmap: " + imgName);
-        if (colorSpace.getType() == ColorSpace.TYPE_CMYK) {
-            gen.writeln("/DeviceCMYK setcolorspace");
-        } else if (colorSpace.getType() == ColorSpace.CS_GRAY) {
-            gen.writeln("/DeviceGray setcolorspace");
-        } else {
-            gen.writeln("/DeviceRGB setcolorspace");
-        }
+        gen.commentln("%AXGBeginBitmap: " + imgDescription);
 
         gen.writeln("{{");
         // Template: (RawData is used for the EOF signal only)
@@ -89,8 +80,27 @@
                 gen.writeln("/Data RawData /RunLengthDecode filter def");
             }
         }
-        gen.writeln("<<");
-        gen.writeln("  /ImageType 1");
+        writeImageCommand(imgDim, colorSpace, gen, "Data");
+        /* the following two lines could be enabled if something still goes wrong
+         * gen.write("Data closefile");
+         * gen.write("RawData flushfile");
+         */
+        gen.writeln("} stopped {handleerror} if");
+        gen.writeln("  RawData flushfile");
+        gen.writeln("} exec");
+
+        encodeBitmap(img, isJPEG, gen);
+
+        gen.writeln("");
+        gen.commentln("%AXGEndBitmap");
+        gen.restoreGraphicsState();
+    }
+
+    private static void writeImageCommand(Dimension imgDim, ColorSpace colorSpace, 
+            PSGenerator gen, String dataSource) throws IOException {
+        boolean iscolor = colorSpace.getType() != ColorSpace.CS_GRAY;
+        prepareColorspace(colorSpace, gen);
+        gen.writeln("<< /ImageType 1");
         gen.writeln("  /Width " + imgDim.width);
         gen.writeln("  /Height " + imgDim.height);
         gen.writeln("  /BitsPerComponent 8");
@@ -109,17 +119,138 @@
         gen.writeln("  /ImageMatrix [" + imgDim.width + " 0 0 "
               + imgDim.height + " 0 0]");
 
-        gen.writeln("  /DataSource Data");
-        gen.writeln(">>");
-        gen.writeln("image");
-        /* the following two lines could be enabled if something still goes wrong
-         * gen.write("Data closefile");
-         * gen.write("RawData flushfile");
-         */
-        gen.writeln("} stopped {handleerror} if");
-        gen.writeln("  RawData flushfile");
-        gen.writeln("} exec");
+        gen.writeln("  /DataSource " + dataSource);
+        gen.writeln(">> image");
+    }
+
+    /**
+     * Writes a bitmap image as a PostScript form enclosed by DSC resource wrappers to the
+     * PostScript file.
+     * @param img the raw bitmap data
+     * @param imgDim the dimensions of the image
+     * @param formName the name of the PostScript form to use
+     * @param imageDescription a description of the image added as a DSC Title comment
+     * @param isJPEG true if "img" contains a DCT-encoded images, false if "img" contains the 
+     *               decoded bitmap
+     * @param colorSpace the color space of the image
+     * @param gen the PostScript generator
+     * @return a PSResource representing the form for resource tracking
+     * @throws IOException In case of an I/O exception
+     */
+    public static PSResource writeReusableImage(byte[] img,
+            Dimension imgDim, String formName, String imageDescription,
+            boolean isJPEG, ColorSpace colorSpace,
+            PSGenerator gen) throws IOException {
+        if (gen.getPSLevel() < 2) {
+            throw new UnsupportedOperationException(
+                    "Reusable images requires at least Level 2 PostScript");
+        }
+        String dataName = formName + ":Data";
+        gen.writeDSCComment(DSCConstants.BEGIN_RESOURCE, formName);
+        if (imageDescription != null) {
+            gen.writeDSCComment(DSCConstants.TITLE, imageDescription);
+        }
+        
+        String additionalFilters;
+        if (isJPEG) {
+            additionalFilters = "/ASCII85Decode filter /DCTDecode filter";
+        } else {
+            if (gen.getPSLevel() >= 3) {
+                additionalFilters = "/ASCII85Decode filter /FlateDecode filter";
+            } else {
+                additionalFilters = "/ASCII85Decode filter /RunLengthDecode filter";
+            }
+        }
 
+        gen.writeln("/" + formName);
+        gen.writeln("<< /FormType 1");
+        gen.writeln("  /BBox [0 0 " + imgDim.width + " " + imgDim.height + "]");
+        gen.writeln("  /Matrix [1 0 0 1 0 0]");
+        gen.writeln("  /PaintProc {");
+        gen.writeln("    pop");
+        gen.writeln("    gsave");
+        if (gen.getPSLevel() == 2) {
+            gen.writeln("    userdict /i 0 put"); //rewind image data
+        } else {
+            gen.writeln("    " + dataName + " 0 setfileposition"); //rewind image data
+        }
+        String dataSource;
+        if (gen.getPSLevel() == 2) {
+            dataSource = "{ " + dataName + " i get /i i 1 add store } bind";
+        } else {
+            dataSource = dataName;
+        }
+        writeImageCommand(imgDim, colorSpace, gen, dataSource); 
+        gen.writeln("    grestore");
+        gen.writeln("  } bind");
+        gen.writeln(">> def");
+        gen.writeln("/" + dataName + " currentfile");
+        gen.writeln(additionalFilters);
+        if (gen.getPSLevel() == 2) {
+            //Creates a data array from the inline file
+            gen.writeln("{ /temp exch def ["
+                    + " { temp 16384 string readstring not {exit } if } loop ] } exec");
+        } else {
+            gen.writeln("/ReusableStreamDecode filter");
+        }
+        encodeBitmap(img, isJPEG, gen);
+        gen.writeln("def");
+        gen.writeDSCComment(DSCConstants.END_RESOURCE);
+        PSResource res = new PSResource(PSResource.TYPE_FORM, formName); 
+        gen.getResourceTracker().registerSuppliedResource(res);
+        return res;
+    }
+    
+    /**
+     * Paints a reusable image (previously added as a PostScript form).
+     * @param formName the name of the PostScript form implementing the image
+     * @param targetRect the target rectangle to place the image in
+     * @param gen the PostScript generator
+     * @throws IOException In case of an I/O exception
+     */
+    public static void paintReusableImage(
+            String formName,
+            Rectangle2D targetRect, 
+            PSGenerator gen) throws IOException {
+        PSResource form = new PSResource(PSResource.TYPE_FORM, formName);
+        paintForm(form, targetRect, gen);
+    }
+    
+    /**
+     * Paints a reusable image (previously added as a PostScript form).
+     * @param form the PostScript form resource implementing the image
+     * @param targetRect the target rectangle to place the image in
+     * @param gen the PostScript generator
+     * @throws IOException In case of an I/O exception
+     */
+    public static void paintForm(
+            PSResource form,
+            Rectangle2D targetRect, 
+            PSGenerator gen) throws IOException {
+        gen.saveGraphicsState();
+        gen.writeln(gen.formatDouble(targetRect.getX()) + " " 
+                + gen.formatDouble(targetRect.getY()) + " translate");
+        gen.writeln(gen.formatDouble(targetRect.getWidth()) + " " 
+                + gen.formatDouble(targetRect.getHeight()) + " scale");
+        gen.writeln(form.getName() + " execform");
+        
+        gen.getResourceTracker().notifyResourceUsageOnPage(form);
+        gen.restoreGraphicsState();
+    }
+    
+    private static void prepareColorspace(ColorSpace colorSpace, PSGenerator gen)
+                throws IOException {
+        if (colorSpace.getType() == ColorSpace.TYPE_CMYK) {
+            gen.writeln("/DeviceCMYK setcolorspace");
+        } else if (colorSpace.getType() == ColorSpace.CS_GRAY) {
+            gen.writeln("/DeviceGray setcolorspace");
+        } else {
+            gen.writeln("/DeviceRGB setcolorspace");
+        }
+    }
+
+    private static void encodeBitmap(byte[] img, boolean isJPEG, PSGenerator gen)
+                throws IOException {
         OutputStream out = gen.getOutputStream();
         out = new ASCII85OutputStream(out);
         if (isJPEG) {
@@ -137,10 +268,7 @@
         } else {
             out.flush();
         }
-
-        gen.writeln("");
-        gen.commentln("%FOPEndBitmap");
-        gen.restoreGraphicsState();
+        gen.newLine();
     }
 
     /**
@@ -184,11 +312,24 @@
         return bitmaps;
     }
     
+    /**
+     * Extracts a packed RGB integer array of a RenderedImage.
+     * @param img the image
+     * @param startX the starting X coordinate
+     * @param startY the starting Y coordinate
+     * @param w the width of the cropped image
+     * @param h the height of the cropped image
+     * @param rgbArray the prepared integer array to write to
+     * @param offset offset in the target array
+     * @param scansize width of a row in the target array
+     * @return the populated integer array previously passed in as rgbArray parameter
+     */
     public static int[] getRGB(RenderedImage img,
-                int startX, int startY, int w, int h,
+                int startX, int startY,
+                int w, int h,
                 int[] rgbArray, int offset, int scansize) {
         Raster raster = img.getData();
-        int yoff  = offset;
+        int yoff = offset;
         int off;
         Object data;
         int nbands = raster.getNumBands();
@@ -215,21 +356,18 @@
         }
         
         if (rgbArray == null) {
-            rgbArray = new int[offset+h*scansize];
+            rgbArray = new int[offset + h * scansize];
         }
         
         ColorModel colorModel = img.getColorModel();
-        for (int y = startY; y < startY+h; y++, yoff+=scansize) {
+        for (int y = startY; y < startY + h; y++, yoff += scansize) {
             off = yoff;
-            for (int x = startX; x < startX+w; x++) {
-                rgbArray[off++] = colorModel.getRGB(raster.getDataElements(x,
-                                    y,
-                                    data));
+            for (int x = startX; x < startX + w; x++) {
+                rgbArray[off++] = colorModel.getRGB(raster.getDataElements(x, y, data));
             }
         }
         
         return rgbArray;
-
     }
     
     /**
@@ -251,8 +389,8 @@
                     float x, float y, float w, float h,
                     float bboxx, float bboxy, float bboxw, float bboxh,
                     PSGenerator gen) throws IOException {
-        gen.notifyResourceUsage(PSProcSets.EPS_PROCSET, false);
-        gen.writeln("%FOPBeginEPS: " + name);
+        gen.getResourceTracker().notifyResourceUsageOnPage(PSProcSets.EPS_PROCSET);
+        gen.writeln("%AXGBeginEPS: " + name);
         gen.writeln("BeginEPSF");
 
         gen.writeln(gen.formatDouble(x) + " " + gen.formatDouble(y) + " translate");
@@ -271,12 +409,12 @@
         gen.writeln("newpath");
         
         PSResource res = new PSResource(PSResource.TYPE_FILE, name);
-        gen.notifyResourceUsage(res, false);
+        gen.getResourceTracker().notifyResourceUsageOnPage(res);
         gen.writeDSCComment(DSCConstants.BEGIN_DOCUMENT, res.getName());
         gen.writeByteArr(rawEPS);
         gen.writeDSCComment(DSCConstants.END_DOCUMENT);
         gen.writeln("EndEPSF");
-        gen.writeln("%FOPEndEPS");
+        gen.writeln("%AXGEndEPS");
     }
 
 }

Added: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSProcSet.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSProcSet.java?view=auto&rev=512838
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSProcSet.java (added)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSProcSet.java Wed Feb 28 08:42:28 2007
@@ -0,0 +1,69 @@
+/*
+ * 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.xmlgraphics.ps;
+
+/**
+ * PSResource subclass that represents a ProcSet resource.
+ */
+public class PSProcSet extends PSResource {
+    
+    private float version;
+    private int revision;
+    
+    /**
+     * Creates a new instance.
+     * @param name name of the resource
+     */
+    public PSProcSet(String name) {
+        this(name, 1.0f, 0);
+    }
+
+    /**
+     * Creates a new instance.
+     * @param name name of the resource
+     * @param version version of the resource
+     * @param revision revision of the resource
+     */
+    public PSProcSet(String name, float version, int revision) {
+        super(TYPE_PROCSET, name);
+        this.version = version;
+        this.revision = revision;
+    }
+
+    /** @return the version */
+    public float getVersion() {
+        return version;
+    }
+
+    /** @return the revision */
+    public int getRevision() {
+        return revision;
+    }
+    
+    /** @return the <resource> specification as defined in DSC v3.0 spec. */
+    public String getResourceSpecification() {
+        StringBuffer sb = new StringBuffer();
+        sb.append(getType()).append(" ").append(PSGenerator.convertStringToDSC(getName()));
+        sb.append(" ").append(PSGenerator.convertRealToDSC(getVersion()));
+        sb.append(" ").append(Integer.toString(getRevision()));
+        return sb.toString();
+    }
+
+}

Propchange: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSProcSet.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSProcSets.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSProcSets.java?view=diff&rev=512838&r1=512837&r2=512838
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSProcSets.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSProcSets.java Wed Feb 28 08:42:28 2007
@@ -22,33 +22,34 @@
 import java.io.IOException;
 
 /**
- * This class defines the basic resources (procsets) used by FOP's PostScript
- * renderer and SVG transcoder.
+ * This class defines the basic resources (procsets) used by the Apache XML Graphics project.
  * 
- * @author <a href="mailto:fop-dev@xmlgraphics.apache.org">Apache FOP Development Team</a>
  * @version $Id$
  */
 public final class PSProcSets {
 
-    /** the standard FOP procset */
+    /** the standard procset for the XML Graphics project */
     public static final PSResource STD_PROCSET = new StdProcSet();
-    /** the EPS FOP procset */
+    /** the EPS procset for the XML Graphics project */
     public static final PSResource EPS_PROCSET = new EPSProcSet();
     
-    private static class StdProcSet extends PSResource {
+    private static class StdProcSet extends PSProcSet {
         
         public StdProcSet() {
-            super("procset", "Apache FOP Std ProcSet");
+            super("Apache XML Graphics Std ProcSet", 1.0f, 0);
         }
         
         public void writeTo(PSGenerator gen) throws IOException {
             gen.writeDSCComment(DSCConstants.BEGIN_RESOURCE, 
-                    new Object[] {"procset", getName(), "1.0", "0"});
+                    new Object[] {TYPE_PROCSET, getName(), 
+                        Float.toString(getVersion()), Integer.toString(getRevision())});
             gen.writeDSCComment(DSCConstants.VERSION, 
-                    new Object[] {"1.0", "0"});
+                    new Object[] {Float.toString(getVersion()), Integer.toString(getRevision())});
             gen.writeDSCComment(DSCConstants.COPYRIGHT, "Copyright 2001-2003 "
-                        + "The Apache Software Foundation. All rights reserved.");
-            gen.writeDSCComment(DSCConstants.TITLE, "Basic set of procedures used by FOP");
+                        + "The Apache Software Foundation. "
+                        + "License terms: http://www.apache.org/licenses/LICENSE-2.0");
+            gen.writeDSCComment(DSCConstants.TITLE, 
+                    "Basic set of procedures used by the XML Graphics project (Batik and FOP)");
 
             gen.writeln("/bd{bind def}bind def");
             gen.writeln("/ld{load def}bd");
@@ -140,24 +141,28 @@
             gen.writeln("} bd");
             
             gen.writeDSCComment(DSCConstants.END_RESOURCE);
+            gen.getResourceTracker().registerSuppliedResource(this);
         }
         
     }
 
-    private static class EPSProcSet extends PSResource {
+    private static class EPSProcSet extends PSProcSet {
         
         public EPSProcSet() {
-            super("procset", "Apache FOP EPS ProcSet");
+            super("Apache XML Graphics EPS ProcSet", 1.0f, 0);
         }
         
         public void writeTo(PSGenerator gen) throws IOException {
             gen.writeDSCComment(DSCConstants.BEGIN_RESOURCE, 
-                    new Object[] {"procset", getName(), "1.0", "0"});
+                    new Object[] {TYPE_PROCSET, getName(), 
+                        Float.toString(getVersion()), Integer.toString(getRevision())});
             gen.writeDSCComment(DSCConstants.VERSION, 
-                    new Object[] {"1.0", "0"});
+                    new Object[] {Float.toString(getVersion()), Integer.toString(getRevision())});
             gen.writeDSCComment(DSCConstants.COPYRIGHT, "Copyright 2002-2003 "
-                        + "The Apache Software Foundation. All rights reserved.");
-            gen.writeDSCComment(DSCConstants.TITLE, "EPS procedures used by FOP");
+                    + "The Apache Software Foundation. "
+                    + "License terms: http://www.apache.org/licenses/LICENSE-2.0");
+            gen.writeDSCComment(DSCConstants.TITLE, 
+                    "EPS procedures used by the Apache XML Graphics project (Batik and FOP)");
 
             gen.writeln("/BeginEPSF { %def");
             gen.writeln("/b4_Inc_state save def         % Save state for cleanup");
@@ -183,6 +188,7 @@
             gen.writeln("} bd");
             
             gen.writeDSCComment(DSCConstants.END_RESOURCE);
+            gen.getResourceTracker().registerSuppliedResource(this);
         }
         
     }
@@ -192,7 +198,7 @@
      * @param gen PSGenerator to use for output
      * @throws IOException In case of an I/O problem
      */
-    public static void writeFOPStdProcSet(PSGenerator gen) throws IOException {
+    public static void writeStdProcSet(PSGenerator gen) throws IOException {
         ((StdProcSet)STD_PROCSET).writeTo(gen);
     }
 
@@ -202,7 +208,7 @@
      * @param gen PSGenerator to use for output
      * @throws IOException In case of an I/O problem
      */
-    public static void writeFOPEPSProcSet(PSGenerator gen) throws IOException {
+    public static void writeEPSProcSet(PSGenerator gen) throws IOException {
         ((EPSProcSet)EPS_PROCSET).writeTo(gen);
     }
 

Modified: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSResource.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSResource.java?view=diff&rev=512838&r1=512837&r2=512838
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSResource.java (original)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/PSResource.java Wed Feb 28 08:42:28 2007
@@ -30,6 +30,12 @@
     public static final String TYPE_FONT = "font";
     /** a procset resource */
     public static final String TYPE_PROCSET = "procset";
+    /** a procset resource */
+    public static final String TYPE_PATTERN = "pattern";
+    /** a procset resource */
+    public static final String TYPE_FORM = "form";
+    /** a procset resource */
+    public static final String TYPE_ENCODING = "encoding";
     
     private String type;
     private String name;
@@ -61,4 +67,26 @@
         return sb.toString();
     }
     
+    
+    /** @see java.lang.Object#equals(java.lang.Object) */
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        } else if (obj instanceof PSResource) {
+            PSResource other = (PSResource)obj;
+            return other.toString().equals(toString());
+        } else {
+            return false;
+        }
+    }
+
+    /** @see java.lang.Object#hashCode() */
+    public int hashCode() {
+        return toString().hashCode();
+    }
+
+    /** @see java.lang.Object#toString() */
+    public String toString() {
+        return getResourceSpecification();
+    }
 }

Added: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCCommentFactory.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCCommentFactory.java?view=auto&rev=512838
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCCommentFactory.java (added)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCCommentFactory.java Wed Feb 28 08:42:28 2007
@@ -0,0 +1,87 @@
+/*
+ * 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.xmlgraphics.ps.dsc;
+
+import java.util.Map;
+
+import org.apache.xmlgraphics.ps.DSCConstants;
+import org.apache.xmlgraphics.ps.dsc.events.DSCComment;
+import org.apache.xmlgraphics.ps.dsc.events.DSCCommentBeginResource;
+import org.apache.xmlgraphics.ps.dsc.events.DSCCommentDocumentNeededResources;
+import org.apache.xmlgraphics.ps.dsc.events.DSCCommentDocumentSuppliedResources;
+import org.apache.xmlgraphics.ps.dsc.events.DSCCommentEndComments;
+import org.apache.xmlgraphics.ps.dsc.events.DSCCommentLanguageLevel;
+import org.apache.xmlgraphics.ps.dsc.events.DSCCommentPage;
+import org.apache.xmlgraphics.ps.dsc.events.DSCCommentPageResources;
+import org.apache.xmlgraphics.ps.dsc.events.DSCCommentPages;
+import org.apache.xmlgraphics.ps.dsc.events.DSCCommentEndOfFile;
+
+/**
+ * Factory for DSCComment subclasses.
+ */
+public class DSCCommentFactory {
+
+    private static final Map DSC_FACTORIES = new java.util.HashMap();
+
+    static {
+        DSC_FACTORIES.put(DSCConstants.END_COMMENTS, 
+                DSCCommentEndComments.class);
+        DSC_FACTORIES.put(DSCConstants.BEGIN_RESOURCE, 
+                DSCCommentBeginResource.class);
+        DSC_FACTORIES.put(DSCConstants.PAGE_RESOURCES, 
+                DSCCommentPageResources.class);
+        DSC_FACTORIES.put(DSCConstants.PAGE, 
+                DSCCommentPage.class);
+        DSC_FACTORIES.put(DSCConstants.PAGES, 
+                DSCCommentPages.class);
+        DSC_FACTORIES.put(DSCConstants.LANGUAGE_LEVEL, 
+                DSCCommentLanguageLevel.class);
+        DSC_FACTORIES.put(DSCConstants.DOCUMENT_NEEDED_RESOURCES, 
+                DSCCommentDocumentNeededResources.class);
+        DSC_FACTORIES.put(DSCConstants.DOCUMENT_SUPPLIED_RESOURCES, 
+                DSCCommentDocumentSuppliedResources.class);
+        DSC_FACTORIES.put(DSCConstants.EOF, 
+                DSCCommentEndOfFile.class);
+        //TODO Add additional implementations as needed
+    }
+    
+    /**
+     * Creates and returns new instances for DSC comments with a given name.
+     * @param name the name of the DSCComment (without the "%%" prefix)
+     * @return the new instance or null if no particular subclass registered for the given
+     *          DSC comment.
+     */
+    public static DSCComment createDSCCommentFor(String name) {
+        Class clazz = (Class)DSC_FACTORIES.get(name);
+        if (clazz == null) {
+            return null;
+        }
+        try {
+            return (DSCComment)clazz.newInstance();
+        } catch (InstantiationException e) {
+            throw new RuntimeException("Error instantiating instance for '" + name + "': " 
+                    + e.getMessage());
+        } catch (IllegalAccessException e) {
+            throw new RuntimeException("Illegal Access error while instantiating instance for '" 
+                    + name + "': " + e.getMessage());
+        }
+    }
+    
+}

Propchange: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCCommentFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCException.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCException.java?view=auto&rev=512838
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCException.java (added)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCException.java Wed Feb 28 08:42:28 2007
@@ -0,0 +1,37 @@
+/*
+ * 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.xmlgraphics.ps.dsc;
+
+/**
+ * Exception to signal problems while parsing a supposedly DSC-conformant file.
+ */
+public class DSCException extends Exception {
+
+    private static final long serialVersionUID = -1549406547978409615L;
+
+    /**
+     * Creates a new DSCException.
+     * @param msg the exception message
+     */
+    public DSCException(String msg) {
+        super(msg);
+    }
+    
+}

Propchange: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCFilter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCFilter.java?view=auto&rev=512838
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCFilter.java (added)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCFilter.java Wed Feb 28 08:42:28 2007
@@ -0,0 +1,36 @@
+/*
+ * 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.xmlgraphics.ps.dsc;
+
+import org.apache.xmlgraphics.ps.dsc.events.DSCEvent;
+
+/**
+ * Filter interface for DSC events used by the DSC parser.
+ */
+public interface DSCFilter {
+
+    /**
+     * Indicates whether a particular event is acceptable or if it should be skipped/ignored.
+     * @param event the DSC event
+     * @return true if the event should be accepted
+     */
+    boolean accept(DSCEvent event);
+    
+}

Propchange: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCFilter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCHandler.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCHandler.java?view=auto&rev=512838
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCHandler.java (added)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCHandler.java Wed Feb 28 08:42:28 2007
@@ -0,0 +1,68 @@
+/*
+ * 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.xmlgraphics.ps.dsc;
+
+import java.io.IOException;
+
+import org.apache.xmlgraphics.ps.dsc.events.DSCComment;
+
+/**
+ * Interface containing events generated by the DSCParser. Applications can implement this
+ * interface to react to certain events.
+ */
+public interface DSCHandler {
+
+    /**
+     * Called as a new PostScript file starts.
+     * @param header the first line of the DSC-compliant file
+     * @throws IOException In case of an I/O error
+     */
+    public void startDocument(String header) throws IOException;
+    
+    /**
+     * Called when the PostScript file is fully processed, i.e. after the %%EOF comment.
+     * @throws IOException In case of an I/O error
+     */
+    public void endDocument() throws IOException;
+
+    /**
+     * Called for each standard DSC comment. The classes passed to this method may be simple
+     * DSCComment classes or special subclasses for some of the DSC comments.
+     * @param comment the DSC comment
+     * @throws IOException In case of an I/O error
+     */
+    public void handleDSCComment(DSCComment comment) throws IOException;
+
+    /**
+     * Called for a normal line of PostScript code.
+     * @param line the line of code
+     * @throws IOException In case of an I/O error
+     */
+    public void line(String line) throws IOException;
+
+    /**
+     * Called for any line containing a full-line PostScript comment. This is also called for
+     * custom comments following the extension mechanism of the DSC specification.
+     * @param comment the comment line
+     * @throws IOException In case of an I/O error
+     */
+    public void comment(String comment) throws IOException;
+    
+}

Propchange: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCParser.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCParser.java?view=auto&rev=512838
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCParser.java (added)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCParser.java Wed Feb 28 08:42:28 2007
@@ -0,0 +1,385 @@
+/*
+ * 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.xmlgraphics.ps.dsc;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.NoSuchElementException;
+
+import org.apache.xmlgraphics.ps.DSCConstants;
+import org.apache.xmlgraphics.ps.PSGenerator;
+import org.apache.xmlgraphics.ps.dsc.events.DSCAtend;
+import org.apache.xmlgraphics.ps.dsc.events.DSCComment;
+import org.apache.xmlgraphics.ps.dsc.events.DSCEvent;
+import org.apache.xmlgraphics.ps.dsc.events.DSCHeaderComment;
+import org.apache.xmlgraphics.ps.dsc.events.PostScriptComment;
+import org.apache.xmlgraphics.ps.dsc.events.PostScriptLine;
+import org.apache.xmlgraphics.ps.dsc.events.UnparsedDSCComment;
+import org.apache.xmlgraphics.ps.dsc.tools.DSCTools;
+
+/**
+ * Parser for DSC-compliant PostScript files (DSC = Document Structuring Conventions). The parser
+ * is implemented as a pull parser but has the ability to act as a push parser through the 
+ * DSCHandler interface.
+ */
+public class DSCParser implements DSCParserConstants {
+
+    private InputStream in;
+    private BufferedReader reader;
+    private boolean eofFound = false;
+    private DSCEvent currentEvent;
+    private DSCEvent nextEvent;
+    private DSCFilter filter;
+    private NestedDocumentHandler nestedDocumentHandler;
+    
+    /**
+     * Creates a new DSC parser.
+     * @param in InputStream to read the PostScript file from
+     *              (the stream is not closed by this class, the caller is responsible for that)
+     * @throws IOException In case of an I/O error
+     * @throws DSCException In case of a violation of the DSC spec
+     */
+    public DSCParser(InputStream in) throws IOException, DSCException {
+        if (in.markSupported()) {
+            this.in = in;
+        } else {
+            //Decorate for better performance
+            this.in = new java.io.BufferedInputStream(this.in);
+        }
+        String encoding = "US-ASCII";
+        try {
+            this.reader = new java.io.BufferedReader(
+                    new java.io.InputStreamReader(this.in, encoding));
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException("Incompatible VM! " + e.getMessage());
+        }
+        parseNext();
+    }
+    
+    /**
+     * Returns the InputStream the PostScript code is read from.
+     * @return the InputStream the PostScript code is read from
+     */
+    public InputStream getInputStream() {
+        return this.in;
+    }
+    
+    /**
+     * This method is used to write out warning messages for the parsing process. Subclass to
+     * override this method. The default implementation writes to System.err.
+     * @param msg the warning message
+     */
+    protected void warn(String msg) {
+        System.err.println(msg);
+    }
+    
+    /**
+     * Reads one line from the input file
+     * @return the line or null if there are no more lines
+     * @throws IOException In case of an I/O error
+     * @throws DSCException In case of a violation of the DSC spec
+     */
+    protected String readLine() throws IOException, DSCException {
+        String line;
+        line = this.reader.readLine();
+        checkLine(line);
+        
+        return line;
+    }
+
+    private void checkLine(String line) throws DSCException {
+        if (line == null) {
+            if (!eofFound) {
+                throw new DSCException("%%EOF not found. File is not well-formed.");
+            }
+        } else if (line.length() > 255) {
+            warn("Line longer than 255 characters. This file is not fully PostScript conforming.");
+        }
+    }
+    
+    private final boolean isWhitespace(char c) {
+        return c == ' ' || c == '\t';
+    }
+    
+    private DSCComment parseDSCLine(String line) throws IOException, DSCException {
+        int colon = line.indexOf(':');
+        String name, value;
+        if (colon > 0) {
+            name = line.substring(2, colon);
+            int startOfValue = colon + 1;
+            if (isWhitespace(line.charAt(startOfValue))) {
+                startOfValue++;
+            }
+            value = line.substring(startOfValue).trim();
+            if (value.equals(DSCConstants.ATEND.toString())) {
+                return new DSCAtend(name);
+            }
+            String nextLine;
+            while (true) {
+                this.reader.mark(512);
+                nextLine = readLine();
+                if (nextLine == null) {
+                    break;
+                } else if (!nextLine.startsWith("%%+")) {
+                    break;
+                }
+                value = value + nextLine.substring(3);
+            }
+            this.reader.reset();
+        } else {
+            name = line.substring(2);
+            value = null;
+        }
+        return parseDSCComment(name, value);
+    }
+
+    private DSCComment parseDSCComment(String name, String value) {
+        DSCComment parsed = DSCCommentFactory.createDSCCommentFor(name);
+        if (parsed != null) {
+            parsed.parseValue(value);
+            return parsed;
+        } else {
+            UnparsedDSCComment unparsed = new UnparsedDSCComment(name);
+            unparsed.parseValue(value);
+            return unparsed;
+        }
+    }
+
+    /**
+     * Starts the parser in push parsing mode sending events to the DSCHandler instance.
+     * @param handler the DSCHandler instance to send the events to
+     * @throws IOException In case of an I/O error
+     * @throws DSCException In case of a violation of the DSC spec
+     */
+    public void parse(DSCHandler handler) throws IOException, DSCException {
+        DSCHeaderComment header = DSCTools.checkAndSkipDSC30Header(this);
+        handler.startDocument("%!" + header.getComment());
+        DSCEvent event;
+        while (hasNext()) {
+            event = nextEvent();
+            switch (event.getEventType()) {
+            case HEADER_COMMENT:
+                handler.startDocument("%!" + ((DSCHeaderComment)event).getComment());
+                break;
+            case DSC_COMMENT:
+                handler.handleDSCComment(event.asDSCComment());
+                break;
+            case COMMENT:
+                handler.comment(((PostScriptComment)event).getComment());
+                break;
+            case LINE:
+                handler.line(getLine());
+                break;
+            case EOF:
+                this.eofFound = true;
+                handler.endDocument();
+                break;
+            default:
+                throw new IllegalStateException("Illegal event type: " + event.getEventType());
+            }
+        }
+    }
+    
+    /**
+     * Indicates whether there are additional items.
+     * @return true if there are additonal items, false if the end of the file has been reached
+     */
+    public boolean hasNext() {
+        return (this.nextEvent != null);
+    }
+
+    /**
+     * Steps to the next item indicating the type of event.
+     * @return the type of event (See {@link DSCParserConstants})
+     * @throws IOException In case of an I/O error
+     * @throws DSCException In case of a violation of the DSC spec
+     * @throws NoSuchElementException If an attempt was made to advance beyond the end of the file
+     */
+    public int next() throws IOException, DSCException {
+        if (hasNext()) {
+            this.currentEvent = nextEvent;
+            parseNext();
+            if (this.nestedDocumentHandler != null) {
+                this.nestedDocumentHandler.handle(this.currentEvent, this);
+            }
+            return this.currentEvent.getEventType();
+        } else {
+            throw new NoSuchElementException("There are no more events");
+        }
+    }
+    
+    /**
+     * Steps to the next item returning the new event.
+     * @return the new event
+     * @throws IOException In case of an I/O error
+     * @throws DSCException In case of a violation of the DSC spec
+     */
+    public DSCEvent nextEvent() throws IOException, DSCException {
+        next();
+        return getCurrentEvent();
+    }
+    
+    /**
+     * Returns the current event.
+     * @return the current event
+     */
+    public DSCEvent getCurrentEvent() {
+        return this.currentEvent;
+    }
+    
+    /**
+     * Returns the next event without moving the cursor to the next event.
+     * @return the next event
+     */
+    public DSCEvent peek() {
+        return this.nextEvent;
+    }
+    
+    /**
+     * Parses the next event.
+     * @throws IOException In case of an I/O error
+     * @throws DSCException In case of a violation of the DSC spec
+     */
+    protected void parseNext() throws IOException, DSCException {
+        String line = readLine();
+        if (line != null) {
+            if (eofFound && (line.length() > 0)) {
+                throw new DSCException("Content found after EOF");
+            }
+            if (line.startsWith("%%")) {
+                DSCComment comment = parseDSCLine(line);
+                if (comment.getEventType() == EOF) {
+                    this.eofFound = true;
+                }
+                this.nextEvent = comment;
+            } else if (line.startsWith("%!")) {
+                this.nextEvent = new DSCHeaderComment(line.substring(2));
+            } else if (line.startsWith("%")) {
+                this.nextEvent = new PostScriptComment(line.substring(1));
+            } else {
+                this.nextEvent = new PostScriptLine(line);
+            }
+            if (this.filter != null && !filter.accept(this.nextEvent)) {
+                parseNext(); //skip
+            }
+        } else {
+            this.nextEvent = null;
+        }
+    }
+    
+    /**
+     * Returns the current PostScript line.
+     * @return the current PostScript line
+     * @throws IllegalStateException if the current event is not a normal PostScript line
+     */
+    public String getLine() {
+        if (this.currentEvent.getEventType() == LINE) {
+            return ((PostScriptLine)this.currentEvent).getLine();
+        } else {
+            throw new IllegalStateException("Current event is not a PostScript line");
+        }
+    }
+
+    /**
+     * Advances to the next DSC comment with the given name.
+     * @param name the name of the DSC comment
+     * @return the requested DSC comment or null if the end of the file is reached
+     * @throws IOException In case of an I/O error
+     * @throws DSCException In case of a violation of the DSC spec
+     */
+    public DSCComment nextDSCComment(String name) 
+                throws IOException, DSCException {
+        return nextDSCComment(name, null);
+    }
+    
+    /**
+     * Advances to the next DSC comment with the given name.
+     * @param name the name of the DSC comment
+     * @param gen PSGenerator to pass the skipped events though to
+     * @return the requested DSC comment or null if the end of the file is reached
+     * @throws IOException In case of an I/O error
+     * @throws DSCException In case of a violation of the DSC spec
+     */
+    public DSCComment nextDSCComment(String name, PSGenerator gen) 
+                throws IOException, DSCException {
+        while (hasNext()) {
+            DSCEvent event = nextEvent();
+            if (event.isDSCComment()) {
+                DSCComment comment = event.asDSCComment();
+                if (name.equals(comment.getName())) {
+                    return comment;
+                }
+            }
+            if (gen != null) {
+                event.generate(gen); //Pipe through to PSGenerator
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Advances to the next PostScript comment with the given prefix. This is used to find
+     * comments following the DSC extension mechanism.
+     * <p>
+     * Example: To find FOP's custom comments, pass in "FOP" as a prefix. This will find comments
+     * like "%FOPFontSetup".
+     * @param prefix the prefix of the extension comment
+     * @param gen PSGenerator to pass the skipped events though to
+     * @return the requested PostScript comment or null if the end of the file is reached
+     * @throws IOException In case of an I/O error
+     * @throws DSCException In case of a violation of the DSC spec
+     */
+    public PostScriptComment nextPSComment(String prefix, PSGenerator gen)
+                    throws IOException, DSCException {
+            while (hasNext()) {
+                DSCEvent event = nextEvent();
+                if (event.isComment()) {
+                    PostScriptComment comment = (PostScriptComment)event;
+                    if (comment.getComment().startsWith(prefix)) {
+                        return comment;
+                    }
+                }
+                if (gen != null) {
+                    event.generate(gen); //Pipe through to PSGenerator
+                }
+            }
+            return null;
+    }
+
+    /**
+     * Sets a filter for DSC events.
+     * @param filter the filter to use or null to disable filtering
+     */
+    public void setFilter(DSCFilter filter) {
+        this.filter = filter;
+    }
+
+    /**
+     * Sets a NestedDocumentHandler which is used to skip nested documents like embedded EPS files.
+     * You can also process those parts in a special way.
+     * @param handler the NestedDocumentHandler instance or null to disable the feature
+     */
+    public void setNestedDocumentHandler(NestedDocumentHandler handler) {
+        this.nestedDocumentHandler = handler;
+    }
+
+}

Propchange: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCParser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCParserConstants.java
URL: http://svn.apache.org/viewvc/xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCParserConstants.java?view=auto&rev=512838
==============================================================================
--- xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCParserConstants.java (added)
+++ xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCParserConstants.java Wed Feb 28 08:42:28 2007
@@ -0,0 +1,38 @@
+/*
+ * 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.xmlgraphics.ps.dsc;
+
+/**
+ * Constants the DSC parser uses.
+ */
+public interface DSCParserConstants {
+
+    /** Indicates a header comment (starting with "%!") */
+    int HEADER_COMMENT = 0;
+    /** Indicates a DSC comment (starting with "%%") */
+    int DSC_COMMENT = 1;
+    /** Indicates a normal PostScript comment (starting with "%") */
+    int COMMENT = 2;
+    /** Indicates a normal PostScript line */
+    int LINE = 3;
+    /** Indicates the end of the file (equivalent to the "%%EOF" DSC comment) */
+    int EOF = 4;
+    
+}

Propchange: xmlgraphics/commons/trunk/src/java/org/apache/xmlgraphics/ps/dsc/DSCParserConstants.java
------------------------------------------------------------------------------
    svn:eol-style = native



---------------------------------------------------------------------
Apache XML Graphics Project URL: http://xmlgraphics.apache.org/
To unsubscribe, e-mail: commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: commits-help@xmlgraphics.apache.org