aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/fop/util
diff options
context:
space:
mode:
authorJeremias Maerki <jeremias@apache.org>2011-02-10 15:58:57 +0000
committerJeremias Maerki <jeremias@apache.org>2011-02-10 15:58:57 +0000
commit3df0d00cdc96c2283046fe200f85d12bb85687c3 (patch)
tree62f91c73633d70b31ef9f1e32598225a2f37d8aa /src/java/org/apache/fop/util
parentf1269cc280b846cd6da396177bc74c4c9808579e (diff)
parent1c11bf98135675a9d6b6acac4fd7856a5dde8751 (diff)
downloadxmlgraphics-fop-3df0d00cdc96c2283046fe200f85d12bb85687c3.tar.gz
xmlgraphics-fop-3df0d00cdc96c2283046fe200f85d12bb85687c3.zip
Re-integrate/merge Temp_Color branch into Trunk.
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1069439 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache/fop/util')
-rw-r--r--src/java/org/apache/fop/util/AbstractPaintingState.java10
-rw-r--r--src/java/org/apache/fop/util/ColorExt.java259
-rw-r--r--src/java/org/apache/fop/util/ColorSpaceCache.java19
-rw-r--r--src/java/org/apache/fop/util/ColorUtil.java840
-rw-r--r--src/java/org/apache/fop/util/ColorWithFallback.java85
5 files changed, 922 insertions, 291 deletions
diff --git a/src/java/org/apache/fop/util/AbstractPaintingState.java b/src/java/org/apache/fop/util/AbstractPaintingState.java
index 5944b546c..96c3633e6 100644
--- a/src/java/org/apache/fop/util/AbstractPaintingState.java
+++ b/src/java/org/apache/fop/util/AbstractPaintingState.java
@@ -75,7 +75,8 @@ public abstract class AbstractPaintingState implements Cloneable, Serializable {
* @return true if the color has changed
*/
public boolean setColor(Color col) {
- if (!col.equals(getData().color)) {
+ Color other = getData().color;
+ if (!org.apache.xmlgraphics.java2d.color.ColorUtil.isSameColor(col, other)) {
getData().color = col;
return true;
}
@@ -114,7 +115,8 @@ public abstract class AbstractPaintingState implements Cloneable, Serializable {
* @return true if the color has changed
*/
public boolean setBackColor(Color col) {
- if (!col.equals(getData().backColor)) {
+ Color other = getData().backColor;
+ if (!org.apache.xmlgraphics.java2d.color.ColorUtil.isSameColor(col, other)) {
getData().backColor = col;
return true;
}
@@ -364,6 +366,7 @@ public abstract class AbstractPaintingState implements Cloneable, Serializable {
}
/** {@inheritDoc} */
+ @Override
public Object clone() {
AbstractPaintingState state = instantiate();
state.stateStack = new StateStack(this.stateStack);
@@ -372,6 +375,7 @@ public abstract class AbstractPaintingState implements Cloneable, Serializable {
}
/** {@inheritDoc} */
+ @Override
public String toString() {
return ", stateStack=" + stateStack
+ ", currentData=" + data;
@@ -506,6 +510,7 @@ public abstract class AbstractPaintingState implements Cloneable, Serializable {
}
/** {@inheritDoc} */
+ @Override
public Object clone() {
AbstractData data = instantiate();
data.color = this.color;
@@ -522,6 +527,7 @@ public abstract class AbstractPaintingState implements Cloneable, Serializable {
}
/** {@inheritDoc} */
+ @Override
public String toString() {
return "color=" + color
+ ", backColor=" + backColor
diff --git a/src/java/org/apache/fop/util/ColorExt.java b/src/java/org/apache/fop/util/ColorExt.java
index 30f6e9fc3..9d4c9b9d3 100644
--- a/src/java/org/apache/fop/util/ColorExt.java
+++ b/src/java/org/apache/fop/util/ColorExt.java
@@ -1,3 +1,4 @@
+<<<<<<< .working
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@@ -248,3 +249,261 @@ public final class ColorExt extends Color {
}
}
+=======
+/*
+ * 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;
+import java.util.Arrays;
+
+import org.apache.xmlgraphics.java2d.color.ColorWithAlternatives;
+
+/**
+ * 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.
+ * @deprecated Replaced by {@link ColorWithAlternatives}
+ */
+@Deprecated
+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( // CSOK: ParameterNumber
+ float red, float green,
+ float blue, float opacity, String profileName, String profileHref,
+ ColorSpace profileCS, float[] colorValues) {
+ //TODO this method is not referenced by FOP, can it be deleted?
+ 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;
+
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public int hashCode() {
+ //implementation from the superclass should be good enough for our purposes
+ return super.hashCode();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!super.equals(obj)) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ ColorExt other = (ColorExt)obj;
+ //TODO maybe use super.getColorComponents() instead
+ if (!Arrays.equals(colorValues, other.colorValues)) {
+ return false;
+ }
+ if (iccProfileName == null) {
+ if (other.iccProfileName != null) {
+ return false;
+ }
+ } else if (!iccProfileName.equals(other.iccProfileName)) {
+ return false;
+ }
+ if (iccProfileSrc == null) {
+ if (other.iccProfileSrc != null) {
+ return false;
+ }
+ } else if (!iccProfileSrc.equals(other.iccProfileSrc)) {
+ return false;
+ }
+ if (Float.floatToIntBits(rgbReplacementBlue)
+ != Float.floatToIntBits(other.rgbReplacementBlue)) {
+ return false;
+ }
+ if (Float.floatToIntBits(rgbReplacementGreen)
+ != Float.floatToIntBits(other.rgbReplacementGreen)) {
+ return false;
+ }
+ if (Float.floatToIntBits(rgbReplacementRed)
+ != Float.floatToIntBits(other.rgbReplacementRed)) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * 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() {
+ //TODO this method is probably unnecessary due to super.cs and getColorSpace()
+ return this.colorSpace;
+ }
+
+ /**
+ * Returns the original color values.
+ * @return the original color values
+ */
+ public float[] getOriginalColorComponents() {
+ //TODO this method is probably unnecessary due to super.fvalue and getColorComponents()
+ float[] copy = new float[this.colorValues.length];
+ System.arraycopy(this.colorValues, 0, copy, 0, copy.length);
+ return copy;
+ }
+
+ /**
+ * 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 + ",");
+ if (this.iccProfileSrc != null) {
+ 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();
+ }
+
+}
+>>>>>>> .merge-right.r1069429
diff --git a/src/java/org/apache/fop/util/ColorSpaceCache.java b/src/java/org/apache/fop/util/ColorSpaceCache.java
index 63d8746f7..63db937a0 100644
--- a/src/java/org/apache/fop/util/ColorSpaceCache.java
+++ b/src/java/org/apache/fop/util/ColorSpaceCache.java
@@ -20,7 +20,6 @@
package org.apache.fop.util;
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;
@@ -33,6 +32,9 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.xmlgraphics.java2d.color.profile.ColorProfileUtil;
+import org.apache.xmlgraphics.java2d.color.ICCColorSpaceWithIntent;
+import org.apache.xmlgraphics.java2d.color.RenderingIntent;
+
/**
* Map with cached ICC based ColorSpace objects.
*/
@@ -61,13 +63,17 @@ public class ColorSpaceCache {
* The FOP URI resolver is used to try and locate the ICC file.
* If that fails null is returned.
*
+ * @param profileName the profile name
* @param base a base URI to resolve relative URIs
* @param iccProfileSrc ICC Profile source to return a ColorSpace for
+ * @param renderingIntent overriding rendering intent
* @return ICC ColorSpace object or null if ColorSpace could not be created
*/
- public ColorSpace get(String base, String iccProfileSrc) {
+ public ColorSpace get(String profileName, String base, String iccProfileSrc,
+ RenderingIntent renderingIntent) {
+ String key = profileName + ":" + base + iccProfileSrc;
ColorSpace colorSpace = null;
- if (!colorSpaceMap.containsKey(base + iccProfileSrc)) {
+ if (!colorSpaceMap.containsKey(key)) {
try {
ICC_Profile iccProfile = null;
// First attempt to use the FOP URI resolver to locate the ICC
@@ -88,7 +94,8 @@ public class ColorSpaceCache {
// iccProfile = ICC_Profile.getInstance(iccProfileSrc);
}
if (iccProfile != null) {
- colorSpace = new ICC_ColorSpace(iccProfile);
+ colorSpace = new ICCColorSpaceWithIntent(iccProfile, renderingIntent,
+ profileName, iccProfileSrc);
}
} catch (Exception e) {
// Ignore exception - will be logged a bit further down
@@ -97,14 +104,14 @@ public class ColorSpaceCache {
if (colorSpace != null) {
// Put in cache (not when VM resolved it as we can't control
- colorSpaceMap.put(base + iccProfileSrc, colorSpace);
+ colorSpaceMap.put(key, 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 = colorSpaceMap.get(base + iccProfileSrc);
+ colorSpace = colorSpaceMap.get(key);
}
return colorSpace;
}
diff --git a/src/java/org/apache/fop/util/ColorUtil.java b/src/java/org/apache/fop/util/ColorUtil.java
index 674079369..e1454a545 100644
--- a/src/java/org/apache/fop/util/ColorUtil.java
+++ b/src/java/org/apache/fop/util/ColorUtil.java
@@ -21,14 +21,23 @@ 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;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.xmlgraphics.java2d.color.CIELabColorSpace;
+import org.apache.xmlgraphics.java2d.color.ColorSpaceOrigin;
import org.apache.xmlgraphics.java2d.color.ColorSpaces;
+import org.apache.xmlgraphics.java2d.color.ColorWithAlternatives;
import org.apache.xmlgraphics.java2d.color.DeviceCMYKColorSpace;
+import org.apache.xmlgraphics.java2d.color.NamedColorSpace;
+import org.apache.xmlgraphics.java2d.color.RenderingIntent;
+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;
@@ -41,15 +50,22 @@ import org.apache.fop.fo.expr.PropertyException;
*/
public final class ColorUtil {
+ //ColorWithFallback is used to preserve the sRGB fallback exclusively for the purpose
+ //of regenerating textual color functions as specified in XSL-FO.
+
/** The name for the uncalibrated CMYK pseudo-profile */
public static final String CMYK_PSEUDO_PROFILE = "#CMYK";
+ /** The name for the Separation pseudo-profile used for spot colors */
+ public static final String SEPARATION_PSEUDO_PROFILE = "#Separation";
+
/**
- *
- * keeps all the predefined and parsed colors.
+ * 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.
+ * <p>
+ * Important: The use of this color map assumes that all Color instances are immutable!
*/
private static Map<String, Color> colorMap = null;
@@ -98,7 +114,7 @@ public final class ColorUtil {
return null;
}
- Color parsedColor = (Color) colorMap.get(value.toLowerCase());
+ Color parsedColor = colorMap.get(value.toLowerCase());
if (parsedColor == null) {
if (value.startsWith("#")) {
@@ -114,6 +130,10 @@ 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("cie-lab-color")) {
+ parsedColor = parseAsCIELabColor(foUserAgent, value);
} else if (value.startsWith("cmyk")) {
parsedColor = parseAsCMYK(value);
}
@@ -125,9 +145,6 @@ public final class ColorUtil {
colorMap.put(value, parsedColor);
}
- // 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;
}
@@ -150,7 +167,7 @@ public final class ColorUtil {
throw new PropertyException("Unknown color format: " + value
+ ". Must be system-color(x)");
}
- return (Color) colorMap.get(value);
+ return colorMap.get(value);
}
/**
@@ -218,34 +235,14 @@ public final class ColorUtil {
throw new PropertyException(
"Invalid number of arguments: rgb(" + value + ")");
}
- float red = 0.0f, green = 0.0f, blue = 0.0f;
- String str = args[0].trim();
- if (str.endsWith("%")) {
- red = Float.parseFloat(str.substring(0,
- str.length() - 1)) / 100f;
- } else {
- red = Float.parseFloat(str) / 255f;
- }
- str = args[1].trim();
- if (str.endsWith("%")) {
- green = Float.parseFloat(str.substring(0,
- str.length() - 1)) / 100f;
- } else {
- green = Float.parseFloat(str) / 255f;
- }
- str = args[2].trim();
- if (str.endsWith("%")) {
- blue = Float.parseFloat(str.substring(0,
- str.length() - 1)) / 100f;
- } else {
- blue = Float.parseFloat(str) / 255f;
- }
- 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");
- }
- parsedColor = new Color(red, green, blue);
+ float red = parseComponent255(args[0], value);
+ float green = parseComponent255(args[1], value);
+ float blue = parseComponent255(args[2], value);
+ //Convert to ints to synchronize the behaviour with toRGBFunctionCall()
+ int r = (int)(red * 255 + 0.5);
+ int g = (int)(green * 255 + 0.5);
+ int b = (int)(blue * 255 + 0.5);
+ parsedColor = new Color(r, g, b);
} catch (PropertyException pe) {
//simply re-throw
throw pe;
@@ -260,8 +257,50 @@ public final class ColorUtil {
return parsedColor;
}
+ private static float parseComponent255(String str, String function)
+ throws PropertyException {
+ float component;
+ str = str.trim();
+ if (str.endsWith("%")) {
+ component = Float.parseFloat(str.substring(0,
+ str.length() - 1)) / 100f;
+ } else {
+ component = Float.parseFloat(str) / 255f;
+ }
+ if ((component < 0.0 || component > 1.0)) {
+ throw new PropertyException("Color value out of range for " + function + ": "
+ + str + ". Valid range: [0..255] or [0%..100%]");
+ }
+ return component;
+ }
+
+ private static float parseComponent1(String argument, String function)
+ throws PropertyException {
+ return parseComponent(argument, 0f, 1f, function);
+ }
+
+ private static float parseComponent(String argument, float min, float max, String function)
+ throws PropertyException {
+ float component = Float.parseFloat(argument.trim());
+ if ((component < min || component > max)) {
+ throw new PropertyException("Color value out of range for " + function + ": "
+ + argument + ". Valid range: [" + min + ".." + max + "]");
+ }
+ return component;
+ }
+
+ private static Color parseFallback(String[] args, String value) throws PropertyException {
+ float red = parseComponent1(args[0], value);
+ float green = parseComponent1(args[1], value);
+ float blue = parseComponent1(args[2], value);
+ //Sun's classlib rounds differently with this constructor than when converting to sRGB
+ //via CIE XYZ.
+ Color sRGB = new Color(red, green, blue);
+ return sRGB;
+ }
+
/**
- * parse a color given in the #.... format.
+ * Parse a color given in the #.... format.
*
* @param value
* the complete line
@@ -320,6 +359,10 @@ public final class ColorUtil {
if (args.length < 5) {
throw new PropertyException("Too few arguments for rgb-icc() function");
}
+
+ //Set up fallback sRGB value
+ Color sRGB = parseFallback(args, value);
+
/* Get and verify ICC profile name */
String iccProfileName = args[3].trim();
if (iccProfileName == null || "".equals(iccProfileName)) {
@@ -330,6 +373,9 @@ public final class ColorUtil {
if (isPseudoProfile(iccProfileName)) {
if (CMYK_PSEUDO_PROFILE.equalsIgnoreCase(iccProfileName)) {
colorSpace = ColorSpaces.getDeviceCMYKColorSpace();
+ } else if (SEPARATION_PSEUDO_PROFILE.equalsIgnoreCase(iccProfileName)) {
+ colorSpace = new NamedColorSpace(args[5], sRGB,
+ SEPARATION_PSEUDO_PROFILE, null);
} else {
assert false : "Incomplete implementation";
}
@@ -339,47 +385,51 @@ 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 */
- float[] iccComponents = new float[args.length - 5];
- for (int ix = 4; ++ix < args.length;) {
- iccComponents[ix - 5] = Float.parseFloat(args[ix].trim());
+ int componentStart = 4;
+ if (colorSpace instanceof NamedColorSpace) {
+ componentStart++;
}
-
- float red = 0, green = 0, blue = 0;
- red = Float.parseFloat(args[0].trim());
- green = Float.parseFloat(args[1].trim());
- 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-icc() must be [0..1]");
+ float[] iccComponents = new float[args.length - componentStart - 1];
+ for (int ix = componentStart; ++ix < args.length;) {
+ iccComponents[ix - componentStart - 1] = Float.parseFloat(args[ix].trim());
+ }
+ if (colorSpace instanceof NamedColorSpace && iccComponents.length == 0) {
+ iccComponents = new float[] {1.0f}; //full tint if not specified
}
/* Ask FOP factory to get ColorSpace for the specified ICC profile source */
if (foUserAgent != null && iccProfileSrc != null) {
- colorSpace = foUserAgent.getFactory().getColorSpace(
- foUserAgent.getBaseURL(), iccProfileSrc);
+ assert colorSpace == null;
+ RenderingIntent renderingIntent = RenderingIntent.AUTO;
+ //TODO connect to fo:color-profile/@rendering-intent
+ colorSpace = foUserAgent.getFactory().getColorSpaceCache().get(
+ iccProfileName,
+ foUserAgent.getBaseURL(), iccProfileSrc,
+ renderingIntent);
}
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);
+ // ColorSpace is available
+ if (ColorSpaces.isDeviceColorSpace(colorSpace)) {
+ //Device-specific colors are handled differently:
+ //sRGB is the primary color with the CMYK as the alternative
+ Color deviceColor = new Color(colorSpace, iccComponents, 1.0f);
+ float[] rgbComps = sRGB.getRGBColorComponents(null);
+ parsedColor = new ColorWithAlternatives(
+ rgbComps[0], rgbComps[1], rgbComps[2],
+ new Color[] {deviceColor});
+ } else {
+ Color specColor = new ColorWithFallback(
+ colorSpace, iccComponents, 1.0f, null, sRGB);
+ parsedColor = specColor;
+ }
} 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(Math.round(red * 255),
- Math.round(green * 255), Math.round(blue * 255));
+ + "' not found. Using sRGB replacement values.");
+ parsedColor = sRGB;
}
} catch (PropertyException pe) {
//simply re-throw
@@ -396,6 +446,161 @@ 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-color() function must have 6 arguments");
+ }
+
+ //Set up fallback sRGB value
+ Color sRGB = parseFallback(args, value);
+
+ /* 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) {
+ RenderingIntent renderingIntent = RenderingIntent.AUTO;
+ //TODO connect to fo:color-profile/@rendering-intent
+ colorSpace = (ICC_ColorSpace)foUserAgent.getFactory().getColorSpaceCache().get(
+ iccProfileName,
+ foUserAgent.getBaseURL(), iccProfileSrc,
+ renderingIntent);
+ }
+ if (colorSpace != null) {
+ ICC_Profile profile = colorSpace.getProfile();
+ if (NamedColorProfileParser.isNamedColorProfile(profile)) {
+ NamedColorProfileParser parser = new NamedColorProfileParser();
+ NamedColorProfile ncp = parser.parseProfile(profile,
+ iccProfileName, iccProfileSrc);
+ NamedColorSpace ncs = ncp.getNamedColor(colorName);
+ if (ncs != null) {
+ Color specColor = new ColorWithFallback(ncs,
+ new float[] {1.0f}, 1.0f, null, sRGB);
+ parsedColor = specColor;
+ } 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;
+ }
+
+ /**
+ * Parse a color specified using the cie-lab-color() function.
+ *
+ * @param value the function call
+ * @return a color if possible
+ * @throws PropertyException if the format is wrong.
+ */
+ private static Color parseAsCIELabColor(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("cie-lab-color() function must have 6 arguments");
+ }
+
+ //Set up fallback sRGB value
+ float red = parseComponent255(args[0], value);
+ float green = parseComponent255(args[1], value);
+ float blue = parseComponent255(args[2], value);
+ Color sRGB = new Color(red, green, blue);
+
+ float l = parseComponent(args[3], 0f, 100f, value);
+ float a = parseComponent(args[4], -127f, 127f, value);
+ float b = parseComponent(args[5], -127f, 127f, value);
+
+ //Assuming the XSL-FO spec uses the D50 white point
+ CIELabColorSpace cs = ColorSpaces.getCIELabColorSpaceD50();
+ //use toColor() to have components normalized
+ Color labColor = cs.toColor(l, a, b, 1.0f);
+ //Convert to ColorWithFallback
+ parsedColor = new ColorWithFallback(labColor, 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 cie-lab-color(r,g,b,Lightness,a-value,b-value)");
+ }
+ 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
@@ -416,48 +621,15 @@ public final class ColorUtil {
throw new PropertyException(
"Invalid number of arguments: cmyk(" + value + ")");
}
- float cyan = 0.0f, magenta = 0.0f, yellow = 0.0f, black = 0.0f;
- String str = args[0].trim();
- if (str.endsWith("%")) {
- cyan = Float.parseFloat(str.substring(0,
- str.length() - 1)) / 100.0f;
- } else {
- cyan = Float.parseFloat(str);
- }
- str = args[1].trim();
- if (str.endsWith("%")) {
- magenta = Float.parseFloat(str.substring(0,
- str.length() - 1)) / 100.0f;
- } else {
- magenta = Float.parseFloat(str);
- }
- str = args[2].trim();
- if (str.endsWith("%")) {
- yellow = Float.parseFloat(str.substring(0,
- str.length() - 1)) / 100.0f;
- } else {
- yellow = Float.parseFloat(str);
- }
- str = args[3].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"
- + "Arguments to cmyk() must be in the range [0%-100%] or [0.0-1.0]");
- }
- float[] cmyk = new float[] {cyan, magenta, yellow, black};
- DeviceCMYKColorSpace cmykCs = ColorSpaces.getDeviceCMYKColorSpace();
- float[] rgb = cmykCs.toRGB(cmyk);
- parsedColor = ColorExt.createFromFoRgbIcc(rgb[0], rgb[1], rgb[2],
- CMYK_PSEUDO_PROFILE, null, cmykCs, cmyk);
+ float cyan = parseComponent1(args[0], value);
+ float magenta = parseComponent1(args[1], value);
+ float yellow = parseComponent1(args[2], value);
+ float black = parseComponent1(args[3], value);
+ float[] comps = new float[] {cyan, magenta, yellow, black};
+ Color cmykColor = DeviceCMYKColorSpace.createCMYKColor(comps);
+ float[] rgbComps = cmykColor.getRGBColorComponents(null);
+ parsedColor = new ColorWithAlternatives(rgbComps[0], rgbComps[1], rgbComps[2],
+ new Color[] {cmykColor});
} catch (PropertyException pe) {
throw pe;
} catch (Exception e) {
@@ -482,40 +654,146 @@ public final class ColorUtil {
*/
public static String colorToString(Color color) {
ColorSpace cs = color.getColorSpace();
- if (color instanceof ColorExt) {
- return ((ColorExt)color).toFunctionCall();
+ if (color instanceof ColorWithAlternatives) {
+ return toFunctionCall((ColorWithAlternatives)color);
} 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 {
- StringBuffer sbuf = new StringBuffer();
- sbuf.append('#');
- String s = Integer.toHexString(color.getRed());
+ return toRGBFunctionCall(color);
+ }
+ }
+
+ private static String toRGBFunctionCall(Color color) {
+ 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);
- s = Integer.toHexString(color.getGreen());
- if (s.length() == 1) {
- sbuf.append('0');
+ }
+ return sbuf.toString();
+ }
+
+ private static Color getsRGBFallback(ColorWithAlternatives color) {
+ Color fallbackColor;
+ if (color instanceof ColorWithFallback) {
+ fallbackColor = ((ColorWithFallback)color).getFallbackColor();
+ if (!fallbackColor.getColorSpace().isCS_sRGB()) {
+ fallbackColor = toSRGBColor(fallbackColor);
}
- sbuf.append(s);
- s = Integer.toHexString(color.getBlue());
- if (s.length() == 1) {
- sbuf.append('0');
+ } else {
+ fallbackColor = toSRGBColor(color);
+ }
+ return fallbackColor;
+ }
+
+ private static Color toSRGBColor(Color color) {
+ float[] comps;
+ ColorSpace sRGB = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+ comps = color.getRGBColorComponents(null);
+ float[] allComps = color.getComponents(null);
+ float alpha = allComps[allComps.length - 1]; //Alpha is on last component
+ return new Color(sRGB, comps, alpha);
+ }
+
+ /**
+ * Create string representation of a fop-rgb-icc (or fop-rgb-named-color) function call from
+ * the given color.
+ * @param color the color to turn into a function call
+ * @return the string representing the internal fop-rgb-icc() or fop-rgb-named-color()
+ * function call
+ */
+ private static String toFunctionCall(ColorWithAlternatives color) {
+ ColorSpace cs = color.getColorSpace();
+ if (cs.isCS_sRGB() && !color.hasAlternativeColors()) {
+ return toRGBFunctionCall(color);
+ }
+ if (cs instanceof CIELabColorSpace) {
+ return toCIELabFunctionCall(color);
+ }
+
+ Color specColor = color;
+ if (color.hasAlternativeColors()) {
+ Color alt = color.getAlternativeColors()[0];
+ if (ColorSpaces.isDeviceColorSpace(alt.getColorSpace())) {
+ cs = alt.getColorSpace();
+ specColor = alt;
}
- sbuf.append(s);
- if (color.getAlpha() != 255) {
- s = Integer.toHexString(color.getAlpha());
- if (s.length() == 1) {
- sbuf.append('0');
- }
- sbuf.append(s);
+ }
+ ColorSpaceOrigin origin = ColorSpaces.getColorSpaceOrigin(cs);
+ String functionName;
+
+ Color fallbackColor = getsRGBFallback(color);
+ float[] rgb = fallbackColor.getColorComponents(null);
+ assert rgb.length == 3;
+ StringBuffer sb = new StringBuffer(40);
+ sb.append("(");
+ sb.append(rgb[0]).append(",");
+ sb.append(rgb[1]).append(",");
+ sb.append(rgb[2]).append(",");
+ String profileName = origin.getProfileName();
+ sb.append(profileName).append(",");
+ if (origin.getProfileURI() != null) {
+ sb.append("\"").append(origin.getProfileURI()).append("\"");
+ }
+
+ if (cs instanceof NamedColorSpace) {
+ NamedColorSpace ncs = (NamedColorSpace)cs;
+ if (SEPARATION_PSEUDO_PROFILE.equalsIgnoreCase(profileName)) {
+ functionName = "fop-rgb-icc";
+ } else {
+ functionName = "fop-rgb-named-color";
+ }
+ sb.append(",").append(ncs.getColorName());
+ } else {
+ functionName = "fop-rgb-icc";
+ float[] colorComponents = specColor.getColorComponents(null);
+ for (int ix = 0; ix < colorComponents.length; ix++) {
+ sb.append(",");
+ sb.append(colorComponents[ix]);
}
- return sbuf.toString();
}
+ sb.append(")");
+ return functionName + sb.toString();
+ }
+
+ private static String toCIELabFunctionCall(ColorWithAlternatives color) {
+ Color fallbackColor = getsRGBFallback(color);
+ StringBuffer sb = new StringBuffer("cie-lab-color(");
+ sb.append(fallbackColor.getRed()).append(',');
+ sb.append(fallbackColor.getGreen()).append(',');
+ sb.append(fallbackColor.getBlue());
+ CIELabColorSpace cs = (CIELabColorSpace)color.getColorSpace();
+ float[] lab = cs.toNativeComponents(color.getColorComponents(null));
+ for (int i = 0; i < 3; i++) {
+ sb.append(',').append(lab[i]);
+ }
+ sb.append(')');
+ return sb.toString();
+ }
+
+ private static Color createColor(int r, int g, int b) {
+ return new Color(r, g, b);
}
/**
@@ -524,155 +802,155 @@ public final class ColorUtil {
private static void initializeColorMap() { // CSOK: MethodLength
colorMap = Collections.synchronizedMap(new java.util.HashMap<String, Color>());
- colorMap.put("aliceblue", new Color(240, 248, 255));
- colorMap.put("antiquewhite", new Color(250, 235, 215));
- colorMap.put("aqua", new Color(0, 255, 255));
- colorMap.put("aquamarine", new Color(127, 255, 212));
- colorMap.put("azure", new Color(240, 255, 255));
- colorMap.put("beige", new Color(245, 245, 220));
- colorMap.put("bisque", new Color(255, 228, 196));
- colorMap.put("black", new Color(0, 0, 0));
- colorMap.put("blanchedalmond", new Color(255, 235, 205));
- colorMap.put("blue", new Color(0, 0, 255));
- colorMap.put("blueviolet", new Color(138, 43, 226));
- colorMap.put("brown", new Color(165, 42, 42));
- colorMap.put("burlywood", new Color(222, 184, 135));
- colorMap.put("cadetblue", new Color(95, 158, 160));
- colorMap.put("chartreuse", new Color(127, 255, 0));
- colorMap.put("chocolate", new Color(210, 105, 30));
- colorMap.put("coral", new Color(255, 127, 80));
- colorMap.put("cornflowerblue", new Color(100, 149, 237));
- colorMap.put("cornsilk", new Color(255, 248, 220));
- colorMap.put("crimson", new Color(220, 20, 60));
- colorMap.put("cyan", new Color(0, 255, 255));
- colorMap.put("darkblue", new Color(0, 0, 139));
- colorMap.put("darkcyan", new Color(0, 139, 139));
- colorMap.put("darkgoldenrod", new Color(184, 134, 11));
- colorMap.put("darkgray", new Color(169, 169, 169));
- colorMap.put("darkgreen", new Color(0, 100, 0));
- colorMap.put("darkgrey", new Color(169, 169, 169));
- colorMap.put("darkkhaki", new Color(189, 183, 107));
- colorMap.put("darkmagenta", new Color(139, 0, 139));
- colorMap.put("darkolivegreen", new Color(85, 107, 47));
- colorMap.put("darkorange", new Color(255, 140, 0));
- colorMap.put("darkorchid", new Color(153, 50, 204));
- colorMap.put("darkred", new Color(139, 0, 0));
- colorMap.put("darksalmon", new Color(233, 150, 122));
- colorMap.put("darkseagreen", new Color(143, 188, 143));
- colorMap.put("darkslateblue", new Color(72, 61, 139));
- colorMap.put("darkslategray", new Color(47, 79, 79));
- colorMap.put("darkslategrey", new Color(47, 79, 79));
- colorMap.put("darkturquoise", new Color(0, 206, 209));
- colorMap.put("darkviolet", new Color(148, 0, 211));
- colorMap.put("deeppink", new Color(255, 20, 147));
- colorMap.put("deepskyblue", new Color(0, 191, 255));
- colorMap.put("dimgray", new Color(105, 105, 105));
- colorMap.put("dimgrey", new Color(105, 105, 105));
- colorMap.put("dodgerblue", new Color(30, 144, 255));
- colorMap.put("firebrick", new Color(178, 34, 34));
- colorMap.put("floralwhite", new Color(255, 250, 240));
- colorMap.put("forestgreen", new Color(34, 139, 34));
- colorMap.put("fuchsia", new Color(255, 0, 255));
- colorMap.put("gainsboro", new Color(220, 220, 220));
- colorMap.put("ghostwhite", new Color(248, 248, 255));
- colorMap.put("gold", new Color(255, 215, 0));
- colorMap.put("goldenrod", new Color(218, 165, 32));
- colorMap.put("gray", new Color(128, 128, 128));
- colorMap.put("green", new Color(0, 128, 0));
- colorMap.put("greenyellow", new Color(173, 255, 47));
- colorMap.put("grey", new Color(128, 128, 128));
- colorMap.put("honeydew", new Color(240, 255, 240));
- colorMap.put("hotpink", new Color(255, 105, 180));
- colorMap.put("indianred", new Color(205, 92, 92));
- colorMap.put("indigo", new Color(75, 0, 130));
- colorMap.put("ivory", new Color(255, 255, 240));
- colorMap.put("khaki", new Color(240, 230, 140));
- colorMap.put("lavender", new Color(230, 230, 250));
- colorMap.put("lavenderblush", new Color(255, 240, 245));
- colorMap.put("lawngreen", new Color(124, 252, 0));
- colorMap.put("lemonchiffon", new Color(255, 250, 205));
- colorMap.put("lightblue", new Color(173, 216, 230));
- colorMap.put("lightcoral", new Color(240, 128, 128));
- colorMap.put("lightcyan", new Color(224, 255, 255));
- colorMap.put("lightgoldenrodyellow", new Color(250, 250, 210));
- colorMap.put("lightgray", new Color(211, 211, 211));
- colorMap.put("lightgreen", new Color(144, 238, 144));
- colorMap.put("lightgrey", new Color(211, 211, 211));
- colorMap.put("lightpink", new Color(255, 182, 193));
- colorMap.put("lightsalmon", new Color(255, 160, 122));
- colorMap.put("lightseagreen", new Color(32, 178, 170));
- colorMap.put("lightskyblue", new Color(135, 206, 250));
- colorMap.put("lightslategray", new Color(119, 136, 153));
- colorMap.put("lightslategrey", new Color(119, 136, 153));
- colorMap.put("lightsteelblue", new Color(176, 196, 222));
- colorMap.put("lightyellow", new Color(255, 255, 224));
- colorMap.put("lime", new Color(0, 255, 0));
- colorMap.put("limegreen", new Color(50, 205, 50));
- colorMap.put("linen", new Color(250, 240, 230));
- colorMap.put("magenta", new Color(255, 0, 255));
- colorMap.put("maroon", new Color(128, 0, 0));
- colorMap.put("mediumaquamarine", new Color(102, 205, 170));
- colorMap.put("mediumblue", new Color(0, 0, 205));
- colorMap.put("mediumorchid", new Color(186, 85, 211));
- colorMap.put("mediumpurple", new Color(147, 112, 219));
- colorMap.put("mediumseagreen", new Color(60, 179, 113));
- colorMap.put("mediumslateblue", new Color(123, 104, 238));
- colorMap.put("mediumspringgreen", new Color(0, 250, 154));
- colorMap.put("mediumturquoise", new Color(72, 209, 204));
- colorMap.put("mediumvioletred", new Color(199, 21, 133));
- colorMap.put("midnightblue", new Color(25, 25, 112));
- colorMap.put("mintcream", new Color(245, 255, 250));
- colorMap.put("mistyrose", new Color(255, 228, 225));
- colorMap.put("moccasin", new Color(255, 228, 181));
- colorMap.put("navajowhite", new Color(255, 222, 173));
- colorMap.put("navy", new Color(0, 0, 128));
- colorMap.put("oldlace", new Color(253, 245, 230));
- colorMap.put("olive", new Color(128, 128, 0));
- colorMap.put("olivedrab", new Color(107, 142, 35));
- colorMap.put("orange", new Color(255, 165, 0));
- colorMap.put("orangered", new Color(255, 69, 0));
- colorMap.put("orchid", new Color(218, 112, 214));
- colorMap.put("palegoldenrod", new Color(238, 232, 170));
- colorMap.put("palegreen", new Color(152, 251, 152));
- colorMap.put("paleturquoise", new Color(175, 238, 238));
- colorMap.put("palevioletred", new Color(219, 112, 147));
- colorMap.put("papayawhip", new Color(255, 239, 213));
- colorMap.put("peachpuff", new Color(255, 218, 185));
- colorMap.put("peru", new Color(205, 133, 63));
- colorMap.put("pink", new Color(255, 192, 203));
- colorMap.put("plum ", new Color(221, 160, 221));
- colorMap.put("plum", new Color(221, 160, 221));
- colorMap.put("powderblue", new Color(176, 224, 230));
- colorMap.put("purple", new Color(128, 0, 128));
- colorMap.put("red", new Color(255, 0, 0));
- colorMap.put("rosybrown", new Color(188, 143, 143));
- colorMap.put("royalblue", new Color(65, 105, 225));
- colorMap.put("saddlebrown", new Color(139, 69, 19));
- colorMap.put("salmon", new Color(250, 128, 114));
- colorMap.put("sandybrown", new Color(244, 164, 96));
- colorMap.put("seagreen", new Color(46, 139, 87));
- colorMap.put("seashell", new Color(255, 245, 238));
- colorMap.put("sienna", new Color(160, 82, 45));
- colorMap.put("silver", new Color(192, 192, 192));
- colorMap.put("skyblue", new Color(135, 206, 235));
- colorMap.put("slateblue", new Color(106, 90, 205));
- colorMap.put("slategray", new Color(112, 128, 144));
- colorMap.put("slategrey", new Color(112, 128, 144));
- colorMap.put("snow", new Color(255, 250, 250));
- colorMap.put("springgreen", new Color(0, 255, 127));
- colorMap.put("steelblue", new Color(70, 130, 180));
- colorMap.put("tan", new Color(210, 180, 140));
- colorMap.put("teal", new Color(0, 128, 128));
- colorMap.put("thistle", new Color(216, 191, 216));
- colorMap.put("tomato", new Color(255, 99, 71));
- colorMap.put("turquoise", new Color(64, 224, 208));
- colorMap.put("violet", new Color(238, 130, 238));
- colorMap.put("wheat", new Color(245, 222, 179));
- colorMap.put("white", new Color(255, 255, 255));
- colorMap.put("whitesmoke", new Color(245, 245, 245));
- colorMap.put("yellow", new Color(255, 255, 0));
- colorMap.put("yellowgreen", new Color(154, 205, 50));
- colorMap.put("transparent", new Color(0, 0, 0, 0));
+ colorMap.put("aliceblue", createColor(240, 248, 255));
+ colorMap.put("antiquewhite", createColor(250, 235, 215));
+ colorMap.put("aqua", createColor(0, 255, 255));
+ colorMap.put("aquamarine", createColor(127, 255, 212));
+ colorMap.put("azure", createColor(240, 255, 255));
+ colorMap.put("beige", createColor(245, 245, 220));
+ colorMap.put("bisque", createColor(255, 228, 196));
+ colorMap.put("black", createColor(0, 0, 0));
+ colorMap.put("blanchedalmond", createColor(255, 235, 205));
+ colorMap.put("blue", createColor(0, 0, 255));
+ colorMap.put("blueviolet", createColor(138, 43, 226));
+ colorMap.put("brown", createColor(165, 42, 42));
+ colorMap.put("burlywood", createColor(222, 184, 135));
+ colorMap.put("cadetblue", createColor(95, 158, 160));
+ colorMap.put("chartreuse", createColor(127, 255, 0));
+ colorMap.put("chocolate", createColor(210, 105, 30));
+ colorMap.put("coral", createColor(255, 127, 80));
+ colorMap.put("cornflowerblue", createColor(100, 149, 237));
+ colorMap.put("cornsilk", createColor(255, 248, 220));
+ colorMap.put("crimson", createColor(220, 20, 60));
+ colorMap.put("cyan", createColor(0, 255, 255));
+ colorMap.put("darkblue", createColor(0, 0, 139));
+ colorMap.put("darkcyan", createColor(0, 139, 139));
+ colorMap.put("darkgoldenrod", createColor(184, 134, 11));
+ colorMap.put("darkgray", createColor(169, 169, 169));
+ colorMap.put("darkgreen", createColor(0, 100, 0));
+ colorMap.put("darkgrey", createColor(169, 169, 169));
+ colorMap.put("darkkhaki", createColor(189, 183, 107));
+ colorMap.put("darkmagenta", createColor(139, 0, 139));
+ colorMap.put("darkolivegreen", createColor(85, 107, 47));
+ colorMap.put("darkorange", createColor(255, 140, 0));
+ colorMap.put("darkorchid", createColor(153, 50, 204));
+ colorMap.put("darkred", createColor(139, 0, 0));
+ colorMap.put("darksalmon", createColor(233, 150, 122));
+ colorMap.put("darkseagreen", createColor(143, 188, 143));
+ colorMap.put("darkslateblue", createColor(72, 61, 139));
+ colorMap.put("darkslategray", createColor(47, 79, 79));
+ colorMap.put("darkslategrey", createColor(47, 79, 79));
+ colorMap.put("darkturquoise", createColor(0, 206, 209));
+ colorMap.put("darkviolet", createColor(148, 0, 211));
+ colorMap.put("deeppink", createColor(255, 20, 147));
+ colorMap.put("deepskyblue", createColor(0, 191, 255));
+ colorMap.put("dimgray", createColor(105, 105, 105));
+ colorMap.put("dimgrey", createColor(105, 105, 105));
+ colorMap.put("dodgerblue", createColor(30, 144, 255));
+ colorMap.put("firebrick", createColor(178, 34, 34));
+ colorMap.put("floralwhite", createColor(255, 250, 240));
+ colorMap.put("forestgreen", createColor(34, 139, 34));
+ colorMap.put("fuchsia", createColor(255, 0, 255));
+ colorMap.put("gainsboro", createColor(220, 220, 220));
+ colorMap.put("ghostwhite", createColor(248, 248, 255));
+ colorMap.put("gold", createColor(255, 215, 0));
+ colorMap.put("goldenrod", createColor(218, 165, 32));
+ colorMap.put("gray", createColor(128, 128, 128));
+ colorMap.put("green", createColor(0, 128, 0));
+ colorMap.put("greenyellow", createColor(173, 255, 47));
+ colorMap.put("grey", createColor(128, 128, 128));
+ colorMap.put("honeydew", createColor(240, 255, 240));
+ colorMap.put("hotpink", createColor(255, 105, 180));
+ colorMap.put("indianred", createColor(205, 92, 92));
+ colorMap.put("indigo", createColor(75, 0, 130));
+ colorMap.put("ivory", createColor(255, 255, 240));
+ colorMap.put("khaki", createColor(240, 230, 140));
+ colorMap.put("lavender", createColor(230, 230, 250));
+ colorMap.put("lavenderblush", createColor(255, 240, 245));
+ colorMap.put("lawngreen", createColor(124, 252, 0));
+ colorMap.put("lemonchiffon", createColor(255, 250, 205));
+ colorMap.put("lightblue", createColor(173, 216, 230));
+ colorMap.put("lightcoral", createColor(240, 128, 128));
+ colorMap.put("lightcyan", createColor(224, 255, 255));
+ colorMap.put("lightgoldenrodyellow", createColor(250, 250, 210));
+ colorMap.put("lightgray", createColor(211, 211, 211));
+ colorMap.put("lightgreen", createColor(144, 238, 144));
+ colorMap.put("lightgrey", createColor(211, 211, 211));
+ colorMap.put("lightpink", createColor(255, 182, 193));
+ colorMap.put("lightsalmon", createColor(255, 160, 122));
+ colorMap.put("lightseagreen", createColor(32, 178, 170));
+ colorMap.put("lightskyblue", createColor(135, 206, 250));
+ colorMap.put("lightslategray", createColor(119, 136, 153));
+ colorMap.put("lightslategrey", createColor(119, 136, 153));
+ colorMap.put("lightsteelblue", createColor(176, 196, 222));
+ colorMap.put("lightyellow", createColor(255, 255, 224));
+ colorMap.put("lime", createColor(0, 255, 0));
+ colorMap.put("limegreen", createColor(50, 205, 50));
+ colorMap.put("linen", createColor(250, 240, 230));
+ colorMap.put("magenta", createColor(255, 0, 255));
+ colorMap.put("maroon", createColor(128, 0, 0));
+ colorMap.put("mediumaquamarine", createColor(102, 205, 170));
+ colorMap.put("mediumblue", createColor(0, 0, 205));
+ colorMap.put("mediumorchid", createColor(186, 85, 211));
+ colorMap.put("mediumpurple", createColor(147, 112, 219));
+ colorMap.put("mediumseagreen", createColor(60, 179, 113));
+ colorMap.put("mediumslateblue", createColor(123, 104, 238));
+ colorMap.put("mediumspringgreen", createColor(0, 250, 154));
+ colorMap.put("mediumturquoise", createColor(72, 209, 204));
+ colorMap.put("mediumvioletred", createColor(199, 21, 133));
+ colorMap.put("midnightblue", createColor(25, 25, 112));
+ colorMap.put("mintcream", createColor(245, 255, 250));
+ colorMap.put("mistyrose", createColor(255, 228, 225));
+ colorMap.put("moccasin", createColor(255, 228, 181));
+ colorMap.put("navajowhite", createColor(255, 222, 173));
+ colorMap.put("navy", createColor(0, 0, 128));
+ colorMap.put("oldlace", createColor(253, 245, 230));
+ colorMap.put("olive", createColor(128, 128, 0));
+ colorMap.put("olivedrab", createColor(107, 142, 35));
+ colorMap.put("orange", createColor(255, 165, 0));
+ colorMap.put("orangered", createColor(255, 69, 0));
+ colorMap.put("orchid", createColor(218, 112, 214));
+ colorMap.put("palegoldenrod", createColor(238, 232, 170));
+ colorMap.put("palegreen", createColor(152, 251, 152));
+ colorMap.put("paleturquoise", createColor(175, 238, 238));
+ colorMap.put("palevioletred", createColor(219, 112, 147));
+ colorMap.put("papayawhip", createColor(255, 239, 213));
+ colorMap.put("peachpuff", createColor(255, 218, 185));
+ colorMap.put("peru", createColor(205, 133, 63));
+ colorMap.put("pink", createColor(255, 192, 203));
+ colorMap.put("plum ", createColor(221, 160, 221));
+ colorMap.put("plum", createColor(221, 160, 221));
+ colorMap.put("powderblue", createColor(176, 224, 230));
+ colorMap.put("purple", createColor(128, 0, 128));
+ colorMap.put("red", createColor(255, 0, 0));
+ colorMap.put("rosybrown", createColor(188, 143, 143));
+ colorMap.put("royalblue", createColor(65, 105, 225));
+ colorMap.put("saddlebrown", createColor(139, 69, 19));
+ colorMap.put("salmon", createColor(250, 128, 114));
+ colorMap.put("sandybrown", createColor(244, 164, 96));
+ colorMap.put("seagreen", createColor(46, 139, 87));
+ colorMap.put("seashell", createColor(255, 245, 238));
+ colorMap.put("sienna", createColor(160, 82, 45));
+ colorMap.put("silver", createColor(192, 192, 192));
+ colorMap.put("skyblue", createColor(135, 206, 235));
+ colorMap.put("slateblue", createColor(106, 90, 205));
+ colorMap.put("slategray", createColor(112, 128, 144));
+ colorMap.put("slategrey", createColor(112, 128, 144));
+ colorMap.put("snow", createColor(255, 250, 250));
+ colorMap.put("springgreen", createColor(0, 255, 127));
+ colorMap.put("steelblue", createColor(70, 130, 180));
+ colorMap.put("tan", createColor(210, 180, 140));
+ colorMap.put("teal", createColor(0, 128, 128));
+ colorMap.put("thistle", createColor(216, 191, 216));
+ colorMap.put("tomato", createColor(255, 99, 71));
+ colorMap.put("turquoise", createColor(64, 224, 208));
+ colorMap.put("violet", createColor(238, 130, 238));
+ colorMap.put("wheat", createColor(245, 222, 179));
+ colorMap.put("white", createColor(255, 255, 255));
+ colorMap.put("whitesmoke", createColor(245, 245, 245));
+ colorMap.put("yellow", createColor(255, 255, 0));
+ colorMap.put("yellowgreen", createColor(154, 205, 50));
+ colorMap.put("transparent", new ColorWithAlternatives(0, 0, 0, 0, null));
}
/**
@@ -692,7 +970,8 @@ public final class ColorUtil {
* @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);
+ return CMYK_PSEUDO_PROFILE.equalsIgnoreCase(colorProfileName)
+ || SEPARATION_PSEUDO_PROFILE.equalsIgnoreCase(colorProfileName);
}
/**
@@ -710,11 +989,6 @@ public final class ColorUtil {
* @return the CMYK color
*/
public static Color toCMYKGrayColor(float black) {
- float[] cmyk = new float[] {0f, 0f, 0f, 1.0f - black};
- DeviceCMYKColorSpace cmykCs = ColorSpaces.getDeviceCMYKColorSpace();
- float[] rgb = cmykCs.toRGB(cmyk);
- return ColorExt.createFromFoRgbIcc(rgb[0], rgb[1], rgb[2],
- CMYK_PSEUDO_PROFILE, null, cmykCs, cmyk);
+ return org.apache.xmlgraphics.java2d.color.ColorUtil.toCMYKGrayColor(black);
}
-
}
diff --git a/src/java/org/apache/fop/util/ColorWithFallback.java b/src/java/org/apache/fop/util/ColorWithFallback.java
new file mode 100644
index 000000000..0ec560367
--- /dev/null
+++ b/src/java/org/apache/fop/util/ColorWithFallback.java
@@ -0,0 +1,85 @@
+/*
+ * 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;
+
+import org.apache.xmlgraphics.java2d.color.ColorWithAlternatives;
+
+/**
+ * This class is a {@link Color} subclass adding a fallback color that FOP uses to re-serialize
+ * color specifications as textual functions. The fallback is otherwise not used in producing
+ * output formats.
+ */
+public class ColorWithFallback extends ColorWithAlternatives {
+
+ private static final long serialVersionUID = 7913922854959637136L;
+
+ private final Color fallback;
+
+ /**
+ * Creates a new color
+ * @param cspace the color space of the primary color
+ * @param components the color components
+ * @param alpha the alpha component
+ * @param alternativeColors the array of alternative colors if applicable (may be null)
+ * @param fallback the fallback color (usually an sRGB color)
+ */
+ public ColorWithFallback(ColorSpace cspace, float[] components, float alpha,
+ Color[] alternativeColors, Color fallback) {
+ super(cspace, components, alpha, alternativeColors);
+ this.fallback = fallback;
+ }
+
+ /**
+ * Copy constructor adding a fallback color.
+ * @param color the color to be duplicated
+ * @param fallback the fallback color (usually an sRGB color)
+ */
+ public ColorWithFallback(Color color, Color fallback) {
+ this(color.getColorSpace(), color.getColorComponents(null),
+ getAlphaFloat(color), getAlternativeColors(color), fallback);
+ }
+
+ private static float getAlphaFloat(Color color) {
+ float[] comps = color.getComponents(null);
+ return comps[comps.length - 1]; //Alpha is on last component
+ }
+
+ private static Color[] getAlternativeColors(Color color) {
+ if (color instanceof ColorWithAlternatives) {
+ ColorWithAlternatives cwa = (ColorWithAlternatives)color;
+ if (cwa.hasAlternativeColors()) {
+ return cwa.getAlternativeColors();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the fallback color.
+ * @return the fallback color
+ */
+ public Color getFallbackColor() {
+ return this.fallback;
+ }
+
+}