You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by je...@apache.org on 2006/06/14 16:34:31 UTC

svn commit: r414272 [1/2] - in /xmlgraphics/fop/trunk: ./ src/java/org/apache/fop/pdf/ src/java/org/apache/fop/render/ src/java/org/apache/fop/render/pdf/ src/java/org/apache/fop/svg/

Author: jeremias
Date: Wed Jun 14 07:34:29 2006
New Revision: 414272

URL: http://svn.apache.org/viewvc?rev=414272&view=rev
Log:
Added initial support for PDF/X-3:2003 (ISO 15930-6:2003(E)).
Fixed bugs in PDF/A support: Transparency is now switched off and the CIDSet object is generated for CID fonts.
PDF/A and PDF/X are now "profiles" (see PDFProfile) which are used to control the allowed, required and forbidden features in PDF. PDF/A-1b and PDF/X-3:2003 can both be activated simultaneously as they are compatible.
For PDF/X, color handling has been improved a little (PDFColorSpace is now an interface, the old PDFColorSpace is now PDFDeviceColorSpace) and most importantly, the "DefaultRGB" color space is now mapped to the sRGB color space (for all colors in DeviceRGB) which ensures that all sRGB colors from XSL-FO are also sRGB colors in PDF which wasn't necessarily the case before.
For PDF/X, added support for a custom, non-sRGB output profile because PDF/X requires a "Output Device Profile" (which sRGB is not).
ICC profiles are now shared/cached among images.
Added support for fox:conversion-mode="bitmap" in the PDFRenderer to handle SVGs with transparency when transparency is forbidden (PDF/X and PDF/A). Only drawback: the image is not combined with the background. An opaque bitmap with a white background is generated.

Added:
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFDeviceColorSpace.java
      - copied, changed from r412970, xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFColorSpace.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFICCBasedColorSpace.java   (with props)
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFProfile.java   (with props)
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFXMode.java   (with props)
Modified:
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/BitmapImage.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFColor.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFColorSpace.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFDocument.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFactory.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFont.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFontDescriptor.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFontNonBase14.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFICCStream.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFImage.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFInfo.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFLink.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFMetadata.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFPage.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFPathPaint.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFResources.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFShading.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFXObject.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/RendererContext.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/FopPDFImage.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFGraphics2DAdapter.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderer.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFSVGHandler.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFGraphics2D.java
    xmlgraphics/fop/trunk/status.xml

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/BitmapImage.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/BitmapImage.java?rev=414272&r1=414271&r2=414272&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/BitmapImage.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/BitmapImage.java Wed Jun 14 07:34:29 2006
@@ -31,7 +31,7 @@
     private int height;
     private int width;
     private int bitsPerPixel;
-    private PDFColorSpace colorSpace;
+    private PDFDeviceColorSpace colorSpace;
     private byte[] bitmaps;
     private String maskRef;
     private PDFColor transparent = null;
@@ -54,7 +54,7 @@
         this.height = height;
         this.width = width;
         this.bitsPerPixel = 8;
-        this.colorSpace = new PDFColorSpace(PDFColorSpace.DEVICE_RGB);
+        this.colorSpace = new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_RGB);
         this.bitmaps = data;
         maskRef = mask;
     }
@@ -103,7 +103,7 @@
      *
      * @param cs the pdf color space
      */
-    public void setColorSpace(PDFColorSpace cs) {
+    public void setColorSpace(PDFDeviceColorSpace cs) {
         colorSpace = cs;
     }
 
@@ -113,7 +113,7 @@
      *
      * @return the pdf doclor space
      */
-    public PDFColorSpace getColorSpace() {
+    public PDFDeviceColorSpace getColorSpace() {
         return colorSpace;
     }
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFColor.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFColor.java?rev=414272&r1=414271&r2=414272&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFColor.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFColor.java Wed Jun 14 07:34:29 2006
@@ -47,7 +47,7 @@
      */
     public PDFColor(double theRed, double theGreen, double theBlue) {
         // super(theNumber);
-        this.colorSpace = new PDFColorSpace(PDFColorSpace.DEVICE_RGB);
+        this.colorSpace = new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_RGB);
 
         this.red = theRed;
         this.green = theGreen;
@@ -60,7 +60,7 @@
      * @param col the sRGB color
      */
     public PDFColor(java.awt.Color col) {
-        this.colorSpace = new PDFColorSpace(PDFColorSpace.DEVICE_RGB);
+        this.colorSpace = new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_RGB);
         float[] comps = new float[3];
         comps = col.getColorComponents(comps);
 
@@ -94,7 +94,7 @@
                     double theBlack) {
         // super(theNumber);//?
 
-        this.colorSpace = new PDFColorSpace(PDFColorSpace.DEVICE_CMYK);
+        this.colorSpace = new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_CMYK);
 
         this.cyan = theCyan;
         this.magenta = theMagenta;
@@ -110,13 +110,13 @@
      */
     public List getVector() {
         List theColorVector = new ArrayList();
-        if (this.colorSpace.getColorSpace() == PDFColorSpace.DEVICE_RGB) {
+        if (this.colorSpace.getColorSpace() == PDFDeviceColorSpace.DEVICE_RGB) {
             // RGB
             theColorVector.add(new Double(this.red));
             theColorVector.add(new Double(this.green));
             theColorVector.add(new Double(this.blue));
         } else if (this.colorSpace.getColorSpace()
-                   == PDFColorSpace.DEVICE_CMYK) {
+                   == PDFDeviceColorSpace.DEVICE_CMYK) {
             // CMYK
             theColorVector.add(new Double(this.cyan));
             theColorVector.add(new Double(this.magenta));
@@ -229,15 +229,15 @@
     public void setColorSpace(int theColorSpace) {
         int theOldColorSpace = this.colorSpace.getColorSpace();
         if (theOldColorSpace != theColorSpace) {
-            if (theOldColorSpace == PDFColorSpace.DEVICE_RGB) {
-                if (theColorSpace == PDFColorSpace.DEVICE_CMYK) {
+            if (theOldColorSpace == PDFDeviceColorSpace.DEVICE_RGB) {
+                if (theColorSpace == PDFDeviceColorSpace.DEVICE_CMYK) {
                     this.convertRGBtoCMYK();
                 } else  {
                     // convert to Gray?
                     this.convertRGBtoGRAY();
                 }
-            } else if (theOldColorSpace == PDFColorSpace.DEVICE_CMYK) {
-                if (theColorSpace == PDFColorSpace.DEVICE_RGB) {
+            } else if (theOldColorSpace == PDFDeviceColorSpace.DEVICE_CMYK) {
+                if (theColorSpace == PDFDeviceColorSpace.DEVICE_RGB) {
                     this.convertCMYKtoRGB();
                 } else {
                     // convert to Gray?
@@ -245,7 +245,7 @@
                 }
             } else {
                 // used to be Gray
-                if (theColorSpace == PDFColorSpace.DEVICE_RGB) {
+                if (theColorSpace == PDFDeviceColorSpace.DEVICE_RGB) {
                     this.convertGRAYtoRGB();
                 } else {
                     // convert to CMYK?
@@ -270,7 +270,7 @@
         double tempDouble;
 
         if (this.colorSpace.getColorSpace()
-                == PDFColorSpace.DEVICE_RGB) {       // colorspace is RGB
+                == PDFDeviceColorSpace.DEVICE_RGB) {       // colorspace is RGB
             // according to pdfspec 12.1 p.399
             // if the colors are the same then just use the g or G operator
             boolean same = false;
@@ -300,7 +300,7 @@
                 }
             }
         } else if (this.colorSpace.getColorSpace()
-                  == PDFColorSpace.DEVICE_CMYK) {
+                  == PDFDeviceColorSpace.DEVICE_CMYK) {
             // colorspace is CMYK
 
             if (fillNotStroke) {

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFColorSpace.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFColorSpace.java?rev=414272&r1=414271&r2=414272&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFColorSpace.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFColorSpace.java Wed Jun 14 07:34:29 2006
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 2006 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,146 +21,28 @@
 /**
  * PDF Color space.
  */
-public class PDFColorSpace {
-    private boolean hasICCProfile;
-    private byte[] iccProfile;
-    private int numComponents;
-
-    // Ok... so I had some grand purpose for this, but I can't recall.
-    // I'm just writing it
-
-    /**
-     * Unknown colorspace
-     */
-    public static final int DEVICE_UNKNOWN = -1;
-
-    /**
-     * Gray colorspace
-     */
-    public static final int DEVICE_GRAY = 1;
-
-    /**
-     * RGB colorspace
-     */
-    public static final int DEVICE_RGB = 2;
-
-    /**
-     * CMYK colorspace
-     */
-    public static final int DEVICE_CMYK = 3;
-
-    // Are there any others?
-
-    /**
-     * Current color space value.
-     */
-    protected int currentColorSpace = DEVICE_UNKNOWN;
-
-    /**
-     * Create a PDF colorspace object.
-     *
-     * @param theColorSpace the current colorspace
-     */
-    public PDFColorSpace(int theColorSpace) {
-        this.currentColorSpace = theColorSpace;
-        hasICCProfile = false;
-        numComponents = calculateNumComponents();
-    }
-
-    private int calculateNumComponents() {
-        if (currentColorSpace == DEVICE_GRAY) {
-            return 1;
-        } else if (currentColorSpace == DEVICE_RGB) {
-            return 3;
-        } else if (currentColorSpace == DEVICE_CMYK) {
-            return 4;
-        } else {
-            return 0;
-        }
-    }
-
-    /**
-     * Set the current colorspace.
-     *
-     * @param theColorSpace the new color space value
-     */
-    public void setColorSpace(int theColorSpace) {
-        this.currentColorSpace = theColorSpace;
-        numComponents = calculateNumComponents();
-    }
-
-    /**
-     * Check if this colorspace has an ICC profile.
-     *
-     * @return true if this has an ICC profile
-     */
-    public boolean hasICCProfile() {
-        return hasICCProfile;
-    }
-
-    /**
-     * Get the ICC profile for this colorspace
-     *
-     * @return the byte array containing the ICC profile data
-     */
-    public byte[] getICCProfile() {
-        if (hasICCProfile) {
-            return iccProfile;
-        } else {
-            return new byte[0];
-        }
-    }
-
-    /**
-     * Set the ICC profile for this colorspace.
-     *
-     * @param iccProfile the ICC profile data
-     */
-    public void setICCProfile(byte[] iccProfile) {
-        this.iccProfile = iccProfile;
-        hasICCProfile = true;
-    }
-
-    /**
-     * Get the colorspace value
-     *
-     * @return the colorspace value
-     */
-    public int getColorSpace() {
-        return (this.currentColorSpace);
-    }
-
+public interface PDFColorSpace {
+    
     /**
      * Get the number of color components for this colorspace
-     *
      * @return the number of components
      */
-    public int getNumComponents() {
-        return numComponents;
-    }
-
-    /**
-     * Get the PDF string for this colorspace.
-     *
-     * @return the PDF string for the colorspace
-     */
-    public String getColorSpacePDFString() {
-        // shouldn't this be a select-case? I can never remember
-        // the syntax for that.
-        switch (currentColorSpace) {
-            case DEVICE_CMYK:
-                return "DeviceCMYK";
-            //break;
-            case DEVICE_GRAY:
-                return "DeviceGray";
-            //break;
-            case DEVICE_RGB:
-            default:
-                // unknown... Error. Tell them it's RGB and hope they
-                // don't notice.
-                return ("DeviceRGB");
-            //break;
-        }
-    }
+    int getNumComponents();
 
+    /** @return the name of the color space */
+    String getName();
+    
+    /**
+     * @return true if the color space is a device-dependent color space (like DeviceRGB, 
+     *         DeviceCMYK and DeviceGray)
+     */
+    boolean isDeviceColorSpace();
+    
+    /** @return true if the color space is an RGB color space */
+    boolean isRGBColorSpace();
+    /** @return true if the color space is an CMYK color space */
+    boolean isCMYKColorSpace();
+    /** @return true if the color space is an Gray color space */
+    boolean isGrayColorSpace();
+    
 }

Copied: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFDeviceColorSpace.java (from r412970, xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFColorSpace.java)
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFDeviceColorSpace.java?p2=xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFDeviceColorSpace.java&p1=xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFColorSpace.java&r1=412970&r2=414272&rev=414272&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFColorSpace.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFDeviceColorSpace.java Wed Jun 14 07:34:29 2006
@@ -19,16 +19,12 @@
 package org.apache.fop.pdf;
 
 /**
- * PDF Color space.
+ * Represents a device-specific color space. Used for mapping DeviceRGB, DeviceCMYK and DeviceGray.
  */
-public class PDFColorSpace {
-    private boolean hasICCProfile;
-    private byte[] iccProfile;
+public class PDFDeviceColorSpace implements PDFColorSpace {
+    
     private int numComponents;
 
-    // Ok... so I had some grand purpose for this, but I can't recall.
-    // I'm just writing it
-
     /**
      * Unknown colorspace
      */
@@ -61,9 +57,8 @@
      *
      * @param theColorSpace the current colorspace
      */
-    public PDFColorSpace(int theColorSpace) {
+    public PDFDeviceColorSpace(int theColorSpace) {
         this.currentColorSpace = theColorSpace;
-        hasICCProfile = false;
         numComponents = calculateNumComponents();
     }
 
@@ -90,38 +85,6 @@
     }
 
     /**
-     * Check if this colorspace has an ICC profile.
-     *
-     * @return true if this has an ICC profile
-     */
-    public boolean hasICCProfile() {
-        return hasICCProfile;
-    }
-
-    /**
-     * Get the ICC profile for this colorspace
-     *
-     * @return the byte array containing the ICC profile data
-     */
-    public byte[] getICCProfile() {
-        if (hasICCProfile) {
-            return iccProfile;
-        } else {
-            return new byte[0];
-        }
-    }
-
-    /**
-     * Set the ICC profile for this colorspace.
-     *
-     * @param iccProfile the ICC profile data
-     */
-    public void setICCProfile(byte[] iccProfile) {
-        this.iccProfile = iccProfile;
-        hasICCProfile = true;
-    }
-
-    /**
      * Get the colorspace value
      *
      * @return the colorspace value
@@ -139,28 +102,38 @@
         return numComponents;
     }
 
-    /**
-     * Get the PDF string for this colorspace.
-     *
-     * @return the PDF string for the colorspace
-     */
-    public String getColorSpacePDFString() {
-        // shouldn't this be a select-case? I can never remember
-        // the syntax for that.
+    /** @return the name of the color space */
+    public String getName() {
         switch (currentColorSpace) {
-            case DEVICE_CMYK:
-                return "DeviceCMYK";
-            //break;
-            case DEVICE_GRAY:
-                return "DeviceGray";
-            //break;
-            case DEVICE_RGB:
-            default:
-                // unknown... Error. Tell them it's RGB and hope they
-                // don't notice.
-                return ("DeviceRGB");
-            //break;
+        case DEVICE_CMYK:
+            return "DeviceCMYK";
+        case DEVICE_GRAY:
+            return "DeviceGray";
+        case DEVICE_RGB:
+            return "DeviceRGB";
+        default:
+            throw new IllegalStateException("Unsupported color space in use.");
         }
     }
 
+    /** @see org.apache.fop.pdf.PDFColorSpace#isDeviceColorSpace() */
+    public boolean isDeviceColorSpace() {
+        return true;
+    }
+
+    /** @see org.apache.fop.pdf.PDFColorSpace#isRGBColorSpace() */
+    public boolean isRGBColorSpace() {
+        return getColorSpace() == DEVICE_RGB;
+    }
+
+    /** @see org.apache.fop.pdf.PDFColorSpace#isCMYKColorSpace() */
+    public boolean isCMYKColorSpace() {
+        return getColorSpace() == DEVICE_CMYK;
+    }
+
+    /** @see org.apache.fop.pdf.PDFColorSpace#isGrayColorSpace() */
+    public boolean isGrayColorSpace() {
+        return getColorSpace() == DEVICE_GRAY;
+    }
+    
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFDocument.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFDocument.java?rev=414272&r1=414271&r2=414272&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFDocument.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFDocument.java Wed Jun 14 07:34:29 2006
@@ -108,10 +108,9 @@
     protected int pdfVersion = PDF_VERSION_1_4;
     
     /**
-     * Indicates the PDF/A-1 mode currently active. Defaults to "no restrictions", i.e. 
-     * PDF/A-1 not active.
+     * Indicates which PDF profiles are active (PDF/A, PDF/X etc.)
      */
-    protected PDFAMode pdfAMode = PDFAMode.DISABLED;
+    protected PDFProfile pdfProfile = new PDFProfile(this);
     
     /**
      * the /Root object
@@ -142,8 +141,8 @@
     /**
      * the colorspace (0=RGB, 1=CMYK)
      */
-    protected PDFColorSpace colorspace =
-        new PDFColorSpace(PDFColorSpace.DEVICE_RGB);
+    protected PDFDeviceColorSpace colorspace =
+        new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_RGB);
 
     /**
      * the counter for Pattern name numbering (e.g. 'Pattern1')
@@ -268,26 +267,9 @@
         }
     }
 
-    /** @return the PDF/A mode currently active. */
-    public PDFAMode getPDFAMode() {
-        return this.pdfAMode;
-    }
-    
-    /**
-     * Sets the active PDF/A mode. This must be set immediately after calling the constructor so
-     * the checks will be activated.
-     * @param mode one of the PDFAMode constants
-     */
-    public void setPDFAMode(PDFAMode mode) {
-        if (mode == null) {
-            throw new NullPointerException("mode must not be null");
-        }
-        if (mode == PDFAMode.PDFA_1A) {
-            throw new UnsupportedOperationException("PDF/A-1a is not implemented, yet");
-        } else if (mode == PDFAMode.PDFA_1B) {
-            //you got the green light!
-        }
-        this.pdfAMode = mode;
+    /** @return the PDF profile currently active. */
+    public PDFProfile getProfile() {
+        return this.pdfProfile;
     }
     
     /**
@@ -514,9 +496,7 @@
      * @param params The encryption parameters for the pdf file
      */
     public void setEncryption(PDFEncryptionParams params) {
-        if (getPDFAMode().isPDFA1LevelB()) {
-            throw new PDFConformanceException("PDF/A-1 doesn't allow encrypted PDFs");
-        }
+        getProfile().verifyEncryptionAllowed();
         this.encryption = PDFEncryptionManager.newInstance(++this.objectcount, params);
         ((PDFObject)this.encryption).setDocument(this);
         if (encryption != null) {
@@ -658,7 +638,7 @@
      *
      * @return the color space
      */
-    public PDFColorSpace getPDFColorSpace() {
+    public PDFDeviceColorSpace getPDFColorSpace() {
         return this.colorspace;
     }
 
@@ -866,9 +846,7 @@
     public void outputHeader(OutputStream stream) throws IOException {
         this.position = 0;
 
-        if (getPDFAMode().isPDFA1LevelB() && getPDFVersion() != PDF_VERSION_1_4) {
-            throw new PDFConformanceException("PDF version must be 1.4 for " + getPDFAMode());
-        }
+        getProfile().verifyPDFVersion();
         
         byte[] pdf = ("%PDF-" + getPDFVersionString() + "\n").getBytes();
         stream.write(pdf);
@@ -899,10 +877,10 @@
             String s = PDFText.toHex(res);
             return "/ID [" + s + " " + s + "]";
         } catch (NoSuchAlgorithmException e) {
-            if (getPDFAMode().isPDFA1LevelB()) {
+            if (getProfile().isIDEntryRequired()) {
                 throw new UnsupportedOperationException("MD5 not available: " + e.getMessage());
             } else {
-                return ""; //Entry is optional if PDF/A is not active
+                return ""; //Entry is optional if PDF/A or PDF/X are not active
             }
         }
     }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFactory.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFactory.java?rev=414272&r1=414271&r2=414272&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFactory.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFactory.java Wed Jun 14 07:34:29 2006
@@ -24,6 +24,8 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.MalformedURLException;
+import java.util.BitSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import javax.xml.transform.Source;
@@ -34,6 +36,7 @@
 
 // Apache libs
 import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.output.ByteArrayOutputStream;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -435,7 +438,7 @@
      * @return the PDF shading that was created
      */
     public PDFShading makeShading(PDFResourceContext res, int theShadingType,
-                                  PDFColorSpace theColorSpace,
+                                  PDFDeviceColorSpace theColorSpace,
                                   List theBackground, List theBBox,
                                   boolean theAntiAlias, List theDomain,
                                   List theMatrix,
@@ -487,7 +490,7 @@
      * @return the PDF shading that was created
      */
     public PDFShading makeShading(PDFResourceContext res, int theShadingType,
-                                  PDFColorSpace theColorSpace,
+                                  PDFDeviceColorSpace theColorSpace,
                                   List theBackground, List theBBox,
                                   boolean theAntiAlias, List theCoords,
                                   List theDomain, PDFFunction theFunction,
@@ -540,7 +543,7 @@
      * @return the PDF shading that was created
      */
     public PDFShading makeShading(PDFResourceContext res, int theShadingType,
-                                  PDFColorSpace theColorSpace,
+                                  PDFDeviceColorSpace theColorSpace,
                                   List theBackground, List theBBox,
                                   boolean theAntiAlias,
                                   int theBitsPerCoordinate,
@@ -595,7 +598,7 @@
      * @return the PDF shading that was created
      */
     public PDFShading makeShading(PDFResourceContext res, int theShadingType,
-                                  PDFColorSpace theColorSpace,
+                                  PDFDeviceColorSpace theColorSpace,
                                   List theBackground, List theBBox,
                                   boolean theAntiAlias,
                                   int theBitsPerCoordinate,
@@ -718,7 +721,7 @@
      * @return the PDF pattern that was created
      */
     public PDFPattern makeGradient(PDFResourceContext res, boolean radial,
-                                   PDFColorSpace theColorspace,
+                                   PDFDeviceColorSpace theColorspace,
                                    List theColors, List theBounds,
                                    List theCoords, List theMatrix) {
         PDFShading myShad;
@@ -887,6 +890,7 @@
     }
 
     private String getGoToReference(String destination, float yoffset) {
+        getDocument().getProfile().verifyActionAllowed();
         String goToReference = null;
         PDFGoTo gt = new PDFGoTo(destination);
         gt.setYPosition(yoffset);
@@ -914,6 +918,7 @@
      * @return the pdf goto remote object
      */
     private PDFGoToRemote getGoToPDFAction(String file, String dest, int page) {
+        getDocument().getProfile().verifyActionAllowed();
         PDFFileSpec fileSpec = new PDFFileSpec(file);
         PDFFileSpec oldspec = getDocument().findFileSpec(fileSpec);
         if (oldspec == null) {
@@ -1122,10 +1127,47 @@
                 descriptor.setFontFile(desc.getFontType(), stream);
                 getDocument().registerObject(stream);
             }
+            CustomFont font = getCustomFont(desc);
+            if (font instanceof CIDFont) {
+                CIDFont cidFont = (CIDFont)font;
+                buildCIDSet(descriptor, cidFont);
+            }
         }
         return descriptor;
     }
 
+    private void buildCIDSet(PDFFontDescriptor descriptor, CIDFont cidFont) {
+        BitSet cidSubset = new BitSet();
+        Iterator iter = cidFont.usedGlyphs.keySet().iterator();
+        while (iter.hasNext()) {
+            Integer cid = (Integer)iter.next();
+            cidSubset.set(cid.intValue());
+        }
+        PDFStream cidSet = makeStream(null, true);
+        ByteArrayOutputStream baout = new ByteArrayOutputStream(cidSubset.length() / 8 + 1);
+        int value = 0;
+        for (int i = 0, c = cidSubset.length(); i < c; i++) {
+            int shift = i % 8;
+            boolean b = cidSubset.get(i); 
+            if (b) {
+                value |= 1 << 7 - shift; 
+            }
+            if (shift == 7) {
+                baout.write(value);
+                value = 0;
+            }
+        }
+        baout.write(value);
+        try {
+            cidSet.setData(baout.toByteArray());
+            descriptor.setCIDSet(cidSet);
+        } catch (IOException ioe) {
+            log.error(
+                    "Failed to write CIDSet [" + cidFont + "] "
+                    + cidFont.getFontName(), ioe);
+        }
+    }
+
     /**
      * Embeds a font.
      * @param desc FontDescriptor of the font.
@@ -1137,18 +1179,7 @@
                                                 + desc.getFontType());
         }
 
-        Typeface tempFont;
-        if (desc instanceof LazyFont) {
-            tempFont = ((LazyFont)desc).getRealFont();
-        } else {
-            tempFont = (Typeface)desc;
-        }
-        if (!(tempFont instanceof CustomFont)) {
-            throw new IllegalArgumentException(
-                      "FontDescriptor must be instance of CustomFont, but is a "
-                       + desc.getClass().getName());
-        }
-        CustomFont font = (CustomFont)tempFont;
+        CustomFont font = getCustomFont(desc);
 
         InputStream in = null;
         try {
@@ -1227,6 +1258,21 @@
         }
     }
 
+    private CustomFont getCustomFont(FontDescriptor desc) {
+        Typeface tempFont;
+        if (desc instanceof LazyFont) {
+            tempFont = ((LazyFont)desc).getRealFont();
+        } else {
+            tempFont = (Typeface)desc;
+        }
+        if (!(tempFont instanceof CustomFont)) {
+            throw new IllegalArgumentException(
+                      "FontDescriptor must be instance of CustomFont, but is a "
+                       + desc.getClass().getName());
+        }
+        return (CustomFont)tempFont;
+    }
+
 
     /* ========================= streams =================================== */
 
@@ -1258,7 +1304,7 @@
      * Create a PDFICCStream
      * @see PDFXObject
      * @see org.apache.fop.image.JpegImage
-     * @see org.apache.fop.pdf.PDFColorSpace
+     * @see org.apache.fop.pdf.PDFDeviceColorSpace
      * @return the new PDF ICC stream object
      */
     public PDFICCStream makePDFICCStream() {
@@ -1273,6 +1319,28 @@
     }
 
     /* ========================= misc. objects ============================= */
+
+    /**
+     * Makes a new ICCBased color space and registers it in the resource context.
+     * @param res the PDF resource context to add the shading, may be null
+     * @param explicitName the explicit name for the color space, may be null
+     * @param iccStream the ICC stream to associate with this color space
+     * @return the newly instantiated color space
+     */
+    public PDFICCBasedColorSpace makeICCBasedColorSpace(PDFResourceContext res,
+            String explicitName, PDFICCStream iccStream) {
+        PDFICCBasedColorSpace cs = new PDFICCBasedColorSpace(explicitName, iccStream);
+        
+        getDocument().registerObject(cs);
+
+        if (res != null) {
+            res.getPDFResources().addColorSpace(cs);
+        } else {
+            getDocument().getResources().addColorSpace(cs);
+        }
+        
+        return cs;
+    }
 
     /**
      * make an Array object (ex. Widths array for a font)

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFont.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFont.java?rev=414272&r1=414271&r2=414272&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFont.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFont.java Wed Jun 14 07:34:29 2006
@@ -193,9 +193,10 @@
      * Validates the PDF object prior to serialization.
      */
     protected void validate() {
-        if (getDocumentSafely().getPDFAMode().isPDFA1LevelB()) {
+        if (getDocumentSafely().getProfile().isFontEmbeddingRequired()) {
             if (this.getClass() == PDFFont.class) {
-                throw new PDFConformanceException("For PDF/A-1, all fonts, even the base 14"
+                throw new PDFConformanceException("For " + getDocumentSafely().getProfile() 
+                    + ", all fonts, even the base 14"
                     + " fonts, have to be embedded! Offending font: " + this.basefont);
             }
         }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFontDescriptor.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFontDescriptor.java?rev=414272&r1=414271&r2=414272&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFontDescriptor.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFontDescriptor.java Wed Jun 14 07:34:29 2006
@@ -44,6 +44,7 @@
     private int maxWidth = 0;
     private int missingWidth = 0;
     private AbstractPDFStream fontfile;
+    private AbstractPDFStream cidSet;
     // private String charSet = null;
 
     private FontType subtype;
@@ -119,6 +120,19 @@
         return this.fontfile;
     }
     
+    /**
+     * Sets the CIDSet stream for this font descriptor. (Optional)
+     * @param cidSet the CIDSet stream
+     */
+    public void setCIDSet(AbstractPDFStream cidSet) {
+        this.cidSet = cidSet;
+    }
+    
+    /** @return the CIDSet stream or null if not applicable */
+    public AbstractPDFStream getCIDSet() {
+        return this.cidSet;
+    }
+    
     // public void setCharSet(){}//for subset fonts
 
     /**
@@ -176,6 +190,10 @@
                 p.append("\n/FontFile2 ");
             }
             p.append(fontfile.referencePDF());
+        }
+        if (getCIDSet() != null) {
+            p.append("\n/CIDSet ");
+            p.append(getCIDSet().referencePDF());
         }
         // charSet for subset fonts // not yet implemented
         // CID optional field

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFontNonBase14.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFontNonBase14.java?rev=414272&r1=414271&r2=414272&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFontNonBase14.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFFontNonBase14.java Wed Jun 14 07:34:29 2006
@@ -95,9 +95,10 @@
     
     /** @see org.apache.fop.pdf.PDFFont#validate() */
     protected void validate() {
-        if (getDocumentSafely().getPDFAMode().isPDFA1LevelB()) {
+        if (getDocumentSafely().getProfile().isFontEmbeddingRequired()) {
             if (this.getDescriptor().getFontFile() == null) {
-                throw new PDFConformanceException("For PDF/A-1, all fonts have to be embedded!");
+                throw new PDFConformanceException("For " + getDocumentSafely().getProfile() 
+                    + ", all fonts have to be embedded!");
             }
         }
     }

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFICCBasedColorSpace.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFICCBasedColorSpace.java?rev=414272&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFICCBasedColorSpace.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFICCBasedColorSpace.java Wed Jun 14 07:34:29 2006
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.pdf;
+
+/**
+ * Represents an ICCBased color space in PDF.
+ */
+public class PDFICCBasedColorSpace extends PDFObject implements PDFColorSpace {
+
+    private PDFICCStream iccStream;
+    private String explicitName;
+    
+    /**
+     * Constructs a the ICCBased color space with an explicit name (ex. "DefaultRGB").
+     * @param explicitName an explicit name or null if a name should be generated
+     * @param iccStream the ICC stream to associate with this color space
+     */
+    public PDFICCBasedColorSpace(String explicitName, PDFICCStream iccStream) {
+        this.explicitName = explicitName;
+        this.iccStream = iccStream;
+    }
+    
+    /**
+     * Constructs a the ICCBased color space.
+     * @param iccStream the ICC stream to associate with this color space
+     */
+    public PDFICCBasedColorSpace(PDFICCStream iccStream) {
+        this(null, iccStream);
+    }
+    
+    /** @return the ICC stream associated with this color space */
+    public PDFICCStream getICCStream() {
+        return this.iccStream;
+    }
+    
+    /** @see org.apache.fop.pdf.PDFColorSpace#getNumComponents() */
+    public int getNumComponents() {
+        return iccStream.getICCProfile().getNumComponents();
+    }
+
+    /** @see org.apache.fop.pdf.PDFColorSpace#getName() */
+    public String getName() {
+        if (explicitName != null) {
+            return explicitName;
+        } else {
+            return "ICC" + iccStream.getObjectNumber();
+        }
+    }
+
+    /** @see org.apache.fop.pdf.PDFColorSpace#isDeviceColorSpace() */
+    public boolean isDeviceColorSpace() {
+        return false;
+    }
+
+    /** @see org.apache.fop.pdf.PDFColorSpace#isRGBColorSpace() */
+    public boolean isRGBColorSpace() {
+        return getNumComponents() == 3;
+    }
+
+    /** @see org.apache.fop.pdf.PDFColorSpace#isCMYKColorSpace() */
+    public boolean isCMYKColorSpace() {
+        return getNumComponents() == 4;
+    }
+
+    /** @see org.apache.fop.pdf.PDFColorSpace#isGrayColorSpace() */
+    public boolean isGrayColorSpace() {
+        return getNumComponents() == 1;
+    }
+
+    /** @see org.apache.fop.pdf.PDFObject#toPDFString() */
+    protected String toPDFString() {
+        StringBuffer sb = new StringBuffer(64);
+        sb.append(getObjectID());
+        sb.append("[/ICCBased ").append(getICCStream().referencePDF()).append("]");
+        sb.append("\nendobj\n");
+        return sb.toString();
+    }
+
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFICCBasedColorSpace.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFICCStream.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFICCStream.java?rev=414272&r1=414271&r2=414272&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFICCStream.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFICCStream.java Wed Jun 14 07:34:29 2006
@@ -27,11 +27,8 @@
  */
 public class PDFICCStream extends PDFStream {
     
-    private int origLength;
-    private int len1, len3;
-
     private ICC_Profile cp;
-    private PDFColorSpace pdfColorSpace;
+    private PDFDeviceColorSpace pdfColorSpace;
 
     /**
      * @see org.apache.fop.pdf.PDFObject#PDFObject()
@@ -43,14 +40,19 @@
 
     /**
      * Sets the color space to encode in PDF.
-     * @param cp the ICC profile
+     * @param icc the ICC profile
      * @param alt the PDF color space
      */
-    public void setColorSpace(ICC_Profile cp, PDFColorSpace alt) {
-        this.cp = cp;
+    public void setColorSpace(ICC_Profile icc, PDFDeviceColorSpace alt) {
+        this.cp = icc;
         pdfColorSpace = alt;
     }
 
+    /** @return the ICC profile */
+    public ICC_Profile getICCProfile() {
+        return this.cp;
+    }
+    
     /**
      * overload the base object method so we don't have to copy
      * byte arrays around so much
@@ -81,7 +83,7 @@
         sb.append("/N " + cp.getNumComponents());
 
         if (pdfColorSpace != null) {
-            sb.append("\n/Alternate /" + pdfColorSpace.getColorSpacePDFString() + " ");
+            sb.append("\n/Alternate /" + pdfColorSpace.getName() + " ");
         }
 
         sb.append("\n/Length " + lengthEntry);

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFImage.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFImage.java?rev=414272&r1=414271&r2=414272&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFImage.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFImage.java Wed Jun 14 07:34:29 2006
@@ -65,7 +65,7 @@
      *
      * @return the color space
      */
-    PDFColorSpace getColorSpace();
+    PDFDeviceColorSpace getColorSpace();
 
     /**
      * Get the bits per pixel for this image.

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFInfo.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFInfo.java?rev=414272&r1=414271&r2=414272&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFInfo.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFInfo.java Wed Jun 14 07:34:29 2006
@@ -146,14 +146,17 @@
      * @see org.apache.fop.pdf.PDFObject#toPDF()
      */
     public byte[] toPDF() {
+        PDFProfile profile = getDocumentSafely().getProfile(); 
         ByteArrayOutputStream bout = new ByteArrayOutputStream(128);
         try {
             bout.write(encode(getObjectID()));
             bout.write(encode("<<\n"));
-            if (title != null) {
+            if (title != null && title.length() > 0) {
                 bout.write(encode("/Title "));
                 bout.write(encodeText(this.title));
                 bout.write(encode("\n"));
+            } else {
+                profile.verifyTitleAbsent();
             }
             if (author != null) {
                 bout.write(encode("/Author "));
@@ -187,7 +190,23 @@
             }
             bout.write(encode("/CreationDate "));
             bout.write(encodeString(formatDateTime(creationDate)));
-            bout.write(encode("\n>>\nendobj\n"));
+            bout.write(encode("\n"));
+            
+            if (profile.isModDateRequired()) {
+                bout.write(encode("/ModDate "));
+                bout.write(encodeString(formatDateTime(creationDate)));
+                bout.write(encode("\n"));
+            }
+            if (profile.isPDFXActive()) {
+                bout.write(encode("/GTS_PDFXVersion "));
+                bout.write(encodeString(profile.getPDFXMode().getName()));
+                bout.write(encode("\n"));
+            }
+            if (profile.isTrappedEntryRequired()) {
+                bout.write(encode("/Trapped /False\n"));
+            }
+            
+            bout.write(encode(">>\nendobj\n"));
         } catch (IOException ioe) {
             log.error("Ignored I/O exception", ioe);
         }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFLink.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFLink.java?rev=414272&r1=414271&r2=414272&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFLink.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFLink.java Wed Jun 14 07:34:29 2006
@@ -71,8 +71,9 @@
      * @see org.apache.fop.pdf.PDFObject#toPDFString()
      */
     public String toPDFString() {
+        getDocumentSafely().getProfile().verifyAnnotAllowed();
         String fFlag = "";
-        if (getDocumentSafely().getPDFAMode().isPDFA1LevelB()) {
+        if (getDocumentSafely().getProfile().getPDFAMode().isPDFA1LevelB()) {
             int f = 0;
             f |= 1 << (3 - 1); //Print, bit 3
             f |= 1 << (4 - 1); //NoZoom, bit 4

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFMetadata.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFMetadata.java?rev=414272&r1=414271&r2=414272&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFMetadata.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFMetadata.java Wed Jun 14 07:34:29 2006
@@ -133,7 +133,7 @@
     /** @see org.apache.fop.pdf.AbstractPDFStream#buildStreamDict(String) */
     protected String buildStreamDict(String lengthEntry) {
         final String filterEntry = getFilterList().buildFilterDictEntries();
-        if (getDocumentSafely().getPDFAMode().isPDFA1LevelB() 
+        if (getDocumentSafely().getProfile().getPDFAMode().isPDFA1LevelB() 
                 && filterEntry != null && filterEntry.length() > 0) {
             throw new PDFConformanceException(
                     "The Filter key is prohibited when PDF/A-1 is active");
@@ -248,6 +248,12 @@
         el = doc.createElementNS(XMPConstants.XMP_BASIC_NAMESPACE, "xmp:CreateDate");
         desc.appendChild(el);
         el.appendChild(doc.createTextNode(formatISO8601Date(info.getCreationDate())));
+        PDFProfile profile = pdfDoc.getProfile(); 
+        if (profile.isModDateRequired()) {
+            el = doc.createElementNS(XMPConstants.XMP_BASIC_NAMESPACE, "xmp:ModifyDate");
+            desc.appendChild(el);
+            el.appendChild(doc.createTextNode(formatISO8601Date(info.getCreationDate())));
+        }
         if (info.getCreator() != null) {
             el = doc.createElementNS(XMPConstants.XMP_BASIC_NAMESPACE, "xmp:CreatorTool");
             desc.appendChild(el);
@@ -274,7 +280,7 @@
         el.appendChild(doc.createTextNode(pdfDoc.getPDFVersionString()));
         
         //PDF/A identification
-        PDFAMode pdfaMode = pdfDoc.getPDFAMode(); 
+        PDFAMode pdfaMode = pdfDoc.getProfile().getPDFAMode(); 
         if (pdfaMode.isPDFA1LevelB()) {
             createPDFAIndentification(doc, rdf, 
                     XMPConstants.PDF_A_IDENTIFICATION, "pdfaid", pdfaMode);

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFPage.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFPage.java?rev=414272&r1=414271&r2=414272&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFPage.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFPage.java Wed Jun 14 07:34:29 2006
@@ -157,11 +157,13 @@
     public String toPDFString() {
         StringBuffer sb = new StringBuffer();
 
+        String box = "[ 0 0 " + getWidth() + " " + getHeight() + " ]";
         sb = sb.append(getObjectID()
                        + "<< /Type /Page\n" 
                        + "/Parent " + this.parentRef + "\n"
-                       + "/MediaBox [ 0 0 " + getWidth() + " "
-                       + getHeight() + " ]\n" 
+                       + "/MediaBox " + box + "\n" 
+                       + "/TrimBox " + box + "\n" //Needed for PDF/X
+                       + "/BleedBox " + box + "\n" //Recommended by PDF/X
                        + "/Resources " + this.resources.referencePDF() + "\n" 
                        + "/Contents " + this.contents.referencePDF() + "\n");
         if (this.annotList != null) {

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFPathPaint.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFPathPaint.java?rev=414272&r1=414271&r2=414272&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFPathPaint.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFPathPaint.java Wed Jun 14 07:34:29 2006
@@ -27,7 +27,7 @@
     /**
      * The color space for this paint
      */
-    protected PDFColorSpace colorSpace;
+    protected PDFDeviceColorSpace colorSpace;
 
     /**
      * Get the PDF string for setting the path paint.

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFProfile.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFProfile.java?rev=414272&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFProfile.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFProfile.java Wed Jun 14 07:34:29 2006
@@ -0,0 +1,244 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.pdf;
+
+import java.text.MessageFormat;
+
+/**
+ * This class allows tracks the enabled PDF profiles (PDF/A and PDF/X) and provides methods to
+ * the libarary and its users to enable the generation of PDFs conforming to the enabled PDF
+ * profiles.
+ * <p>
+ * Some profile from PDF/X and PDF/A can be active simultaneously (example: PDF/A-1 and 
+ * PDF/X-3:2003).
+ */
+public class PDFProfile {
+
+    /**
+     * Indicates the PDF/A mode currently active. Defaults to "no restrictions", i.e. 
+     * PDF/A not active.
+     */
+    protected PDFAMode pdfAMode = PDFAMode.DISABLED;
+    
+    /**
+     * Indicates the PDF/X mode currently active. Defaults to "no restrictions", i.e. 
+     * PDF/X not active.
+     */
+    protected PDFXMode pdfXMode = PDFXMode.DISABLED;
+    
+    private PDFDocument doc;
+    
+    /**
+     * Main constructor
+     * @param doc the PDF document
+     */
+    public PDFProfile(PDFDocument doc) {
+        this.doc = doc;
+    }
+    
+    /**
+     * Validates if the requested profile combination is compatible.
+     */
+    protected void validateProfileCombination() {
+        if (pdfAMode != PDFAMode.DISABLED) {
+            if (pdfAMode == PDFAMode.PDFA_1A) {
+                throw new UnsupportedOperationException("PDF/A-1a is not implemented, yet");
+            }
+            if (pdfAMode == PDFAMode.PDFA_1B) {
+                if (pdfXMode != PDFXMode.DISABLED && pdfXMode != PDFXMode.PDFX_3_2003) {
+                    throw new PDFConformanceException(
+                            pdfAMode + " and " + pdfXMode + " are not compatible!");
+                }
+            }
+        }
+    }
+    
+    /** @return the PDFDocument this profile is attached to */
+    public PDFDocument getDocument() {
+        return this.doc;
+    }
+    
+    /** @return the PDF/A mode */
+    public PDFAMode getPDFAMode() {
+        return this.pdfAMode;
+    }
+    
+    /** @return true if any PDF/A mode is active */
+    public boolean isPDFAActive() {
+        return getPDFAMode() != PDFAMode.DISABLED;
+    }
+    
+    /**
+     * Sets the PDF/A mode
+     * @param mode the PDF/A mode
+     */
+    public void setPDFAMode(PDFAMode mode) {
+        if (mode == null) {
+            mode = PDFAMode.DISABLED;
+        }
+        this.pdfAMode = mode;
+        validateProfileCombination();
+    }
+    
+    /** @return the PDF/X mode */
+    public PDFXMode getPDFXMode() {
+        return this.pdfXMode;
+    }
+    
+    /** @return true if any PDF/X mode is active */
+    public boolean isPDFXActive() {
+        return getPDFXMode() != PDFXMode.DISABLED;
+    }
+    
+    /**
+     * Sets the PDF/X mode
+     * @param mode the PDF/X mode
+     */
+    public void setPDFXMode(PDFXMode mode) {
+        if (mode == null) {
+            mode = PDFXMode.DISABLED;
+        }
+        this.pdfXMode = mode;
+        validateProfileCombination();
+    }
+
+    /** @see java.lang.Object#toString() */
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        if (isPDFAActive() && isPDFXActive()) {
+            sb.append("[").append(getPDFAMode()).append(",").append(getPDFXMode()).append("]");
+        } else if (isPDFAActive()) {
+            sb.append(getPDFAMode());
+        } else if (isPDFXActive()) {
+            sb.append(getPDFXMode());
+        } else {
+            sb.append(super.toString());
+        }
+        return sb.toString();
+    }
+    
+    //---------=== Info and validation methods ===---------
+    
+    private String format(String pattern, Object arg) {
+        return MessageFormat.format(pattern, new Object[] {arg});
+    }
+    
+    /** Checks if encryption is allowed. */
+    public void verifyEncryptionAllowed() {
+        final String err = "{0} doesn't allow encrypted PDFs";
+        if (isPDFAActive()) {
+            throw new PDFConformanceException(format(err, getPDFAMode()));
+        }
+        if (isPDFXActive()) {
+            throw new PDFConformanceException(format(err, getPDFXMode()));
+        }
+    }
+
+    /** Checks if PostScript XObjects are allowed. */
+    public void verifyPSXObjectsAllowed() {
+        final String err = "PostScript XObjects are prohibited when {0}"
+                + " is active. Convert EPS graphics to another format.";
+        if (isPDFAActive()) {
+            throw new PDFConformanceException(format(err, getPDFAMode()));
+        }
+        if (isPDFXActive()) {
+            throw new PDFConformanceException(format(err, getPDFXMode()));
+        }
+    }
+
+    /**
+     * Checks if the use of transparency is allowed.
+     * @param context Context information for the user to identify the problem spot
+     */
+    public void verifyTransparencyAllowed(String context) {
+        final String err = "{0} does not allow the use of transparency. ({1})";
+        if (isPDFAActive()) {
+            throw new PDFConformanceException(MessageFormat.format(err, 
+                    new Object[] {getPDFAMode(), context}));
+        }
+        if (isPDFXActive()) {
+            throw new PDFConformanceException(MessageFormat.format(err, 
+                    new Object[] {getPDFXMode(), context}));
+        }
+    }
+
+    /** Checks if the right PDF version is set. */
+    public void verifyPDFVersion() {
+        final String err = "PDF version must be 1.4 for {0}";
+        if (getPDFAMode().isPDFA1LevelB() 
+                && getDocument().getPDFVersion() != PDFDocument.PDF_VERSION_1_4) {
+            throw new PDFConformanceException(format(err, getPDFAMode()));
+        }
+        if (getPDFXMode() == PDFXMode.PDFX_3_2003 
+                && getDocument().getPDFVersion() != PDFDocument.PDF_VERSION_1_4) {
+            throw new PDFConformanceException(format(err, getPDFXMode()));
+        }
+    }
+    
+    /** @return true if the ID entry must be present in the trailer. */
+    public boolean isIDEntryRequired() {
+        return isPDFAActive() || isPDFXActive();
+    }
+
+    /** @return true if all fonts need to be embedded. */
+    public boolean isFontEmbeddingRequired() {
+        return isPDFAActive() || isPDFXActive();
+    }
+
+    /** Checks if a title may be absent. */
+    public void verifyTitleAbsent() {
+        if (isPDFXActive()) {
+            final String err = "{0} requires the title to be set.";
+            throw new PDFConformanceException(format(err, getPDFXMode()));
+        }
+    }
+
+    /** @return true if the ModDate Info entry must be present. */
+    public boolean isModDateRequired() {
+        return getPDFXMode() == PDFXMode.PDFX_3_2003;
+    }
+
+    /** @return true if the Trapped Info entry must be present. */
+    public boolean isTrappedEntryRequired() {
+        return getPDFXMode() == PDFXMode.PDFX_3_2003;
+    }
+
+    /** @return true if annotations are allowed */
+    public boolean isAnnotationAllowed() {
+        return !isPDFXActive();
+    }
+    
+    /** Checks if annotations are allowed. */
+    public void verifyAnnotAllowed() {
+        if (!isAnnotationAllowed()) {
+            final String err = "{0} does not allow annotations inside the printable area.";
+            //Note: this rule is simplified. Refer to the standard for details.
+            throw new PDFConformanceException(format(err, getPDFXMode()));
+        }
+    }
+
+    /** Checks if Actions are allowed. */
+    public void verifyActionAllowed() {
+        if (isPDFXActive()) {
+            final String err = "{0} does not allow Actions.";
+            throw new PDFConformanceException(format(err, getPDFXMode()));
+        }
+    }
+
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFProfile.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFResources.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFResources.java?rev=414272&r1=414271&r2=414272&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFResources.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFResources.java Wed Jun 14 07:34:29 2006
@@ -21,6 +21,7 @@
 import org.apache.fop.fonts.FontInfo;
 import org.apache.fop.fonts.Typeface;
 import org.apache.fop.fonts.FontDescriptor;
+import org.apache.fop.util.ColorProfileUtil;
 
 // Java
 import java.util.Iterator;
@@ -62,6 +63,12 @@
      */
     protected Set gstates = new HashSet();
 
+    /** Map of color spaces (key: color space name) */
+    protected Map colorSpaces = new HashMap();
+    
+    /** Map of ICC color spaces (key: ICC profile description) */
+    protected Map iccColorSpaces = new HashMap();
+    
     /**
      * create a /Resources object.
      *
@@ -140,6 +147,37 @@
     }
 
     /**
+     * Add a ColorSpace dictionary to the resources.
+     * @param colorSpace the color space 
+     */
+    public void addColorSpace(PDFICCBasedColorSpace colorSpace) {
+        this.colorSpaces.put(colorSpace.getName(), colorSpace);
+        String desc = ColorProfileUtil.getICCProfileDescription(
+                colorSpace.getICCStream().getICCProfile());
+        this.iccColorSpaces.put(desc, colorSpace);
+    }
+
+    /**
+     * Returns a ICCBased color space by profile name.
+     * @param desc the name of the color space
+     * @return the requested color space or null if it wasn't found
+     */
+    public PDFICCBasedColorSpace getICCColorSpaceByProfileName(String desc) {
+        PDFICCBasedColorSpace cs = (PDFICCBasedColorSpace)this.iccColorSpaces.get(desc);
+        return cs;
+    }
+
+    /**
+     * Returns a color space by name.
+     * @param name the name of the color space
+     * @return the requested color space or null if it wasn't found
+     */
+    public PDFICCBasedColorSpace getColorSpace(String name) {
+        PDFICCBasedColorSpace cs = (PDFICCBasedColorSpace)this.colorSpaces.get(name);
+        return cs;
+    }
+
+    /**
      * represent the object in PDF
      * This adds the references to all the objects in the current
      * resource context.
@@ -214,6 +252,17 @@
                 PDFGState gs = (PDFGState)iter.next();
                 p = p.append("  /" + gs.getName() + " "
                              + gs.referencePDF()
+                             + "\n");
+            }
+            p = p.append(">>\n");
+        }
+
+        if (!this.colorSpaces.isEmpty()) {
+            p = p.append("/ColorSpace <<\n");
+            for (Iterator iter = colorSpaces.values().iterator(); iter.hasNext();) {
+                PDFICCBasedColorSpace colorSpace = (PDFICCBasedColorSpace)iter.next();
+                p = p.append("  /" + colorSpace.getName() + " "
+                             + colorSpace.referencePDF()
                              + "\n");
             }
             p = p.append(">>\n");

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFShading.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFShading.java?rev=414272&r1=414271&r2=414272&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFShading.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFShading.java Wed Jun 14 07:34:29 2006
@@ -47,7 +47,7 @@
     /**
      * A ColorSpace representing the colorspace. "DeviceRGB" is an example.
      */
-    protected PDFColorSpace colorSpace = null;
+    protected PDFDeviceColorSpace colorSpace = null;
 
     /**
      * The background color. Since shading is opaque,
@@ -163,7 +163,7 @@
      * It's optional, the default is the identity matrix
      * @param theFunction The PDF Function that maps an (x,y) location to a color
      */
-    public PDFShading(int theShadingType, PDFColorSpace theColorSpace,
+    public PDFShading(int theShadingType, PDFDeviceColorSpace theColorSpace,
                       List theBackground, List theBBox,
                       boolean theAntiAlias, List theDomain,
                       List theMatrix, PDFFunction theFunction) {
@@ -201,7 +201,7 @@
      *                  and end colors past the start and end points
      * The default is [false, false]
      */
-    public PDFShading(int theShadingType, PDFColorSpace theColorSpace,
+    public PDFShading(int theShadingType, PDFDeviceColorSpace theColorSpace,
                       List theBackground, List theBBox,
                       boolean theAntiAlias, List theCoords,
                       List theDomain, PDFFunction theFunction,
@@ -241,7 +241,7 @@
      * @param theDecode List of Doubles see PDF 1.3 spec pages 303 to 312.
      * @param theFunction the PDFFunction
      */
-    public PDFShading(int theShadingType, PDFColorSpace theColorSpace,
+    public PDFShading(int theShadingType, PDFDeviceColorSpace theColorSpace,
                       List theBackground, List theBBox,
                       boolean theAntiAlias, int theBitsPerCoordinate,
                       int theBitsPerComponent, int theBitsPerFlag,
@@ -280,7 +280,7 @@
      * @param theVerticesPerRow number of vertices in each "row" of the lattice.
      * @param theFunction The PDFFunction that's mapped on to this shape
      */
-    public PDFShading(int theShadingType, PDFColorSpace theColorSpace,
+    public PDFShading(int theShadingType, PDFDeviceColorSpace theColorSpace,
                       List theBackground, List theBBox,
                       boolean theAntiAlias, int theBitsPerCoordinate,
                       int theBitsPerComponent, List theDecode,
@@ -341,7 +341,7 @@
             + "<< \n/ShadingType " + this.shadingType + " \n");
         if (this.colorSpace != null) {
             p.append("/ColorSpace /"
-                     + this.colorSpace.getColorSpacePDFString() + " \n");
+                     + this.colorSpace.getName() + " \n");
         }
 
         if (this.background != null) {

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFXMode.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFXMode.java?rev=414272&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFXMode.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFXMode.java Wed Jun 14 07:34:29 2006
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.pdf;
+
+/** Enum class for PDF/X modes. */
+public final class PDFXMode {
+
+    /** PDF/X disabled */
+    public static final PDFXMode DISABLED = new PDFXMode("PDF/X disabled");
+    /** PDF/X-3:2003 enabled */
+    public static final PDFXMode PDFX_3_2003 = new PDFXMode("PDF/X-3:2003");
+    
+    private String name;
+
+    /**
+     * Constructor to add a new named item.
+     * @param name Name of the item.
+     */
+    private PDFXMode(String name) {
+        this.name = name;
+    }
+
+    /** @return the name of the enum */
+    public String getName() {
+        return this.name;
+    }
+    
+    /**
+     * Returns the mode enum object given a String.
+     * @param s the string
+     * @return the PDFAMode enum object (DISABLED will be returned if no match is found)
+     */
+    public static PDFXMode valueOf(String s) {
+        if (PDFX_3_2003.getName().equalsIgnoreCase(s)) {
+            return PDFX_3_2003;
+        } else {
+            return DISABLED;
+        }
+    }
+    
+    /** @see java.lang.Object#toString() */
+    public String toString() {
+        return name;
+    }
+    
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFXMode.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFXObject.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFXObject.java?rev=414272&r1=414271&r2=414272&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFXObject.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFXObject.java Wed Jun 14 07:34:29 2006
@@ -94,10 +94,7 @@
     
     private String buildDictionaryFromPS(String lengthEntry, 
                                          String dictEntries) {
-        if (getDocumentSafely().getPDFAMode().isPDFA1LevelB()) {
-            throw new PDFConformanceException("PostScript XObjects are prohibited when PDF/A"
-                    + " is active. Convert EPS graphics to another format.");
-        }
+        getDocumentSafely().getProfile().verifyPSXObjectsAllowed();
         StringBuffer sb = new StringBuffer(128);
         sb.append(getObjectID());
         sb.append("<</Type /XObject\n");
@@ -126,8 +123,8 @@
             sb.append("/ColorSpace [/ICCBased "
                 + pdfICCStream.referencePDF() + "]\n");
         } else {
-            PDFColorSpace cs = pdfimage.getColorSpace();
-            sb.append("/ColorSpace /" + cs.getColorSpacePDFString()
+            PDFDeviceColorSpace cs = pdfimage.getColorSpace();
+            sb.append("/ColorSpace /" + cs.getName()
                   + "\n");
         }
 
@@ -136,11 +133,11 @@
              * this will invert the values - too bad if it's not
              * a PhotoShop image...
              */
-            if (pdfimage.getColorSpace().getColorSpace() == PDFColorSpace.DEVICE_CMYK) {
+            if (pdfimage.getColorSpace().getColorSpace() == PDFDeviceColorSpace.DEVICE_CMYK) {
                 sb.append("/Decode [ 1.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0 ]\n");
-            } else if (pdfimage.getColorSpace().getColorSpace() == PDFColorSpace.DEVICE_RGB) {
+            } else if (pdfimage.getColorSpace().getColorSpace() == PDFDeviceColorSpace.DEVICE_RGB) {
                 sb.append("/Decode [ 1.0 0.0 1.0 0.0 1.0 0.0 ]\n");
-            } else if (pdfimage.getColorSpace().getColorSpace() == PDFColorSpace.DEVICE_GRAY) {
+            } else if (pdfimage.getColorSpace().getColorSpace() == PDFDeviceColorSpace.DEVICE_GRAY) {
                 sb.append("/Decode [ 1.0 0.0 ]\n");
             }
         }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/RendererContext.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/RendererContext.java?rev=414272&r1=414271&r2=414272&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/RendererContext.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/RendererContext.java Wed Jun 14 07:34:29 2006
@@ -130,6 +130,11 @@
             this.context = context;
         }
         
+        /** @return the user agent */
+        public FOUserAgent getUserAgent() {
+            return context.getUserAgent();
+        }
+
         /** @return the currentXPosition */
         public int getCurrentXPosition() {
             return ((Integer)context.getProperty(RendererContextConstants.XPOS)).intValue();

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/FopPDFImage.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/FopPDFImage.java?rev=414272&r1=414271&r2=414272&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/FopPDFImage.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/FopPDFImage.java Wed Jun 14 07:34:29 2006
@@ -21,6 +21,7 @@
 import org.apache.commons.logging.LogFactory;
 import org.apache.fop.pdf.PDFConformanceException;
 import org.apache.fop.pdf.PDFFilterList;
+import org.apache.fop.pdf.PDFICCBasedColorSpace;
 import org.apache.fop.pdf.PDFImage;
 import org.apache.fop.pdf.PDFFilter;
 import org.apache.fop.pdf.PDFICCStream;
@@ -28,7 +29,7 @@
 import org.apache.fop.pdf.PDFDocument;
 import org.apache.fop.pdf.DCTFilter;
 import org.apache.fop.pdf.CCFFilter;
-import org.apache.fop.pdf.PDFColorSpace;
+import org.apache.fop.pdf.PDFDeviceColorSpace;
 import org.apache.fop.pdf.PDFXObject;
 import org.apache.fop.pdf.BitmapImage;
 import org.apache.fop.util.ColorProfileUtil;
@@ -118,23 +119,35 @@
             fopImage.load(FopImage.BITMAP);
         }
         ICC_Profile prof = fopImage.getICCProfile();
-        PDFColorSpace pdfCS = toPDFColorSpace(fopImage.getColorSpace());
+        PDFDeviceColorSpace pdfCS = toPDFColorSpace(fopImage.getColorSpace());
         if (prof != null) {
             boolean defaultsRGB = ColorProfileUtil.isDefaultsRGB(prof);
+            String desc = ColorProfileUtil.getICCProfileDescription(prof);
             if (log.isDebugEnabled()) {
-                String desc = ColorProfileUtil.getICCProfileDescription(prof);
                 log.debug("Image returns ICC profile: " + desc + ", default sRGB=" + defaultsRGB);
             }
-            //TODO Instead of skipping the ICC profile for sRGB, let's think about embedding our 
-            //own sRGB profile instead, but if possible only once per PDF (Need a new structure in 
-            //the PDF library for that).
+            PDFICCBasedColorSpace cs = doc.getResources().getICCColorSpaceByProfileName(desc);
             if (!defaultsRGB) {
-                pdfICCStream = doc.getFactory().makePDFICCStream();
-                pdfICCStream.setColorSpace(prof, pdfCS);
+                if (cs == null) {
+                    pdfICCStream = doc.getFactory().makePDFICCStream();
+                    pdfICCStream.setColorSpace(prof, pdfCS);
+                    cs = doc.getFactory().makeICCBasedColorSpace(null, null, pdfICCStream);
+                } else {
+                    pdfICCStream = cs.getICCStream();
+                }
+            } else {
+                if (cs == null && "sRGB".equals(desc)) {
+                    //It's the default sRGB profile which we mapped to DefaultRGB in PDFRenderer
+                    cs = doc.getResources().getColorSpace("DefaultRGB");
+                }
+                pdfICCStream = cs.getICCStream();
             }
         }
         //Handle transparency mask if applicable
         if (fopImage.hasSoftMask()) {
+            doc.getProfile().verifyTransparencyAllowed(fopImage.getOriginalURI());
+            //TODO Implement code to combine image with background color if transparency is not
+            //allowed (need BufferedImage support for that)
             byte [] softMask = fopImage.getSoftMask();
             if (softMask == null) {
                 return;
@@ -142,19 +155,20 @@
             BitmapImage fopimg = new BitmapImage
                 ("Mask:" + key, fopImage.getWidth(), fopImage.getHeight(), 
                  softMask, null);
-            fopimg.setColorSpace(new PDFColorSpace(PDFColorSpace.DEVICE_GRAY));
+            fopimg.setColorSpace(new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_GRAY));
             PDFXObject xobj = doc.addImage(null, fopimg);
             softMaskRef = xobj.referencePDF();
         }
-        if (doc.getPDFAMode().isPDFA1LevelB()) {
+        if (doc.getProfile().getPDFAMode().isPDFA1LevelB()) {
             if (pdfCS != null
-                    && pdfCS.getColorSpace() != PDFColorSpace.DEVICE_RGB 
-                    && pdfCS.getColorSpace() != PDFColorSpace.DEVICE_GRAY
+                    && pdfCS.getColorSpace() != PDFDeviceColorSpace.DEVICE_RGB 
+                    && pdfCS.getColorSpace() != PDFDeviceColorSpace.DEVICE_GRAY
                     && prof == null) {
                 //See PDF/A-1, ISO 19005:1:2005(E), 6.2.3.3
                 //FOP is currently restricted to DeviceRGB if PDF/A-1 is active.
                 throw new PDFConformanceException(
-                        "PDF/A-1 does not allow mixing DeviceRGB and DeviceCMYK.");
+                        "PDF/A-1 does not allow mixing DeviceRGB and DeviceCMYK: " 
+                                + fopImage.getOriginalURI());
             }
         }
     }
@@ -176,7 +190,7 @@
     /**
      * @see org.apache.fop.pdf.PDFImage#getColorSpace()
      */
-    public PDFColorSpace getColorSpace() {
+    public PDFDeviceColorSpace getColorSpace() {
         // DeviceGray, DeviceRGB, or DeviceCMYK
         if (isCCF || isDCT || isPS) {
             return toPDFColorSpace(fopImage.getColorSpace());
@@ -320,21 +334,21 @@
      * @param cs ColorSpace instance
      * @return PDFColorSpace new converted object
      */
-    public static PDFColorSpace toPDFColorSpace(ColorSpace cs) {
+    public static PDFDeviceColorSpace toPDFColorSpace(ColorSpace cs) {
         if (cs == null) {
             return null;
         }
 
-        PDFColorSpace pdfCS = new PDFColorSpace(0);
+        PDFDeviceColorSpace pdfCS = new PDFDeviceColorSpace(0);
         switch(cs.getType()) {
             case ColorSpace.TYPE_CMYK:
-                pdfCS.setColorSpace(PDFColorSpace.DEVICE_CMYK);
+                pdfCS.setColorSpace(PDFDeviceColorSpace.DEVICE_CMYK);
             break;
             case ColorSpace.TYPE_RGB:
-                pdfCS.setColorSpace(PDFColorSpace.DEVICE_RGB);
+                pdfCS.setColorSpace(PDFDeviceColorSpace.DEVICE_RGB);
             break;
             case ColorSpace.TYPE_GRAY:
-                pdfCS.setColorSpace(PDFColorSpace.DEVICE_GRAY);
+                pdfCS.setColorSpace(PDFDeviceColorSpace.DEVICE_GRAY);
             break;
         }
         return pdfCS;

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFGraphics2DAdapter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFGraphics2DAdapter.java?rev=414272&r1=414271&r2=414272&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFGraphics2DAdapter.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFGraphics2DAdapter.java Wed Jun 14 07:34:29 2006
@@ -20,19 +20,23 @@
 
 import java.awt.Color;
 import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
 import java.awt.geom.AffineTransform;
 import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
 import java.io.IOException;
 
-import org.apache.fop.render.Graphics2DAdapter;
+import org.apache.fop.render.AbstractGraphics2DAdapter;
 import org.apache.fop.render.Graphics2DImagePainter;
 import org.apache.fop.render.RendererContext;
+import org.apache.fop.render.RendererContext.RendererContextWrapper;
 import org.apache.fop.svg.PDFGraphics2D;
 
 /**
  * Graphics2DAdapter implementation for PDF.
  */
-public class PDFGraphics2DAdapter implements Graphics2DAdapter {
+public class PDFGraphics2DAdapter extends AbstractGraphics2DAdapter {
 
     private PDFRenderer renderer;
 
@@ -50,7 +54,6 @@
             int x, int y, int width, int height) throws IOException {
         
         PDFSVGHandler.PDFInfo pdfInfo = PDFSVGHandler.getPDFInfo(context);
-        
         float fwidth = width / 1000f;
         float fheight = height / 1000f;
         float fx = x / 1000f;
@@ -78,6 +81,9 @@
 
 
         final boolean textAsShapes = false;
+        if (pdfInfo.pdfContext == null) {
+            pdfInfo.pdfContext = pdfInfo.pdfPage;
+        }
         PDFGraphics2D graphics = new PDFGraphics2D(textAsShapes, 
                 pdfInfo.fi, pdfInfo.pdfDoc,
                 pdfInfo.pdfContext, pdfInfo.pdfPage.referencePDF(),
@@ -91,13 +97,35 @@
         graphics.setPDFState(pdfInfo.pdfState);
         graphics.setOutputStream(pdfInfo.outputStream);
 
-        Rectangle2D area = new Rectangle2D.Double(0.0, 0.0, imw, imh);
-        painter.paint(graphics, area);
+        if (pdfInfo.paintAsBitmap) {
+            //Fallback solution: Paint to a BufferedImage
+            int resolution = (int)Math.round(context.getUserAgent().getTargetResolution());
+            RendererContextWrapper ctx = RendererContext.wrapRendererContext(context);
+            BufferedImage bi = paintToBufferedImage(painter, ctx, resolution, false, false);
+
+            float scale = PDFRenderer.NORMAL_PDF_RESOLUTION 
+                            / context.getUserAgent().getTargetResolution();
+            graphics.drawImage(bi, new AffineTransform(scale, 0, 0, scale, 0, 0), null);
+        } else {
+            Rectangle2D area = new Rectangle2D.Double(0.0, 0.0, imw, imh);
+            painter.paint(graphics, area);
+        }
 
         pdfInfo.currentStream.add(graphics.getString());
         renderer.restoreGraphicsState();
         pdfInfo.pdfState.pop();
-    
+    }
+
+    /**
+     * @see org.apache.fop.render.AbstractGraphics2DAdapter#setRenderingHintsForBufferedImage(
+     *              java.awt.Graphics2D)
+     */
+    protected void setRenderingHintsForBufferedImage(Graphics2D g2d) {
+        super.setRenderingHintsForBufferedImage(g2d);
+        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
+                RenderingHints.VALUE_ANTIALIAS_ON);
+        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, 
+                RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
     }
 
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org