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 2009/09/16 21:38:14 UTC

svn commit: r815938 - in /xmlgraphics/fop/trunk: ./ src/documentation/content/xdocs/trunk/ src/java/org/apache/fop/fo/expr/ src/java/org/apache/fop/util/ test/java/org/apache/fop/util/ test/layoutengine/standard-testcases/

Author: jeremias
Date: Wed Sep 16 19:38:13 2009
New Revision: 815938

URL: http://svn.apache.org/viewvc?rev=815938&view=rev
Log:
Added support for the #CMYK pseudo-profile supported by some commercial XSL implementations on the rgb-icc() function.

Modified:
    xmlgraphics/fop/trunk/src/documentation/content/xdocs/trunk/extensions.xml
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/ICCColorFunction.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/PropertyTokenizer.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/util/ColorExt.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/util/ColorUtilTestCase.java
    xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/color_1.xml

Modified: xmlgraphics/fop/trunk/src/documentation/content/xdocs/trunk/extensions.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/documentation/content/xdocs/trunk/extensions.xml?rev=815938&r1=815937&r2=815938&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/documentation/content/xdocs/trunk/extensions.xml (original)
+++ xmlgraphics/fop/trunk/src/documentation/content/xdocs/trunk/extensions.xml Wed Sep 16 19:38:13 2009
@@ -226,6 +226,23 @@
             color space the CMYK value is converted to an sRGB value.
           </p>
         </section>
+        <section id="pseudo-color-profiles">
+          <title>#CMYK pseudo-profile</title>
+          <p><code>color rgb-icc(numeric, numeric, numeric, #CMYK, numeric, numeric, numeric, numeric)</code></p>
+          <p>
+            The <code>rgb-icc</code> function will respond to a pseudo-profile called "#CMYK"
+            which indicates a device-specific CMYK color space. The "#CMYK" profile is implicitely
+            available and doesn't have to be (and cannot be) defined through an
+            <code>fo:color-profile</code> element. It is provided for compatibility with certain
+            commercial XSL-FO implementations. Please note that this is not part of the official
+            specification but rather a convention. The following two color specifications are
+            equivalent:
+          </p>
+          <ul>
+            <li><code>cmyk(0%,0%,20%,40%)</code></li>
+            <li><code>rgb-icc(153, 153, 102, #CMYK, 0, 0, 0.2, 0.4)</code></li>
+          </ul>
+        </section>
       </section>
       <section id="prepress">
         <title>Prepress Support</title>

Modified: 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?rev=815938&r1=815937&r2=815938&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/ICCColorFunction.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/ICCColorFunction.java Wed Sep 16 19:38:13 2009
@@ -24,6 +24,7 @@
 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.
@@ -63,13 +64,15 @@
         } else {
             cp = decls.getColorProfile(colorProfileName);
             if (cp == null) {
-                PropertyException pe = new PropertyException("The " + colorProfileName
-                        + " color profile was not declared");
-                pe.setPropertyInfo(pInfo);
-                throw pe;
+                if (!ColorUtil.isPseudoProfile(colorProfileName)) {
+                    PropertyException pe = new PropertyException("The " + colorProfileName
+                            + " color profile was not declared");
+                    pe.setPropertyInfo(pInfo);
+                    throw pe;
+                }
             }
         }
-        String src = cp.getSrc();
+        String src = (cp != null ? cp.getSrc() : "");
 
         float red = 0, green = 0, blue = 0;
         red = args[0].getNumber().floatValue();

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/PropertyTokenizer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/PropertyTokenizer.java?rev=815938&r1=815937&r2=815938&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/PropertyTokenizer.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/PropertyTokenizer.java Wed Sep 16 19:38:13 2009
@@ -243,15 +243,20 @@
     }
 
 
-    private void nextColor () throws PropertyException {
+    private void nextColor() throws PropertyException {
         if (exprIndex < exprLength
                 && isHexDigit(expr.charAt(exprIndex))) {
             ++exprIndex;
             scanHexDigits();
-            currentToken = TOK_COLORSPEC;
+            int len = exprIndex - currentTokenStartIndex - 1;
+            if (len % 3 == 0) {
+                currentToken = TOK_COLORSPEC;
+            } else {
+                scanRestOfName();
+                currentToken = TOK_NCNAME;
+            }
             currentTokenValue = expr.substring(currentTokenStartIndex,
                     exprIndex);
-            // Probably should have some multiple of 3 for length!
             return;
         } else {
             throw new PropertyException("illegal character '#'");
@@ -263,11 +268,15 @@
      */
     private void scanName() {
         if (exprIndex < exprLength && isNameStartChar(expr.charAt(exprIndex))) {
-            while (++exprIndex < exprLength
-                   && isNameChar(expr.charAt(exprIndex))) { }
+            scanRestOfName();
         }
     }
 
+    private void scanRestOfName() {
+        while (++exprIndex < exprLength
+               && isNameChar(expr.charAt(exprIndex))) { }
+    }
+
     /**
      * Attempt to recognize a valid sequence of decimal DIGITS in the
      * input expression.

Modified: 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?rev=815938&r1=815937&r2=815938&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/util/ColorExt.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/util/ColorExt.java Wed Sep 16 19:38:13 2009
@@ -176,7 +176,9 @@
         sb.append(this.rgbReplacementGreen + ",");
         sb.append(this.rgbReplacementBlue + ",");
         sb.append(this.iccProfileName + ",");
-        sb.append("\"" + this.iccProfileSrc + "\"");
+        if (this.iccProfileSrc != null) {
+            sb.append("\"" + this.iccProfileSrc + "\"");
+        }
         float[] colorComponents = this.getColorComponents(null);
         for (int ix = 0; ix < colorComponents.length; ix++) {
             sb.append(",");

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?rev=815938&r1=815937&r2=815938&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/util/ColorUtil.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/util/ColorUtil.java Wed Sep 16 19:38:13 2009
@@ -38,6 +38,9 @@
  */
 public final class ColorUtil {
 
+    /** The name for the uncalibrated CMYK pseudo-profile */
+    public static final String CMYK_PSEUDO_PROFILE = "#CMYK";
+
     /**
      *
      * keeps all the predefined and parsed colors.
@@ -319,26 +322,32 @@
                 if (iccProfileName == null || "".equals(iccProfileName)) {
                     throw new PropertyException("ICC profile name missing");
                 }
-                /* Get and verify ICC profile source */
-                String iccProfileSrc = args[4].trim();
-                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);
+                ColorSpace colorSpace = null;
+                String iccProfileSrc = null;
+                if (isPseudoProfile(iccProfileName)) {
+                    if (CMYK_PSEUDO_PROFILE.equalsIgnoreCase(iccProfileName)) {
+                        colorSpace = CMYKColorSpace.getInstance();
+                    } else {
+                        assert false : "Incomplete implementation";
+                    }
+                } else {
+                    /* Get and verify ICC profile source */
+                    iccProfileSrc = args[4].trim();
+                    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);
+                    }
                 }
                 /* ICC profile arguments */
                 float[] iccComponents = new float[args.length - 5];
                 for (int ix = 4; ++ix < args.length;) {
                     iccComponents[ix - 5] = Float.parseFloat(args[ix].trim());
                 }
-                /* Ask FOP factory to get ColorSpace for the specified ICC profile source */
-                ColorSpace colorSpace = (foUserAgent != null
-                        ? foUserAgent.getFactory().getColorSpace(
-                                foUserAgent.getBaseURL(), iccProfileSrc) : null);
 
                 float red = 0, green = 0, blue = 0;
                 red = Float.parseFloat(args[0].trim());
@@ -352,6 +361,11 @@
                             + "Fallback RGB arguments to fop-rgb-icc() must be [0..1]");
                 }
 
+                /* Ask FOP factory to get ColorSpace for the specified ICC profile source */
+                if (foUserAgent != null && iccProfileSrc != null) {
+                    colorSpace = foUserAgent.getFactory().getColorSpace(
+                            foUserAgent.getBaseURL(), iccProfileSrc);
+                }
                 if (colorSpace != null) {
                     // ColorSpace available - create ColorExt (keeps track of replacement rgb
                     // values for possible later colorTOsRGBString call
@@ -440,7 +454,7 @@
                 CMYKColorSpace cmykCs = CMYKColorSpace.getInstance();
                 float[] rgb = cmykCs.toRGB(cmyk);
                 parsedColor = ColorExt.createFromFoRgbIcc(rgb[0], rgb[1], rgb[2],
-                        null, "#CMYK", cmykCs, cmyk);
+                        CMYK_PSEUDO_PROFILE, null, cmykCs, cmyk);
             } catch (PropertyException pe) {
                 throw pe;
             } catch (Exception e) {
@@ -465,13 +479,13 @@
      */
     public static String colorToString(Color color) {
         ColorSpace cs = color.getColorSpace();
-        if (cs != null && cs.getType() == ColorSpace.TYPE_CMYK) {
+        if (color instanceof ColorExt) {
+            return ((ColorExt)color).toFunctionCall();
+        } else 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('#');
@@ -681,4 +695,35 @@
         return new Color(cols[0], cols[1], cols[2], cols[3]);
     }
 
+    /**
+     * Indicates whether the given color profile name is one of the pseudo-profiles supported
+     * by FOP (ex. #CMYK).
+     * @param colorProfileName the color profile name to check
+     * @return true if the color profile name is of a built-in pseudo-profile
+     */
+    public static boolean isPseudoProfile(String colorProfileName) {
+        return CMYK_PSEUDO_PROFILE.equalsIgnoreCase(colorProfileName);
+    }
+
+    /**
+     * Indicates whether the color is a gray value.
+     * @param col the color
+     * @return true if it is a gray value
+     */
+    public static boolean isGray(Color col) {
+        return (col.getRed() == col.getBlue() && col.getRed() == col.getGreen());
+    }
+
+    /**
+     * Creates an uncalibrary CMYK color with the given gray value.
+     * @param black the gray component (0 - 1)
+     * @return the CMYK color
+     */
+    public static Color toCMYKGrayColor(float black) {
+        float[] cmyk = new float[] {0f, 0f, 0f, 1.0f - black};
+        CMYKColorSpace cmykCs = CMYKColorSpace.getInstance();
+        float[] rgb = cmykCs.toRGB(cmyk);
+        return ColorExt.createFromFoRgbIcc(rgb[0], rgb[1], rgb[2],
+                CMYK_PSEUDO_PROFILE, null, cmykCs, cmyk);
+    }
 }

Modified: xmlgraphics/fop/trunk/status.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/status.xml?rev=815938&r1=815937&r2=815938&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/status.xml (original)
+++ xmlgraphics/fop/trunk/status.xml Wed Sep 16 19:38:13 2009
@@ -58,6 +58,10 @@
       documents. Example: the fix of marks layering will be such a case when it's done.
     -->
     <release version="FOP Trunk" date="TBD">
+      <action context="Extensions" dev="JM" type="add">
+        Added support for the #CMYK pseudo-profile supported by some commercial XSL implementations
+        on the rgb-icc() function.
+      </action>
       <action context="Layout" dev="VH" type="add" importance="high">
         Added limited support for pages of different inline-progression-dimensions within a 
         page-sequence.

Modified: xmlgraphics/fop/trunk/test/java/org/apache/fop/util/ColorUtilTestCase.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/java/org/apache/fop/util/ColorUtilTestCase.java?rev=815938&r1=815937&r2=815938&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/test/java/org/apache/fop/util/ColorUtilTestCase.java (original)
+++ xmlgraphics/fop/trunk/test/java/org/apache/fop/util/ColorUtilTestCase.java Wed Sep 16 19:38:13 2009
@@ -154,7 +154,8 @@
         assertEquals(0f, comps[1], 0);
         assertEquals(1f, comps[2], 0);
         assertEquals(0f, comps[3], 0);
-        assertEquals("cmyk(0.0,0.0,1.0,0.0)", ColorUtil.colorToString(colActual));
+        assertEquals("fop-rgb-icc(1.0,1.0,0.0,#CMYK,,0.0,0.0,1.0,0.0)",
+                ColorUtil.colorToString(colActual));
 
         colSpec = "cmyk(0.0274, 0.2196, 0.3216, 0.0)";
         colActual = (ColorExt)ColorUtil.parseColorString(null, colSpec);
@@ -167,7 +168,23 @@
         assertEquals(0.2196f, comps[1], 0.001);
         assertEquals(0.3216f, comps[2], 0.001);
         assertEquals(0f, comps[3], 0);
-        assertEquals("cmyk(0.0274,0.2196,0.3216,0.0)", ColorUtil.colorToString(colActual));
+        assertEquals("fop-rgb-icc(0.9726,0.7804,0.67840004,#CMYK,,0.0274,0.2196,0.3216,0.0)",
+                ColorUtil.colorToString(colActual));
+
+        colSpec = "fop-rgb-icc(1.0,1.0,0.0,#CMYK,,0.0,0.0,1.0,0.0)";
+        colActual = (ColorExt)ColorUtil.parseColorString(null, colSpec);
+        assertEquals(255, colActual.getRed());
+        assertEquals(255, colActual.getGreen());
+        assertEquals(0, colActual.getBlue());
+        assertEquals(CMYKColorSpace.getInstance(), colActual.getColorSpace());
+        comps = colActual.getOriginalColorComponents();
+        assertEquals(4, comps.length);
+        assertEquals(0f, comps[0], 0);
+        assertEquals(0f, comps[1], 0);
+        assertEquals(1f, comps[2], 0);
+        assertEquals(0f, comps[3], 0);
+        assertEquals("fop-rgb-icc(1.0,1.0,0.0,#CMYK,,0.0,0.0,1.0,0.0)",
+                ColorUtil.colorToString(colActual));
     }
 
 }

Modified: xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/color_1.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/color_1.xml?rev=815938&r1=815937&r2=815938&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/color_1.xml (original)
+++ xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/color_1.xml Wed Sep 16 19:38:13 2009
@@ -41,9 +41,7 @@
           <fo:block color="rgb-icc(100%,50%,0%, sRGB, 1, 0.5, 0)">color "rgb-icc(100%,50%,0%, sRGB, 1, 0.5, 0)"</fo:block>
           <fo:block color="rgb-icc(0%,100%,0%, unknown, 1, 0.5, 0)">color "rgb-icc(0%,100%,0%, unknown, 1, 0.5, 0)"</fo:block>
           <fo:block color="cmyk(0%,0%,20%,40%)">color "cmyk(0%,0%,20%,40%)" (Khaki)</fo:block>
-          <!-- NYI
           <fo:block color="rgb-icc(153, 153, 102, #CMYK, 0, 0, 0.2, 0.4)">color "rgb-icc(153, 153, 102, #CMYK, 0, 0, 0.2, 0.4)" (Khaki)</fo:block>
-          -->
         </fo:flow>
       </fo:page-sequence>
     </fo:root>
@@ -58,6 +56,7 @@
     <eval expected="#ff8000" xpath="//block[3]//text/@color"/>
     <eval expected="fop-rgb-icc(1.0,0.5,0.0,sRGB,&quot;../../../src/java/org/apache/fop/pdf/sRGB Color Space Profile.icm&quot;,1.0,0.5,0.0)" xpath="//block[4]//text/@color"/>
     <eval expected="#00ff00" xpath="//block[5]//text/@color"/>
-    <eval expected="cmyk(0.0,0.0,0.2,0.4)" xpath="//block[6]//text/@color"/>
+    <eval expected="fop-rgb-icc(0.6,0.6,0.48000002,#CMYK,,0.0,0.0,0.2,0.4)" xpath="//block[6]//text/@color"/>
+    <eval expected="fop-rgb-icc(0.6,0.6,0.48000002,#CMYK,,0.0,0.0,0.2,0.4)" xpath="//block[7]//text/@color"/>
   </checks>
 </testcase>



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