git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/FOP-2393_gradient-rendering@1611778 13f79535-47bb-0310-9956-ffa450edef68tags/fop-2_0
} else if (func.getRange() != null) { | } else if (func.getRange() != null) { | ||||
return false; | return false; | ||||
} | } | ||||
if (function.getSize() != null) { | |||||
if (!function.getSize().equals(func.getSize())) { | |||||
return false; | |||||
} | |||||
} else if (func.getSize() != null) { | |||||
return false; | |||||
} | |||||
if (function.getEncode() != null) { | if (function.getEncode() != null) { | ||||
if (!function.getEncode().equals(func.getEncode())) { | if (!function.getEncode().equals(func.getEncode())) { | ||||
return false; | return false; | ||||
} else if (func.getEncode() != null) { | } else if (func.getEncode() != null) { | ||||
return false; | return false; | ||||
} | } | ||||
if (function.getDecode() != null) { | |||||
if (!function.getDecode().equals(func.getDecode())) { | |||||
return false; | |||||
} | |||||
} else if (func.getDecode() != null) { | |||||
return false; | |||||
} | |||||
if (function.getDataStream() != null) { | |||||
if (!function.getDataStream().equals(func.getDataStream())) { | |||||
return false; | |||||
} | |||||
} else if (func.getDataStream() != null) { | |||||
return false; | |||||
} | |||||
if (function.getFilter() != null) { | |||||
if (!function.getFilter().equals(func.getFilter())) { | |||||
return false; | |||||
} | |||||
} else if (func.getFilter() != null) { | |||||
return false; | |||||
} | |||||
if (!Arrays.equals(function.getCZero(), func.getCZero())) { | if (!Arrays.equals(function.getCZero(), func.getCZero())) { | ||||
return false; | return false; | ||||
} | } |
private final Shading shading; | private final Shading shading; | ||||
private final PDFFunction pdfFunction; | private final PDFFunction pdfFunction; | ||||
/** | |||||
* A ColorSpace representing the colorspace. "DeviceRGB" is an example. | |||||
*/ | |||||
protected PDFDeviceColorSpace colorSpace; | |||||
/** | /** | ||||
* Constructor for Type 2 and 3 | * Constructor for Type 2 and 3 | ||||
} else if (other.getColorSpace() != null) { | } else if (other.getColorSpace() != null) { | ||||
return false; | return false; | ||||
} | } | ||||
if (shading.getBackground() != null) { | |||||
if (!shading.getBackground().equals(other.getBackground())) { | |||||
return false; | |||||
} | |||||
} else if (other.getBackground() != null) { | |||||
return false; | |||||
} | |||||
if (shading.getBBox() != null) { | |||||
if (!shading.getBBox().equals(other.getBBox())) { | |||||
return false; | |||||
} | |||||
} else if (other.getBBox() != null) { | |||||
return false; | |||||
} | |||||
if (shading.getMatrix() != null) { | |||||
if (!shading.getMatrix().equals(other.getMatrix())) { | |||||
return false; | |||||
} | |||||
} else if (other.getMatrix() != null) { | |||||
return false; | |||||
} | |||||
if (shading.getCoords() != null) { | if (shading.getCoords() != null) { | ||||
if (!shading.getCoords().equals(other.getCoords())) { | if (!shading.getCoords().equals(other.getCoords())) { | ||||
return false; | return false; | ||||
} else if (other.getExtend() != null) { | } else if (other.getExtend() != null) { | ||||
return false; | return false; | ||||
} | } | ||||
if (shading.getDecode() != null) { | |||||
if (!shading.getDecode().equals(other.getDecode())) { | |||||
return false; | |||||
} | |||||
} else if (other.getDecode() != null) { | |||||
return false; | |||||
} | |||||
if (shading.getFunction() != null) { | if (shading.getFunction() != null) { | ||||
if (!shading.getFunction().equals(other.getFunction())) { | if (!shading.getFunction().equals(other.getFunction())) { | ||||
return false; | return false; |
*/ | */ | ||||
private List<Double> range; | private List<Double> range; | ||||
/* ********************TYPE 0***************************** */ | |||||
// FunctionType 0 specific function guts | |||||
/** | |||||
* Required: Array containing the Integer size of the Domain and Range, respectively. | |||||
* Note: This is really more like two seperate integers, sizeDomain, and sizeRange, | |||||
* but since they're expressed as an array in PDF, my implementation reflects that. | |||||
*/ | |||||
protected List<Double> size; | |||||
/** | /** | ||||
* Required for Type 0: Number of Bits used to represent each sample value. | * Required for Type 0: Number of Bits used to represent each sample value. | ||||
* Limited to 1,2,4,8,12,16,24, or 32 | * Limited to 1,2,4,8,12,16,24, or 32 | ||||
*/ | */ | ||||
private List<Double> encode; | private List<Double> encode; | ||||
/** | |||||
* Optional for Type 0: A 2 * n array of Doubles which provides | |||||
* a linear mapping of sample values to the range. Defaults to Range. | |||||
*/ | |||||
private List<Double> decode; | |||||
/** | |||||
* Optional For Type 0: A stream of sample values | |||||
*/ | |||||
/** | |||||
* Required For Type 4: Postscript Calculator function | |||||
* composed of arithmetic, boolean, and stack operators + boolean constants | |||||
*/ | |||||
private StringBuffer functionDataStream; | |||||
/** | |||||
* Required (possibly) For Type 0: A vector of Strings for the | |||||
* various filters to be used to decode the stream. | |||||
* These are how the string is compressed. Flate, LZW, etc. | |||||
*/ | |||||
private List<String> filter; | |||||
/* *************************TYPE 2************************** */ | /* *************************TYPE 2************************** */ | ||||
/** | /** | ||||
return domain; | return domain; | ||||
} | } | ||||
/** | |||||
* The function size | |||||
*/ | |||||
public List<Double> getSize() { | |||||
return size; | |||||
} | |||||
/** | /** | ||||
* Gets the function encoding | * Gets the function encoding | ||||
*/ | */ | ||||
} | } | ||||
} | } | ||||
/** | |||||
* Gets the function filter | |||||
*/ | |||||
public List<String> getFilter() { | |||||
return filter; | |||||
} | |||||
/** | /** | ||||
* Gets the bits per sample of the function | * Gets the bits per sample of the function | ||||
*/ | */ | ||||
return range; | return range; | ||||
} | } | ||||
/** | |||||
* Gets the function decoding | |||||
*/ | |||||
public List<Double> getDecode() { | |||||
return decode; | |||||
} | |||||
/** | |||||
* Gets the function data stream | |||||
*/ | |||||
public StringBuffer getDataStream() { | |||||
return functionDataStream; | |||||
} | |||||
/** | /** | ||||
* Gets the function C0 value (color for gradient) | * Gets the function C0 value (color for gradient) | ||||
*/ | */ | ||||
out.append("<<\n/FunctionType " + functionType + "\n"); | out.append("<<\n/FunctionType " + functionType + "\n"); | ||||
outputDomain(out, doubleFormatter); | outputDomain(out, doubleFormatter); | ||||
if (this.functionType == 0) { | if (this.functionType == 0) { | ||||
outputSize(out, doubleFormatter); | |||||
outputEncode(out, doubleFormatter); | outputEncode(out, doubleFormatter); | ||||
outputBitsPerSample(out); | outputBitsPerSample(out); | ||||
outputOrder(out); | outputOrder(out); | ||||
outputRange(out, doubleFormatter); | outputRange(out, doubleFormatter); | ||||
outputDecode(out, doubleFormatter); | |||||
if (functionDataStream != null) { | |||||
out.append("/Length " + (functionDataStream.length() + 1) + "\n"); | |||||
} | |||||
outputFilter(out); | |||||
out.append(">>"); | out.append(">>"); | ||||
if (functionDataStream != null) { | |||||
out.append("\nstream\n" + functionDataStream + "\nendstream"); | |||||
} | |||||
} else if (functionType == 2) { | } else if (functionType == 2) { | ||||
outputRange(out, doubleFormatter); | outputRange(out, doubleFormatter); | ||||
outputCZero(out, doubleFormatter); | outputCZero(out, doubleFormatter); | ||||
out.append("\n>>"); | out.append("\n>>"); | ||||
} else if (functionType == 4) { | } else if (functionType == 4) { | ||||
outputRange(out, doubleFormatter); | outputRange(out, doubleFormatter); | ||||
if (functionDataStream != null) { | |||||
out.append("/Length " + (functionDataStream.length() + 1) + "\n"); | |||||
} | |||||
out.append(">>"); | out.append(">>"); | ||||
if (functionDataStream != null) { | |||||
out.append("\nstream\n{ " + functionDataStream + " }\nendstream"); | |||||
} | |||||
} | } | ||||
return out.toString(); | return out.toString(); | ||||
} | } | ||||
p.append("\n"); | p.append("\n"); | ||||
} | } | ||||
private void outputSize(StringBuilder out, DoubleFormatter doubleFormatter) { | |||||
if (size != null) { | |||||
out.append("/Size "); | |||||
GradientMaker.outputDoubles(out, doubleFormatter, size); | |||||
out.append("\n"); | |||||
} | |||||
} | |||||
private void outputBitsPerSample(StringBuilder out) { | private void outputBitsPerSample(StringBuilder out) { | ||||
out.append("/BitsPerSample " + bitsPerSample + "\n"); | out.append("/BitsPerSample " + bitsPerSample + "\n"); | ||||
} | } | ||||
out.append("\n"); | out.append("\n"); | ||||
} | } | ||||
private void outputDecode(StringBuilder out, DoubleFormatter doubleFormatter) { | |||||
if (decode != null) { | |||||
out.append("/Decode "); | |||||
GradientMaker.outputDoubles(out, doubleFormatter, decode); | |||||
out.append("\n"); | |||||
} | |||||
} | |||||
private void outputFilter(StringBuilder out) { | |||||
if (filter != null) { | |||||
int size = filter.size(); | |||||
out.append("/Filter "); | |||||
if (size == 1) { | |||||
out.append("/" + filter.get(0) + "\n"); | |||||
} else { | |||||
out.append("[ "); | |||||
for (int i = 0; i < size; i++) { | |||||
out.append("/" + filter.get(0) + " "); | |||||
} | |||||
out.append("]\n"); | |||||
} | |||||
} | |||||
} | |||||
private void outputCZero(StringBuilder out, DoubleFormatter doubleFormatter) { | private void outputCZero(StringBuilder out, DoubleFormatter doubleFormatter) { | ||||
if (cZero != null) { | if (cZero != null) { | ||||
out.append("/C0 [ "); | out.append("/C0 [ "); |
Point2D startPoint = gp.getStartPoint(); | Point2D startPoint = gp.getStartPoint(); | ||||
Point2D endPoint = gp.getEndPoint(); | Point2D endPoint = gp.getEndPoint(); | ||||
List<Double> coords = new java.util.ArrayList<Double>(4); | List<Double> coords = new java.util.ArrayList<Double>(4); | ||||
coords.add(new Double(startPoint.getX())); | |||||
coords.add(new Double(startPoint.getY())); | |||||
coords.add(new Double(endPoint.getX())); | |||||
coords.add(new Double(endPoint.getY())); | |||||
coords.add(Double.valueOf(startPoint.getX())); | |||||
coords.add(Double.valueOf(startPoint.getY())); | |||||
coords.add(Double.valueOf(endPoint.getX())); | |||||
coords.add(Double.valueOf(endPoint.getY())); | |||||
return makeGradient(gp, coords, baseTransform, transform); | return makeGradient(gp, coords, baseTransform, transform); | ||||
} | } | ||||
*/ | */ | ||||
private final Function function; | private final Function function; | ||||
/** | |||||
* Optional: A List specifying the clipping rectangle | |||||
*/ | |||||
private final List<Double> bbox; | |||||
/** | |||||
* Optional for Type 1: A transformation matrix | |||||
*/ | |||||
private final List<Double> matrix; | |||||
/** | |||||
* The background color. Since shading is opaque, | |||||
* this is very rarely used. | |||||
*/ | |||||
private final List<Double> background; | |||||
/** | |||||
* Required for Type 4,5,6, and 7: Array of Doubles which specifies | |||||
* how to decode coordinate and color component values. | |||||
* Each type has a differing number of decode array members, so check | |||||
* the spec. | |||||
* Page 303 in PDF Spec 1.3 | |||||
*/ | |||||
private final List<Double> decode; | |||||
/** | /** | ||||
* Required for Type 2+3: An Array of two boolean values specifying | * Required for Type 2+3: An Array of two boolean values specifying | ||||
* whether to extend the start and end colors past the start | * whether to extend the start and end colors past the start | ||||
List<Double> coords, Function function) { | List<Double> coords, Function function) { | ||||
this.shadingType = shadingType; | this.shadingType = shadingType; | ||||
this.colorSpace = colorSpace; | this.colorSpace = colorSpace; | ||||
this.background = null; | |||||
this.bbox = null; | |||||
this.antiAlias = false; | this.antiAlias = false; | ||||
this.coords = coords; | this.coords = coords; | ||||
this.function = function; | this.function = function; | ||||
this.extend = Arrays.asList(true, true); | this.extend = Arrays.asList(true, true); | ||||
this.matrix = null; | |||||
this.decode = null; | |||||
this.bitsPerCoordinate = 0; | this.bitsPerCoordinate = 0; | ||||
this.bitsPerFlag = 0; | this.bitsPerFlag = 0; | ||||
this.bitsPerComponent = 0; | this.bitsPerComponent = 0; | ||||
return function; | return function; | ||||
} | } | ||||
public List<Double> getBBox() { | |||||
return bbox; | |||||
} | |||||
public List<Double> getMatrix() { | |||||
return matrix; | |||||
} | |||||
public List<Double> getBackground() { | |||||
return background; | |||||
} | |||||
public List<Double> getDecode() { | |||||
return decode; | |||||
} | |||||
public List<Boolean> getExtend() { | public List<Boolean> getExtend() { | ||||
return extend; | return extend; | ||||
} | } | ||||
out.append("/ColorSpace /" + colorSpace.getName() + "\n"); | out.append("/ColorSpace /" + colorSpace.getName() + "\n"); | ||||
} | } | ||||
if (background != null) { | |||||
out.append("/Background "); | |||||
GradientMaker.outputDoubles(out, doubleFormatter, background); | |||||
out.append("\n"); | |||||
} | |||||
if (bbox != null) { | |||||
out.append("/BBox"); | |||||
GradientMaker.outputDoubles(out, doubleFormatter, bbox); | |||||
out.append("\n"); | |||||
} | |||||
if (antiAlias) { | if (antiAlias) { | ||||
out.append("/AntiAlias " + antiAlias + "\n"); | out.append("/AntiAlias " + antiAlias + "\n"); | ||||
} | } | ||||
private void outputShadingType1(StringBuilder out, DoubleFormatter doubleFormatter, | private void outputShadingType1(StringBuilder out, DoubleFormatter doubleFormatter, | ||||
Shading.FunctionRenderer functionRenderer) { | Shading.FunctionRenderer functionRenderer) { | ||||
if (matrix != null) { | |||||
out.append("/Matrix "); | |||||
GradientMaker.outputDoubles(out, doubleFormatter, matrix); | |||||
out.append("\n"); | |||||
} | |||||
outputFunction(out, functionRenderer); | outputFunction(out, functionRenderer); | ||||
} | } | ||||
out.append("/BitsPerFlag 2 \n"); | out.append("/BitsPerFlag 2 \n"); | ||||
} | } | ||||
if (decode != null) { | |||||
out.append("/Decode "); | |||||
GradientMaker.outputDoubles(out, doubleFormatter, decode); | |||||
out.append("\n"); | |||||
} | |||||
outputFunction(out, functionRenderer); | outputFunction(out, functionRenderer); | ||||
} | } | ||||
out.append("/BitsPerComponent 1 \n"); | out.append("/BitsPerComponent 1 \n"); | ||||
} | } | ||||
if (decode != null) { | |||||
out.append("/Decode "); | |||||
GradientMaker.outputDoubles(out, doubleFormatter, decode); | |||||
out.append("\n"); | |||||
} | |||||
outputFunction(out, functionRenderer); | outputFunction(out, functionRenderer); | ||||
if (verticesPerRow > 0) { | if (verticesPerRow > 0) { |