Moved GrayScaleColorConverter as a package-local class from XGC to the AFP package (doesn't require deprecation when we can put the functionality in XGC later with the new color infrastructure). git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@959945 13f79535-47bb-0310-9956-ffa450edef68tags/fop-1_0
import org.apache.xmlgraphics.java2d.color.ColorConverter; | import org.apache.xmlgraphics.java2d.color.ColorConverter; | ||||
import org.apache.xmlgraphics.java2d.color.DefaultColorConverter; | import org.apache.xmlgraphics.java2d.color.DefaultColorConverter; | ||||
import org.apache.xmlgraphics.java2d.color.GrayScaleColorConverter; | |||||
import org.apache.fop.afp.fonts.AFPPageFonts; | import org.apache.fop.afp.fonts.AFPPageFonts; | ||||
import org.apache.fop.util.AbstractPaintingState; | import org.apache.fop.util.AbstractPaintingState; |
/* | |||||
* 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.afp; | |||||
import java.awt.Color; | |||||
import org.apache.xmlgraphics.java2d.color.ColorConverter; | |||||
import org.apache.fop.util.ColorUtil; | |||||
/** | |||||
* Converts to grayscale using the standard RED=30%, GREEN=59% and BLUE=11% | |||||
* weights (see http://en.wikipedia.org/wiki/Grayscale) | |||||
*/ | |||||
final class GrayScaleColorConverter implements ColorConverter { | |||||
private static final int RED_WEIGHT = 77; | |||||
private static final int GREEN_WEIGTH = 150; | |||||
private static final int BLUE_WEIGHT = 28; | |||||
private static final GrayScaleColorConverter SINGLETON = new GrayScaleColorConverter(); | |||||
private GrayScaleColorConverter() { } | |||||
/** | |||||
* static factory | |||||
* | |||||
* @return singleton instance of GrayScaleColorConverter | |||||
*/ | |||||
public static GrayScaleColorConverter getInstance() { | |||||
return SINGLETON; | |||||
} | |||||
/** | |||||
* The color is converted to CMYK with just the K component {@inheritDoc} | |||||
*/ | |||||
public Color convert(Color color) { | |||||
float kValue = (RED_WEIGHT * color.getRed() + GREEN_WEIGTH * color.getGreen() + BLUE_WEIGHT | |||||
* color.getBlue()) / 255.0f / 255.0f; | |||||
return ColorUtil.toCMYKGrayColor(kValue); | |||||
} | |||||
} |
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.List; | import java.util.List; | ||||
import org.apache.xmlgraphics.java2d.color.CMYKColorSpace; | |||||
import org.apache.xmlgraphics.java2d.color.ColorExt; | |||||
import org.apache.xmlgraphics.java2d.color.DeviceCMYKColorSpace; | |||||
import org.apache.fop.util.ColorExt; | |||||
/** | /** | ||||
* PDF Color object. | * PDF Color object. | ||||
ce = (ColorExt)col; | ce = (ColorExt)col; | ||||
cs = ce.getOrigColorSpace(); | cs = ce.getOrigColorSpace(); | ||||
} | } | ||||
if (cs != null && cs instanceof CMYKColorSpace) { | |||||
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 |
import org.apache.xmlgraphics.image.loader.impl.ImageRendered; | import org.apache.xmlgraphics.image.loader.impl.ImageRendered; | ||||
import org.apache.xmlgraphics.java2d.AbstractGraphics2D; | import org.apache.xmlgraphics.java2d.AbstractGraphics2D; | ||||
import org.apache.xmlgraphics.java2d.GraphicContext; | import org.apache.xmlgraphics.java2d.GraphicContext; | ||||
import org.apache.xmlgraphics.java2d.color.ColorExt; | |||||
import org.apache.fop.fonts.Font; | import org.apache.fop.fonts.Font; | ||||
import org.apache.fop.fonts.FontInfo; | import org.apache.fop.fonts.FontInfo; | ||||
import org.apache.fop.render.pdf.ImageRawCCITTFaxAdapter; | import org.apache.fop.render.pdf.ImageRawCCITTFaxAdapter; | ||||
import org.apache.fop.render.pdf.ImageRawJPEGAdapter; | import org.apache.fop.render.pdf.ImageRawJPEGAdapter; | ||||
import org.apache.fop.render.pdf.ImageRenderedAdapter; | import org.apache.fop.render.pdf.ImageRenderedAdapter; | ||||
import org.apache.fop.util.ColorExt; | |||||
/** | /** | ||||
* PDF Graphics 2D. | * PDF Graphics 2D. |
/* | |||||
* 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; | |||||
/** | |||||
* 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. | |||||
*/ | |||||
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(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} */ | |||||
public int hashCode() { | |||||
//implementation from the superclass should be good enough for our purposes | |||||
return super.hashCode(); | |||||
} | |||||
/** {@inheritDoc} */ | |||||
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(); | |||||
} | |||||
} |
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.CMYKColorSpace; | |||||
import org.apache.xmlgraphics.java2d.color.ColorExt; | |||||
import org.apache.xmlgraphics.java2d.color.DeviceCMYKColorSpace; | |||||
import org.apache.fop.apps.FOUserAgent; | import org.apache.fop.apps.FOUserAgent; | ||||
import org.apache.fop.fo.expr.PropertyException; | import org.apache.fop.fo.expr.PropertyException; | ||||
String iccProfileSrc = null; | String iccProfileSrc = null; | ||||
if (isPseudoProfile(iccProfileName)) { | if (isPseudoProfile(iccProfileName)) { | ||||
if (CMYK_PSEUDO_PROFILE.equalsIgnoreCase(iccProfileName)) { | if (CMYK_PSEUDO_PROFILE.equalsIgnoreCase(iccProfileName)) { | ||||
colorSpace = CMYKColorSpace.getInstance(); | |||||
colorSpace = DeviceCMYKColorSpace.getInstance(); | |||||
} else { | } else { | ||||
assert false : "Incomplete implementation"; | assert false : "Incomplete implementation"; | ||||
} | } | ||||
+ "Arguments to cmyk() must be in the range [0%-100%] or [0.0-1.0]"); | + "Arguments to cmyk() must be in the range [0%-100%] or [0.0-1.0]"); | ||||
} | } | ||||
float[] cmyk = new float[] {cyan, magenta, yellow, black}; | float[] cmyk = new float[] {cyan, magenta, yellow, black}; | ||||
CMYKColorSpace cmykCs = CMYKColorSpace.getInstance(); | |||||
DeviceCMYKColorSpace cmykCs = DeviceCMYKColorSpace.getInstance(); | |||||
float[] rgb = cmykCs.toRGB(cmyk); | float[] rgb = cmykCs.toRGB(cmyk); | ||||
parsedColor = ColorExt.createFromFoRgbIcc(rgb[0], rgb[1], rgb[2], | parsedColor = ColorExt.createFromFoRgbIcc(rgb[0], rgb[1], rgb[2], | ||||
CMYK_PSEUDO_PROFILE, null, cmykCs, cmyk); | CMYK_PSEUDO_PROFILE, null, cmykCs, cmyk); | ||||
} | } | ||||
/** | /** | ||||
* 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 | ||||
*/ | */ | ||||
public static Color toCMYKGrayColor(float black) { | public static Color toCMYKGrayColor(float black) { | ||||
return org.apache.xmlgraphics.java2d.color.ColorUtil.toCMYKGrayColor(black); | |||||
float[] cmyk = new float[] {0f, 0f, 0f, 1.0f - black}; | |||||
DeviceCMYKColorSpace cmykCs = DeviceCMYKColorSpace.getInstance(); | |||||
float[] rgb = cmykCs.toRGB(cmyk); | |||||
return ColorExt.createFromFoRgbIcc(rgb[0], rgb[1], rgb[2], | |||||
CMYK_PSEUDO_PROFILE, null, cmykCs, cmyk); | |||||
} | } | ||||
} | } |
import junit.framework.TestCase; | import junit.framework.TestCase; | ||||
import org.apache.xmlgraphics.java2d.color.CMYKColorSpace; | |||||
import org.apache.xmlgraphics.java2d.color.ColorExt; | |||||
import org.apache.xmlgraphics.java2d.color.DeviceCMYKColorSpace; | |||||
import org.apache.fop.fo.Constants; | import org.apache.fop.fo.Constants; | ||||
import org.apache.fop.util.ColorExt; | |||||
import org.apache.fop.util.ColorUtil; | import org.apache.fop.util.ColorUtil; | ||||
/** | /** | ||||
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}; | ||||
CMYKColorSpace cmykCs = CMYKColorSpace.getInstance(); | |||||
DeviceCMYKColorSpace cmykCs = DeviceCMYKColorSpace.getInstance(); | |||||
float[] rgb = cmykCs.toRGB(cmyk); | float[] rgb = cmykCs.toRGB(cmyk); | ||||
col = ColorExt.createFromFoRgbIcc(rgb[0], rgb[1], rgb[2], | col = ColorExt.createFromFoRgbIcc(rgb[0], rgb[1], rgb[2], | ||||
"#CMYK", null, cmykCs, cmyk); | "#CMYK", null, cmykCs, cmyk); |
import junit.framework.TestCase; | import junit.framework.TestCase; | ||||
import org.apache.xmlgraphics.java2d.color.CMYKColorSpace; | |||||
import org.apache.xmlgraphics.java2d.color.ColorExt; | |||||
import org.apache.xmlgraphics.java2d.color.DeviceCMYKColorSpace; | |||||
import org.apache.fop.apps.FOUserAgent; | import org.apache.fop.apps.FOUserAgent; | ||||
import org.apache.fop.apps.FopFactory; | import org.apache.fop.apps.FopFactory; | ||||
assertEquals(255, colActual.getRed()); | assertEquals(255, colActual.getRed()); | ||||
assertEquals(255, colActual.getGreen()); | assertEquals(255, colActual.getGreen()); | ||||
assertEquals(0, colActual.getBlue()); | assertEquals(0, colActual.getBlue()); | ||||
assertEquals(CMYKColorSpace.getInstance(), colActual.getColorSpace()); | |||||
assertEquals(DeviceCMYKColorSpace.getInstance(), colActual.getColorSpace()); | |||||
float[] comps = colActual.getColorComponents(null); | float[] comps = colActual.getColorComponents(null); | ||||
assertEquals(4, comps.length); | assertEquals(4, comps.length); | ||||
assertEquals(0f, comps[0], 0); | assertEquals(0f, comps[0], 0); | ||||
assertEquals(248, colActual.getRed()); | assertEquals(248, colActual.getRed()); | ||||
assertEquals(199, colActual.getGreen()); | assertEquals(199, colActual.getGreen()); | ||||
assertEquals(172, colActual.getBlue()); | assertEquals(172, colActual.getBlue()); | ||||
assertEquals(CMYKColorSpace.getInstance(), colActual.getColorSpace()); | |||||
assertEquals(DeviceCMYKColorSpace.getInstance(), colActual.getColorSpace()); | |||||
comps = colActual.getColorComponents(null); | comps = colActual.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(255, colActual.getRed()); | assertEquals(255, colActual.getRed()); | ||||
assertEquals(255, colActual.getGreen()); | assertEquals(255, colActual.getGreen()); | ||||
assertEquals(0, colActual.getBlue()); | assertEquals(0, colActual.getBlue()); | ||||
assertEquals(CMYKColorSpace.getInstance(), colActual.getColorSpace()); | |||||
assertEquals(DeviceCMYKColorSpace.getInstance(), colActual.getColorSpace()); | |||||
comps = colActual.getColorComponents(null); | comps = colActual.getColorComponents(null); | ||||
assertEquals(4, comps.length); | assertEquals(4, comps.length); | ||||
assertEquals(0f, comps[0], 0); | assertEquals(0f, comps[0], 0); | ||||
assertEquals(127, colActual.getRed()); | assertEquals(127, colActual.getRed()); | ||||
assertEquals(127, colActual.getGreen()); | assertEquals(127, colActual.getGreen()); | ||||
assertEquals(127, colActual.getBlue()); | assertEquals(127, colActual.getBlue()); | ||||
assertEquals(CMYKColorSpace.getInstance(), colActual.getColorSpace()); | |||||
assertEquals(DeviceCMYKColorSpace.getInstance(), colActual.getColorSpace()); | |||||
comps = colActual.getColorComponents(null); | comps = colActual.getColorComponents(null); | ||||
assertEquals(4, comps.length); | assertEquals(4, comps.length); | ||||
assertEquals(0f, comps[0], 0); | assertEquals(0f, comps[0], 0); |