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 2010/06/29 16:30:53 UTC

svn commit: r958992 - in /xmlgraphics/fop/branches/Temp_Color/src/java/org/apache/fop: fo/expr/NamedColorFunction.java fo/expr/PropertyParser.java util/ColorUtil.java

Author: jeremias
Date: Tue Jun 29 14:30:53 2010
New Revision: 958992

URL: http://svn.apache.org/viewvc?rev=958992&view=rev
Log:
Added support for the rgb-named-color() function that is found in the current XSL 2.0 design notes.

Added:
    xmlgraphics/fop/branches/Temp_Color/src/java/org/apache/fop/fo/expr/NamedColorFunction.java
      - copied, changed from r956535, xmlgraphics/fop/branches/Temp_Color/src/java/org/apache/fop/fo/expr/ICCColorFunction.java
Modified:
    xmlgraphics/fop/branches/Temp_Color/src/java/org/apache/fop/fo/expr/PropertyParser.java
    xmlgraphics/fop/branches/Temp_Color/src/java/org/apache/fop/util/ColorUtil.java

Copied: xmlgraphics/fop/branches/Temp_Color/src/java/org/apache/fop/fo/expr/NamedColorFunction.java (from r956535, xmlgraphics/fop/branches/Temp_Color/src/java/org/apache/fop/fo/expr/ICCColorFunction.java)
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Color/src/java/org/apache/fop/fo/expr/NamedColorFunction.java?p2=xmlgraphics/fop/branches/Temp_Color/src/java/org/apache/fop/fo/expr/NamedColorFunction.java&p1=xmlgraphics/fop/branches/Temp_Color/src/java/org/apache/fop/fo/expr/ICCColorFunction.java&r1=956535&r2=958992&rev=958992&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Color/src/java/org/apache/fop/fo/expr/ICCColorFunction.java (original)
+++ xmlgraphics/fop/branches/Temp_Color/src/java/org/apache/fop/fo/expr/NamedColorFunction.java Tue Jun 29 14:30:53 2010
@@ -24,25 +24,24 @@ import org.apache.fop.fo.pagination.Colo
 import org.apache.fop.fo.pagination.Declarations;
 import org.apache.fop.fo.properties.ColorProperty;
 import org.apache.fop.fo.properties.Property;
-import org.apache.fop.util.ColorUtil;
 
 /**
- * Implements the rgb-icc() function.
+ * Implements the rgb-named-color() function.
+ * @since XSL-FO 2.0
  */
-class ICCColorFunction extends FunctionBase {
+class NamedColorFunction extends FunctionBase {
 
     /**
-     * rgb-icc takes a variable number of arguments.
-     * At least 4 should be passed - returns -4
+     * rgb-named-color() takes a 5 arguments.
      * {@inheritDoc}
      */
     public int nbArgs() {
-        return -4;
+        return 5;
     }
 
     /** {@inheritDoc} */
     public PercentBase getPercentBase() {
-        return new ICCPercentBase();
+        return new NamedPercentBase();
     }
 
     /** {@inheritDoc} */
@@ -50,29 +49,18 @@ class ICCColorFunction extends FunctionB
                          PropertyInfo pInfo) throws PropertyException {
         // Map color profile NCNAME to src from declarations/color-profile element
         String colorProfileName = args[3].getString();
+        String colorName = args[4].getString();
+
         Declarations decls = pInfo.getFO().getRoot().getDeclarations();
         ColorProfile cp = null;
-        if (decls == null) {
-            //function used in a color-specification
-            //on a FO occurring:
-            //a) before the fo:declarations,
-            //b) or in a document without fo:declarations?
-            //=> return the sRGB fallback
-            if (!ColorUtil.isPseudoProfile(colorProfileName)) {
-                Property[] rgbArgs = new Property[3];
-                System.arraycopy(args, 0, rgbArgs, 0, 3);
-                return new RGBColorFunction().eval(rgbArgs, pInfo);
-            }
-        } else {
+        if (decls != null) {
             cp = decls.getColorProfile(colorProfileName);
-            if (cp == null) {
-                if (!ColorUtil.isPseudoProfile(colorProfileName)) {
-                    PropertyException pe = new PropertyException("The " + colorProfileName
-                            + " color profile was not declared");
-                    pe.setPropertyInfo(pInfo);
-                    throw pe;
-                }
-            }
+        }
+        if (cp == null) {
+            PropertyException pe = new PropertyException("The " + colorProfileName
+                    + " color profile was not declared");
+            pe.setPropertyInfo(pInfo);
+            throw pe;
         }
         String src = (cp != null ? cp.getSrc() : "");
 
@@ -84,31 +72,27 @@ class ICCColorFunction extends FunctionB
         if ((red < 0 || red > 255)
                 || (green < 0 || green > 255)
                 || (blue < 0 || blue > 255)) {
-            throw new PropertyException("Color values out of range. "
-                    + "Arguments to rgb-icc() must be [0..255] or [0%..100%]");
+            throw new PropertyException("sRGB color values out of range. "
+                    + "Arguments to rgb-named-color() must be [0..255] or [0%..100%]");
         }
 
-        // 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.
+        // rgb-named-color is replaced with fop-rgb-named-color which has an extra argument
+        // containing the color profile src attribute as it is defined in the color-profile
+        // declarations element.
         StringBuffer sb = new StringBuffer();
-        sb.append("fop-rgb-icc(");
+        sb.append("fop-rgb-named-color(");
         sb.append(red / 255f);
         sb.append(',').append(green / 255f);
         sb.append(',').append(blue / 255f);
-        for (int ix = 3; ix < args.length; ix++) {
-            if (ix == 3) {
-                sb.append(',').append(colorProfileName);
-                sb.append(',').append(src);
-            } else {
-                sb.append(',').append(args[ix]);
-            }
-        }
+        sb.append(',').append(colorProfileName);
+        sb.append(',').append(src);
+        sb.append(", '").append(colorName).append('\'');
         sb.append(")");
 
         return ColorProperty.getInstance(pInfo.getUserAgent(), sb.toString());
     }
 
-    private static final class ICCPercentBase implements PercentBase {
+    private static final class NamedPercentBase implements PercentBase {
 
         /** {@inheritDoc} */
         public int getBaseLength(PercentBaseContext context) throws PropertyException {

Modified: xmlgraphics/fop/branches/Temp_Color/src/java/org/apache/fop/fo/expr/PropertyParser.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Color/src/java/org/apache/fop/fo/expr/PropertyParser.java?rev=958992&r1=958991&r2=958992&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Color/src/java/org/apache/fop/fo/expr/PropertyParser.java (original)
+++ xmlgraphics/fop/branches/Temp_Color/src/java/org/apache/fop/fo/expr/PropertyParser.java Tue Jun 29 14:30:53 2010
@@ -69,6 +69,7 @@ public final class PropertyParser extend
         FUNCTION_TABLE.put("label-end", new LabelEndFunction());
         FUNCTION_TABLE.put("body-start", new BodyStartFunction());
         FUNCTION_TABLE.put("rgb-icc", new ICCColorFunction());
+        FUNCTION_TABLE.put("rgb-named-color", new NamedColorFunction());
         FUNCTION_TABLE.put("cmyk", new CMYKcolorFunction()); //non-standard!!!
 
         /**

Modified: xmlgraphics/fop/branches/Temp_Color/src/java/org/apache/fop/util/ColorUtil.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Color/src/java/org/apache/fop/util/ColorUtil.java?rev=958992&r1=958991&r2=958992&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Color/src/java/org/apache/fop/util/ColorUtil.java (original)
+++ xmlgraphics/fop/branches/Temp_Color/src/java/org/apache/fop/util/ColorUtil.java Tue Jun 29 14:30:53 2010
@@ -21,6 +21,8 @@ package org.apache.fop.util;
 
 import java.awt.Color;
 import java.awt.color.ColorSpace;
+import java.awt.color.ICC_ColorSpace;
+import java.awt.color.ICC_Profile;
 import java.util.Collections;
 import java.util.Map;
 
@@ -32,6 +34,8 @@ import org.apache.xmlgraphics.java2d.col
 import org.apache.xmlgraphics.java2d.color.DeviceCMYKColorSpace;
 import org.apache.xmlgraphics.java2d.color.ICCColor;
 import org.apache.xmlgraphics.java2d.color.NamedColorSpace;
+import org.apache.xmlgraphics.java2d.color.profile.NamedColorProfile;
+import org.apache.xmlgraphics.java2d.color.profile.NamedColorProfileParser;
 
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.fo.expr.PropertyException;
@@ -124,6 +128,8 @@ public final class ColorUtil {
                 parsedColor = parseAsSystemColor(value);
             } else if (value.startsWith("fop-rgb-icc")) {
                 parsedColor = parseAsFopRgbIcc(foUserAgent, value);
+            } else if (value.startsWith("fop-rgb-named-color")) {
+                parsedColor = parseAsFopRgbNamedColor(foUserAgent, value);
             } else if (value.startsWith("cmyk")) {
                 parsedColor = parseAsCMYK(value);
             }
@@ -366,12 +372,7 @@ public final class ColorUtil {
                     if (iccProfileSrc == null || "".equals(iccProfileSrc)) {
                         throw new PropertyException("ICC profile source missing");
                     }
-                    if (iccProfileSrc.startsWith("\"") || iccProfileSrc.startsWith("'")) {
-                        iccProfileSrc = iccProfileSrc.substring(1);
-                    }
-                    if (iccProfileSrc.endsWith("\"") || iccProfileSrc.endsWith("'")) {
-                        iccProfileSrc = iccProfileSrc.substring(0, iccProfileSrc.length() - 1);
-                    }
+                    iccProfileSrc = unescapeString(iccProfileSrc);
                 }
                 /* ICC profile arguments */
                 int componentStart = 4;
@@ -418,6 +419,116 @@ public final class ColorUtil {
     }
 
     /**
+     * Parse a color specified using the fop-rgb-named-color() function.
+     *
+     * @param value the function call
+     * @return a color if possible
+     * @throws PropertyException if the format is wrong.
+     */
+    private static Color parseAsFopRgbNamedColor(FOUserAgent foUserAgent, String value)
+            throws PropertyException {
+        Color parsedColor;
+        int poss = value.indexOf("(");
+        int pose = value.indexOf(")");
+        if (poss != -1 && pose != -1) {
+            String[] args = value.substring(poss + 1, pose).split(",");
+
+            try {
+                if (args.length != 6) {
+                    throw new PropertyException("rgb-named() function must have 6 arguments");
+                }
+
+                //Set up fallback sRGB value
+                float red = Float.parseFloat(args[0].trim());
+                float green = Float.parseFloat(args[1].trim());
+                float blue = Float.parseFloat(args[2].trim());
+                /* Verify rgb replacement arguments */
+                if ((red < 0 || red > 1)
+                        || (green < 0 || green > 1)
+                        || (blue < 0 || blue > 1)) {
+                    throw new PropertyException("Color values out of range. "
+                            + "Fallback RGB arguments to fop-rgb-named-color() must be [0..1]");
+                }
+                Color sRGB = new ColorExt(red, green, blue, null);
+
+                /* Get and verify ICC profile name */
+                String iccProfileName = args[3].trim();
+                if (iccProfileName == null || "".equals(iccProfileName)) {
+                    throw new PropertyException("ICC profile name missing");
+                }
+                ICC_ColorSpace colorSpace = null;
+                String iccProfileSrc = null;
+                if (isPseudoProfile(iccProfileName)) {
+                    throw new IllegalArgumentException(
+                            "Pseudo-profiles are not allowed with fop-rgb-named-color()");
+                } else {
+                    /* Get and verify ICC profile source */
+                    iccProfileSrc = args[4].trim();
+                    if (iccProfileSrc == null || "".equals(iccProfileSrc)) {
+                        throw new PropertyException("ICC profile source missing");
+                    }
+                    iccProfileSrc = unescapeString(iccProfileSrc);
+                }
+
+                // color name
+                String colorName = unescapeString(args[5].trim());
+
+                /* Ask FOP factory to get ColorSpace for the specified ICC profile source */
+                if (foUserAgent != null && iccProfileSrc != null) {
+                    colorSpace = (ICC_ColorSpace)foUserAgent.getFactory().getColorSpace(
+                            foUserAgent.getBaseURL(), iccProfileSrc);
+                }
+                if (colorSpace != null) {
+                    ICC_Profile profile = colorSpace.getProfile();
+                    if (NamedColorProfileParser.isNamedColorProfile(profile)) {
+                        NamedColorProfileParser parser = new NamedColorProfileParser();
+                        NamedColorProfile ncp = parser.parseProfile(profile);
+                        NamedColorSpace ncs = ncp.getNamedColor(colorName);
+                        if (ncs != null) {
+                            ICCColor iccColor = new ICCColor(ncs,
+                                    iccProfileName, iccProfileSrc,
+                                    new float[] {1.0f}, 1.0f);
+                            parsedColor = new ColorExt(red, green, blue, new Color[] {iccColor});
+                        } else {
+                            log.warn("Color '" + colorName
+                                    + "' does not exist in named color profile: " + iccProfileSrc);
+                            parsedColor = sRGB;
+                        }
+                    } else {
+                        log.warn("ICC profile is no named color profile: " + iccProfileSrc);
+                        parsedColor = sRGB;
+                    }
+                } else {
+                    // ICC profile could not be loaded - use rgb replacement values */
+                    log.warn("Color profile '" + iccProfileSrc
+                            + "' not found. Using sRGB replacement values.");
+                    parsedColor = sRGB;
+                }
+            } catch (PropertyException pe) {
+                //simply re-throw
+                throw pe;
+            } catch (Exception e) {
+                //wrap in a PropertyException
+                throw new PropertyException(e);
+            }
+        } else {
+            throw new PropertyException("Unknown color format: " + value
+                    + ". Must be fop-rgb-named-color(r,g,b,NCNAME,src,color-name)");
+        }
+        return parsedColor;
+    }
+
+    private static String unescapeString(String iccProfileSrc) {
+        if (iccProfileSrc.startsWith("\"") || iccProfileSrc.startsWith("'")) {
+            iccProfileSrc = iccProfileSrc.substring(1);
+        }
+        if (iccProfileSrc.endsWith("\"") || iccProfileSrc.endsWith("'")) {
+            iccProfileSrc = iccProfileSrc.substring(0, iccProfileSrc.length() - 1);
+        }
+        return iccProfileSrc;
+    }
+
+    /**
      * Parse a color given with the cmyk() function.
      *
      * @param value



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