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/11/13 11:08:21 UTC

svn commit: r474225 [1/2] - in /xmlgraphics/fop/trunk: ./ src/java/org/apache/fop/apps/ src/java/org/apache/fop/area/ src/java/org/apache/fop/fo/ src/java/org/apache/fop/fo/expr/ src/java/org/apache/fop/fo/flow/ src/java/org/apache/fop/fo/pagination/ s...

Author: jeremias
Date: Mon Nov 13 02:08:19 2006
New Revision: 474225

URL: http://svn.apache.org/viewvc?view=rev&rev=474225
Log:
Bugzilla #40729:
Support for the rgb-icc() function and for a proprietary cmyk() function (for device CMYK colors only through the PDF renderer so far).
Submitted by: Peter Coppens <pc.subscriptions.at.gmail.com>

Patch slightly modified to comply with our Java conventions, plus some minor editing.

Added:
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/CMYKcolorFunction.java   (with props)
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/ICCColorFunction.java   (with props)
    xmlgraphics/fop/trunk/src/java/org/apache/fop/util/ColorExt.java   (with props)
    xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/color_1.xml   (with props)
Modified:
    xmlgraphics/fop/trunk/build.xml
    xmlgraphics/fop/trunk/src/java/org/apache/fop/apps/FopFactory.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/area/AreaTreeParser.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Trait.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOPropertyMapping.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOText.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/PropertyList.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/NCnameProperty.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/NumericProperty.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/PropertyParser.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/RGBColorFunction.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/SystemColorFunction.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/BidiOverride.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/Block.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/Character.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/InitialPropertySet.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/InlineLevel.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/PageNumber.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/PageNumberCitation.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/ColorProfile.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/Declarations.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/ColorProperty.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonTextDecoration.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/NumberProperty.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/Property.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFColor.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderer.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/xml/XMLRenderer.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFGraphics2D.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/traits/BorderProps.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/util/CMYKColorSpace.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/util/ColorUtil.java
    xmlgraphics/fop/trunk/status.xml
    xmlgraphics/fop/trunk/test/java/org/apache/fop/traits/BorderPropsTestCase.java
    xmlgraphics/fop/trunk/test/java/org/apache/fop/traits/TraitColorTestCase.java

Modified: xmlgraphics/fop/trunk/build.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/build.xml?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/build.xml (original)
+++ xmlgraphics/fop/trunk/build.xml Mon Nov 13 02:08:19 2006
@@ -604,6 +604,7 @@
       <include name="org/apache/fop/image/Abstract*"/>
       <include name="org/apache/fop/image/analyser/*.class"/>
       <include name="org/apache/fop/util/CMYKColorSpace*.class"/>
+      <include name="org/apache/fop/util/ColorExt*.class"/>
       <include name="org/apache/fop/util/ASCII*.class"/>
       <include name="org/apache/fop/util/*OutputStream.class"/>
       <include name="org/apache/fop/util/SubInputStream.class"/>

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/apps/FopFactory.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/apps/FopFactory.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/apps/FopFactory.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/apps/FopFactory.java Mon Nov 13 02:08:19 2006
@@ -19,17 +19,22 @@
 
 package org.apache.fop.apps;
 
+import java.awt.color.ColorSpace;
+import java.awt.color.ICC_ColorSpace;
+import java.awt.color.ICC_Profile;
 import java.io.File;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.net.MalformedURLException;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Map;
 import java.util.Set;
 
 import javax.xml.transform.Source;
 import javax.xml.transform.TransformerException;
 import javax.xml.transform.URIResolver;
+import javax.xml.transform.stream.StreamSource;
 
 import org.xml.sax.SAXException;
 
@@ -119,11 +124,16 @@
 
     private Set ignoredNamespaces = new java.util.HashSet();
     
+    /** Map with cached ICC based ColorSpace objects. */
+    private Map colorSpaceMap = null;
+    
     /**
      * Main constructor.
      */
     protected FopFactory() {
         this.elementMappingRegistry = new ElementMappingRegistry(this);
+        // Use a synchronized Map - I am not really sure this is needed, but better safe than sorry.
+        this.colorSpaceMap = Collections.synchronizedMap(new java.util.HashMap());
     }
     
     /**
@@ -632,7 +642,63 @@
         }
         return source;
     }
+        
+    /**
+     * Create (if needed) and return an ICC ColorSpace instance.
+     * 
+     * The ICC profile source is taken from the src attribute of the color-profile FO element.
+     * If the ICC ColorSpace is not yet in the cache a new one is created and stored in the cache.
+     * 
+     * The FOP URI resolver is used to try and locate the ICC file. 
+     * If that fails null is returned.
+     * 
+     * @param base a base URI to resolve relative URIs
+     * @param iccProfileSrc ICC Profile source to return a ColorSpace for
+     * @return ICC ColorSpace object or null if ColorSpace could not be created 
+     */
+    public ColorSpace getColorSpace(String base, String iccProfileSrc) {
+        ColorSpace colorSpace = null;
+        if (!this.colorSpaceMap.containsKey(base + iccProfileSrc)) {
+            try {
+                ICC_Profile iccProfile = null;
+                // First attempt to use the FOP URI resolver to locate the ICC
+                // profile
+                Source src = this.resolveURI(iccProfileSrc, base);
+                if (src != null && src instanceof StreamSource) {
+                    // FOP URI resolver found ICC profile - create ICC profile
+                    // from the Source
+                    iccProfile = ICC_Profile.getInstance(((StreamSource) src)
+                            .getInputStream());
+                } else {
+                    // TODO - Would it make sense to fall back on VM ICC
+                    // resolution
+                    // Problem is the cache might be more difficult to maintain
+                    // 
+                    // FOP URI resolver did not find ICC profile - perhaps the
+                    // Java VM can find it?
+                    // iccProfile = ICC_Profile.getInstance(iccProfileSrc);
+                }
+                if (iccProfile != null) {
+                    colorSpace = new ICC_ColorSpace(iccProfile);
+                }
+            } catch (IOException e) {
+                // Ignore exception - will be logged a bit further down
+                // (colorSpace == null case)
+            }
 
-    
+            if (colorSpace != null) {
+                // Put in cache (not when VM resolved it as we can't control
+                this.colorSpaceMap.put(base + iccProfileSrc, colorSpace);
+            } else {
+                // TODO To avoid an excessive amount of warnings perhaps
+                // register a null ColorMap in the colorSpaceMap
+                log.warn("Color profile '" + iccProfileSrc + "' not found.");
+            }
+        } else {
+            colorSpace = (ColorSpace) this.colorSpaceMap.get(base
+                    + iccProfileSrc);
+        }
+        return colorSpace;
+    }
     
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/AreaTreeParser.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/AreaTreeParser.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/AreaTreeParser.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/AreaTreeParser.java Mon Nov 13 02:08:19 2006
@@ -928,16 +928,15 @@
                         area.addTrait(trait, value);
                     } else if (cl == Color.class) {
                         try {
-                            area.addTrait(trait, ColorUtil.parseColorString(value));
+                            area.addTrait(trait, ColorUtil.parseColorString(this.userAgent, value));
                         } catch (PropertyException e) {
                             throw new IllegalArgumentException(e.getMessage());
                         }
                     } else if (cl == Background.class) {
                         Background bkg = new Background();
                         try {
-                            Color col = ColorUtil
-                                    .parseColorString(attributes
-                                            .getValue("bkg-color"));
+                            Color col = ColorUtil.parseColorString(
+                                        this.userAgent, attributes.getValue("bkg-color"));
                             bkg.setColor(col);
                         } catch (PropertyException e) {
                             throw new IllegalArgumentException(e.getMessage());
@@ -970,7 +969,7 @@
                         }
                         area.addTrait(trait, bkg);
                     } else if (cl == BorderProps.class) {
-                        area.addTrait(trait, BorderProps.valueOf(value));
+                        area.addTrait(trait, BorderProps.valueOf(this.userAgent, value));
                     }
                 } else {
                     if (trait == Trait.FONT) {

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Trait.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Trait.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Trait.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Trait.java Mon Nov 13 02:08:19 2006
@@ -571,7 +571,7 @@
         public String toString() {
             StringBuffer sb = new StringBuffer();
             if (color != null) {
-                sb.append("color=").append(ColorUtil.colorTOsRGBString(color));
+                sb.append("color=").append(ColorUtil.colorToString(color));
             }
             if (url != null) {
                 if (color != null) {

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOPropertyMapping.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOPropertyMapping.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOPropertyMapping.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOPropertyMapping.java Mon Nov 13 02:08:19 2006
@@ -22,6 +22,7 @@
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.datatypes.LengthBase;
 import org.apache.fop.fo.expr.PropertyException;
 import org.apache.fop.fo.properties.BackgroundPositionShorthandParser;
@@ -564,7 +565,9 @@
                     Property p, PropertyList propertyList, FObj fo) throws PropertyException {
                 String nameval = p.getNCname();
                 if (nameval != null) {
-                    return new ColorProperty(nameval);
+                    FObj fobj = (fo == null ? propertyList.getFObj() : fo);
+                    FOUserAgent ua = (fobj == null ? null : fobj.getUserAgent());
+                    return new ColorProperty(ua, nameval);
                 }
                 return super.convertPropertyDatatype(p, propertyList, fo);
             }
@@ -1289,7 +1292,7 @@
         m.addEnum("mathematical", getEnumProperty(EN_MATHEMATICAL, "MATHEMATICAL"));
         m.addEnum("central", getEnumProperty(EN_CENTRAL, "CENTRAL"));
         m.addEnum("middle", getEnumProperty(EN_MIDDLE, "MIDDLE"));
-        m.addEnum("text-after-edge", getEnumProperty(EN_TEXT_AFTER_EDGE, "TEXT_AFTER_EDGE"        ));
+        m.addEnum("text-after-edge", getEnumProperty(EN_TEXT_AFTER_EDGE, "TEXT_AFTER_EDGE"));
         m.addEnum("text-before-edge", getEnumProperty(EN_TEXT_BEFORE_EDGE, "TEXT_BEFORE_EDGE"));
         m.setDefault("auto");
         m.addShorthand(s_generics[PR_VERTICAL_ALIGN]);

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOText.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOText.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOText.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOText.java Mon Nov 13 02:08:19 2006
@@ -145,7 +145,7 @@
      * @see org.apache.fop.fo.FONode#clone(FONode, boolean)
      */
     public FONode clone(FONode parent, boolean removeChildren)
-        throws FOPException {
+            throws FOPException {
         FOText ft = (FOText) super.clone(parent, removeChildren);
         if (removeChildren) {
             //not really removing, but just make sure the char array 
@@ -164,8 +164,7 @@
     public void bind(PropertyList pList) throws FOPException {
         commonFont = pList.getFontProps();
         commonHyphenation = pList.getHyphenationProps();
-        
-        color = pList.get(Constants.PR_COLOR).getColor();
+        color = pList.get(Constants.PR_COLOR).getColor(getUserAgent());
         lineHeight = pList.get(Constants.PR_LINE_HEIGHT).getSpace();
         letterSpacing = pList.get(Constants.PR_LETTER_SPACING);
         whiteSpaceCollapse = pList.get(Constants.PR_WHITE_SPACE_COLLAPSE).getEnum();

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/PropertyList.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/PropertyList.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/PropertyList.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/PropertyList.java Mon Nov 13 02:08:19 2006
@@ -421,7 +421,7 @@
                 }
             } catch (PropertyException e) {
                 log.error("Ignoring property: " 
-                        + attributeName + "=\"" + attributeValue + "\"");
+                        + attributeName + "=\"" + attributeValue + "\" (" + e.getMessage() + ")");
             }
         }
     }

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/CMYKcolorFunction.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/CMYKcolorFunction.java?view=auto&rev=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/CMYKcolorFunction.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/CMYKcolorFunction.java Mon Nov 13 02:08:19 2006
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+ 
+package org.apache.fop.fo.expr;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.fo.properties.ColorProperty;
+import org.apache.fop.fo.properties.Property;
+
+/**
+ * Implements the cmyk() function.
+ */
+class CMYKcolorFunction extends FunctionBase {
+    
+    /**
+     * cmyk takes four arguments. 
+     * @see org.apache.fop.fo.expr.Function#nbArgs() 
+     */
+    public int nbArgs() {
+        return 4;
+    }
+    
+    /** @see org.apache.fop.fo.expr.Function */
+    public Property eval(Property[] args,
+                         PropertyInfo pInfo) throws PropertyException {
+        StringBuffer sb = new StringBuffer();
+        sb.append("cmyk(" + args[0] + "," + args[1] + "," + args[2] + "," + args[3] + ")");
+        FOUserAgent ua = (pInfo == null) 
+                ? null 
+                : (pInfo.getFO() == null ? null : pInfo.getFO().getUserAgent());
+        return new ColorProperty(ua, sb.toString());
+    }
+
+
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/CMYKcolorFunction.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/ICCColorFunction.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/ICCColorFunction.java?view=auto&rev=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/ICCColorFunction.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/ICCColorFunction.java Mon Nov 13 02:08:19 2006
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+ 
+package org.apache.fop.fo.expr;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.fo.pagination.ColorProfile;
+import org.apache.fop.fo.pagination.Declarations;
+import org.apache.fop.fo.properties.ColorProperty;
+import org.apache.fop.fo.properties.Property;
+
+/**
+ * Implements the rgb-icc() function.
+ */
+class ICCColorFunction extends FunctionBase {
+    
+    /**
+     * rgb-icc takes a variable number of arguments. 
+     * At least 4 should be passed - returns -4 
+     * @see org.apache.fop.fo.expr.Function#nbArgs() 
+     */
+    public int nbArgs() {
+        return -4;
+    }
+    
+    /** @see org.apache.fop.fo.expr.Function */
+    public Property eval(Property[] args,
+                         PropertyInfo pInfo) throws PropertyException {
+        StringBuffer sb = new StringBuffer();
+
+        // Map color profile NCNAME to src from declarations/color-profile element
+        String colorProfileName = args[3].getString();
+        Declarations decls = pInfo.getFO().getRoot().getDeclarations();
+        ColorProfile cp = decls.getColorProfile(colorProfileName);
+        if (cp == null) {
+            PropertyException pe = new PropertyException("The " + colorProfileName 
+                    + " color profile was not declared");
+            pe.setPropertyInfo(pInfo);
+            throw pe;
+        }
+        String src = cp.getSrc();
+        
+        // rgb-icc is replaced with fop-rgb-icc which has an extra fifth argument containing the 
+        // color profile src attribute as it is defined in the color-profile declarations element.
+        sb.append("fop-rgb-icc(" + args[0]);
+        for (int ix = 1; ix < args.length; ix++) {
+            if (ix == 3) {
+                sb.append("," + colorProfileName); 
+                sb.append(",\"" + src + "\""); 
+            } else {
+                sb.append("," + args[ix]);
+            }
+        }
+        sb.append(")");
+        FOUserAgent ua = (pInfo == null
+                ? null
+                : (pInfo.getFO() == null ? null : pInfo.getFO().getUserAgent()));
+        return new ColorProperty(ua, sb.toString());
+    }
+
+
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/ICCColorFunction.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/NCnameProperty.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/NCnameProperty.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/NCnameProperty.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/NCnameProperty.java Mon Nov 13 02:08:19 2006
@@ -21,6 +21,7 @@
 
 import java.awt.Color;
 
+import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.fo.properties.Property;
 import org.apache.fop.util.ColorUtil;
 
@@ -42,13 +43,17 @@
     /**
      * If a system color, return the corresponding value.
      * 
+     * @param foUserAgent 
+     *     Reference to FOP user agent - keeps track of cached ColorMaps for ICC colors
      * @return Color object corresponding to the NCName
      */
-    public Color getColor()  {
+    public Color getColor(FOUserAgent foUserAgent)  {
         try { 
-            return ColorUtil.parseColorString(ncName);
+            return ColorUtil.parseColorString(foUserAgent, ncName);
         } catch (PropertyException e) {
-            //TODO: This should probably print an error message?
+            //Not logging this error since for properties like "border" you would get an awful
+            //lot of error messages for things like "solid" not being valid colors.
+            //log.error("Can't create color value: " + e.getMessage());
             return null;
         }
     }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/NumericProperty.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/NumericProperty.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/NumericProperty.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/NumericProperty.java Mon Nov 13 02:08:19 2006
@@ -20,6 +20,8 @@
 package org.apache.fop.fo.expr;
 
 import java.awt.Color;
+
+import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.datatypes.Length;
 import org.apache.fop.datatypes.PercentBaseContext;
 import org.apache.fop.datatypes.Numeric;
@@ -105,8 +107,8 @@
         return null;
     }
 
-    /** @see org.apache.fop.fo.properties.Property#getColor() */
-    public Color getColor() {
+    /** @see org.apache.fop.fo.properties.Property#getColor(FOUserAgent) */
+    public Color getColor(FOUserAgent foUserAgent) {
         // TODO:  try converting to numeric number and then to color
         return null;
     }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/PropertyParser.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/PropertyParser.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/PropertyParser.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/PropertyParser.java Mon Nov 13 02:08:19 2006
@@ -19,6 +19,7 @@
 
 package org.apache.fop.fo.expr;
 
+import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.datatypes.Numeric;
 import org.apache.fop.datatypes.PercentBase;
 import org.apache.fop.fo.properties.ColorProperty;
@@ -30,6 +31,8 @@
 import org.apache.fop.fo.properties.StringProperty;
 
 import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
 
 /**
  * Class to parse XSL-FO property expressions.
@@ -62,12 +65,12 @@
                           new PPColWidthFunction());
         FUNCTION_TABLE.put("label-end", new LabelEndFunction());
         FUNCTION_TABLE.put("body-start", new BodyStartFunction());
+        FUNCTION_TABLE.put("rgb-icc", new ICCColorFunction());
+        FUNCTION_TABLE.put("cmyk", new CMYKcolorFunction()); //non-standard!!!
 
         /**
          * * NOT YET IMPLEMENTED!!!
-         * FUNCTION_TABLE.put("icc-color", new ICCcolorFunction());
          * FUNCTION_TABLE.put("system-font", new SystemFontFunction());
-         *
          * FUNCTION_TABLE.put("merge-property-values", new MergePropsFunction());
          */
     }
@@ -295,7 +298,10 @@
             break;
 
         case TOK_COLORSPEC:
-            prop = new ColorProperty(currentTokenValue);
+            FOUserAgent ua = (propInfo == null) 
+                ? null
+                : (propInfo.getFO() == null ? null : propInfo.getFO().getUserAgent());
+            prop = new ColorProperty(ua, currentTokenValue);
             break;
 
         case TOK_FUNCTION_LPAR:
@@ -307,7 +313,12 @@
             next();
             // Push new function (for function context: getPercentBase())
             propInfo.pushFunction(function);
-            prop = function.eval(parseArgs(function), propInfo);
+            if (function.nbArgs() < 0) {
+                // Negative nbArgs --> function with variable number of arguments
+                prop = function.eval(parseVarArgs(function), propInfo);
+            } else {
+                prop = function.eval(parseArgs(function), propInfo);
+            }
             propInfo.popFunction();
             return prop;
         
@@ -361,6 +372,54 @@
                                         + ", but got " + i + " args for function");
         }
         return args;
+    }
+    
+    /**
+     * 
+     * Parse a comma separated list of function arguments. Each argument
+     * may itself be an expression. This method consumes the closing right
+     * parenthesis of the argument list.
+     * 
+     * The method differs from parseArgs in that it accepts a variable 
+     * number of arguments.
+     * 
+     * @param function The function object for which the arguments are 
+     * collected.
+     * @return An array of Property objects representing the arguments
+     * found.
+     * @throws PropertyException If the number of arguments found isn't equal
+     * to the number expected.
+     * 
+     * TODO Merge this with parseArgs? 
+     */
+    Property[] parseVarArgs(Function function) throws PropertyException {
+        // For variable argument functions the minimum number of arguments is returned as a 
+        // negative integer from the nbArgs method
+        int nbArgs = -function.nbArgs();
+        List args = new LinkedList();
+        Property prop;
+        if (currentToken == TOK_RPAR) {
+            // No args: func()
+            next();
+        } else {
+            while (true) {
+                prop = parseAdditiveExpr();
+                args.add(prop);
+                // ignore extra args
+                if (currentToken != TOK_COMMA) {
+                    break;
+                }
+                next();
+            }
+            expectRpar();
+        }
+        if (nbArgs > args.size()) {
+            throw new PropertyException("Expected at least " + nbArgs
+                                        + ", but got " + args.size() + " args for function");
+        }
+        Property[] propArray = new Property[args.size()];
+        args.toArray(propArray);
+        return propArray;
     }
 
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/RGBColorFunction.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/RGBColorFunction.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/RGBColorFunction.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/RGBColorFunction.java Mon Nov 13 02:08:19 2006
@@ -19,6 +19,7 @@
  
 package org.apache.fop.fo.expr;
 
+import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.datatypes.PercentBaseContext;
 import org.apache.fop.datatypes.PercentBase;
 import org.apache.fop.fo.properties.ColorProperty;
@@ -46,7 +47,10 @@
     /** @see org.apache.fop.fo.expr.Function */
     public Property eval(Property[] args,
                          PropertyInfo pInfo) throws PropertyException {
-        return new ColorProperty("rgb(" + args[0] + "," + args[1] + "," + args[2] + ")");
+      FOUserAgent ua = (pInfo == null) 
+              ? null 
+              : (pInfo.getFO() == null ? null : pInfo.getFO().getUserAgent());
+      return new ColorProperty(ua, "rgb(" + args[0] + "," + args[1] + "," + args[2] + ")");
 
     }
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/SystemColorFunction.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/SystemColorFunction.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/SystemColorFunction.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/SystemColorFunction.java Mon Nov 13 02:08:19 2006
@@ -19,6 +19,7 @@
  
 package org.apache.fop.fo.expr;
 
+import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.fo.properties.ColorProperty;
 import org.apache.fop.fo.properties.Property;
 
@@ -35,7 +36,10 @@
     /** @see org.apache.fop.fo.expr.Function */
     public Property eval(Property[] args,
                          PropertyInfo pInfo) throws PropertyException {
-        return new ColorProperty("system-color(" + args[0] + ")");
+        FOUserAgent ua = (pInfo == null) 
+                ? null 
+                : (pInfo.getFO() == null ? null : pInfo.getFO().getUserAgent());
+        return new ColorProperty(ua, "system-color(" + args[0] + ")");
 
     }
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/BidiOverride.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/BidiOverride.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/BidiOverride.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/BidiOverride.java Mon Nov 13 02:08:19 2006
@@ -87,7 +87,7 @@
         commonAural = pList.getAuralProps();
         commonFont = pList.getFontProps();
         commonRelativePosition = pList.getRelativePositionProps();
-        prColor = pList.get(PR_COLOR).getColor();
+        prColor = pList.get(PR_COLOR).getColor(getUserAgent());
         // prDirection = pList.get(PR_DIRECTION);
         // prLetterSpacing = pList.get(PR_LETTER_SPACING);
         lineHeight = pList.get(PR_LINE_HEIGHT).getSpace();

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/Block.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/Block.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/Block.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/Block.java Mon Nov 13 02:08:19 2006
@@ -110,7 +110,7 @@
 
         breakAfter = pList.get(PR_BREAK_AFTER).getEnum();
         breakBefore = pList.get(PR_BREAK_BEFORE).getEnum();
-        color = pList.get(PR_COLOR).getColor();
+        color = pList.get(PR_COLOR).getColor(getUserAgent());
         textDepth = pList.get(PR_TEXT_DEPTH).getLength();
         textAltitude = pList.get(PR_TEXT_ALTITUDE).getLength();
         hyphenationKeep = pList.get(PR_HYPHENATION_KEEP).getEnum();

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/Character.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/Character.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/Character.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/Character.java Mon Nov 13 02:08:19 2006
@@ -117,7 +117,7 @@
         alignmentBaseline = pList.get(PR_ALIGNMENT_BASELINE).getEnum();
         baselineShift = pList.get(PR_BASELINE_SHIFT).getLength();
         character = pList.get(PR_CHARACTER).getCharacter();
-        color = pList.get(PR_COLOR).getColor();
+        color = pList.get(PR_COLOR).getColor(getUserAgent());
         dominantBaseline = pList.get(PR_DOMINANT_BASELINE).getEnum();
         textDepth = pList.get(PR_TEXT_DEPTH).getLength();
         textAltitude = pList.get(PR_TEXT_ALTITUDE).getLength();

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/InitialPropertySet.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/InitialPropertySet.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/InitialPropertySet.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/InitialPropertySet.java Mon Nov 13 02:08:19 2006
@@ -73,7 +73,7 @@
         commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
         commonFont = pList.getFontProps();
         commonRelativePosition = pList.getRelativePositionProps();
-        color = pList.get(PR_COLOR).getColor();
+        color = pList.get(PR_COLOR).getColor(getUserAgent());
         id = pList.get(PR_ID).getString();
         // letterSpacing = pList.get(PR_LETTER_SPACING);
         lineHeight = pList.get(PR_LINE_HEIGHT).getSpace();

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/InlineLevel.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/InlineLevel.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/InlineLevel.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/InlineLevel.java Mon Nov 13 02:08:19 2006
@@ -65,7 +65,7 @@
         commonMarginInline = pList.getMarginInlineProps();
         commonAural = pList.getAuralProps();
         commonFont = pList.getFontProps();
-        color = pList.get(PR_COLOR).getColor();
+        color = pList.get(PR_COLOR).getColor(getUserAgent());
         lineHeight = pList.get(PR_LINE_HEIGHT).getSpace();
         visibility = pList.get(PR_VISIBILITY).getEnum();
     }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/PageNumber.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/PageNumber.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/PageNumber.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/PageNumber.java Mon Nov 13 02:08:19 2006
@@ -112,7 +112,7 @@
         wrapOption = pList.get(PR_WRAP_OPTION).getEnum();
 
         // implicit properties
-        color = pList.get(Constants.PR_COLOR).getColor();
+        color = pList.get(Constants.PR_COLOR).getColor(getUserAgent());
     }
 
     /**

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/PageNumberCitation.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/PageNumberCitation.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/PageNumberCitation.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/PageNumberCitation.java Mon Nov 13 02:08:19 2006
@@ -117,7 +117,7 @@
         wrapOption = pList.get(PR_WRAP_OPTION).getEnum();
         
         // implicit properties
-        color = pList.get(Constants.PR_COLOR).getColor();
+        color = pList.get(Constants.PR_COLOR).getColor(getUserAgent());
     }
 
     /**

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/ColorProfile.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/ColorProfile.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/ColorProfile.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/ColorProfile.java Mon Nov 13 02:08:19 2006
@@ -19,24 +19,16 @@
 
 package org.apache.fop.fo.pagination;
 
-// Java
-import java.awt.Color;
-import java.awt.color.ICC_ColorSpace;
-import java.awt.color.ICC_Profile;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-
 import org.apache.fop.apps.FOPException;
 import org.apache.fop.fo.FONode;
 import org.apache.fop.fo.FObj;
 import org.apache.fop.fo.PropertyList;
 import org.apache.fop.fo.ValidationException;
+
 import org.xml.sax.Locator;
 
 /**
  * The fo:color-profile formatting object.
- * TODO: This needs to be implemented properly!
  * This loads the color profile when needed and resolves a requested color.
  */
 public class ColorProfile extends FObj {
@@ -45,8 +37,6 @@
     private String colorProfileName;
     private int renderingIntent;
     // End of property values
-    
-    private ICC_ColorSpace colorSpace = null;
 
     /**
      * @see org.apache.fop.fo.FONode#FONode(FONode)
@@ -80,38 +70,6 @@
         return colorProfileName;
     }
 
-    /**
-     * Get the color specified with the color values from the color profile.
-     * The default values are used if the profile could not be loaded
-     * or the value is not found.
-     * @param colorVals integer array containing the color profile?
-     * @param defR integer value for red channel (0-255)?
-     * @param defG integer value for green channel (0-255)?
-     * @param defB integer value for blue channel (0-255)?
-     * @return the ColorType object corresponding to the input
-     */
-    public Color getColor(int[] colorVals, int defR, int defG, int defB) {
-        // float[] rgbvals = colorSpace.toRGB(colorVals);
-        // return new ColorType(rgbvals);
-        return null;
-    }
-
-    /**
-     * Load the color profile.
-     */
-    private void load() {
-        try {
-            URL url = new URL(src);
-            InputStream is = url.openStream();
-            ICC_Profile iccProfile = ICC_Profile.getInstance(is);
-            colorSpace = new ICC_ColorSpace(iccProfile);
-        } catch (IOException ioe) {
-            getLogger().error("Could not read Color Profile src", ioe);
-        } catch (IllegalArgumentException iae) {
-            getLogger().error("Color Profile src not an ICC Profile", iae);
-        }
-    }
-
     /** @see org.apache.fop.fo.FONode#getLocalName() */
     public String getLocalName() {
         return "color-profile";
@@ -122,5 +80,30 @@
      */
     public int getNameId() {
         return FO_COLOR_PROFILE;
+    }
+    
+    /** 
+     * Get src attribute
+     * 
+     * @return Value of color-profile src attribute
+     */
+    public String getSrc() {
+        return this.src;
+    }
+    
+    /**
+     * Get rendering-intent attribute
+     * 
+     * Returned value is one of
+     *   Constants.EN_AUTO
+     *   Constants.EN_PERCEPTUAL
+     *   Constants.EN_RELATIVE_COLOMETRIC
+     *   Constants.EN_SATURATION
+     *   Constants.EN_ABSOLUTE_COLORMETRIC
+     *    
+     * @return Rendering intent attribute
+     */
+    public int getRenderingIntent() {
+        return this.renderingIntent;
     }
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/Declarations.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/Declarations.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/Declarations.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/pagination/Declarations.java Mon Nov 13 02:08:19 2006
@@ -83,15 +83,7 @@
                 if (node.getName().equals("fo:color-profile")) {
                     ColorProfile cp = (ColorProfile)node;
                     if (!"".equals(cp.getColorProfileName())) {
-                        if (colorProfiles == null) {
-                            colorProfiles = new java.util.HashMap();
-                        }
-                        if (colorProfiles.get(cp.getColorProfileName()) != null) {
-                            // duplicate names
-                            getLogger().warn("Duplicate fo:color-profile profile name : "
-                                    + cp.getColorProfileName());
-                        }
-                        colorProfiles.put(cp.getColorProfileName(), cp);
+                        addColorProfile(cp);
                     } else {
                         getLogger().warn("color-profile-name required for color profile");
                     }
@@ -104,6 +96,18 @@
         childNodes = null;
     }
 
+    private void addColorProfile(ColorProfile cp) {
+        if (colorProfiles == null) {
+            colorProfiles = new java.util.HashMap();
+        }
+        if (colorProfiles.get(cp.getColorProfileName()) != null) {
+            // duplicate names
+            getLogger().warn("Duplicate fo:color-profile profile name: "
+                    + cp.getColorProfileName());
+        }
+        colorProfiles.put(cp.getColorProfileName(), cp);
+    }
+
     /**
      * @see org.apache.fop.fo.FObj#getName()
      */
@@ -117,4 +121,22 @@
     public int getNameId() {
         return FO_DECLARATIONS;
     }
+    
+    /**
+     * Return ColorProfile with given name.
+     * 
+     * @param cpName Name of ColorProfile, i.e. the value of the color-profile-name attribute of 
+     *               the fo:color-profile element
+     * @return The org.apache.fop.fo.pagination.ColorProfile object associated with this 
+     *         color-profile-name or null
+     */
+    public ColorProfile getColorProfile(String cpName) {
+        ColorProfile profile = null;
+        if (this.colorProfiles != null) {
+            profile = (ColorProfile)this.colorProfiles.get(cpName);
+        }
+        return profile;
+    }
+    
+    
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/ColorProperty.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/ColorProperty.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/ColorProperty.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/ColorProperty.java Mon Nov 13 02:08:19 2006
@@ -21,6 +21,7 @@
 
 import java.awt.Color;
 
+import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.fo.FObj;
 import org.apache.fop.fo.PropertyList;
 import org.apache.fop.fo.expr.PropertyException;
@@ -74,7 +75,9 @@
             if (p instanceof ColorProperty) {
                 return p;
             }
-            Color val = p.getColor();
+            FObj fobj = (fo == null ? propertyList.getFObj() : fo);
+            FOUserAgent ua = (fobj == null ? null : fobj.getUserAgent());
+            Color val = p.getColor(ua);
             if (val != null) {
                 return new ColorProperty(val);
             }
@@ -83,17 +86,17 @@
 
     }
 
-
     /**
      * Set the color given a particular String. For a full List of supported
      * values please see ColorUtil.
      * 
+     * @param foUserAgent FOP user agent
      * @param value RGB value as String to be parsed
      * @throws PropertyException if the value can't be parsed
      * @see ColorUtil#parseColorString(String)
      */
-    public ColorProperty(String value) throws PropertyException {
-        this.color = ColorUtil.parseColorString(value);
+    public ColorProperty(FOUserAgent foUserAgent, String value) throws PropertyException {
+        this.color = ColorUtil.parseColorString(foUserAgent, value);
     }
 
     /**
@@ -107,9 +110,10 @@
     
     /**
      * Returns an AWT instance of this color
+     * @param foUserAgent FOP user agent
      * @return float the AWT color represented by this ColorType instance
      */
-    public Color getColor() {
+    public Color getColor(FOUserAgent foUserAgent) {
         return color;
     }
 
@@ -117,7 +121,7 @@
      * @see java.lang.Object#toString()
      */
     public String toString() {
-        return ColorUtil.colorTOsRGBString(color);
+        return ColorUtil.colorToString(color);
     }
 
     /**

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java Mon Nov 13 02:08:19 2006
@@ -144,7 +144,8 @@
     public CommonBorderPaddingBackground(PropertyList pList, FObj fobj) throws PropertyException {
         
         backgroundAttachment = pList.get(Constants.PR_BACKGROUND_ATTACHMENT).getEnum();
-        backgroundColor = pList.get(Constants.PR_BACKGROUND_COLOR).getColor();
+        backgroundColor = pList.get(Constants.PR_BACKGROUND_COLOR).getColor(
+                fobj == null ? null : fobj.getUserAgent());
         if (backgroundColor.getAlpha() == 0) {
             backgroundColor = null;
         }
@@ -206,9 +207,12 @@
         // If style = none, force width to 0, don't get Color (spec 7.7.20)
         int style = pList.get(styleProp).getEnum();
         if (style != Constants.EN_NONE) {
+            FOUserAgent ua = (pList == null) 
+                    ? null 
+                    : (pList.getFObj() == null ? null : pList.getFObj().getUserAgent());
             setBorderInfo(new BorderInfo(style,
                 pList.get(widthProp).getCondLength(),
-                pList.get(colorProp).getColor()), side);
+                pList.get(colorProp).getColor(ua)), side);
         }
     }
     
@@ -290,7 +294,7 @@
 
     public Color getBorderColor(int side) {
         if (borderInfo[side] != null) {
-            return borderInfo[side].mColor;
+            return borderInfo[side].getColor();
         } else {
             return null;
         }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonTextDecoration.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonTextDecoration.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonTextDecoration.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonTextDecoration.java Mon Nov 13 02:08:19 2006
@@ -23,6 +23,8 @@
 import java.util.List;
 
 import java.awt.Color;
+
+import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.PropertyList;
 import org.apache.fop.fo.expr.PropertyException;
@@ -76,6 +78,9 @@
             while (i.hasNext()) {
                 Property prop = (Property)i.next(); 
                 int propEnum = prop.getEnum();
+                FOUserAgent ua = (pList == null)
+                        ? null
+                        : (pList.getFObj() == null ? null : pList.getFObj().getUserAgent());
                 if (propEnum == Constants.EN_NONE) {
                     if (deco != null) {
                         deco.decoration = 0;
@@ -86,33 +91,33 @@
                         deco = new CommonTextDecoration();
                     }
                     deco.decoration |= UNDERLINE;
-                    deco.underColor = pList.get(Constants.PR_COLOR).getColor();
+                    deco.underColor = pList.get(Constants.PR_COLOR).getColor(ua);
                 } else if (propEnum == Constants.EN_NO_UNDERLINE) {
                     if (deco != null) {
                         deco.decoration &= OVERLINE | LINE_THROUGH | BLINK;
-                        deco.underColor = pList.get(Constants.PR_COLOR).getColor();
+                        deco.underColor = pList.get(Constants.PR_COLOR).getColor(ua);
                     }
                 } else if (propEnum == Constants.EN_OVERLINE) {
                     if (deco == null) {
                         deco = new CommonTextDecoration();
                     }
                     deco.decoration |= OVERLINE;
-                    deco.overColor = pList.get(Constants.PR_COLOR).getColor();
+                    deco.overColor = pList.get(Constants.PR_COLOR).getColor(ua);
                 } else if (propEnum == Constants.EN_NO_OVERLINE) {
                     if (deco != null) {
                         deco.decoration &= UNDERLINE | LINE_THROUGH | BLINK;
-                        deco.overColor = pList.get(Constants.PR_COLOR).getColor();
+                        deco.overColor = pList.get(Constants.PR_COLOR).getColor(ua);
                     }
                 } else if (propEnum == Constants.EN_LINE_THROUGH) {
                     if (deco == null) {
                         deco = new CommonTextDecoration();
                     }
                     deco.decoration |= LINE_THROUGH;
-                    deco.throughColor = pList.get(Constants.PR_COLOR).getColor();
+                    deco.throughColor = pList.get(Constants.PR_COLOR).getColor(ua);
                 } else if (propEnum == Constants.EN_NO_LINE_THROUGH) {
                     if (deco != null) {
                         deco.decoration &= UNDERLINE | OVERLINE | BLINK;
-                        deco.throughColor = pList.get(Constants.PR_COLOR).getColor();
+                        deco.throughColor = pList.get(Constants.PR_COLOR).getColor(ua);
                     }
                 } else if (propEnum == Constants.EN_BLINK) {
                     if (deco == null) {

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/NumberProperty.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/NumberProperty.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/NumberProperty.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/NumberProperty.java Mon Nov 13 02:08:19 2006
@@ -21,6 +21,7 @@
 
 import java.awt.Color;
 
+import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.datatypes.Length;
 import org.apache.fop.datatypes.Numeric;
 import org.apache.fop.datatypes.PercentBaseContext;
@@ -176,9 +177,10 @@
 
     /**
      * Convert NumberProperty to a Color. Not sure why this is needed.
+     * @param foUserAgent FOUserAgent 
      * @return Color that corresponds to black
      */
-    public Color getColor() {
+    public Color getColor(FOUserAgent foUserAgent) {
         // TODO: Implement somehow
         // Convert numeric value to color ???
         // Convert to hexadecimal and then try to make it into a color?

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/Property.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/Property.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/Property.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/Property.java Mon Nov 13 02:08:19 2006
@@ -25,6 +25,7 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
+import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.datatypes.Length;
 import org.apache.fop.datatypes.Numeric;
 import org.apache.fop.fo.Constants;
@@ -74,9 +75,10 @@
 
     /**
      * This method expects to be overridden by subclasses
+     * @param foUserAgent FOP user agent
      * @return ColorType property value
      */
-    public Color getColor() {
+    public Color getColor(FOUserAgent foUserAgent) {
         return null;
     }
 

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?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFColor.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFColor.java Mon Nov 13 02:08:19 2006
@@ -19,10 +19,15 @@
  
 package org.apache.fop.pdf;
 
-// Java
+import java.awt.Color;
+import java.awt.color.ColorSpace;
+import java.awt.color.ICC_ColorSpace;
+import java.io.IOException;
 import java.util.List;
 import java.util.ArrayList;
 
+import org.apache.fop.util.ColorExt;
+
 /**
  * PDF Color object.
  * This is used to output color to a PDF content stream.
@@ -38,6 +43,12 @@
     private double magenta = -1.0;
     private double yellow = -1.0;
     private double black = -1.0;
+    
+    // TODO - It would probably be better to reorganize PDFPathPaint/PDFColor/PDFColorSpace
+    //        class hierarchy. However, at this early stages of my FOP understanding, I can 
+    //        not really oversee the consequences of such a switch (nor whether it would be 
+    //        appropriate). 
+    private ColorExt colorExt = null;
 
     /**
      * Create a PDF color with double values ranging from 0 to 1
@@ -54,20 +65,90 @@
         this.green = theGreen;
         this.blue = theBlue;
     }
-
+    
+    /**
+     * Create PDFColor for the given document and based on the java.awt.Color object
+     * 
+     * In case the java.awt.Color is an instance of the ColorExt class a PDFICCStream is added to 
+     * the PDFDocument that is being created
+     * 
+     * @param pdfDoc PDFDocument that is being created
+     * @param col Color object from which to create this PDFColor
+     */
+    public PDFColor(PDFDocument pdfDoc, Color col) {
+        this(col);
+        // TODO - 1) There is a potential conflict when FOP and Batik elements use the same color
+        //           profile name for different profiles.  
+        //        2) In case the same color profile is used with different names it will be 
+        //           included multiple times in the PDF
+        //
+        if (colorExt != null 
+                && pdfDoc.getResources().getColorSpace(colorExt.getIccProfileName()) == null) {
+            PDFICCStream pdfIccStream = new PDFICCStream();
+            ColorSpace ceCs = colorExt.getOrigColorSpace();
+            try {
+                pdfIccStream.setColorSpace(((ICC_ColorSpace)ceCs).getProfile(), null);
+                pdfIccStream.setData(
+                        ((ICC_ColorSpace)colorExt.getColorSpace()).getProfile().getData());
+            } catch (IOException ioe) {
+                log.error("Failed to set profile data for " + colorExt.getIccProfileName());
+            }
+            pdfDoc.registerObject(pdfIccStream);
+            pdfDoc.getFactory().makeICCBasedColorSpace(
+                    null, colorExt.getIccProfileName(), pdfIccStream);
+            if (log.isInfoEnabled()) {
+                log.info("Adding PDFICCStream " + colorExt.getIccProfileName() 
+                        + " for " + colorExt.getIccProfileSrc());
+            }
+        }
+    }
+    
     /**
      * Create a PDF color from a java.awt.Color object.
+     * 
+     * Different Color objects are handled differently. Cases recognized are.
+     * 
+     * 1. CMYK color
+     * 2. ColorExt color
+     * 3. 'Normal' java.awt.Color (RGB case assumed)
      *
-     * @param col the sRGB color
+     * @param col the java.awt.Color object for which to create a PDFColor object
      */
     public PDFColor(java.awt.Color col) {
-        this.colorSpace = new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_RGB);
-        float[] comps = new float[3];
-        comps = col.getColorComponents(comps);
-
-        this.red = comps[0];
-        this.green = comps[1];
-        this.blue = comps[2];
+        ColorSpace cs = col.getColorSpace();
+        ColorExt ce = null;
+        if (col instanceof ColorExt) {
+            ce = (ColorExt)col;
+            cs = ce.getOrigColorSpace();  
+        }
+        if (cs != null && cs.getType() == ColorSpace.TYPE_CMYK) {
+            // CMYK case
+            this.colorSpace = new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_CMYK);
+            float[] cmyk = (ce == null 
+                    ? col.getColorComponents(null)
+                    : ce.getOriginalColorComponents());
+            this.cyan = cmyk[0];
+            this.magenta = cmyk[1];
+            this.yellow = cmyk[2];
+            this.black = cmyk[3];
+        } else if (ce != null) {
+            // ColorExt (ICC) case
+            this.colorExt = ce;
+            float[] rgb = col.getRGBColorComponents(null);
+            this.red = rgb[0];
+            this.green = rgb[1];
+            this.blue = rgb[2];
+            // TODO - See earlier todo
+            this.colorSpace = new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_RGB);
+        } else {
+            // Default (RGB) Color
+            this.colorSpace = new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_RGB);
+            float[] comps = new float[3];
+            comps = col.getColorComponents(comps);
+            this.red = comps[0];
+            this.green = comps[1];
+            this.blue = comps[2];
+        }
     }
     
     /**
@@ -268,9 +349,26 @@
     public String getColorSpaceOut(boolean fillNotStroke) {
         StringBuffer p = new StringBuffer("");
 
-        double tempDouble;
-
-        if (this.colorSpace.getColorSpace()
+        if (this.colorExt != null) {
+            if (fillNotStroke)  {
+                p.append("/" + this.colorExt.getIccProfileName() + " cs ");
+            } else {
+                p.append("/" + this.colorExt.getIccProfileName() + " CS ");
+            }
+            float[] colorArgs;
+            colorArgs = this.colorExt.getOriginalColorComponents();
+            if (colorArgs == null) {
+                colorArgs = this.colorExt.getColorComponents(null);
+            }
+            for (int ix = 0; ix < colorArgs.length; ix++) {
+                p.append(colorArgs[ix] + " ");
+            }
+            if (fillNotStroke)  {
+                p.append("sc\n");
+            } else {
+                p.append("SC\n");
+            }
+        } else if (this.colorSpace.getColorSpace()
                 == 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
@@ -454,7 +552,8 @@
         }
         PDFColor color = (PDFColor)obj;
 
-        if (color.red == this.red && color.green == this.green
+        if (color.red == this.red 
+                && color.green == this.green
                 && color.blue == this.blue) {
             return true;
         }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderer.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderer.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderer.java Mon Nov 13 02:08:19 2006
@@ -1331,7 +1331,7 @@
      *     written to the current stream.
      */
     protected void setColor(Color col, boolean fill, StringBuffer pdf) {
-        PDFColor color = new PDFColor(col);
+        PDFColor color = new PDFColor(this.pdfDoc, col);
 
         closeText();
         

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/xml/XMLRenderer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/xml/XMLRenderer.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/xml/XMLRenderer.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/xml/XMLRenderer.java Mon Nov 13 02:08:19 2006
@@ -384,7 +384,7 @@
                     }
                 } else if (clazz.equals(Color.class)) {
                     Color c = (Color)value;
-                    addAttribute(name, ColorUtil.colorTOsRGBString(c));
+                    addAttribute(name, ColorUtil.colorToString(c));
                 } else if (key == Trait.START_INDENT || key == Trait.END_INDENT) {
                     if (((Integer)value).intValue() != 0) {
                         addAttribute(name, value.toString());

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFGraphics2D.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFGraphics2D.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFGraphics2D.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFGraphics2D.java Mon Nov 13 02:08:19 2006
@@ -42,6 +42,7 @@
 import org.apache.fop.image.JpegImage;
 import org.apache.fop.fonts.CIDFont;
 import org.apache.fop.render.pdf.FopPDFImage;
+import org.apache.fop.util.ColorExt;
 
 import org.apache.xmlgraphics.java2d.AbstractGraphics2D;
 import org.apache.xmlgraphics.java2d.GraphicContext;
@@ -821,8 +822,12 @@
      */
     protected void applyColor(Color col, boolean fill) {
         preparePainting();
+
         Color c = col;
-        if (c.getColorSpace().getType()
+        if (col instanceof ColorExt) {
+            PDFColor currentColour = new PDFColor(this.pdfDoc, col);
+            currentStream.write(currentColour.getColorSpaceOut(fill));
+        } else if (c.getColorSpace().getType()
                 == ColorSpace.TYPE_RGB) {
             PDFColor currentColour = new PDFColor(c.getRed(), c.getGreen(),
                                          c.getBlue());

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/traits/BorderProps.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/traits/BorderProps.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/traits/BorderProps.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/traits/BorderProps.java Mon Nov 13 02:08:19 2006
@@ -23,6 +23,7 @@
 import java.io.Serializable;
 import java.util.StringTokenizer;
 
+import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.expr.PropertyException;
 import org.apache.fop.util.ColorUtil;
@@ -154,10 +155,11 @@
     /**
      * Returns a BorderProps represtation of a string of the format as written by 
      * BorderProps.toString().
+     * @param foUserAgent FOP user agent caching ICC profiles
      * @param s the string
      * @return a BorderProps instance
      */
-    public static BorderProps valueOf(String s) {
+    public static BorderProps valueOf(FOUserAgent foUserAgent, String s) {
         if (s.startsWith("(") && s.endsWith(")")) {
             s = s.substring(1, s.length() - 1);
             StringTokenizer st = new StringTokenizer(s, ",");
@@ -175,7 +177,7 @@
             }
             Color c;
             try {
-                c = ColorUtil.parseColorString(color);
+                c = ColorUtil.parseColorString(foUserAgent, color);
             } catch (PropertyException e) {
                 throw new IllegalArgumentException(e.getMessage());
             } 
@@ -192,7 +194,7 @@
         sbuf.append('(');
         sbuf.append(getStyleString());
         sbuf.append(',');
-        sbuf.append(ColorUtil.colorTOsRGBString(color));
+        sbuf.append(ColorUtil.colorToString(color));
         sbuf.append(',');
         sbuf.append(width);
         if (mode != SEPARATE) {

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/util/CMYKColorSpace.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/util/CMYKColorSpace.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/util/CMYKColorSpace.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/util/CMYKColorSpace.java Mon Nov 13 02:08:19 2006
@@ -51,7 +51,10 @@
      * @see java.awt.color.ColorSpace#toRGB(float[])
      */
     public float[] toRGB(float[] colorvalue) {
-        throw new UnsupportedOperationException("NYI");
+        return new float [] {
+            (1 - colorvalue[0]) * (1 - colorvalue[3]),
+            (1 - colorvalue[1]) * (1 - colorvalue[3]),
+            (1 - colorvalue[2]) * (1 - colorvalue[3])};
     }
 
     /**

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/util/ColorExt.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/util/ColorExt.java?view=auto&rev=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/util/ColorExt.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/util/ColorExt.java Mon Nov 13 02:08:19 2006
@@ -0,0 +1,189 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.util;
+
+import java.awt.Color;
+import java.awt.color.ColorSpace;
+
+/**
+ * Color helper class.
+ * <p>
+ * This class extends java.awt.Color class keeping track of the original color
+ * property values specified by the fo user in a rgb-icc call.
+ */
+public final class ColorExt extends Color {
+    //
+    private static final long serialVersionUID = 1L;
+
+    // Values of fop-rgb-icc arguments
+    private float rgbReplacementRed;
+    private float rgbReplacementGreen;
+    private float rgbReplacementBlue;
+    
+    private String iccProfileName;
+    private String iccProfileSrc;
+    private ColorSpace colorSpace;
+    
+    private float[] colorValues;
+
+    /*
+     * Helper for createFromFoRgbIcc
+     */
+    private ColorExt(ColorSpace colorSpace, float[] colorValues, float opacity) {
+        super(colorSpace, colorValues, opacity);
+    }
+
+    /*
+     * Helper for createFromSvgIccColor
+     */
+    private ColorExt(float red, float green, float blue, float opacity) {
+        super(red, green, blue, opacity);
+    }
+
+    /**
+     * Create ColorExt object backup up FO's rgb-icc color function
+     * 
+     * @param redReplacement
+     *            Red part of RGB replacement color that will be used when ICC
+     *            profile can not be loaded
+     * @param greenReplacement
+     *            Green part of RGB replacement color that will be used when ICC
+     *            profile can not be loaded
+     * @param blueReplacement
+     *            Blue part of RGB replacement color that will be used when ICC
+     *            profile can not be loaded
+     * @param profileName
+     *            Name of ICC profile
+     * @param profileSrc
+     *            Source of ICC profile
+     * @param colorSpace
+     *            ICC ColorSpace for the ICC profile
+     * @param iccValues
+     *            color values
+     * @return the requested color object
+     */
+    public static ColorExt createFromFoRgbIcc(float redReplacement,
+            float greenReplacement, float blueReplacement, String profileName,
+            String profileSrc, ColorSpace colorSpace, float[] iccValues) {
+        ColorExt ce = new ColorExt(colorSpace, iccValues, 1.0f);
+        ce.rgbReplacementRed = redReplacement;
+        ce.rgbReplacementGreen = greenReplacement;
+        ce.rgbReplacementBlue = blueReplacement;
+        ce.iccProfileName = profileName;
+        ce.iccProfileSrc = profileSrc;
+        ce.colorSpace = colorSpace;
+        ce.colorValues = iccValues;
+        return ce;
+    }
+
+    /**
+     * Create ColorExt object backing up SVG's icc-color function.
+     * 
+     * @param red
+     *            Red value resulting from the conversion from the user provided
+     *            (icc) color values to the batik (rgb) color space
+     * @param green
+     *            Green value resulting from the conversion from the user
+     *            provided (icc) color values to the batik (rgb) color space
+     * @param blue
+     *            Blue value resulting from the conversion from the user
+     *            provided (icc) color values to the batik (rgb) color space
+     * @param opacity
+     *            Opacity
+     * @param profileName
+     *            ICC profile name
+     * @param profileHref
+     *            the URI to the color profile
+     * @param profileCS
+     *            ICC ColorSpace profile
+     * @param colorValues
+     *            ICC color values
+     * @return the requested color object
+     */
+    public static ColorExt createFromSvgIccColor(float red, float green,
+            float blue, float opacity, String profileName, String profileHref,
+            ColorSpace profileCS, float[] colorValues) {
+        ColorExt ce = new ColorExt(red, green, blue, opacity);
+        ce.rgbReplacementRed = -1;
+        ce.rgbReplacementGreen = -1;
+        ce.rgbReplacementBlue = -1;
+        ce.iccProfileName = profileName;
+        ce.iccProfileSrc = profileHref;
+        ce.colorSpace = profileCS;
+        ce.colorValues = colorValues;
+        return ce;
+
+    }
+
+    /**
+     * Get ICC profile name
+     * 
+     * @return ICC profile name
+     */
+    public String getIccProfileName() {
+        return this.iccProfileName;
+    }
+
+    /**
+     * Get ICC profile source
+     * 
+     * @return ICC profile source
+     */
+    public String getIccProfileSrc() {
+        return this.iccProfileSrc;
+    }
+
+    /**
+     * @return the original ColorSpace
+     */
+    public ColorSpace getOrigColorSpace() {
+        return this.colorSpace;
+    }
+
+    /**
+     * @return the original color values
+     */
+    public float[] getOriginalColorComponents() {
+        return this.colorValues;
+    }
+
+    /**
+     * Create string representation of fop-rgb-icc function call to map this
+     * ColorExt settings
+     * @return the string representing the internal fop-rgb-icc() function call
+     */
+    public String toFunctionCall() {
+        StringBuffer sb = new StringBuffer(40);
+        sb.append("fop-rgb-icc(");
+        sb.append(this.rgbReplacementRed + ",");
+        sb.append(this.rgbReplacementGreen + ",");
+        sb.append(this.rgbReplacementBlue + ",");
+        sb.append(this.iccProfileName + ",");
+        sb.append("\"" + this.iccProfileSrc + "\"");
+        float[] colorComponents = this.getColorComponents(null);
+        for (int ix = 0; ix < colorComponents.length; ix++) {
+            sb.append(",");
+            sb.append(colorComponents[ix]);
+        }
+        sb.append(")");
+        return sb.toString();
+    }
+
+}

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

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/util/ColorUtil.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/util/ColorUtil.java?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/util/ColorUtil.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/util/ColorUtil.java Mon Nov 13 02:08:19 2006
@@ -20,10 +20,16 @@
 package org.apache.fop.util;
 
 import java.awt.Color;
+import java.awt.color.ColorSpace;
 import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Map;
 import java.util.StringTokenizer;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.fo.expr.PropertyException;
 
 /**
@@ -31,19 +37,21 @@
  * <p>
  * This class supports parsing string values into color values and creating
  * color values for strings. It provides a list of standard color names.
- * <p>
- * TODO: Add support for color Profiles.
  */
 public final class ColorUtil {
 
     /**
+     * 
      * keeps all the predefined and parsed colors.
      * <p>
      * This map is used to predefine given colors, as well as speeding up
      * parsing of already parsed colors.
      */
     private static Map colorMap = null;
-
+    
+    /** Logger instance */
+    protected static Log log = LogFactory.getLog(ColorUtil.class);
+    
     static {
         initializeColorMap();
     }
@@ -68,8 +76,11 @@
      * <li>system-color(colorname)</li>
      * <li>transparent</li>
      * <li>colorname</li>
+     * <li>fop-rgb-icc</li>
+     * <li>cmyk</li>
      * </ul>
      * 
+     * @param foUserAgent FOUserAgent object  
      * @param value
      *            the string to parse.
      * @return a Color representing the string if possible
@@ -77,7 +88,8 @@
      *             if the string is not parsable or does not follow any of the
      *             given formats.
      */
-    public static Color parseColorString(String value) throws PropertyException {
+    public static Color parseColorString(FOUserAgent foUserAgent, String value) 
+            throws PropertyException {
         if (value == null) {
             return null;
         }
@@ -96,18 +108,23 @@
                 parsedColor = parseAsJavaAWTColor(value);
             } else if (value.startsWith("system-color(")) {
                 parsedColor = parseAsSystemColor(value);
+            } else if (value.startsWith("fop-rgb-icc")) {
+                parsedColor = parseAsFopRgbIcc(foUserAgent, value);
+            } else if (value.startsWith("cmyk")) {
+                parsedColor = parseAsCMYK(value);
             }
-
+            
             if (parsedColor == null) {
-                throw new PropertyException("Unkown Color: " + value);
+                throw new PropertyException("Unknown Color: " + value);
             }
             
             colorMap.put(value, parsedColor);
         }
 
-        // TODO: Check if this is really necessary
-        return new Color(parsedColor.getRed(), parsedColor.getGreen(),
-                parsedColor.getBlue(), parsedColor.getAlpha());
+        // TODO - Returned Color object can be one from the static colorMap cache.
+        //        That means it should be treated as read only for the rest of its lifetime.
+        //        Not sure that is the case though.
+        return parsedColor;
     }
 
     /**
@@ -282,6 +299,174 @@
     }
 
     /**
+     * Parse a color specified using the fop-rgb-icc() function.
+     * 
+     * @param value the function call
+     * @return a color if possible
+     * @throws PropertyException if the format is wrong.
+     */
+    private static Color parseAsFopRgbIcc(FOUserAgent foUserAgent, String value) 
+            throws PropertyException {
+        Color parsedColor;
+        int poss = value.indexOf("(");
+        int pose = value.indexOf(")");
+        if (poss != -1 && pose != -1) {
+            value = value.substring(poss + 1, pose);
+            StringTokenizer st = new StringTokenizer(value, ",");
+            try {
+                float red = 0.0f, green = 0.0f, blue = 0.0f;
+                if (st.hasMoreTokens()) {
+                    String str = st.nextToken().trim();
+                    red = Float.parseFloat(str);
+                }
+                if (st.hasMoreTokens()) {
+                    String str = st.nextToken().trim();
+                    green = Float.parseFloat(str);
+                }
+                if (st.hasMoreTokens()) {
+                    String str = st.nextToken().trim();
+                    blue = Float.parseFloat(str);
+                }
+                /* Verify rgb replacement arguments */
+                if ((red < 0.0 || red > 1.0) 
+                        || (green < 0.0 || green > 1.0) 
+                        || (blue < 0.0 || blue > 1.0)) {
+                  throw new PropertyException("Color values out of range");
+                 }
+                /* Get and verify ICC profile name */
+                String iccProfileName = null;
+                if (st.hasMoreTokens()) {
+                    iccProfileName = st.nextToken().trim();
+                }
+                if (iccProfileName == null || iccProfileName.length() == 0) {
+                    throw new PropertyException("ICC profile name missing");
+                }
+                /* Get and verify ICC profile source */
+                String iccProfileSrc = null;
+                if (st.hasMoreTokens()) {
+                    iccProfileSrc = st.nextToken().trim();
+                    // Strip quotes
+                    iccProfileSrc = iccProfileSrc.substring(1, iccProfileSrc.length() - 1);
+                }
+                if (iccProfileSrc == null || iccProfileSrc.length() == 0) {
+                    throw new PropertyException("ICC profile source missing");
+                }
+                /* ICC profile arguments */
+                List iccArgList = new LinkedList();
+                while (st.hasMoreTokens()) {
+                    String str = st.nextToken().trim();
+                    iccArgList.add(new Float(str));
+                }
+                /* Copy ICC profile arguments from list to array */
+                float[] iccComponents = new float[iccArgList.size()];
+                for (int ix = 0; ix < iccArgList.size(); ix++) {
+                    iccComponents[ix] = ((Float)iccArgList.get(ix)).floatValue();
+                }
+                /* Ask FOP factory to get ColorSpace for the specified ICC profile source */
+                ColorSpace colorSpace = (foUserAgent != null
+                        ? foUserAgent.getFactory().getColorSpace(
+                                foUserAgent.getBaseURL(), iccProfileSrc) : null);
+                if (colorSpace != null) {
+                    // ColorSpace available - create ColorExt (keeps track of replacement rgb 
+                    // values for possible later colorTOsRGBString call
+                    parsedColor = ColorExt.createFromFoRgbIcc(red, green, blue, 
+                            iccProfileName, iccProfileSrc, colorSpace, iccComponents);
+                } else {
+                    // ICC profile could not be loaded - use rgb replacement values */
+                    log.warn("Color profile '" + iccProfileSrc 
+                            + "' not found. Using rgb replacement values.");
+                    parsedColor = new Color(red, green, blue);
+                }
+            } catch (Exception e) {
+                throw new PropertyException(
+                        "Arguments to rgb-icc() must be [0..255] or [0%..100%]");
+            }
+        } else {
+            throw new PropertyException("Unknown color format: " + value
+                    + ". Must be fop-rgb-icc(r,g,b,NCNAME,\"src\",....)");
+        }
+        return parsedColor;
+    }
+
+    /**
+     * Parse a color given with the cmyk() function.
+     * 
+     * @param value
+     *            the complete line
+     * @return a color if possible
+     * @throws PropertyException
+     *             if the format is wrong.
+     */
+    private static Color parseAsCMYK(String value) throws PropertyException {
+        Color parsedColor;
+        int poss = value.indexOf("(");
+        int pose = value.indexOf(")");
+        if (poss != -1 && pose != -1) {
+            value = value.substring(poss + 1, pose);
+            StringTokenizer st = new StringTokenizer(value, ",");
+            try {
+                float cyan = 0.0f, magenta = 0.0f, yellow = 0.0f, black = 0.0f;
+                if (st.hasMoreTokens()) {
+                    String str = st.nextToken().trim();
+                    if (str.endsWith("%")) {
+                      cyan  = Float.parseFloat(str.substring(0,
+                                str.length() - 1)) / 100.0f;
+                    } else {
+                      cyan  = Float.parseFloat(str);
+                    }
+                }
+                if (st.hasMoreTokens()) {
+                    String str = st.nextToken().trim();
+                    if (str.endsWith("%")) {
+                      magenta = Float.parseFloat(str.substring(0,
+                                str.length() - 1)) / 100.0f;
+                    } else {
+                      magenta = Float.parseFloat(str);
+                    }
+                }
+                if (st.hasMoreTokens()) {
+                    String str = st.nextToken().trim();
+                    if (str.endsWith("%")) {
+                      yellow = Float.parseFloat(str.substring(0,
+                                str.length() - 1)) / 100.0f;
+                    } else {
+                      yellow = Float.parseFloat(str);
+                    }
+                }
+                if (st.hasMoreTokens()) {
+                  String str = st.nextToken().trim();
+                  if (str.endsWith("%")) {
+                    black = Float.parseFloat(str.substring(0,
+                              str.length() - 1)) / 100.0f;
+                  } else {
+                    black = Float.parseFloat(str);
+                  }
+              }
+                if ((cyan < 0.0 || cyan > 1.0) 
+                        || (magenta < 0.0 || magenta > 1.0)
+                        || (yellow < 0.0 || yellow > 1.0)
+                        || (black < 0.0 || black > 1.0)) {
+                    throw new PropertyException("Color values out of range");
+                }
+                float[] cmyk = new float[] {cyan, magenta, yellow, black};
+                CMYKColorSpace cmykCs = CMYKColorSpace.getInstance();
+                float[] rgb = cmykCs.toRGB(cmyk);
+                parsedColor = ColorExt.createFromFoRgbIcc(rgb[0], rgb[1], rgb[2], 
+                        null, "#CMYK", cmykCs, cmyk);
+
+                
+            } catch (Exception e) {
+                throw new PropertyException(
+                        "Arguments to cmyk() must be in the range [0%-100%] or [0.0-1.0]");
+            }
+        } else {
+            throw new PropertyException("Unknown color format: " + value
+                    + ". Must be cmyk(c,m,y,k)");
+        }
+        return parsedColor;
+    }
+    
+    /**
      * Creates a re-parsable string representation of the given color.
      * <p>
      * First, the color will be converted into the sRGB colorspace. It will then
@@ -291,33 +476,42 @@
      *            the color to represent.
      * @return a re-parsable string representadion.
      */
-    public static String colorTOsRGBString(Color color) {
-        StringBuffer sbuf = new StringBuffer(10);
-        sbuf.append('#');
-        String s = Integer.toHexString(color.getRed());
-        if (s.length() == 1) {
-            sbuf.append('0');
-        }
-        sbuf.append(s);
-        s = Integer.toHexString(color.getGreen());
-        if (s.length() == 1) {
-            sbuf.append('0');
-        }
-        sbuf.append(s);
-        s = Integer.toHexString(color.getBlue());
-        if (s.length() == 1) {
-            sbuf.append('0');
-        }
-        sbuf.append(s);
-        if (color.getAlpha() != 255) {
-            s = Integer.toHexString(color.getAlpha());
+    public static String colorToString(Color color) {
+        ColorSpace cs = color.getColorSpace();
+        if (cs != null && cs.getType() == ColorSpace.TYPE_CMYK) {
+            StringBuffer sbuf = new StringBuffer(24);
+            float[] cmyk = color.getColorComponents(null);
+            sbuf.append("cmyk(" + cmyk[0] + "," + cmyk[1] + "," + cmyk[2] + "," +  cmyk[3] + ")");
+            return sbuf.toString();
+        } else if (color instanceof ColorExt) {
+            return ((ColorExt)color).toFunctionCall();
+        } else {
+            StringBuffer sbuf = new StringBuffer();
+            sbuf.append('#');
+            String s = Integer.toHexString(color.getRed());
+            if (s.length() == 1) {
+                sbuf.append('0');
+            }
+            sbuf.append(s);
+            s = Integer.toHexString(color.getGreen());
             if (s.length() == 1) {
                 sbuf.append('0');
             }
             sbuf.append(s);
+            s = Integer.toHexString(color.getBlue());
+            if (s.length() == 1) {
+                sbuf.append('0');
+            }
+            sbuf.append(s);
+            if (color.getAlpha() != 255) {
+                s = Integer.toHexString(color.getAlpha());
+                if (s.length() == 1) {
+                    sbuf.append('0');
+                }
+                sbuf.append(s);
+            }
+            return sbuf.toString();
         }
-        return sbuf.toString();
-
     }
 
     /**

Modified: xmlgraphics/fop/trunk/status.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/status.xml?view=diff&rev=474225&r1=474224&r2=474225
==============================================================================
--- xmlgraphics/fop/trunk/status.xml (original)
+++ xmlgraphics/fop/trunk/status.xml Mon Nov 13 02:08:19 2006
@@ -28,6 +28,10 @@
 
   <changes>
     <release version="FOP Trunk">
+      <action context="Code" dev="JM" type="add" fixes-bug="40729" due-to="Peter Coppens">
+        Support for the rgb-icc() function and for a proprietary cmyk() function (for device CMYK
+        colors only through the PDF renderer so far). 
+      </action>
       <action context="Code" dev="JM" type="update" fixes-bug="40813" due-to="Richard Wheeldon">
         Minor fixes and improvements for the AWT Preview (keyboard shortcuts, scrolling, windows
         setup).



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