Adjusted to changes of design in color branch. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_Color@961379 13f79535-47bb-0310-9956-ffa450edef68pull/20/head
import org.apache.xmlgraphics.image.loader.ImageContext; | import org.apache.xmlgraphics.image.loader.ImageContext; | ||||
import org.apache.xmlgraphics.image.loader.ImageManager; | import org.apache.xmlgraphics.image.loader.ImageManager; | ||||
import org.apache.xmlgraphics.java2d.color.ICCColorSpaceExt; | |||||
import org.apache.fop.fo.ElementMapping; | import org.apache.fop.fo.ElementMapping; | ||||
import org.apache.fop.fo.ElementMappingRegistry; | import org.apache.fop.fo.ElementMappingRegistry; | ||||
/** | /** | ||||
* Create (if needed) and return an ICC ColorSpace instance. | * Create (if needed) and return an ICC ColorSpace instance. | ||||
* | |||||
* <p> | |||||
* The ICC profile source is taken from the src attribute of the color-profile FO element. | * The ICC profile source is taken from the src attribute of the color-profile FO element. | ||||
* If the ICC ColorSpace is not yet in the cache a new one is created and stored in the cache. | * If the ICC ColorSpace is not yet in the cache a new one is created and stored in the cache. | ||||
* | |||||
* <p> | |||||
* The FOP URI resolver is used to try and locate the ICC file. | * The FOP URI resolver is used to try and locate the ICC file. | ||||
* If that fails null is returned. | * If that fails null is returned. | ||||
* | |||||
* <p> | |||||
* Note: this method should not be considered as part of FOP's external API. | |||||
* @param profileName the profile name | |||||
* @param baseUri a base URI to resolve relative URIs | * @param baseUri a base URI to resolve relative URIs | ||||
* @param iccProfileSrc ICC Profile source to return a ColorSpace for | * @param iccProfileSrc ICC Profile source to return a ColorSpace for | ||||
* @param renderingIntent overriding rendering intent (see {@link ICCColorSpaceExt}.*) | |||||
* @return ICC ColorSpace object or null if ColorSpace could not be created | * @return ICC ColorSpace object or null if ColorSpace could not be created | ||||
*/ | */ | ||||
public ColorSpace getColorSpace(String baseUri, String iccProfileSrc) { | |||||
return colorSpaceCache.get(baseUri, iccProfileSrc); | |||||
public ColorSpace getColorSpace(String profileName, String baseUri, String iccProfileSrc, | |||||
int renderingIntent) { | |||||
return colorSpaceCache.get(profileName, baseUri, iccProfileSrc, renderingIntent); | |||||
} | } | ||||
} | } |
import java.awt.Color; | import java.awt.Color; | ||||
import java.awt.color.ColorSpace; | import java.awt.color.ColorSpace; | ||||
import java.awt.color.ICC_ColorSpace; | |||||
import java.io.IOException; | |||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.List; | import java.util.List; | ||||
import org.apache.xmlgraphics.java2d.color.ColorExt; | |||||
import org.apache.xmlgraphics.java2d.color.ColorWithAlternatives; | |||||
import org.apache.xmlgraphics.java2d.color.DeviceCMYKColorSpace; | import org.apache.xmlgraphics.java2d.color.DeviceCMYKColorSpace; | ||||
/** | /** | ||||
// class hierarchy. However, at this early stages of my FOP understanding, I can | // class hierarchy. However, at this early stages of my FOP understanding, I can | ||||
// not really oversee the consequences of such a switch (nor whether it would be | // not really oversee the consequences of such a switch (nor whether it would be | ||||
// appropriate). | // appropriate). | ||||
private ColorExt colorExt = null; | |||||
private ColorWithAlternatives colorExt = null; | |||||
/** | /** | ||||
* Create a PDF color with double values ranging from 0 to 1 | * Create a PDF color with double values ranging from 0 to 1 | ||||
// 2) In case the same color profile is used with different names it will be | // 2) In case the same color profile is used with different names it will be | ||||
// included multiple times in the PDF | // included multiple times in the PDF | ||||
// | // | ||||
/* | |||||
if (colorExt != null | if (colorExt != null | ||||
&& pdfDoc.getResources().getColorSpace(colorExt.getIccProfileName()) == null) { | && pdfDoc.getResources().getColorSpace(colorExt.getIccProfileName()) == null) { | ||||
PDFICCStream pdfIccStream = new PDFICCStream(); | PDFICCStream pdfIccStream = new PDFICCStream(); | ||||
log.info("Adding PDFICCStream " + colorExt.getIccProfileName() | log.info("Adding PDFICCStream " + colorExt.getIccProfileName() | ||||
+ " for " + colorExt.getIccProfileSrc()); | + " for " + colorExt.getIccProfileSrc()); | ||||
} | } | ||||
} | |||||
}*/ | |||||
} | } | ||||
/** | /** | ||||
*/ | */ | ||||
public PDFColor(java.awt.Color col) { | public PDFColor(java.awt.Color col) { | ||||
ColorSpace cs = col.getColorSpace(); | ColorSpace cs = col.getColorSpace(); | ||||
ColorExt ce = null; | |||||
if (col instanceof ColorExt) { | |||||
ce = (ColorExt)col; | |||||
cs = ce.getOrigColorSpace(); | |||||
ColorWithAlternatives ce = null; | |||||
if (col instanceof ColorWithAlternatives) { | |||||
ce = (ColorWithAlternatives)col; | |||||
//cs = ce.getOrigColorSpace(); | |||||
} | } | ||||
if (cs != null && cs instanceof DeviceCMYKColorSpace) { | if (cs != null && cs instanceof DeviceCMYKColorSpace) { | ||||
// CMYK case | // CMYK case | ||||
this.colorSpace = new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_CMYK); | this.colorSpace = new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_CMYK); | ||||
float[] cmyk = (ce == null | float[] cmyk = (ce == null | ||||
? col.getColorComponents(null) | ? col.getColorComponents(null) | ||||
: ce.getOriginalColorComponents()); | |||||
: col.getColorComponents(null)/*ce.getOriginalColorComponents()*/); | |||||
this.cyan = cmyk[0]; | this.cyan = cmyk[0]; | ||||
this.magenta = cmyk[1]; | this.magenta = cmyk[1]; | ||||
this.yellow = cmyk[2]; | this.yellow = cmyk[2]; | ||||
public String getColorSpaceOut(boolean fillNotStroke) { | public String getColorSpaceOut(boolean fillNotStroke) { | ||||
StringBuffer p = new StringBuffer(""); | StringBuffer p = new StringBuffer(""); | ||||
if (this.colorExt != null) { | |||||
if (false && this.colorExt != null) { | |||||
/* | |||||
if (fillNotStroke) { | if (fillNotStroke) { | ||||
p.append("/" + this.colorExt.getIccProfileName() + " cs "); | p.append("/" + this.colorExt.getIccProfileName() + " cs "); | ||||
} else { | } else { | ||||
} else { | } else { | ||||
p.append("SC\n"); | p.append("SC\n"); | ||||
} | } | ||||
*/ | |||||
} else if (this.colorSpace.getColorSpace() | } else if (this.colorSpace.getColorSpace() | ||||
== PDFDeviceColorSpace.DEVICE_RGB) { // colorspace is RGB | == PDFDeviceColorSpace.DEVICE_RGB) { // colorspace is RGB | ||||
// according to pdfspec 12.1 p.399 | // according to pdfspec 12.1 p.399 |
import org.apache.commons.logging.LogFactory; | import org.apache.commons.logging.LogFactory; | ||||
import org.apache.xmlgraphics.java2d.color.CIELabColorSpace; | import org.apache.xmlgraphics.java2d.color.CIELabColorSpace; | ||||
import org.apache.xmlgraphics.java2d.color.ColorExt; | |||||
import org.apache.xmlgraphics.java2d.color.ColorWithAlternatives; | |||||
import org.apache.xmlgraphics.java2d.color.ColorUtil; | import org.apache.xmlgraphics.java2d.color.ColorUtil; | ||||
import org.apache.xmlgraphics.java2d.color.DeviceCMYKColorSpace; | import org.apache.xmlgraphics.java2d.color.DeviceCMYKColorSpace; | ||||
import org.apache.xmlgraphics.java2d.color.NamedColorSpace; | import org.apache.xmlgraphics.java2d.color.NamedColorSpace; | ||||
* @param fill true for fill color, false for stroke color | * @param fill true for fill color, false for stroke color | ||||
*/ | */ | ||||
public void establishColor(StringBuffer codeBuffer, Color color, boolean fill) { | public void establishColor(StringBuffer codeBuffer, Color color, boolean fill) { | ||||
if (color instanceof ColorExt) { | |||||
ColorExt colExt = (ColorExt)color; | |||||
if (color instanceof ColorWithAlternatives) { | |||||
ColorWithAlternatives colExt = (ColorWithAlternatives)color; | |||||
//Alternate colors have priority | //Alternate colors have priority | ||||
Color[] alt = colExt.getAlternateColors(); | |||||
Color[] alt = colExt.getAlternativeColors(); | |||||
for (int i = 0, c = alt.length; i < c; i++) { | for (int i = 0, c = alt.length; i < c; i++) { | ||||
Color col = alt[i]; | Color col = alt[i]; | ||||
boolean established = establishColorFromColor(codeBuffer, col, fill); | boolean established = establishColorFromColor(codeBuffer, col, fill); |
package org.apache.fop.util; | package org.apache.fop.util; | ||||
import java.awt.color.ColorSpace; | import java.awt.color.ColorSpace; | ||||
import java.awt.color.ICC_ColorSpace; | |||||
import java.awt.color.ICC_Profile; | import java.awt.color.ICC_Profile; | ||||
import java.util.Collections; | import java.util.Collections; | ||||
import java.util.Map; | import java.util.Map; | ||||
import org.apache.commons.logging.Log; | import org.apache.commons.logging.Log; | ||||
import org.apache.commons.logging.LogFactory; | import org.apache.commons.logging.LogFactory; | ||||
import org.apache.xmlgraphics.java2d.color.ICCColorSpaceExt; | |||||
/** | /** | ||||
* Map with cached ICC based ColorSpace objects. | * Map with cached ICC based ColorSpace objects. | ||||
*/ | */ | ||||
* The FOP URI resolver is used to try and locate the ICC file. | * The FOP URI resolver is used to try and locate the ICC file. | ||||
* If that fails null is returned. | * If that fails null is returned. | ||||
* | * | ||||
* @param profileName the profile name | |||||
* @param base a base URI to resolve relative URIs | * @param base a base URI to resolve relative URIs | ||||
* @param iccProfileSrc ICC Profile source to return a ColorSpace for | * @param iccProfileSrc ICC Profile source to return a ColorSpace for | ||||
* @param renderingIntent overriding rendering intent (see {@link ICCColorSpaceExt}.*) | |||||
* @return ICC ColorSpace object or null if ColorSpace could not be created | * @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, | |||||
int renderingIntent) { | |||||
String key = profileName + ":" + base + iccProfileSrc; | |||||
ColorSpace colorSpace = null; | ColorSpace colorSpace = null; | ||||
if (!colorSpaceMap.containsKey(base + iccProfileSrc)) { | |||||
if (!colorSpaceMap.containsKey(key)) { | |||||
try { | try { | ||||
ICC_Profile iccProfile = null; | ICC_Profile iccProfile = null; | ||||
// First attempt to use the FOP URI resolver to locate the ICC | // First attempt to use the FOP URI resolver to locate the ICC | ||||
// iccProfile = ICC_Profile.getInstance(iccProfileSrc); | // iccProfile = ICC_Profile.getInstance(iccProfileSrc); | ||||
} | } | ||||
if (iccProfile != null) { | if (iccProfile != null) { | ||||
colorSpace = new ICC_ColorSpace(iccProfile); | |||||
colorSpace = new ICCColorSpaceExt(iccProfile, renderingIntent, | |||||
profileName, iccProfileSrc); | |||||
} | } | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
// Ignore exception - will be logged a bit further down | // Ignore exception - will be logged a bit further down | ||||
if (colorSpace != null) { | if (colorSpace != null) { | ||||
// Put in cache (not when VM resolved it as we can't control | // Put in cache (not when VM resolved it as we can't control | ||||
colorSpaceMap.put(base + iccProfileSrc, colorSpace); | |||||
colorSpaceMap.put(key, colorSpace); | |||||
} else { | } else { | ||||
// TODO To avoid an excessive amount of warnings perhaps | // TODO To avoid an excessive amount of warnings perhaps | ||||
// register a null ColorMap in the colorSpaceMap | // register a null ColorMap in the colorSpaceMap | ||||
log.warn("Color profile '" + iccProfileSrc + "' not found."); | log.warn("Color profile '" + iccProfileSrc + "' not found."); | ||||
} | } | ||||
} else { | } else { | ||||
colorSpace = (ColorSpace)colorSpaceMap.get(base | |||||
+ iccProfileSrc); | |||||
colorSpace = (ColorSpace)colorSpaceMap.get(key); | |||||
} | } | ||||
return colorSpace; | return colorSpace; | ||||
} | } |
import org.apache.commons.logging.LogFactory; | import org.apache.commons.logging.LogFactory; | ||||
import org.apache.xmlgraphics.java2d.color.CIELabColorSpace; | import org.apache.xmlgraphics.java2d.color.CIELabColorSpace; | ||||
import org.apache.xmlgraphics.java2d.color.ColorExt; | |||||
import org.apache.xmlgraphics.java2d.color.ColorSpaceOrigin; | |||||
import org.apache.xmlgraphics.java2d.color.ColorSpaces; | 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.DeviceCMYKColorSpace; | ||||
import org.apache.xmlgraphics.java2d.color.ICCColor; | |||||
import org.apache.xmlgraphics.java2d.color.ICCColorSpaceExt; | |||||
import org.apache.xmlgraphics.java2d.color.NamedColorSpace; | import org.apache.xmlgraphics.java2d.color.NamedColorSpace; | ||||
import org.apache.xmlgraphics.java2d.color.profile.NamedColorProfile; | import org.apache.xmlgraphics.java2d.color.profile.NamedColorProfile; | ||||
import org.apache.xmlgraphics.java2d.color.profile.NamedColorProfileParser; | import org.apache.xmlgraphics.java2d.color.profile.NamedColorProfileParser; | ||||
*/ | */ | ||||
public final class ColorUtil { | public final class ColorUtil { | ||||
//Implementation note: this class should ALWAYS create ColorExt instances instead of using | |||||
//java.awt.Color since the latter has an equals() method that can't detect two different | |||||
//colors using the same sRGB fallback. | |||||
//Implementation note: this class should ALWAYS create ColorWithAlternatives instances instead | |||||
//of using java.awt.Color since the latter has an equals() method that can't detect two | |||||
//different colors using the same sRGB fallback. | |||||
//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 */ | /** The name for the uncalibrated CMYK pseudo-profile */ | ||||
public static final String CMYK_PSEUDO_PROFILE = "#CMYK"; | public static final String CMYK_PSEUDO_PROFILE = "#CMYK"; | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
throw new PropertyException(e); | throw new PropertyException(e); | ||||
} | } | ||||
return new ColorExt(red, green, blue, null); | |||||
return new ColorWithAlternatives(red, green, blue, null); | |||||
} | } | ||||
/** | /** | ||||
float red = parseComponent255(args[0], value); | float red = parseComponent255(args[0], value); | ||||
float green = parseComponent255(args[1], value); | float green = parseComponent255(args[1], value); | ||||
float blue = parseComponent255(args[2], value); | float blue = parseComponent255(args[2], value); | ||||
parsedColor = new ColorExt(red, green, blue, null); | |||||
parsedColor = new ColorWithAlternatives(red, green, blue, null); | |||||
} catch (PropertyException pe) { | } catch (PropertyException pe) { | ||||
//simply re-throw | //simply re-throw | ||||
throw pe; | throw pe; | ||||
return component; | 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 ColorWithAlternatives(red, green, blue, null); | |||||
/* | |||||
Color sRGB = new ColorWithAlternatives(ColorSpace.getInstance(ColorSpace.CS_sRGB), | |||||
new float[] {red, green, blue}, 1.0f, null); | |||||
*/ | |||||
return sRGB; | |||||
} | |||||
/** | /** | ||||
* parse a color given in the #.... format. | * parse a color given in the #.... format. | ||||
* | * | ||||
} else { | } else { | ||||
throw new NumberFormatException(); | throw new NumberFormatException(); | ||||
} | } | ||||
parsedColor = new ColorExt(red, green, blue, alpha, null); | |||||
parsedColor = new ColorWithAlternatives(red, green, blue, alpha, null); | |||||
} catch (Exception e) { | } catch (Exception e) { | ||||
throw new PropertyException("Unknown color format: " + value | throw new PropertyException("Unknown color format: " + value | ||||
+ ". Must be #RGB. #RGBA, #RRGGBB, or #RRGGBBAA"); | + ". Must be #RGB. #RGBA, #RRGGBB, or #RRGGBBAA"); | ||||
} | } | ||||
//Set up fallback sRGB value | //Set up fallback sRGB value | ||||
float red = parseComponent1(args[0], value); | |||||
float green = parseComponent1(args[1], value); | |||||
float blue = parseComponent1(args[2], value); | |||||
Color sRGB = new ColorExt(red, green, blue, null); | |||||
Color sRGB = parseFallback(args, value); | |||||
/* Get and verify ICC profile name */ | /* Get and verify ICC profile name */ | ||||
String iccProfileName = args[3].trim(); | String iccProfileName = args[3].trim(); | ||||
if (CMYK_PSEUDO_PROFILE.equalsIgnoreCase(iccProfileName)) { | if (CMYK_PSEUDO_PROFILE.equalsIgnoreCase(iccProfileName)) { | ||||
colorSpace = ColorSpaces.getDeviceCMYKColorSpace(); | colorSpace = ColorSpaces.getDeviceCMYKColorSpace(); | ||||
} else if (SEPARATION_PSEUDO_PROFILE.equalsIgnoreCase(iccProfileName)) { | } else if (SEPARATION_PSEUDO_PROFILE.equalsIgnoreCase(iccProfileName)) { | ||||
colorSpace = new NamedColorSpace(args[5], sRGB); | |||||
colorSpace = new NamedColorSpace(args[5], sRGB, | |||||
SEPARATION_PSEUDO_PROFILE, null); | |||||
} else { | } else { | ||||
assert false : "Incomplete implementation"; | assert false : "Incomplete implementation"; | ||||
} | } | ||||
/* Ask FOP factory to get ColorSpace for the specified ICC profile source */ | /* Ask FOP factory to get ColorSpace for the specified ICC profile source */ | ||||
if (foUserAgent != null && iccProfileSrc != null) { | if (foUserAgent != null && iccProfileSrc != null) { | ||||
colorSpace = foUserAgent.getFactory().getColorSpace( | |||||
foUserAgent.getBaseURL(), iccProfileSrc); | |||||
assert colorSpace == null; | |||||
int renderingIntent = ICCColorSpaceExt.AUTO; //TODO connect to fo:color-profile | |||||
colorSpace = foUserAgent.getFactory().getColorSpace(iccProfileName, | |||||
foUserAgent.getBaseURL(), iccProfileSrc, | |||||
renderingIntent); | |||||
} | } | ||||
if (colorSpace != null) { | if (colorSpace != null) { | ||||
// ColorSpace available - create ColorExt (keeps track of replacement rgb | |||||
// values for possible later colorTOsRGBString call | |||||
ICCColor iccColor = new ICCColor(colorSpace, iccProfileName, iccProfileSrc, | |||||
iccComponents, 1.0f); | |||||
parsedColor = new ColorExt(red, green, blue, new Color[] {iccColor}); | |||||
// 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 ColorWithAlternatives( | |||||
colorSpace, iccComponents, 1.0f, null); | |||||
float[] rgbComps = sRGB.getColorComponents(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 { | } else { | ||||
// ICC profile could not be loaded - use rgb replacement values */ | // ICC profile could not be loaded - use rgb replacement values */ | ||||
log.warn("Color profile '" + iccProfileSrc | log.warn("Color profile '" + iccProfileSrc | ||||
} | } | ||||
//Set up fallback sRGB value | //Set up fallback sRGB value | ||||
float red = parseComponent1(args[0], value); | |||||
float green = parseComponent1(args[1], value); | |||||
float blue = parseComponent1(args[2], value); | |||||
Color sRGB = new ColorExt(red, green, blue, null); | |||||
Color sRGB = parseFallback(args, value); | |||||
/* Get and verify ICC profile name */ | /* Get and verify ICC profile name */ | ||||
String iccProfileName = args[3].trim(); | String iccProfileName = args[3].trim(); | ||||
/* Ask FOP factory to get ColorSpace for the specified ICC profile source */ | /* Ask FOP factory to get ColorSpace for the specified ICC profile source */ | ||||
if (foUserAgent != null && iccProfileSrc != null) { | if (foUserAgent != null && iccProfileSrc != null) { | ||||
int renderingIntent = ICCColorSpaceExt.AUTO; //TODO connect to fo:color-profile | |||||
colorSpace = (ICC_ColorSpace)foUserAgent.getFactory().getColorSpace( | colorSpace = (ICC_ColorSpace)foUserAgent.getFactory().getColorSpace( | ||||
foUserAgent.getBaseURL(), iccProfileSrc); | |||||
iccProfileName, | |||||
foUserAgent.getBaseURL(), iccProfileSrc, | |||||
renderingIntent); | |||||
} | } | ||||
if (colorSpace != null) { | if (colorSpace != null) { | ||||
ICC_Profile profile = colorSpace.getProfile(); | ICC_Profile profile = colorSpace.getProfile(); | ||||
if (NamedColorProfileParser.isNamedColorProfile(profile)) { | if (NamedColorProfileParser.isNamedColorProfile(profile)) { | ||||
NamedColorProfileParser parser = new NamedColorProfileParser(); | NamedColorProfileParser parser = new NamedColorProfileParser(); | ||||
NamedColorProfile ncp = parser.parseProfile(profile); | |||||
NamedColorProfile ncp = parser.parseProfile(profile, | |||||
iccProfileName, iccProfileSrc); | |||||
NamedColorSpace ncs = ncp.getNamedColor(colorName); | NamedColorSpace ncs = ncp.getNamedColor(colorName); | ||||
if (ncs != null) { | 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}); | |||||
Color specColor = new ColorWithFallback(ncs, | |||||
new float[] {1.0f}, 1.0f, null, sRGB); | |||||
parsedColor = specColor; | |||||
} else { | } else { | ||||
log.warn("Color '" + colorName | log.warn("Color '" + colorName | ||||
+ "' does not exist in named color profile: " + iccProfileSrc); | + "' does not exist in named color profile: " + iccProfileSrc); | ||||
float red = parseComponent255(args[0], value); | float red = parseComponent255(args[0], value); | ||||
float green = parseComponent255(args[1], value); | float green = parseComponent255(args[1], value); | ||||
float blue = parseComponent255(args[2], value); | float blue = parseComponent255(args[2], value); | ||||
Color sRGB = new ColorWithAlternatives(red, green, blue, null); | |||||
float l = parseComponent(args[3], 0f, 100f, value); | float l = parseComponent(args[3], 0f, 100f, value); | ||||
float a = parseComponent(args[4], -127f, 127f, value); | float a = parseComponent(args[4], -127f, 127f, value); | ||||
CIELabColorSpace cs = ColorSpaces.getCIELabColorSpaceD50(); | CIELabColorSpace cs = ColorSpaces.getCIELabColorSpaceD50(); | ||||
//use toColor() to have components normalized | //use toColor() to have components normalized | ||||
Color labColor = cs.toColor(l, a, b, 1.0f); | Color labColor = cs.toColor(l, a, b, 1.0f); | ||||
parsedColor = new ColorExt(red, green, blue, new Color[] {labColor}); | |||||
//Convert to ColorWithFallback | |||||
parsedColor = new ColorWithFallback(labColor, sRGB); | |||||
} catch (PropertyException pe) { | } catch (PropertyException pe) { | ||||
//simply re-throw | //simply re-throw | ||||
float yellow = parseComponent1(args[2], value); | float yellow = parseComponent1(args[2], value); | ||||
float black = parseComponent1(args[3], value); | float black = parseComponent1(args[3], value); | ||||
float[] comps = new float[] {cyan, magenta, yellow, black}; | float[] comps = new float[] {cyan, magenta, yellow, black}; | ||||
parsedColor = DeviceCMYKColorSpace.createColorExt(comps); | |||||
Color cmykColor = DeviceCMYKColorSpace.createCMYKColor(comps); | |||||
parsedColor = new ColorWithAlternatives(cmykColor.getRGB(), | |||||
new Color[] {cmykColor}); | |||||
} catch (PropertyException pe) { | } catch (PropertyException pe) { | ||||
throw pe; | throw pe; | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
*/ | */ | ||||
public static String colorToString(Color color) { | public static String colorToString(Color color) { | ||||
ColorSpace cs = color.getColorSpace(); | ColorSpace cs = color.getColorSpace(); | ||||
if (color instanceof ColorExt) { | |||||
return toFunctionCall((ColorExt)color); | |||||
if (color instanceof ColorWithAlternatives) { | |||||
return toFunctionCall((ColorWithAlternatives)color); | |||||
} else if (cs != null && cs.getType() == ColorSpace.TYPE_CMYK) { | } else if (cs != null && cs.getType() == ColorSpace.TYPE_CMYK) { | ||||
StringBuffer sbuf = new StringBuffer(24); | StringBuffer sbuf = new StringBuffer(24); | ||||
float[] cmyk = color.getColorComponents(null); | float[] cmyk = color.getColorComponents(null); | ||||
return sbuf.toString(); | 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); | |||||
} | |||||
} else { | |||||
fallbackColor = toSRGBColor(color); | |||||
} | |||||
return fallbackColor; | |||||
} | |||||
private static Color toSRGBColor(Color color) { | |||||
float[] comps; | |||||
ColorSpace sRGB = ColorSpace.getInstance(ColorSpace.CS_sRGB); | |||||
if (color.getColorSpace().isCS_sRGB()) { | |||||
comps = color.getColorComponents(null); | |||||
} else { | |||||
comps = color.getColorComponents(sRGB, null); | |||||
} | |||||
float[] allComps = color.getComponents(null); | |||||
float alpha = allComps[comps.length - 1]; //Alpha is on last component | |||||
return new Color(sRGB, comps, alpha); | |||||
} | |||||
/** | /** | ||||
* Create string representation of fop-rgb-icc function call to map this | * Create string representation of fop-rgb-icc function call to map this | ||||
* ColorExt settings. | * ColorExt settings. | ||||
* @param color the color to turn into a function call | * @param color the color to turn into a function call | ||||
* @return the string representing the internal fop-rgb-icc() function call | * @return the string representing the internal fop-rgb-icc() function call | ||||
*/ | */ | ||||
public static String toFunctionCall(ColorExt color) { | |||||
Color[] alt = color.getAlternateColors(); | |||||
ICCColor icc = null; | |||||
for (int i = 0, c = alt.length; i < c; i++) { | |||||
if (alt[i] instanceof ICCColor) { | |||||
//Find first ICCColor in alternatives | |||||
icc = (ICCColor)alt[i]; | |||||
break; | |||||
} | |||||
public static String toFunctionCall(ColorWithAlternatives color) { | |||||
ColorSpace cs = color.getColorSpace(); | |||||
Color fallbackColor = getsRGBFallback(color); | |||||
if (cs instanceof CIELabColorSpace) { | |||||
return toCIELabFunctionCall(color); | |||||
} | } | ||||
if (icc == null) { | |||||
if (cs.isCS_sRGB() && !color.hasAlternativeColors()) { | |||||
return toRGBFunctionCall(color); | return toRGBFunctionCall(color); | ||||
} | } | ||||
if (icc.getColorSpace() instanceof CIELabColorSpace) { | |||||
return toCIELabFunctionCall(color, icc); | |||||
} | |||||
StringBuffer sb = new StringBuffer(40); | StringBuffer sb = new StringBuffer(40); | ||||
Color specColor = color; | |||||
if (color.hasAlternativeColors()) { | |||||
Color alt = color.getAlternativeColors()[0]; | |||||
if (ColorSpaces.isDeviceColorSpace(alt.getColorSpace())) { | |||||
cs = alt.getColorSpace(); | |||||
specColor = alt; | |||||
} | |||||
} | |||||
ColorSpaceOrigin origin = ColorSpaces.getColorSpaceOrigin(cs); | |||||
String functionName; | String functionName; | ||||
float[] rgb = color.getColorComponents(null); | |||||
float[] rgb = fallbackColor.getColorComponents(null); | |||||
assert rgb.length == 3; | assert rgb.length == 3; | ||||
sb.append("("); | sb.append("("); | ||||
sb.append(rgb[0]).append(","); | sb.append(rgb[0]).append(","); | ||||
sb.append(rgb[1]).append(","); | sb.append(rgb[1]).append(","); | ||||
sb.append(rgb[2]).append(","); | sb.append(rgb[2]).append(","); | ||||
String profileName = icc.getColorProfileName(); | |||||
String profileName = origin.getProfileName(); | |||||
sb.append(profileName).append(","); | sb.append(profileName).append(","); | ||||
if (icc.getColorProfileSource() != null) { | |||||
sb.append("\"").append(icc.getColorProfileSource()).append("\""); | |||||
if (origin.getProfileURI() != null) { | |||||
sb.append("\"").append(origin.getProfileURI()).append("\""); | |||||
} | } | ||||
if (icc.getColorSpace() instanceof NamedColorSpace) { | |||||
NamedColorSpace ncs = (NamedColorSpace)icc.getColorSpace(); | |||||
if (cs instanceof NamedColorSpace) { | |||||
NamedColorSpace ncs = (NamedColorSpace)cs; | |||||
if (SEPARATION_PSEUDO_PROFILE.equalsIgnoreCase(profileName)) { | if (SEPARATION_PSEUDO_PROFILE.equalsIgnoreCase(profileName)) { | ||||
functionName = "fop-rgb-icc"; | functionName = "fop-rgb-icc"; | ||||
} else { | } else { | ||||
sb.append(",").append(ncs.getColorName()); | sb.append(",").append(ncs.getColorName()); | ||||
} else { | } else { | ||||
functionName = "fop-rgb-icc"; | functionName = "fop-rgb-icc"; | ||||
float[] colorComponents = icc.getColorComponents(null); | |||||
float[] colorComponents = specColor.getColorComponents(null); | |||||
for (int ix = 0; ix < colorComponents.length; ix++) { | for (int ix = 0; ix < colorComponents.length; ix++) { | ||||
sb.append(","); | sb.append(","); | ||||
sb.append(colorComponents[ix]); | sb.append(colorComponents[ix]); | ||||
return functionName + sb.toString(); | return functionName + sb.toString(); | ||||
} | } | ||||
private static String toCIELabFunctionCall(ColorExt color, Color cieLab) { | |||||
private static String toCIELabFunctionCall(ColorWithAlternatives color) { | |||||
Color fallbackColor = getsRGBFallback(color); | |||||
StringBuffer sb = new StringBuffer("cie-lab-color("); | StringBuffer sb = new StringBuffer("cie-lab-color("); | ||||
sb.append(color.getRed()).append(','); | |||||
sb.append(color.getGreen()).append(','); | |||||
sb.append(color.getBlue()); | |||||
CIELabColorSpace cs = (CIELabColorSpace)cieLab.getColorSpace(); | |||||
float[] lab = cs.toNativeComponents(cieLab.getColorComponents(null)); | |||||
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++) { | for (int i = 0; i < 3; i++) { | ||||
sb.append(',').append(lab[i]); | sb.append(',').append(lab[i]); | ||||
} | } | ||||
} | } | ||||
private static Color createColor(int r, int g, int b) { | private static Color createColor(int r, int g, int b) { | ||||
return new ColorExt(r, g, b, null); | |||||
return new ColorWithAlternatives(r, g, b, null); | |||||
} | } | ||||
/** | /** | ||||
colorMap.put("whitesmoke", createColor(245, 245, 245)); | colorMap.put("whitesmoke", createColor(245, 245, 245)); | ||||
colorMap.put("yellow", createColor(255, 255, 0)); | colorMap.put("yellow", createColor(255, 255, 0)); | ||||
colorMap.put("yellowgreen", createColor(154, 205, 50)); | colorMap.put("yellowgreen", createColor(154, 205, 50)); | ||||
colorMap.put("transparent", new ColorExt(0, 0, 0, 0, null)); | |||||
colorMap.put("transparent", new ColorWithAlternatives(0, 0, 0, 0, null)); | |||||
} | } | ||||
/** | /** | ||||
} | } | ||||
/** | /** | ||||
* Creates an uncalibrary CMYK color with the given gray value. | |||||
* Creates an uncalibrated CMYK color with the given gray value. | |||||
* @param black the gray component (0 - 1) | * @param black the gray component (0 - 1) | ||||
* @return the CMYK color | * @return the CMYK 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 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; | |||||
} | |||||
} |
assertEquals(b1, b2); | assertEquals(b1, b2); | ||||
float[] cmyk = new float[] {1.0f, 1.0f, 0.5f, 1.0f}; | float[] cmyk = new float[] {1.0f, 1.0f, 0.5f, 1.0f}; | ||||
col = DeviceCMYKColorSpace.createColorExt(cmyk); | |||||
col = DeviceCMYKColorSpace.createCMYKColor(cmyk); | |||||
b1 = new BorderProps(Constants.EN_INSET, 9999, | b1 = new BorderProps(Constants.EN_INSET, 9999, | ||||
col, BorderProps.SEPARATE); | col, BorderProps.SEPARATE); | ||||
ser = b1.toString(); | ser = b1.toString(); |
import junit.framework.TestCase; | import junit.framework.TestCase; | ||||
import org.apache.xmlgraphics.java2d.color.ColorExt; | |||||
import org.apache.xmlgraphics.java2d.color.ColorSpaces; | import org.apache.xmlgraphics.java2d.color.ColorSpaces; | ||||
import org.apache.xmlgraphics.java2d.color.ColorWithAlternatives; | |||||
import org.apache.xmlgraphics.java2d.color.ICCColorSpaceExt; | |||||
import org.apache.xmlgraphics.java2d.color.NamedColorSpace; | import org.apache.xmlgraphics.java2d.color.NamedColorSpace; | ||||
import org.apache.fop.apps.FOUserAgent; | import org.apache.fop.apps.FOUserAgent; | ||||
assertEquals(col1, col2); | assertEquals(col1, col2); | ||||
col1 = ColorUtil.parseColorString(null, "fop-rgb-icc(0.5,0.5,0.5,#CMYK,,0.0,0.0,0.0,0.5)"); | col1 = ColorUtil.parseColorString(null, "fop-rgb-icc(0.5,0.5,0.5,#CMYK,,0.0,0.0,0.0,0.5)"); | ||||
/* The following doesn't work since java.awt.Color from Sun doesn't round consistently | |||||
col2 = ColorUtil.parseColorString(null, "cmyk(0.0,0.0,0.0,0.5)"); | col2 = ColorUtil.parseColorString(null, "cmyk(0.0,0.0,0.0,0.5)"); | ||||
assertEquals(col1, col2); | assertEquals(col1, col2); | ||||
*/ | |||||
col2 = ColorUtil.parseColorString(null, "fop-rgb-icc(0.5,0.5,0.5,#CMYK,,0.5,0.5,0.5,0.0)"); | col2 = ColorUtil.parseColorString(null, "fop-rgb-icc(0.5,0.5,0.5,#CMYK,,0.5,0.5,0.5,0.0)"); | ||||
assertFalse(col1.equals(col2)); | assertFalse(col1.equals(col2)); | ||||
FopFactory fopFactory = FopFactory.newInstance(); | FopFactory fopFactory = FopFactory.newInstance(); | ||||
URI sRGBLoc = new URI( | URI sRGBLoc = new URI( | ||||
"file:src/java/org/apache/fop/pdf/sRGB%20Color%20Space%20Profile.icm"); | "file:src/java/org/apache/fop/pdf/sRGB%20Color%20Space%20Profile.icm"); | ||||
ColorSpace cs = fopFactory.getColorSpace(null, sRGBLoc.toASCIIString()); | |||||
assertNotNull(cs); | |||||
ColorSpace cs = fopFactory.getColorSpace("sRGBAlt", null, sRGBLoc.toASCIIString(), | |||||
ICCColorSpaceExt.AUTO); | |||||
assertNotNull("Color profile not found", cs); | |||||
FOUserAgent ua = fopFactory.newFOUserAgent(); | FOUserAgent ua = fopFactory.newFOUserAgent(); | ||||
ColorExt colActual; | |||||
ColorWithFallback colActual; | |||||
//fop-rgb-icc() is used instead of rgb-icc() inside FOP! | //fop-rgb-icc() is used instead of rgb-icc() inside FOP! | ||||
String colSpec = "fop-rgb-icc(1.0,0.0,0.0,sRGBAlt," | String colSpec = "fop-rgb-icc(1.0,0.0,0.0,sRGBAlt," | ||||
+ "\"" + sRGBLoc.toASCIIString() + "\",1.0,0.0,0.0)"; | + "\"" + sRGBLoc.toASCIIString() + "\",1.0,0.0,0.0)"; | ||||
colActual = (ColorExt)ColorUtil.parseColorString(ua, colSpec); | |||||
colActual = (ColorWithFallback)ColorUtil.parseColorString(ua, colSpec); | |||||
assertEquals(cs, colActual.getColorSpace()); | |||||
assertEquals(255, colActual.getRed()); | assertEquals(255, colActual.getRed()); | ||||
assertEquals(0, colActual.getGreen()); | assertEquals(0, colActual.getGreen()); | ||||
assertEquals(0, colActual.getBlue()); | assertEquals(0, colActual.getBlue()); | ||||
assertEquals(ColorSpace.getInstance(ColorSpace.CS_sRGB), colActual.getColorSpace()); | |||||
float[] comps = colActual.getColorComponents(null); | float[] comps = colActual.getColorComponents(null); | ||||
assertEquals(3, comps.length); | assertEquals(3, comps.length); | ||||
assertEquals(1f, comps[0], 0); | assertEquals(1f, comps[0], 0); | ||||
assertEquals(0f, comps[1], 0); | assertEquals(0f, comps[1], 0); | ||||
assertEquals(0f, comps[2], 0); | assertEquals(0f, comps[2], 0); | ||||
assertEquals(0, colActual.getAlternativeColors().length); | |||||
Color alt = colActual.getAlternateColors()[0]; | |||||
assertEquals(cs, alt.getColorSpace()); | |||||
comps = colActual.getColorComponents(null); | |||||
assertEquals(3, comps.length); | |||||
assertEquals(1f, comps[0], 0); | |||||
assertEquals(0f, comps[1], 0); | |||||
assertEquals(0f, comps[2], 0); | |||||
Color fallback = colActual.getFallbackColor(); | |||||
assertTrue(fallback.getColorSpace().isCS_sRGB()); | |||||
assertEquals(255, colActual.getRed()); | |||||
assertEquals(0, colActual.getGreen()); | |||||
assertEquals(0, colActual.getBlue()); | |||||
assertEquals(colSpec, ColorUtil.colorToString(colActual)); | assertEquals(colSpec, ColorUtil.colorToString(colActual)); | ||||
* @throws Exception if an error occurs | * @throws Exception if an error occurs | ||||
*/ | */ | ||||
public void testCMYK() throws Exception { | public void testCMYK() throws Exception { | ||||
ColorExt colActual; | |||||
ColorWithAlternatives colActual; | |||||
String colSpec; | String colSpec; | ||||
colSpec = "cmyk(0.0, 0.0, 1.0, 0.0)"; | colSpec = "cmyk(0.0, 0.0, 1.0, 0.0)"; | ||||
colActual = (ColorExt)ColorUtil.parseColorString(null, colSpec); | |||||
colActual = (ColorWithAlternatives)ColorUtil.parseColorString(null, colSpec); | |||||
assertEquals(255, colActual.getRed()); | assertEquals(255, colActual.getRed()); | ||||
assertEquals(255, colActual.getGreen()); | assertEquals(255, colActual.getGreen()); | ||||
assertEquals(0, colActual.getBlue()); | assertEquals(0, colActual.getBlue()); | ||||
Color alt = colActual.getAlternateColors()[0]; | |||||
Color alt = colActual.getAlternativeColors()[0]; | |||||
assertEquals(ColorSpaces.getDeviceCMYKColorSpace(), alt.getColorSpace()); | assertEquals(ColorSpaces.getDeviceCMYKColorSpace(), alt.getColorSpace()); | ||||
float[] comps = alt.getColorComponents(null); | float[] comps = alt.getColorComponents(null); | ||||
assertEquals(4, comps.length); | assertEquals(4, comps.length); | ||||
ColorUtil.colorToString(colActual)); | ColorUtil.colorToString(colActual)); | ||||
colSpec = "cmyk(0.0274, 0.2196, 0.3216, 0.0)"; | colSpec = "cmyk(0.0274, 0.2196, 0.3216, 0.0)"; | ||||
colActual = (ColorExt)ColorUtil.parseColorString(null, colSpec); | |||||
colActual = (ColorWithAlternatives)ColorUtil.parseColorString(null, colSpec); | |||||
assertEquals(248, colActual.getRed(), 1); | assertEquals(248, colActual.getRed(), 1); | ||||
assertEquals(199, colActual.getGreen(), 1); | assertEquals(199, colActual.getGreen(), 1); | ||||
assertEquals(172, colActual.getBlue(), 1); | assertEquals(172, colActual.getBlue(), 1); | ||||
alt = colActual.getAlternateColors()[0]; | |||||
alt = colActual.getAlternativeColors()[0]; | |||||
assertEquals(ColorSpaces.getDeviceCMYKColorSpace(), alt.getColorSpace()); | assertEquals(ColorSpaces.getDeviceCMYKColorSpace(), alt.getColorSpace()); | ||||
comps = alt.getColorComponents(null); | comps = alt.getColorComponents(null); | ||||
assertEquals(0.0274f, comps[0], 0.001); | assertEquals(0.0274f, comps[0], 0.001); | ||||
assertEquals(0.2196f, comps[1], 0.001); | assertEquals(0.2196f, comps[1], 0.001); | ||||
assertEquals(0.3216f, comps[2], 0.001); | assertEquals(0.3216f, comps[2], 0.001); | ||||
assertEquals(0f, comps[3], 0); | assertEquals(0f, comps[3], 0); | ||||
assertEquals("fop-rgb-icc(0.9726,0.7804,0.67840004,#CMYK,,0.0274,0.2196,0.3216,0.0)", | |||||
assertEquals("fop-rgb-icc(0.972549,0.78039217,0.6745098,#CMYK,,0.0274,0.2196,0.3216,0.0)", | |||||
ColorUtil.colorToString(colActual)); | ColorUtil.colorToString(colActual)); | ||||
colSpec = "fop-rgb-icc(1.0,1.0,0.0,#CMYK,,0.0,0.0,1.0,0.0)"; | 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); | |||||
colActual = (ColorWithAlternatives)ColorUtil.parseColorString(null, colSpec); | |||||
assertEquals(255, colActual.getRed()); | assertEquals(255, colActual.getRed()); | ||||
assertEquals(255, colActual.getGreen()); | assertEquals(255, colActual.getGreen()); | ||||
assertEquals(0, colActual.getBlue()); | assertEquals(0, colActual.getBlue()); | ||||
alt = colActual.getAlternateColors()[0]; | |||||
alt = colActual.getAlternativeColors()[0]; | |||||
assertEquals(ColorSpaces.getDeviceCMYKColorSpace(), alt.getColorSpace()); | assertEquals(ColorSpaces.getDeviceCMYKColorSpace(), alt.getColorSpace()); | ||||
comps = alt.getColorComponents(null); | comps = alt.getColorComponents(null); | ||||
assertEquals(4, comps.length); | assertEquals(4, comps.length); | ||||
ColorUtil.colorToString(colActual)); | ColorUtil.colorToString(colActual)); | ||||
colSpec = "fop-rgb-icc(0.5,0.5,0.5,#CMYK,,0.0,0.0,0.0,0.5)"; | colSpec = "fop-rgb-icc(0.5,0.5,0.5,#CMYK,,0.0,0.0,0.0,0.5)"; | ||||
colActual = (ColorExt)ColorUtil.parseColorString(null, colSpec); | |||||
colActual = (ColorWithAlternatives)ColorUtil.parseColorString(null, colSpec); | |||||
assertEquals(127, colActual.getRed(), 1); | assertEquals(127, colActual.getRed(), 1); | ||||
assertEquals(127, colActual.getGreen(), 1); | assertEquals(127, colActual.getGreen(), 1); | ||||
assertEquals(127, colActual.getBlue(), 1); | assertEquals(127, colActual.getBlue(), 1); | ||||
alt = colActual.getAlternateColors()[0]; | |||||
alt = colActual.getAlternativeColors()[0]; | |||||
assertEquals(ColorSpaces.getDeviceCMYKColorSpace(), alt.getColorSpace()); | assertEquals(ColorSpaces.getDeviceCMYKColorSpace(), alt.getColorSpace()); | ||||
comps = alt.getColorComponents(null); | comps = alt.getColorComponents(null); | ||||
assertEquals(4, comps.length); | assertEquals(4, comps.length); | ||||
* @throws Exception if an error occurs | * @throws Exception if an error occurs | ||||
*/ | */ | ||||
public void testSeparationColor() throws Exception { | public void testSeparationColor() throws Exception { | ||||
ColorExt colActual; | |||||
ColorWithFallback colActual; | |||||
String colSpec; | String colSpec; | ||||
colSpec = "fop-rgb-icc(1.0,0.8,0.0,#Separation,,Postgelb)"; | colSpec = "fop-rgb-icc(1.0,0.8,0.0,#Separation,,Postgelb)"; | ||||
colActual = (ColorExt)ColorUtil.parseColorString(null, colSpec); | |||||
assertEquals(255, colActual.getRed()); | |||||
assertEquals(204, colActual.getGreen()); | |||||
colActual = (ColorWithFallback)ColorUtil.parseColorString(null, colSpec); | |||||
assertEquals(255, colActual.getRed(), 1); | |||||
assertEquals(204, colActual.getGreen(), 1); | |||||
assertEquals(0, colActual.getBlue()); | assertEquals(0, colActual.getBlue()); | ||||
Color alt = colActual.getAlternateColors()[0]; | |||||
assertTrue(alt.getColorSpace() instanceof NamedColorSpace); | |||||
Color fallback = colActual.getFallbackColor(); | |||||
assertEquals(255, fallback.getRed()); | |||||
assertEquals(204, fallback.getGreen()); | |||||
assertEquals(0, fallback.getBlue()); | |||||
assertFalse(colActual.hasAlternativeColors()); | |||||
assertTrue(colActual.getColorSpace() instanceof NamedColorSpace); | |||||
NamedColorSpace ncs; | NamedColorSpace ncs; | ||||
ncs = (NamedColorSpace)alt.getColorSpace(); | |||||
ncs = (NamedColorSpace)colActual.getColorSpace(); | |||||
assertEquals("Postgelb", ncs.getColorName()); | assertEquals("Postgelb", ncs.getColorName()); | ||||
float[] comps = alt.getColorComponents(null); | |||||
float[] comps = colActual.getColorComponents(null); | |||||
assertEquals(1, comps.length); | assertEquals(1, comps.length); | ||||
assertEquals(1f, comps[0], 0); | assertEquals(1f, comps[0], 0); | ||||
assertEquals(colSpec, ColorUtil.colorToString(colActual)); | assertEquals(colSpec, ColorUtil.colorToString(colActual)); | ||||
} | } | ||||
/** | /** | ||||
public void testNamedColorProfile() throws Exception { | public void testNamedColorProfile() throws Exception { | ||||
FopFactory fopFactory = FopFactory.newInstance(); | FopFactory fopFactory = FopFactory.newInstance(); | ||||
URI ncpLoc = new URI("file:test/resources/color/ncp-example.icc"); | URI ncpLoc = new URI("file:test/resources/color/ncp-example.icc"); | ||||
ColorSpace cs = fopFactory.getColorSpace(null, ncpLoc.toASCIIString()); | |||||
assertNotNull(cs); | |||||
ColorSpace cs = fopFactory.getColorSpace("NCP", null, ncpLoc.toASCIIString(), | |||||
ICCColorSpaceExt.AUTO); | |||||
assertNotNull("Color profile not found", cs); | |||||
FOUserAgent ua = fopFactory.newFOUserAgent(); | FOUserAgent ua = fopFactory.newFOUserAgent(); | ||||
ColorExt colActual; | |||||
ColorWithFallback colActual; | |||||
//fop-rgb-named-color() is used instead of rgb-named-color() inside FOP! | //fop-rgb-named-color() is used instead of rgb-named-color() inside FOP! | ||||
String colSpec = "fop-rgb-named-color(1.0,0.8,0.0,NCP," | String colSpec = "fop-rgb-named-color(1.0,0.8,0.0,NCP," | ||||
+ "\"" + ncpLoc.toASCIIString() + "\",Postgelb)"; | + "\"" + ncpLoc.toASCIIString() + "\",Postgelb)"; | ||||
colActual = (ColorExt)ColorUtil.parseColorString(ua, colSpec); | |||||
colActual = (ColorWithFallback)ColorUtil.parseColorString(ua, colSpec); | |||||
assertEquals(255, colActual.getRed()); | assertEquals(255, colActual.getRed()); | ||||
assertEquals(204, colActual.getGreen()); | |||||
assertEquals(193, colActual.getGreen()); | |||||
assertEquals(0, colActual.getBlue()); | assertEquals(0, colActual.getBlue()); | ||||
assertEquals(ColorSpace.getInstance(ColorSpace.CS_sRGB), colActual.getColorSpace()); | |||||
float[] comps = colActual.getColorComponents(null); | |||||
Color fallback = colActual.getFallbackColor(); | |||||
assertEquals(255, fallback.getRed()); | |||||
assertEquals(204, fallback.getGreen()); | |||||
assertEquals(0, fallback.getBlue()); | |||||
assertEquals(ColorSpace.getInstance(ColorSpace.CS_sRGB), fallback.getColorSpace()); | |||||
float[] comps = fallback.getColorComponents(null); | |||||
assertEquals(3, comps.length); | assertEquals(3, comps.length); | ||||
assertEquals(1f, comps[0], 0); | assertEquals(1f, comps[0], 0); | ||||
assertEquals(0.8f, comps[1], 0); | assertEquals(0.8f, comps[1], 0); | ||||
assertEquals(0f, comps[2], 0); | assertEquals(0f, comps[2], 0); | ||||
Color alt = colActual.getAlternateColors()[0]; | |||||
assertTrue(alt.getColorSpace() instanceof NamedColorSpace); | |||||
assertTrue(colActual.getColorSpace() instanceof NamedColorSpace); | |||||
NamedColorSpace ncs; | NamedColorSpace ncs; | ||||
ncs = (NamedColorSpace)alt.getColorSpace(); | |||||
ncs = (NamedColorSpace)colActual.getColorSpace(); | |||||
assertEquals("Postgelb", ncs.getColorName()); | assertEquals("Postgelb", ncs.getColorName()); | ||||
comps = alt.getColorComponents(null); | |||||
comps = colActual.getColorComponents(null); | |||||
assertEquals(1, comps.length); | assertEquals(1, comps.length); | ||||
assertEquals(1f, comps[0], 0); | assertEquals(1f, comps[0], 0); | ||||