diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/documentation/content/xdocs/trunk/extensions.xml | 17 | ||||
-rw-r--r-- | src/java/org/apache/fop/fo/expr/ICCColorFunction.java | 13 | ||||
-rw-r--r-- | src/java/org/apache/fop/fo/expr/PropertyTokenizer.java | 19 | ||||
-rw-r--r-- | src/java/org/apache/fop/util/ColorExt.java | 4 | ||||
-rw-r--r-- | src/java/org/apache/fop/util/ColorUtil.java | 81 |
5 files changed, 105 insertions, 29 deletions
diff --git a/src/documentation/content/xdocs/trunk/extensions.xml b/src/documentation/content/xdocs/trunk/extensions.xml index a635205d2..107f6c5b3 100644 --- a/src/documentation/content/xdocs/trunk/extensions.xml +++ b/src/documentation/content/xdocs/trunk/extensions.xml @@ -226,6 +226,23 @@ to following pages. Here is an example of FO code creating such a table-header:< 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> diff --git a/src/java/org/apache/fop/fo/expr/ICCColorFunction.java b/src/java/org/apache/fop/fo/expr/ICCColorFunction.java index 2069945f1..9e2ef2e7d 100644 --- a/src/java/org/apache/fop/fo/expr/ICCColorFunction.java +++ b/src/java/org/apache/fop/fo/expr/ICCColorFunction.java @@ -24,6 +24,7 @@ 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; +import org.apache.fop.util.ColorUtil; /** * Implements the rgb-icc() function. @@ -63,13 +64,15 @@ class ICCColorFunction extends FunctionBase { } 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(); diff --git a/src/java/org/apache/fop/fo/expr/PropertyTokenizer.java b/src/java/org/apache/fop/fo/expr/PropertyTokenizer.java index 2ddcd0922..5baa0c4d8 100644 --- a/src/java/org/apache/fop/fo/expr/PropertyTokenizer.java +++ b/src/java/org/apache/fop/fo/expr/PropertyTokenizer.java @@ -243,15 +243,20 @@ class PropertyTokenizer { } - 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 @@ class PropertyTokenizer { */ 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. diff --git a/src/java/org/apache/fop/util/ColorExt.java b/src/java/org/apache/fop/util/ColorExt.java index d2e73d227..22c2dcc36 100644 --- a/src/java/org/apache/fop/util/ColorExt.java +++ b/src/java/org/apache/fop/util/ColorExt.java @@ -176,7 +176,9 @@ public final class ColorExt extends Color { 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(","); diff --git a/src/java/org/apache/fop/util/ColorUtil.java b/src/java/org/apache/fop/util/ColorUtil.java index 9534bfba3..8100aef96 100644 --- a/src/java/org/apache/fop/util/ColorUtil.java +++ b/src/java/org/apache/fop/util/ColorUtil.java @@ -38,6 +38,9 @@ import org.apache.fop.fo.expr.PropertyException; */ 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 @@ public final class ColorUtil { 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 @@ public final class ColorUtil { + "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 @@ public final class ColorUtil { 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 final class ColorUtil { */ 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 @@ public final class ColorUtil { 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); + } } |