Removed makeFunction/Shading/Gradient methods in PDFFactory that were not used, duplicates of methods in (PDF)GradientFactory and getting in the way of refactoring git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/FOP-2393_gradient-rendering@1609745 13f79535-47bb-0310-9956-ffa450edef68tags/fop-2_0
@@ -20,7 +20,6 @@ | |||
package org.apache.fop.pdf; | |||
// Java | |||
import java.awt.Color; | |||
import java.awt.geom.Point2D; | |||
import java.awt.geom.Rectangle2D; | |||
import java.io.ByteArrayInputStream; | |||
@@ -41,7 +40,6 @@ import org.apache.commons.io.output.ByteArrayOutputStream; | |||
import org.apache.commons.logging.Log; | |||
import org.apache.commons.logging.LogFactory; | |||
import org.apache.xmlgraphics.java2d.color.ColorUtil; | |||
import org.apache.xmlgraphics.java2d.color.NamedColorSpace; | |||
import org.apache.xmlgraphics.xmp.Metadata; | |||
@@ -243,81 +241,6 @@ public class PDFFactory { | |||
/* ========================= functions ================================= */ | |||
/** | |||
* Make a Type 0 sampled function | |||
* | |||
* @param theDomain List objects of Double objects. | |||
* This is the domain of the function. | |||
* See page 264 of the PDF 1.3 Spec. | |||
* @param theRange List objects of Double objects. | |||
* This is the Range of the function. | |||
* See page 264 of the PDF 1.3 Spec. | |||
* @param theSize A List object of Integer objects. | |||
* This is the number of samples in each input dimension. | |||
* I can't imagine there being more or less than two input dimensions, | |||
* so maybe this should be an array of length 2. | |||
* | |||
* See page 265 of the PDF 1.3 Spec. | |||
* @param theBitsPerSample An int specifying the number of bits user | |||
* to represent each sample value. | |||
* Limited to 1,2,4,8,12,16,24 or 32. | |||
* See page 265 of the 1.3 PDF Spec. | |||
* @param theOrder The order of interpolation between samples. | |||
* Default is 1 (one). Limited | |||
* to 1 (one) or 3, which means linear or cubic-spline interpolation. | |||
* | |||
* This attribute is optional. | |||
* | |||
* See page 265 in the PDF 1.3 spec. | |||
* @param theEncode List objects of Double objects. | |||
* This is the linear mapping of input values intop the domain | |||
* of the function's sample table. Default is hard to represent in | |||
* ascii, but basically [0 (Size0 1) 0 (Size1 1)...]. | |||
* This attribute is optional. | |||
* | |||
* See page 265 in the PDF 1.3 spec. | |||
* @param theDecode List objects of Double objects. | |||
* This is a linear mapping of sample values into the range. | |||
* The default is just the range. | |||
* | |||
* This attribute is optional. | |||
* Read about it on page 265 of the PDF 1.3 spec. | |||
* @param theFunctionDataStream The sample values that specify | |||
* the function are provided in a stream. | |||
* | |||
* This is optional, but is almost always used. | |||
* | |||
* Page 265 of the PDF 1.3 spec has more. | |||
* @param theFilter This is a vector of String objects which | |||
* are the various filters that have are to be | |||
* applied to the stream to make sense of it. | |||
* Order matters, so watch out. | |||
* | |||
* This is not documented in the Function section of the PDF 1.3 spec, | |||
* it was deduced from samples that this is sometimes used, even if we may never | |||
* use it in FOP. It is added for completeness sake. | |||
* @param theFunctionType This is the type of function (0,2,3, or 4). | |||
* It should be 0 as this is the constructor for sampled functions. | |||
* @return the PDF function that was created | |||
*/ | |||
public PDFFunction makeFunction(int theFunctionType, List theDomain, | |||
List theRange, List theSize, | |||
int theBitsPerSample, int theOrder, | |||
List theEncode, List theDecode, | |||
StringBuffer theFunctionDataStream, | |||
List theFilter) { | |||
// Type 0 function | |||
PDFFunction function = new PDFFunction(theFunctionType, theDomain, | |||
theRange, theSize, | |||
theBitsPerSample, theOrder, | |||
theEncode, theDecode, | |||
theFunctionDataStream, | |||
theFilter); | |||
function = registerFunction(function); | |||
return (function); | |||
} | |||
/** | |||
* make a type Exponential interpolation function | |||
* (for shading usually) | |||
@@ -352,80 +275,7 @@ public class PDFFactory { | |||
theRange, theCZero, theCOne, | |||
theInterpolationExponentN); | |||
function = registerFunction(function); | |||
return (function); | |||
} | |||
/** | |||
* Make a Type 3 Stitching function | |||
* | |||
* @param theDomain List objects of Double objects. | |||
* This is the domain of the function. | |||
* See page 264 of the PDF 1.3 Spec. | |||
* @param theRange List objects of Double objects. | |||
* This is the Range of the function. | |||
* See page 264 of the PDF 1.3 Spec. | |||
* @param theFunctions An List of the PDFFunction objects | |||
* that the stitching function stitches. | |||
* | |||
* This attributed is required. | |||
* It is described on page 269 of the PDF spec. | |||
* @param theBounds This is a vector of Doubles representing | |||
* the numbers that, in conjunction with Domain | |||
* define the intervals to which each function from | |||
* the 'functions' object applies. It must be in | |||
* order of increasing magnitude, and each must be | |||
* within Domain. | |||
* | |||
* It basically sets how much of the gradient each function handles. | |||
* | |||
* This attributed is required. | |||
* It's described on page 269 of the PDF 1.3 spec. | |||
* @param theEncode List objects of Double objects. | |||
* This is the linear mapping of input values intop the domain | |||
* of the function's sample table. Default is hard to represent in | |||
* ascii, but basically [0 (Size0 1) 0 (Size1 1)...]. | |||
* This attribute is required. | |||
* | |||
* See page 270 in the PDF 1.3 spec. | |||
* @param theFunctionType This is the function type. It should be 3, | |||
* for a stitching function. | |||
* @return the PDF function that was created | |||
*/ | |||
public PDFFunction makeFunction(int theFunctionType, List theDomain, | |||
List theRange, List theFunctions, | |||
List theBounds, | |||
List theEncode) { | |||
// Type 3 | |||
PDFFunction function = new PDFFunction(theFunctionType, theDomain, | |||
theRange, theFunctions, | |||
theBounds, theEncode); | |||
function = registerFunction(function); | |||
return (function); | |||
} | |||
/** | |||
* make a postscript calculator function | |||
* | |||
* @param theNumber the PDF object number | |||
* @param theFunctionType the type of function to make | |||
* @param theDomain the domain values | |||
* @param theRange the range values of the function | |||
* @param theFunctionDataStream a string containing the pdf drawing | |||
* @return the PDF function that was created | |||
*/ | |||
public PDFFunction makeFunction(int theNumber, int theFunctionType, | |||
List theDomain, List theRange, | |||
StringBuffer theFunctionDataStream) { | |||
// Type 4 | |||
PDFFunction function = new PDFFunction(theFunctionType, theDomain, | |||
theRange, | |||
theFunctionDataStream); | |||
function = registerFunction(function); | |||
return (function); | |||
return function; | |||
} | |||
/** | |||
@@ -444,175 +294,6 @@ public class PDFFactory { | |||
/* ========================= shadings ================================== */ | |||
/** | |||
* make a function based shading object | |||
* | |||
* @param res the PDF resource context to add the shading, may be null | |||
* @param theShadingType The type of shading object, which should be 1 for function | |||
* based shading. | |||
* @param theColorSpace The colorspace is 'DeviceRGB' or something similar. | |||
* @param theBackground An array of color components appropriate to the | |||
* colorspace key specifying a single color value. | |||
* This key is used by the f operator buy ignored by the sh operator. | |||
* @param theBBox List of double's representing a rectangle | |||
* in the coordinate space that is current at the | |||
* time of shading is imaged. Temporary clipping | |||
* boundary. | |||
* @param theAntiAlias Whether or not to anti-alias. | |||
* @param theDomain Optional vector of Doubles specifying the domain. | |||
* @param theMatrix List of Doubles specifying the matrix. | |||
* If it's a pattern, then the matrix maps it to pattern space. | |||
* If it's a shading, then it maps it to current user space. | |||
* It's optional, the default is the identity matrix | |||
* @param theFunction The PDF Function that maps an (x,y) location to a color | |||
* @return the PDF shading that was created | |||
*/ | |||
public PDFShading makeShading(PDFResourceContext res, int theShadingType, | |||
PDFDeviceColorSpace theColorSpace, | |||
List theBackground, List theBBox, | |||
boolean theAntiAlias, List theDomain, | |||
List theMatrix, | |||
PDFFunction theFunction) { | |||
// make Shading of Type 1 | |||
PDFShading shading = new PDFShading(theShadingType, | |||
theColorSpace, theBackground, | |||
theBBox, theAntiAlias, theDomain, | |||
theMatrix, theFunction); | |||
shading = registerShading(res, shading); | |||
return (shading); | |||
} | |||
/** | |||
* Make an axial or radial shading object. | |||
* | |||
* @param res the PDF resource context to add the shading, may be null | |||
* @param theShadingType 2 or 3 for axial or radial shading | |||
* @param theColorSpace "DeviceRGB" or similar. | |||
* @param theBackground theBackground An array of color components appropriate to the | |||
* colorspace key specifying a single color value. | |||
* This key is used by the f operator buy ignored by the sh operator. | |||
* @param theBBox List of double's representing a rectangle | |||
* in the coordinate space that is current at the | |||
* time of shading is imaged. Temporary clipping | |||
* boundary. | |||
* @param theAntiAlias Default is false | |||
* @param theCoords List of four (type 2) or 6 (type 3) Double | |||
* @param theDomain List of Doubles specifying the domain | |||
* @param theFunction the Stitching (PDFfunction type 3) function, | |||
* even if it's stitching a single function | |||
* @param theExtend List of Booleans of whether to extend the | |||
* start and end colors past the start and end points | |||
* The default is [false, false] | |||
* @return the PDF shading that was created | |||
*/ | |||
public PDFShading makeShading(PDFResourceContext res, int theShadingType, | |||
PDFDeviceColorSpace theColorSpace, | |||
List theBackground, List theBBox, | |||
boolean theAntiAlias, List theCoords, | |||
List theDomain, PDFFunction theFunction, | |||
List theExtend) { | |||
// make Shading of Type 2 or 3 | |||
PDFShading shading = new PDFShading(theShadingType, | |||
theColorSpace, theBackground, | |||
theBBox, theAntiAlias, theCoords, | |||
theDomain, theFunction, | |||
theExtend); | |||
shading = registerShading(res, shading); | |||
return (shading); | |||
} | |||
/** | |||
* Make a free-form gouraud shaded triangle mesh, coons patch mesh, or tensor patch mesh | |||
* shading object | |||
* | |||
* @param res the PDF resource context to add the shading, may be null | |||
* @param theShadingType 4, 6, or 7 depending on whether it's | |||
* Free-form gouraud-shaded triangle meshes, coons patch meshes, | |||
* or tensor product patch meshes, respectively. | |||
* @param theColorSpace "DeviceRGB" or similar. | |||
* @param theBackground theBackground An array of color components appropriate to the | |||
* colorspace key specifying a single color value. | |||
* This key is used by the f operator buy ignored by the sh operator. | |||
* @param theBBox List of double's representing a rectangle | |||
* in the coordinate space that is current at the | |||
* time of shading is imaged. Temporary clipping | |||
* boundary. | |||
* @param theAntiAlias Default is false | |||
* @param theBitsPerCoordinate 1,2,4,8,12,16,24 or 32. | |||
* @param theBitsPerComponent 1,2,4,8,12, and 16 | |||
* @param theBitsPerFlag 2,4,8. | |||
* @param theDecode List of Doubles see PDF 1.3 spec pages 303 to 312. | |||
* @param theFunction the PDFFunction | |||
* @return the PDF shading that was created | |||
*/ | |||
public PDFShading makeShading(PDFResourceContext res, int theShadingType, | |||
PDFDeviceColorSpace theColorSpace, | |||
List theBackground, List theBBox, | |||
boolean theAntiAlias, | |||
int theBitsPerCoordinate, | |||
int theBitsPerComponent, | |||
int theBitsPerFlag, List theDecode, | |||
PDFFunction theFunction) { | |||
// make Shading of type 4,6 or 7 | |||
PDFShading shading = new PDFShading(theShadingType, | |||
theColorSpace, theBackground, | |||
theBBox, theAntiAlias, | |||
theBitsPerCoordinate, | |||
theBitsPerComponent, | |||
theBitsPerFlag, theDecode, | |||
theFunction); | |||
shading = registerShading(res, shading); | |||
return (shading); | |||
} | |||
/** | |||
* make a Lattice-Form Gouraud mesh shading object | |||
* | |||
* @param res the PDF resource context to add the shading, may be null | |||
* @param theShadingType 5 for lattice-Form Gouraud shaded-triangle mesh | |||
* without spaces. "Shading1" or "Sh1" are good examples. | |||
* @param theColorSpace "DeviceRGB" or similar. | |||
* @param theBackground theBackground An array of color components appropriate to the | |||
* colorspace key specifying a single color value. | |||
* This key is used by the f operator buy ignored by the sh operator. | |||
* @param theBBox List of double's representing a rectangle | |||
* in the coordinate space that is current at the | |||
* time of shading is imaged. Temporary clipping | |||
* boundary. | |||
* @param theAntiAlias Default is false | |||
* @param theBitsPerCoordinate 1,2,4,8,12,16, 24, or 32 | |||
* @param theBitsPerComponent 1,2,4,8,12,24,32 | |||
* @param theDecode List of Doubles. See page 305 in PDF 1.3 spec. | |||
* @param theVerticesPerRow number of vertices in each "row" of the lattice. | |||
* @param theFunction The PDFFunction that's mapped on to this shape | |||
* @return the PDF shading that was created | |||
*/ | |||
public PDFShading makeShading(PDFResourceContext res, int theShadingType, | |||
PDFDeviceColorSpace theColorSpace, | |||
List theBackground, List theBBox, | |||
boolean theAntiAlias, | |||
int theBitsPerCoordinate, | |||
int theBitsPerComponent, List theDecode, | |||
int theVerticesPerRow, | |||
PDFFunction theFunction) { | |||
// make shading of Type 5 | |||
PDFShading shading = new PDFShading(theShadingType, | |||
theColorSpace, theBackground, | |||
theBBox, theAntiAlias, | |||
theBitsPerCoordinate, | |||
theBitsPerComponent, theDecode, | |||
theVerticesPerRow, theFunction); | |||
shading = registerShading(res, shading); | |||
return (shading); | |||
} | |||
/** | |||
* Registers a shading object against the document | |||
* @param res The PDF resource context | |||
@@ -731,114 +412,6 @@ public class PDFFactory { | |||
return (pattern); | |||
} | |||
/** | |||
* Make a gradient | |||
* | |||
* @param res the PDF resource context to add the shading, may be null | |||
* @param radial if true a radial gradient will be created | |||
* @param theColorspace the colorspace of the gradient | |||
* @param theColors the list of colors for the gradient | |||
* @param theBounds the list of bounds associated with the colors | |||
* @param theCoords the coordinates for the gradient | |||
* @param theMatrix the coordinate-transformation matrix | |||
* @return the PDF pattern that was created | |||
*/ | |||
public PDFPattern makeGradient(PDFResourceContext res, boolean radial, | |||
PDFDeviceColorSpace theColorspace, | |||
List theColors, List theBounds, | |||
List theCoords, List theMatrix) { | |||
PDFShading myShad; | |||
PDFFunction myfunky; | |||
PDFFunction myfunc; | |||
List theCzero; | |||
List theCone; | |||
PDFPattern myPattern; | |||
//PDFColorSpace theColorSpace; | |||
double interpolation = 1.000; | |||
List theFunctions = new ArrayList(); | |||
int currentPosition; | |||
int lastPosition = theColors.size() - 1; | |||
// if 5 elements, the penultimate element is 3. | |||
// do not go beyond that, because you always need | |||
// to have a next color when creating the function. | |||
for (currentPosition = 0; currentPosition < lastPosition; | |||
currentPosition++) { // for every consecutive color pair | |||
Color currentColor = (Color)theColors.get(currentPosition); | |||
Color nextColor = (Color)theColors.get(currentPosition + 1); | |||
// colorspace must be consistent, so we simply convert to sRGB where necessary | |||
if (!currentColor.getColorSpace().isCS_sRGB()) { | |||
//Convert to sRGB | |||
currentColor = ColorUtil.toSRGBColor(currentColor); | |||
theColors.set(currentPosition, currentColor); | |||
} | |||
if (!nextColor.getColorSpace().isCS_sRGB()) { | |||
//Convert to sRGB | |||
nextColor = ColorUtil.toSRGBColor(nextColor); | |||
theColors.set(currentPosition + 1, nextColor); | |||
} | |||
theCzero = toColorVector(currentColor); | |||
theCone = toColorVector(nextColor); | |||
myfunc = makeFunction(2, null, null, theCzero, theCone, | |||
interpolation); | |||
theFunctions.add(myfunc); | |||
} // end of for every consecutive color pair | |||
myfunky = makeFunction(3, null, null, theFunctions, theBounds, | |||
null); | |||
if (radial) { | |||
if (theCoords.size() == 6) { | |||
myShad = makeShading(res, 3, getDocument().getPDFColorSpace(), | |||
null, null, | |||
false, theCoords, null, myfunky, | |||
null); | |||
} else { // if the center x, center y, and radius specifiy | |||
// the gradient, then assume the same center x, center y, | |||
// and radius of zero for the other necessary component | |||
List newCoords = new ArrayList(); | |||
newCoords.add(theCoords.get(0)); | |||
newCoords.add(theCoords.get(1)); | |||
newCoords.add(theCoords.get(2)); | |||
newCoords.add(theCoords.get(0)); | |||
newCoords.add(theCoords.get(1)); | |||
newCoords.add(new Double(0.0)); | |||
myShad = makeShading(res, 3, getDocument().getPDFColorSpace(), | |||
null, null, | |||
false, newCoords, null, myfunky, | |||
null); | |||
} | |||
} else { | |||
myShad = makeShading(res, 2, getDocument().getPDFColorSpace(), | |||
null, null, | |||
false, theCoords, null, myfunky, | |||
null); | |||
} | |||
myPattern = makePattern(res, 2, myShad, null, null, theMatrix); | |||
return (myPattern); | |||
} | |||
private List toColorVector(Color nextColor) { | |||
List vector = new java.util.ArrayList(); | |||
float[] comps = nextColor.getColorComponents(null); | |||
for (int i = 0, c = comps.length; i < c; i++) { | |||
vector.add(new Double(comps[i])); | |||
} | |||
return vector; | |||
} | |||
/* ============= named destinations and the name dictionary ============ */ | |||
@@ -19,11 +19,11 @@ | |||
package org.apache.fop.pdf; | |||
// Java... | |||
import java.util.ArrayList; | |||
import java.util.Collections; | |||
import java.util.List; | |||
import org.apache.fop.render.shading.Function; | |||
import org.apache.fop.render.shading.FunctionDelegate; | |||
import org.apache.fop.render.shading.FunctionPattern; | |||
/** | |||
@@ -37,75 +37,11 @@ import org.apache.fop.render.shading.FunctionPattern; | |||
* | |||
* All PDF Functions have a FunctionType (0,2,3, or 4), a Domain, and a Range. | |||
*/ | |||
public class PDFFunction extends PDFObject implements Function { | |||
public class PDFFunction extends PDFObject { | |||
private FunctionDelegate delegate; | |||
private final Function function; | |||
/** | |||
* create an complete Function object of Type 0, A Sampled function. | |||
* | |||
* Use null for an optional object parameter if you choose not to use it. | |||
* For optional int parameters, pass the default. | |||
* | |||
* @param theDomain List objects of Double objects. | |||
* This is the domain of the function. | |||
* See page 264 of the PDF 1.3 Spec. | |||
* @param theRange List objects of Double objects. | |||
* This is the Range of the function. | |||
* See page 264 of the PDF 1.3 Spec. | |||
* @param theSize A List object of Integer objects. | |||
* This is the number of samples in each input dimension. | |||
* I can't imagine there being more or less than two input dimensions, | |||
* so maybe this should be an array of length 2. | |||
* | |||
* See page 265 of the PDF 1.3 Spec. | |||
* @param theBitsPerSample An int specifying the number of bits | |||
used to represent each sample value. | |||
* Limited to 1,2,4,8,12,16,24 or 32. | |||
* See page 265 of the 1.3 PDF Spec. | |||
* @param theOrder The order of interpolation between samples. Default is 1 (one). Limited | |||
* to 1 (one) or 3, which means linear or cubic-spline interpolation. | |||
* | |||
* This attribute is optional. | |||
* | |||
* See page 265 in the PDF 1.3 spec. | |||
* @param theEncode List objects of Double objects. | |||
* This is the linear mapping of input values intop the domain | |||
* of the function's sample table. Default is hard to represent in | |||
* ascii, but basically [0 (Size0 1) 0 (Size1 1)...]. | |||
* This attribute is optional. | |||
* | |||
* See page 265 in the PDF 1.3 spec. | |||
* @param theDecode List objects of Double objects. | |||
* This is a linear mapping of sample values into the range. | |||
* The default is just the range. | |||
* | |||
* This attribute is optional. | |||
* Read about it on page 265 of the PDF 1.3 spec. | |||
* @param theFunctionDataStream The sample values that specify | |||
* the function are provided in a stream. | |||
* | |||
* This is optional, but is almost always used. | |||
* | |||
* Page 265 of the PDF 1.3 spec has more. | |||
* @param theFilter This is a vector of String objects which are the various filters that | |||
* have are to be applied to the stream to make sense of it. Order matters, | |||
* so watch out. | |||
* | |||
* This is not documented in the Function section of the PDF 1.3 spec, | |||
* it was deduced from samples that this is sometimes used, even if we may never | |||
* use it in FOP. It is added for completeness sake. | |||
* @param theFunctionType This is the type of function (0,2,3, or 4). | |||
* It should be 0 as this is the constructor for sampled functions. | |||
*/ | |||
public PDFFunction(int theFunctionType, List<Double> theDomain, | |||
List<Double> theRange, List<Double> theSize, int theBitsPerSample, | |||
int theOrder, List<Double> theEncode, List<Double> theDecode, | |||
StringBuffer theFunctionDataStream, List<String> theFilter) { | |||
delegate = new FunctionDelegate(this, theFunctionType, theDomain, theRange, | |||
theSize, theBitsPerSample, theOrder, theEncode, theDecode, | |||
theFunctionDataStream, theFilter); | |||
} | |||
private final List<PDFFunction> pdfFunctions; | |||
/** | |||
* create an complete Function object of Type 2, an Exponential Interpolation function. | |||
@@ -137,80 +73,23 @@ public class PDFFunction extends PDFObject implements Function { | |||
public PDFFunction(int theFunctionType, List<Double> theDomain, | |||
List<Double> theRange, List<Double> theCZero, List<Double> theCOne, | |||
double theInterpolationExponentN) { | |||
delegate = new FunctionDelegate(this, theFunctionType, theDomain, theRange, | |||
theCZero, theCOne, theInterpolationExponentN); | |||
this(new Function(theFunctionType, theDomain, theRange, | |||
theCZero, theCOne, theInterpolationExponentN)); | |||
} | |||
/** | |||
* create an complete Function object of Type 3, a Stitching function. | |||
* | |||
* Use null for an optional object parameter if you choose not to use it. | |||
* For optional int parameters, pass the default. | |||
* | |||
* @param theDomain List objects of Double objects. | |||
* This is the domain of the function. | |||
* See page 264 of the PDF 1.3 Spec. | |||
* @param theRange List objects of Double objects. | |||
* This is the Range of the function. | |||
* See page 264 of the PDF 1.3 Spec. | |||
* @param theFunctions A List of the PDFFunction objects that the stitching function stitches. | |||
* | |||
* This attributed is required. | |||
* It is described on page 269 of the PDF spec. | |||
* @param theBounds This is a vector of Doubles representing the numbers that, | |||
* in conjunction with Domain define the intervals to which each function from | |||
* the 'functions' object applies. It must be in order of increasing magnitude, | |||
* and each must be within Domain. | |||
* | |||
* It basically sets how much of the gradient each function handles. | |||
* | |||
* This attributed is required. | |||
* It's described on page 269 of the PDF 1.3 spec. | |||
* @param theEncode List objects of Double objects. | |||
* This is the linear mapping of input values intop the domain | |||
* of the function's sample table. Default is hard to represent in | |||
* ascii, but basically [0 (Size0 1) 0 (Size1 1)...]. | |||
* This attribute is required. | |||
* | |||
* See page 270 in the PDF 1.3 spec. | |||
* @param theFunctionType This is the function type. It should be 3, | |||
* for a stitching function. | |||
*/ | |||
public PDFFunction(int theFunctionType, List<Double> theDomain, | |||
List<Double> theRange, List<Function> theFunctions, | |||
List<Double> theBounds, List<Double> theEncode) { | |||
delegate = new FunctionDelegate(this, theFunctionType, theDomain, theRange, | |||
theFunctions, theBounds, theEncode); | |||
@SuppressWarnings("unchecked") | |||
public PDFFunction(Function function) { | |||
this(function, Collections.EMPTY_LIST); | |||
} | |||
public PDFFunction(Function function, List<PDFFunction> pdfFunctions) { | |||
this.function = function; | |||
this.pdfFunctions = pdfFunctions; | |||
} | |||
/** | |||
* create an complete Function object of Type 4, a postscript calculator function. | |||
* | |||
* Use null for an optional object parameter if you choose not to use it. | |||
* For optional int parameters, pass the default. | |||
* | |||
* @param theDomain List object of Double objects. | |||
* This is the domain of the function. | |||
* See page 264 of the PDF 1.3 Spec. | |||
* @param theRange List object of Double objects. | |||
* This is the Range of the function. | |||
* See page 264 of the PDF 1.3 Spec. | |||
* @param theFunctionDataStream This is a stream of arithmetic, | |||
* boolean, and stack operators and boolean constants. | |||
* I end up enclosing it in the '{' and '}' braces for you, so don't do it | |||
* yourself. | |||
* | |||
* This attribute is required. | |||
* It's described on page 269 of the PDF 1.3 spec. | |||
* @param theFunctionType The type of function which should be 4, as this is | |||
* a Postscript calculator function | |||
*/ | |||
public PDFFunction(int theFunctionType, List<Double> theDomain, | |||
List<Double> theRange, StringBuffer theFunctionDataStream) { | |||
delegate = new FunctionDelegate(this, theFunctionType, theDomain, theRange, | |||
theFunctionDataStream); | |||
public Function getFunction() { | |||
return function; | |||
} | |||
/** | |||
@@ -230,8 +109,12 @@ public class PDFFunction extends PDFObject implements Function { | |||
public byte[] toByteString() { | |||
FunctionPattern pattern = new FunctionPattern(this); | |||
return encode(pattern.toWriteableString()); | |||
FunctionPattern pattern = new FunctionPattern(function); | |||
List<String> functionsStrings = new ArrayList<String>(function.getFunctions().size()); | |||
for (PDFFunction f : pdfFunctions) { | |||
functionsStrings.add(f.referencePDF()); | |||
} | |||
return encode(pattern.toWriteableString(functionsStrings)); | |||
} | |||
/** {@inheritDoc} */ | |||
@@ -245,91 +128,87 @@ public class PDFFunction extends PDFObject implements Function { | |||
if (!(obj instanceof PDFFunction)) { | |||
return false; | |||
} | |||
PDFFunction func = (PDFFunction)obj; | |||
if (delegate.getFunctionType() != func.getFunctionType()) { | |||
Function func = ((PDFFunction) obj).function; | |||
if (function.getFunctionType() != func.getFunctionType()) { | |||
return false; | |||
} | |||
if (delegate.getBitsPerSample() != func.getBitsPerSample()) { | |||
if (function.getBitsPerSample() != func.getBitsPerSample()) { | |||
return false; | |||
} | |||
if (delegate.getOrder() != func.getOrder()) { | |||
if (function.getOrder() != func.getOrder()) { | |||
return false; | |||
} | |||
if (delegate.getInterpolationExponentN() != func.getInterpolationExponentN()) { | |||
if (function.getInterpolationExponentN() != func.getInterpolationExponentN()) { | |||
return false; | |||
} | |||
if (delegate.getDomain() != null) { | |||
if (!delegate.getDomain().equals(func.getDomain())) { | |||
if (function.getDomain() != null) { | |||
if (!function.getDomain().equals(func.getDomain())) { | |||
return false; | |||
} | |||
} else if (func.getDomain() != null) { | |||
return false; | |||
} | |||
if (delegate.getRange() != null) { | |||
if (!delegate.getRange().equals(func.getRange())) { | |||
if (function.getRange() != null) { | |||
if (!function.getRange().equals(func.getRange())) { | |||
return false; | |||
} | |||
} else if (func.getRange() != null) { | |||
return false; | |||
} | |||
if (delegate.getSize() != null) { | |||
if (!delegate.getSize().equals(func.getSize())) { | |||
if (function.getSize() != null) { | |||
if (!function.getSize().equals(func.getSize())) { | |||
return false; | |||
} | |||
} else if (func.getSize() != null) { | |||
return false; | |||
} | |||
if (delegate.getEncode() != null) { | |||
if (!delegate.getEncode().equals(func.getEncode())) { | |||
if (function.getEncode() != null) { | |||
if (!function.getEncode().equals(func.getEncode())) { | |||
return false; | |||
} | |||
} else if (func.getEncode() != null) { | |||
return false; | |||
} | |||
if (delegate.getDecode() != null) { | |||
if (!delegate.getDecode().equals(func.getDecode())) { | |||
if (function.getDecode() != null) { | |||
if (!function.getDecode().equals(func.getDecode())) { | |||
return false; | |||
} | |||
} else if (func.getDecode() != null) { | |||
return false; | |||
} | |||
if (delegate.getDataStream() != null) { | |||
if (!delegate.getDataStream().equals(func.getDataStream())) { | |||
if (function.getDataStream() != null) { | |||
if (!function.getDataStream().equals(func.getDataStream())) { | |||
return false; | |||
} | |||
} else if (func.getDataStream() != null) { | |||
return false; | |||
} | |||
if (delegate.getFilter() != null) { | |||
if (!delegate.getFilter().equals(func.getFilter())) { | |||
if (function.getFilter() != null) { | |||
if (!function.getFilter().equals(func.getFilter())) { | |||
return false; | |||
} | |||
} else if (func.getFilter() != null) { | |||
return false; | |||
} | |||
if (delegate.getCZero() != null) { | |||
if (!delegate.getCZero().equals(func.getCZero())) { | |||
if (function.getCZero() != null) { | |||
if (!function.getCZero().equals(func.getCZero())) { | |||
return false; | |||
} | |||
} else if (func.getCZero() != null) { | |||
return false; | |||
} | |||
if (delegate.getCOne() != null) { | |||
if (!delegate.getCOne().equals(func.getCOne())) { | |||
if (function.getCOne() != null) { | |||
if (!function.getCOne().equals(func.getCOne())) { | |||
return false; | |||
} | |||
} else if (func.getCOne() != null) { | |||
return false; | |||
} | |||
if (delegate.getFunctions() != null) { | |||
if (!delegate.getFunctions().equals(func.getFunctions())) { | |||
return false; | |||
} | |||
} else if (func.getFunctions() != null) { | |||
if (!pdfFunctions.equals(((PDFFunction) obj).pdfFunctions)) { | |||
return false; | |||
} | |||
if (delegate.getBounds() != null) { | |||
if (!delegate.getBounds().equals(func.getBounds())) { | |||
if (function.getBounds() != null) { | |||
if (!function.getBounds().equals(func.getBounds())) { | |||
return false; | |||
} | |||
} else if (func.getBounds() != null) { | |||
@@ -338,63 +217,4 @@ public class PDFFunction extends PDFObject implements Function { | |||
return true; | |||
} | |||
public int getFunctionType() { | |||
return delegate.getFunctionType(); | |||
} | |||
public List<Double> getBounds() { | |||
return delegate.getBounds(); | |||
} | |||
public List<Double> getDomain() { | |||
return delegate.getDomain(); | |||
} | |||
public List<Double> getSize() { | |||
return delegate.getSize(); | |||
} | |||
public List<String> getFilter() { | |||
return delegate.getFilter(); | |||
} | |||
public List<Double> getEncode() { | |||
return delegate.getEncode(); | |||
} | |||
public List<Function> getFunctions() { | |||
return delegate.getFunctions(); | |||
} | |||
public int getBitsPerSample() { | |||
return delegate.getBitsPerSample(); | |||
} | |||
public double getInterpolationExponentN() { | |||
return delegate.getInterpolationExponentN(); | |||
} | |||
public int getOrder() { | |||
return delegate.getOrder(); | |||
} | |||
public List<Double> getRange() { | |||
return delegate.getRange(); | |||
} | |||
public List<Double> getDecode() { | |||
return delegate.getDecode(); | |||
} | |||
public StringBuffer getDataStream() { | |||
return delegate.getDataStream(); | |||
} | |||
public List<Double> getCZero() { | |||
return delegate.getCZero(); | |||
} | |||
public List<Double> getCOne() { | |||
return delegate.getCOne(); | |||
} | |||
} |
@@ -22,7 +22,6 @@ package org.apache.fop.pdf; | |||
// Java... | |||
import java.util.List; | |||
import org.apache.fop.render.shading.Function; | |||
import org.apache.fop.render.shading.Shading; | |||
import org.apache.fop.render.shading.ShadingPattern; | |||
@@ -209,7 +208,7 @@ public class PDFShading extends PDFObject implements Shading { | |||
public PDFShading(int theShadingType, PDFDeviceColorSpace theColorSpace, | |||
List theBackground, List theBBox, | |||
boolean theAntiAlias, List theCoords, | |||
List theDomain, Function theFunction, | |||
List theDomain, PDFFunction theFunction, | |||
List theExtend) { | |||
super(); | |||
this.shadingType = theShadingType; // 2 or 3 | |||
@@ -220,8 +219,7 @@ public class PDFShading extends PDFObject implements Shading { | |||
this.coords = theCoords; | |||
this.domain = theDomain; | |||
assert theFunction instanceof PDFFunction; | |||
this.function = (PDFFunction)theFunction; | |||
this.function = theFunction; | |||
this.extend = theExtend; | |||
} |
@@ -20,15 +20,13 @@ | |||
package org.apache.fop.render.ps.svg; | |||
import java.io.UnsupportedEncodingException; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import org.apache.fop.render.shading.Function; | |||
import org.apache.fop.render.shading.FunctionDelegate; | |||
import org.apache.fop.render.shading.FunctionPattern; | |||
public class PSFunction implements Function { | |||
private FunctionDelegate delegate; | |||
public class PSFunction extends Function { | |||
/** | |||
* Creates a Postscript function dictionary | |||
@@ -46,8 +44,7 @@ public class PSFunction implements Function { | |||
public PSFunction(int theFunctionType, List<Double> theDomain, | |||
List<Double> theRange, List<Function> theFunctions, | |||
List<Double> theBounds, List<Double> theEncode) { | |||
delegate = new FunctionDelegate(this, theFunctionType, theDomain, theRange, theFunctions, | |||
theBounds, theEncode); | |||
super(theFunctionType, theDomain, theRange, theFunctions, theBounds, theEncode); | |||
} | |||
/** | |||
@@ -64,8 +61,7 @@ public class PSFunction implements Function { | |||
public PSFunction(int theFunctionType, List<Double> theDomain, | |||
List<Double> theRange, List<Double> theCZero, List<Double> theCOne, | |||
double theInterpolationExponentN) { | |||
delegate = new FunctionDelegate(this, theFunctionType, theDomain, theRange, theCZero, | |||
theCOne, theInterpolationExponentN); | |||
super(theFunctionType, theDomain, theRange, theCZero, theCOne, theInterpolationExponentN); | |||
} | |||
/** | |||
@@ -74,70 +70,15 @@ public class PSFunction implements Function { | |||
public byte[] toByteString() { | |||
FunctionPattern pattern = new FunctionPattern(this); | |||
try { | |||
return pattern.toWriteableString().getBytes("UTF-8"); | |||
List<String> functionsStrings = new ArrayList<String>(getFunctions().size()); | |||
for (Function f : getFunctions()) { | |||
functionsStrings.add(new String(((PSFunction) f).toByteString(), "UTF-8")); | |||
} | |||
return pattern.toWriteableString(functionsStrings).getBytes("UTF-8"); | |||
} catch (UnsupportedEncodingException ex) { | |||
//This should have been made an enum type to avoid throwing exceptions. | |||
return new byte[0]; | |||
} | |||
} | |||
public int getFunctionType() { | |||
return delegate.getFunctionType(); | |||
} | |||
public List<Double> getBounds() { | |||
return delegate.getBounds(); | |||
} | |||
public List<Double> getDomain() { | |||
return delegate.getDomain(); | |||
} | |||
public List<Double> getSize() { | |||
return delegate.getSize(); | |||
} | |||
public List<String> getFilter() { | |||
return delegate.getFilter(); | |||
} | |||
public List<Double> getEncode() { | |||
return delegate.getEncode(); | |||
} | |||
public List<Function> getFunctions() { | |||
return delegate.getFunctions(); | |||
} | |||
public int getBitsPerSample() { | |||
return delegate.getBitsPerSample(); | |||
} | |||
public double getInterpolationExponentN() { | |||
return delegate.getInterpolationExponentN(); | |||
} | |||
public int getOrder() { | |||
return delegate.getOrder(); | |||
} | |||
public List<Double> getRange() { | |||
return delegate.getRange(); | |||
} | |||
public List<Double> getDecode() { | |||
return delegate.getDecode(); | |||
} | |||
public StringBuffer getDataStream() { | |||
return delegate.getDataStream(); | |||
} | |||
public List<Double> getCZero() { | |||
return delegate.getCZero(); | |||
} | |||
public List<Double> getCOne() { | |||
return delegate.getCOne(); | |||
} | |||
} |
@@ -17,23 +17,426 @@ | |||
package org.apache.fop.render.shading; | |||
import java.util.Collections; | |||
import java.util.List; | |||
public interface Function { | |||
int getFunctionType(); | |||
List<Double> getBounds(); | |||
List<Double> getDomain(); | |||
List<Double> getSize(); | |||
List<String> getFilter(); | |||
List<Double> getEncode(); | |||
List<Function> getFunctions(); | |||
int getBitsPerSample(); | |||
double getInterpolationExponentN(); | |||
int getOrder(); | |||
List<Double> getRange(); | |||
List<Double> getDecode(); | |||
StringBuffer getDataStream(); | |||
List<Double> getCZero(); | |||
List<Double> getCOne(); | |||
byte[] toByteString(); | |||
public class Function { | |||
/** | |||
* Required: The Type of function (0,2,3,4) default is 0. | |||
*/ | |||
protected int functionType = 0; // Default | |||
/** | |||
* Required: 2 * m Array of Double numbers which are possible inputs to the function | |||
*/ | |||
protected List<Double> domain = null; | |||
/** | |||
* Required: 2 * n Array of Double numbers which are possible outputs to the function | |||
*/ | |||
protected List<Double> range = null; | |||
/* ********************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 = null; | |||
/** | |||
* Required for Type 0: Number of Bits used to represent each sample value. | |||
* Limited to 1,2,4,8,12,16,24, or 32 | |||
*/ | |||
protected int bitsPerSample = 1; | |||
/** | |||
* Optional for Type 0: order of interpolation between samples. | |||
* Limited to linear (1) or cubic (3). Default is 1 | |||
*/ | |||
protected int order = 1; | |||
/** | |||
* Optional for Type 0: A 2 * m array of Doubles which provides a | |||
* linear mapping of input values to the domain. | |||
* | |||
* Required for Type 3: A 2 * k array of Doubles that, taken | |||
* in pairs, map each subset of the domain defined by Domain | |||
* and the Bounds array to the domain of the corresponding function. | |||
* Should be two values per function, usually (0,1), | |||
* as in [0 1 0 1] for 2 functions. | |||
*/ | |||
protected List<Double> encode = null; | |||
/** | |||
* Optional for Type 0: A 2 * n array of Doubles which provides | |||
* a linear mapping of sample values to the range. Defaults to Range. | |||
*/ | |||
protected List<Double> decode = null; | |||
/** | |||
* 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 | |||
*/ | |||
protected StringBuffer functionDataStream = null; | |||
/** | |||
* 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. | |||
*/ | |||
protected List<String> filter = null; | |||
/* *************************TYPE 2************************** */ | |||
/** | |||
* Required For Type 2: An Array of n Doubles defining | |||
* the function result when x=0. Default is [0]. | |||
*/ | |||
protected List<Double> cZero = null; | |||
/** | |||
* Required For Type 2: An Array of n Doubles defining | |||
* the function result when x=1. Default is [1]. | |||
*/ | |||
protected List<Double> cOne = null; | |||
/** | |||
* Required for Type 2: The interpolation exponent. | |||
* Each value x will return n results. | |||
* Must be greater than 0. | |||
*/ | |||
protected double interpolationExponentN = 1; | |||
/* *************************TYPE 3************************** */ | |||
/** | |||
* Required for Type 3: An vector of PDFFunctions which | |||
* form an array of k single input functions making up | |||
* the stitching function. | |||
*/ | |||
protected List<Function> functions = null; | |||
/** | |||
* Optional for Type 3: An array of (k-1) Doubles that, | |||
* in combination with Domain, define the intervals to which | |||
* each function from the Functions array apply. Bounds | |||
* elements must be in order of increasing magnitude, | |||
* and each value must be within the value of Domain. | |||
* k is the number of functions. | |||
* If you pass null, it will output (1/k) in an array of k-1 elements. | |||
* This makes each function responsible for an equal amount of the stitching function. | |||
* It makes the gradient even. | |||
*/ | |||
protected List<Double> bounds = null; | |||
/** | |||
* create an complete Function object of Type 0, A Sampled function. | |||
* | |||
* Use null for an optional object parameter if you choose not to use it. | |||
* For optional int parameters, pass the default. | |||
* @param theFunctionType This is the type of function (0,2,3, or 4). | |||
* It should be 0 as this is the constructor for sampled functions. | |||
* @param theDomain List objects of Double objects. | |||
* This is the domain of the function. | |||
* See page 264 of the PDF 1.3 Spec. | |||
* @param theRange List objects of Double objects. | |||
* This is the Range of the function. | |||
* See page 264 of the PDF 1.3 Spec. | |||
* @param theSize A List object of Integer objects. | |||
* This is the number of samples in each input dimension. | |||
* I can't imagine there being more or less than two input dimensions, | |||
* so maybe this should be an array of length 2. | |||
* | |||
* See page 265 of the PDF 1.3 Spec. | |||
* @param theBitsPerSample An int specifying the number of bits | |||
used to represent each sample value. | |||
* Limited to 1,2,4,8,12,16,24 or 32. | |||
* See page 265 of the 1.3 PDF Spec. | |||
* @param theOrder The order of interpolation between samples. Default is 1 (one). Limited | |||
* to 1 (one) or 3, which means linear or cubic-spline interpolation. | |||
* | |||
* This attribute is optional. | |||
* | |||
* See page 265 in the PDF 1.3 spec. | |||
* @param theEncode List objects of Double objects. | |||
* This is the linear mapping of input values intop the domain | |||
* of the function's sample table. Default is hard to represent in | |||
* ascii, but basically [0 (Size0 1) 0 (Size1 1)...]. | |||
* This attribute is optional. | |||
* | |||
* See page 265 in the PDF 1.3 spec. | |||
* @param theDecode List objects of Double objects. | |||
* This is a linear mapping of sample values into the range. | |||
* The default is just the range. | |||
* | |||
* This attribute is optional. | |||
* Read about it on page 265 of the PDF 1.3 spec. | |||
* @param theFunctionDataStream The sample values that specify | |||
* the function are provided in a stream. | |||
* | |||
* This is optional, but is almost always used. | |||
* | |||
* Page 265 of the PDF 1.3 spec has more. | |||
* @param theFilter This is a vector of String objects which are the various filters that | |||
* have are to be applied to the stream to make sense of it. Order matters, | |||
* so watch out. | |||
* | |||
* This is not documented in the Function section of the PDF 1.3 spec, | |||
* it was deduced from samples that this is sometimes used, even if we may never | |||
* use it in FOP. It is added for completeness sake. | |||
*/ | |||
public Function(int theFunctionType, List<Double> theDomain, List<Double> theRange, | |||
List<Double> theSize, int theBitsPerSample, int theOrder, | |||
List<Double> theEncode, List<Double> theDecode, StringBuffer theFunctionDataStream, | |||
List<String> theFilter) { | |||
this.functionType = 0; // dang well better be 0; | |||
this.size = theSize; | |||
this.bitsPerSample = theBitsPerSample; | |||
this.order = theOrder; // int | |||
this.encode = theEncode; // vector of int | |||
this.decode = theDecode; // vector of int | |||
this.functionDataStream = theFunctionDataStream; | |||
this.filter = theFilter; // vector of Strings | |||
// the domain and range are actually two dimensional arrays. | |||
// so if there's not an even number of items, bad stuff | |||
// happens. | |||
this.domain = theDomain; | |||
this.range = theRange; | |||
} | |||
/** | |||
* create an complete Function object of Type 2, an Exponential Interpolation function. | |||
* | |||
* Use null for an optional object parameter if you choose not to use it. | |||
* For optional int parameters, pass the default. | |||
* @param theFunctionType The type of the function, which should be 2. | |||
* @param theDomain List objects of Double objects. | |||
* This is the domain of the function. | |||
* See page 264 of the PDF 1.3 Spec. | |||
* @param theRange List of Doubles that is the Range of the function. | |||
* See page 264 of the PDF 1.3 Spec. | |||
* @param theCZero This is a vector of Double objects which defines the function result | |||
* when x=0. | |||
* | |||
* This attribute is optional. | |||
* It's described on page 268 of the PDF 1.3 spec. | |||
* @param theCOne This is a vector of Double objects which defines the function result | |||
* when x=1. | |||
* | |||
* This attribute is optional. | |||
* It's described on page 268 of the PDF 1.3 spec. | |||
* @param theInterpolationExponentN This is the inerpolation exponent. | |||
* | |||
* This attribute is required. | |||
* PDF Spec page 268 | |||
*/ | |||
public Function(int theFunctionType, List<Double> theDomain, List<Double> theRange, | |||
List<Double> theCZero, List<Double> theCOne, double theInterpolationExponentN) { | |||
this.functionType = 2; // dang well better be 2; | |||
this.cZero = theCZero; | |||
this.cOne = theCOne; | |||
this.interpolationExponentN = theInterpolationExponentN; | |||
this.domain = theDomain; | |||
this.range = theRange; | |||
} | |||
/** | |||
* create an complete Function object of Type 3, a Stitching function. | |||
* | |||
* Use null for an optional object parameter if you choose not to use it. | |||
* For optional int parameters, pass the default. | |||
* @param theFunctionType This is the function type. It should be 3, | |||
* for a stitching function. | |||
* @param theDomain List objects of Double objects. | |||
* This is the domain of the function. | |||
* See page 264 of the PDF 1.3 Spec. | |||
* @param theRange List objects of Double objects. | |||
* This is the Range of the function. | |||
* See page 264 of the PDF 1.3 Spec. | |||
* @param theFunctions A List of the PDFFunction objects that the stitching function stitches. | |||
* | |||
* This attributed is required. | |||
* It is described on page 269 of the PDF spec. | |||
* @param theBounds This is a vector of Doubles representing the numbers that, | |||
* in conjunction with Domain define the intervals to which each function from | |||
* the 'functions' object applies. It must be in order of increasing magnitude, | |||
* and each must be within Domain. | |||
* | |||
* It basically sets how much of the gradient each function handles. | |||
* | |||
* This attributed is required. | |||
* It's described on page 269 of the PDF 1.3 spec. | |||
* @param theEncode List objects of Double objects. | |||
* This is the linear mapping of input values intop the domain | |||
* of the function's sample table. Default is hard to represent in | |||
* ascii, but basically [0 (Size0 1) 0 (Size1 1)...]. | |||
* This attribute is required. | |||
* | |||
* See page 270 in the PDF 1.3 spec. | |||
*/ | |||
public Function(int theFunctionType, List<Double> theDomain, List<Double> theRange, | |||
List<Function> theFunctions, List<Double> theBounds, | |||
List<Double> theEncode) { | |||
this.functionType = 3; // dang well better be 3; | |||
this.functions = theFunctions; | |||
this.bounds = theBounds; | |||
this.encode = theEncode; | |||
this.domain = theDomain; | |||
this.range = theRange; | |||
} | |||
/** | |||
* create an complete Function object of Type 4, a postscript calculator function. | |||
* | |||
* Use null for an optional object parameter if you choose not to use it. | |||
* For optional int parameters, pass the default. | |||
* @param theFunctionType The type of function which should be 4, as this is | |||
* a Postscript calculator function | |||
* @param theDomain List object of Double objects. | |||
* This is the domain of the function. | |||
* See page 264 of the PDF 1.3 Spec. | |||
* @param theRange List object of Double objects. | |||
* This is the Range of the function. | |||
* See page 264 of the PDF 1.3 Spec. | |||
* @param theFunctionDataStream This is a stream of arithmetic, | |||
* boolean, and stack operators and boolean constants. | |||
* I end up enclosing it in the '{' and '}' braces for you, so don't do it | |||
* yourself. | |||
* | |||
* This attribute is required. | |||
* It's described on page 269 of the PDF 1.3 spec. | |||
*/ | |||
public Function(int theFunctionType, List<Double> theDomain, List<Double> theRange, | |||
StringBuffer theFunctionDataStream) { | |||
this.functionType = 4; // dang well better be 4; | |||
this.functionDataStream = theFunctionDataStream; | |||
this.domain = theDomain; | |||
this.range = theRange; | |||
} | |||
/** | |||
* Gets the function type | |||
*/ | |||
public int getFunctionType() { | |||
return functionType; | |||
} | |||
/** | |||
* Gets the function bounds | |||
*/ | |||
public List<Double> getBounds() { | |||
return bounds; | |||
} | |||
/** | |||
* The function domain | |||
*/ | |||
public List<Double> getDomain() { | |||
return domain; | |||
} | |||
/** | |||
* The function size | |||
*/ | |||
public List<Double> getSize() { | |||
return size; | |||
} | |||
/** | |||
* Gets the function encoding | |||
*/ | |||
public List<Double> getEncode() { | |||
return encode; | |||
} | |||
/** | |||
* Gets the sub-functions | |||
*/ | |||
public List<Function> getFunctions() { | |||
if (functions == null) { | |||
return Collections.emptyList(); | |||
} else { | |||
return functions; | |||
} | |||
} | |||
/** | |||
* Gets the function filter | |||
*/ | |||
public List<String> getFilter() { | |||
return filter; | |||
} | |||
/** | |||
* Gets the bits per sample of the function | |||
*/ | |||
public int getBitsPerSample() { | |||
return bitsPerSample; | |||
} | |||
/** | |||
* Gets the interpolation exponent of the function | |||
*/ | |||
public double getInterpolationExponentN() { | |||
return interpolationExponentN; | |||
} | |||
/** | |||
* Gets the function order | |||
*/ | |||
public int getOrder() { | |||
return order; | |||
} | |||
/** | |||
* Gets the function range | |||
*/ | |||
public List<Double> getRange() { | |||
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) | |||
*/ | |||
public List<Double> getCZero() { | |||
return cZero; | |||
} | |||
/** | |||
* Gets the function C1 value (color for gradient) | |||
*/ | |||
public List<Double> getCOne() { | |||
return cOne; | |||
} | |||
} |
@@ -1,451 +0,0 @@ | |||
/* | |||
* 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. | |||
*/ | |||
package org.apache.fop.render.shading; | |||
import java.util.List; | |||
public class FunctionDelegate implements Function { | |||
private Function parentFunction; | |||
/** | |||
* Required: The Type of function (0,2,3,4) default is 0. | |||
*/ | |||
protected int functionType = 0; // Default | |||
/** | |||
* Required: 2 * m Array of Double numbers which are possible inputs to the function | |||
*/ | |||
protected List<Double> domain = null; | |||
/** | |||
* Required: 2 * n Array of Double numbers which are possible outputs to the function | |||
*/ | |||
protected List<Double> range = null; | |||
/* ********************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 = null; | |||
/** | |||
* Required for Type 0: Number of Bits used to represent each sample value. | |||
* Limited to 1,2,4,8,12,16,24, or 32 | |||
*/ | |||
protected int bitsPerSample = 1; | |||
/** | |||
* Optional for Type 0: order of interpolation between samples. | |||
* Limited to linear (1) or cubic (3). Default is 1 | |||
*/ | |||
protected int order = 1; | |||
/** | |||
* Optional for Type 0: A 2 * m array of Doubles which provides a | |||
* linear mapping of input values to the domain. | |||
* | |||
* Required for Type 3: A 2 * k array of Doubles that, taken | |||
* in pairs, map each subset of the domain defined by Domain | |||
* and the Bounds array to the domain of the corresponding function. | |||
* Should be two values per function, usually (0,1), | |||
* as in [0 1 0 1] for 2 functions. | |||
*/ | |||
protected List<Double> encode = null; | |||
/** | |||
* Optional for Type 0: A 2 * n array of Doubles which provides | |||
* a linear mapping of sample values to the range. Defaults to Range. | |||
*/ | |||
protected List<Double> decode = null; | |||
/** | |||
* 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 | |||
*/ | |||
protected StringBuffer functionDataStream = null; | |||
/** | |||
* 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. | |||
*/ | |||
protected List<String> filter = null; | |||
/* *************************TYPE 2************************** */ | |||
/** | |||
* Required For Type 2: An Array of n Doubles defining | |||
* the function result when x=0. Default is [0]. | |||
*/ | |||
protected List<Double> cZero = null; | |||
/** | |||
* Required For Type 2: An Array of n Doubles defining | |||
* the function result when x=1. Default is [1]. | |||
*/ | |||
protected List<Double> cOne = null; | |||
/** | |||
* Required for Type 2: The interpolation exponent. | |||
* Each value x will return n results. | |||
* Must be greater than 0. | |||
*/ | |||
protected double interpolationExponentN = 1; | |||
/* *************************TYPE 3************************** */ | |||
/** | |||
* Required for Type 3: An vector of PDFFunctions which | |||
* form an array of k single input functions making up | |||
* the stitching function. | |||
*/ | |||
protected List<Function> functions = null; | |||
/** | |||
* Optional for Type 3: An array of (k-1) Doubles that, | |||
* in combination with Domain, define the intervals to which | |||
* each function from the Functions array apply. Bounds | |||
* elements must be in order of increasing magnitude, | |||
* and each value must be within the value of Domain. | |||
* k is the number of functions. | |||
* If you pass null, it will output (1/k) in an array of k-1 elements. | |||
* This makes each function responsible for an equal amount of the stitching function. | |||
* It makes the gradient even. | |||
*/ | |||
protected List<Double> bounds = null; | |||
/** | |||
* create an complete Function object of Type 0, A Sampled function. | |||
* | |||
* Use null for an optional object parameter if you choose not to use it. | |||
* For optional int parameters, pass the default. | |||
* | |||
* @param theDomain List objects of Double objects. | |||
* This is the domain of the function. | |||
* See page 264 of the PDF 1.3 Spec. | |||
* @param theRange List objects of Double objects. | |||
* This is the Range of the function. | |||
* See page 264 of the PDF 1.3 Spec. | |||
* @param theSize A List object of Integer objects. | |||
* This is the number of samples in each input dimension. | |||
* I can't imagine there being more or less than two input dimensions, | |||
* so maybe this should be an array of length 2. | |||
* | |||
* See page 265 of the PDF 1.3 Spec. | |||
* @param theBitsPerSample An int specifying the number of bits | |||
used to represent each sample value. | |||
* Limited to 1,2,4,8,12,16,24 or 32. | |||
* See page 265 of the 1.3 PDF Spec. | |||
* @param theOrder The order of interpolation between samples. Default is 1 (one). Limited | |||
* to 1 (one) or 3, which means linear or cubic-spline interpolation. | |||
* | |||
* This attribute is optional. | |||
* | |||
* See page 265 in the PDF 1.3 spec. | |||
* @param theEncode List objects of Double objects. | |||
* This is the linear mapping of input values intop the domain | |||
* of the function's sample table. Default is hard to represent in | |||
* ascii, but basically [0 (Size0 1) 0 (Size1 1)...]. | |||
* This attribute is optional. | |||
* | |||
* See page 265 in the PDF 1.3 spec. | |||
* @param theDecode List objects of Double objects. | |||
* This is a linear mapping of sample values into the range. | |||
* The default is just the range. | |||
* | |||
* This attribute is optional. | |||
* Read about it on page 265 of the PDF 1.3 spec. | |||
* @param theFunctionDataStream The sample values that specify | |||
* the function are provided in a stream. | |||
* | |||
* This is optional, but is almost always used. | |||
* | |||
* Page 265 of the PDF 1.3 spec has more. | |||
* @param theFilter This is a vector of String objects which are the various filters that | |||
* have are to be applied to the stream to make sense of it. Order matters, | |||
* so watch out. | |||
* | |||
* This is not documented in the Function section of the PDF 1.3 spec, | |||
* it was deduced from samples that this is sometimes used, even if we may never | |||
* use it in FOP. It is added for completeness sake. | |||
* @param theFunctionType This is the type of function (0,2,3, or 4). | |||
* It should be 0 as this is the constructor for sampled functions. | |||
*/ | |||
public FunctionDelegate(Function parentFunction, int theFunctionType, List<Double> theDomain, | |||
List<Double> theRange, List<Double> theSize, int theBitsPerSample, | |||
int theOrder, List<Double> theEncode, List<Double> theDecode, | |||
StringBuffer theFunctionDataStream, List<String> theFilter) { | |||
this.parentFunction = parentFunction; | |||
this.functionType = 0; // dang well better be 0; | |||
this.size = theSize; | |||
this.bitsPerSample = theBitsPerSample; | |||
this.order = theOrder; // int | |||
this.encode = theEncode; // vector of int | |||
this.decode = theDecode; // vector of int | |||
this.functionDataStream = theFunctionDataStream; | |||
this.filter = theFilter; // vector of Strings | |||
// the domain and range are actually two dimensional arrays. | |||
// so if there's not an even number of items, bad stuff | |||
// happens. | |||
this.domain = theDomain; | |||
this.range = theRange; | |||
} | |||
/** | |||
* create an complete Function object of Type 2, an Exponential Interpolation function. | |||
* | |||
* Use null for an optional object parameter if you choose not to use it. | |||
* For optional int parameters, pass the default. | |||
* | |||
* @param theDomain List objects of Double objects. | |||
* This is the domain of the function. | |||
* See page 264 of the PDF 1.3 Spec. | |||
* @param theRange List of Doubles that is the Range of the function. | |||
* See page 264 of the PDF 1.3 Spec. | |||
* @param theCZero This is a vector of Double objects which defines the function result | |||
* when x=0. | |||
* | |||
* This attribute is optional. | |||
* It's described on page 268 of the PDF 1.3 spec. | |||
* @param theCOne This is a vector of Double objects which defines the function result | |||
* when x=1. | |||
* | |||
* This attribute is optional. | |||
* It's described on page 268 of the PDF 1.3 spec. | |||
* @param theInterpolationExponentN This is the inerpolation exponent. | |||
* | |||
* This attribute is required. | |||
* PDF Spec page 268 | |||
* @param theFunctionType The type of the function, which should be 2. | |||
*/ | |||
public FunctionDelegate(Function parentFunction, int theFunctionType, List<Double> theDomain, | |||
List<Double> theRange, List<Double> theCZero, List<Double> theCOne, | |||
double theInterpolationExponentN) { | |||
this.parentFunction = parentFunction; | |||
this.functionType = 2; // dang well better be 2; | |||
this.cZero = theCZero; | |||
this.cOne = theCOne; | |||
this.interpolationExponentN = theInterpolationExponentN; | |||
this.domain = theDomain; | |||
this.range = theRange; | |||
} | |||
/** | |||
* create an complete Function object of Type 3, a Stitching function. | |||
* | |||
* Use null for an optional object parameter if you choose not to use it. | |||
* For optional int parameters, pass the default. | |||
* | |||
* @param theDomain List objects of Double objects. | |||
* This is the domain of the function. | |||
* See page 264 of the PDF 1.3 Spec. | |||
* @param theRange List objects of Double objects. | |||
* This is the Range of the function. | |||
* See page 264 of the PDF 1.3 Spec. | |||
* @param theFunctions A List of the PDFFunction objects that the stitching function stitches. | |||
* | |||
* This attributed is required. | |||
* It is described on page 269 of the PDF spec. | |||
* @param theBounds This is a vector of Doubles representing the numbers that, | |||
* in conjunction with Domain define the intervals to which each function from | |||
* the 'functions' object applies. It must be in order of increasing magnitude, | |||
* and each must be within Domain. | |||
* | |||
* It basically sets how much of the gradient each function handles. | |||
* | |||
* This attributed is required. | |||
* It's described on page 269 of the PDF 1.3 spec. | |||
* @param theEncode List objects of Double objects. | |||
* This is the linear mapping of input values intop the domain | |||
* of the function's sample table. Default is hard to represent in | |||
* ascii, but basically [0 (Size0 1) 0 (Size1 1)...]. | |||
* This attribute is required. | |||
* | |||
* See page 270 in the PDF 1.3 spec. | |||
* @param theFunctionType This is the function type. It should be 3, | |||
* for a stitching function. | |||
*/ | |||
public FunctionDelegate(Function parentFunction, int theFunctionType, List<Double> theDomain, | |||
List<Double> theRange, List<Function> theFunctions, | |||
List<Double> theBounds, List<Double> theEncode) { | |||
this.parentFunction = parentFunction; | |||
this.functionType = 3; // dang well better be 3; | |||
this.functions = theFunctions; | |||
this.bounds = theBounds; | |||
this.encode = theEncode; | |||
this.domain = theDomain; | |||
this.range = theRange; | |||
} | |||
/** | |||
* create an complete Function object of Type 4, a postscript calculator function. | |||
* | |||
* Use null for an optional object parameter if you choose not to use it. | |||
* For optional int parameters, pass the default. | |||
* | |||
* @param theDomain List object of Double objects. | |||
* This is the domain of the function. | |||
* See page 264 of the PDF 1.3 Spec. | |||
* @param theRange List object of Double objects. | |||
* This is the Range of the function. | |||
* See page 264 of the PDF 1.3 Spec. | |||
* @param theFunctionDataStream This is a stream of arithmetic, | |||
* boolean, and stack operators and boolean constants. | |||
* I end up enclosing it in the '{' and '}' braces for you, so don't do it | |||
* yourself. | |||
* | |||
* This attribute is required. | |||
* It's described on page 269 of the PDF 1.3 spec. | |||
* @param theFunctionType The type of function which should be 4, as this is | |||
* a Postscript calculator function | |||
*/ | |||
public FunctionDelegate(Function parentFunction, int theFunctionType, List<Double> theDomain, | |||
List<Double> theRange, StringBuffer theFunctionDataStream) { | |||
this.parentFunction = parentFunction; | |||
this.functionType = 4; // dang well better be 4; | |||
this.functionDataStream = theFunctionDataStream; | |||
this.domain = theDomain; | |||
this.range = theRange; | |||
} | |||
/** | |||
* Gets the function type | |||
*/ | |||
public int getFunctionType() { | |||
return functionType; | |||
} | |||
/** | |||
* Gets the function bounds | |||
*/ | |||
public List<Double> getBounds() { | |||
return bounds; | |||
} | |||
/** | |||
* The function domain | |||
*/ | |||
public List<Double> getDomain() { | |||
return domain; | |||
} | |||
/** | |||
* The function size | |||
*/ | |||
public List<Double> getSize() { | |||
return size; | |||
} | |||
/** | |||
* Gets the function encoding | |||
*/ | |||
public List<Double> getEncode() { | |||
return encode; | |||
} | |||
/** | |||
* Gets the sub-functions | |||
*/ | |||
public List<Function> getFunctions() { | |||
return functions; | |||
} | |||
/** | |||
* Gets the function filter | |||
*/ | |||
public List<String> getFilter() { | |||
return filter; | |||
} | |||
/** | |||
* Gets the bits per sample of the function | |||
*/ | |||
public int getBitsPerSample() { | |||
return bitsPerSample; | |||
} | |||
/** | |||
* Gets the interpolation exponent of the function | |||
*/ | |||
public double getInterpolationExponentN() { | |||
return interpolationExponentN; | |||
} | |||
/** | |||
* Gets the function order | |||
*/ | |||
public int getOrder() { | |||
return order; | |||
} | |||
/** | |||
* Gets the function range | |||
*/ | |||
public List<Double> getRange() { | |||
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) | |||
*/ | |||
public List<Double> getCZero() { | |||
return cZero; | |||
} | |||
/** | |||
* Gets the function C1 value (color for gradient) | |||
*/ | |||
public List<Double> getCOne() { | |||
return cOne; | |||
} | |||
public byte[] toByteString() { | |||
return parentFunction.toByteString(); | |||
} | |||
} |
@@ -19,11 +19,9 @@ | |||
package org.apache.fop.render.shading; | |||
import java.io.UnsupportedEncodingException; | |||
import java.util.List; | |||
import org.apache.fop.pdf.PDFFunction; | |||
import org.apache.fop.pdf.PDFNumber; | |||
import org.apache.fop.render.ps.svg.PSFunction; | |||
/** | |||
* A class for writing function objects for different output formats | |||
@@ -43,7 +41,7 @@ public class FunctionPattern { | |||
/** | |||
* Outputs the function to a byte array | |||
*/ | |||
public String toWriteableString() { | |||
public String toWriteableString(List<String> functionsStrings) { | |||
int vectorSize = 0; | |||
int numberOfFunctions = 0; | |||
int tempInt = 0; | |||
@@ -246,21 +244,12 @@ public class FunctionPattern { | |||
} | |||
// FUNCTIONS | |||
if (function.getFunctions() != null) { | |||
if (!function.getFunctions().isEmpty()) { | |||
p.append("/Functions [ "); | |||
numberOfFunctions = function.getFunctions().size(); | |||
for (tempInt = 0; tempInt < numberOfFunctions; tempInt++) { | |||
try { | |||
if (function instanceof PSFunction) { | |||
p.append(new String(function.getFunctions().get(tempInt).toByteString(), "UTF-8") | |||
+ " "); | |||
} else { | |||
p.append(((PDFFunction)function.getFunctions().get(tempInt)).referencePDF() | |||
+ " "); | |||
} | |||
} catch (UnsupportedEncodingException ex) { | |||
//This should have been made an enum type to avoid throwing exceptions. | |||
} | |||
for (String f : functionsStrings) { | |||
p.append(f); | |||
p.append(' '); | |||
} | |||
p.append("] \n"); | |||
} | |||
@@ -298,7 +287,7 @@ public class FunctionPattern { | |||
} | |||
} else { | |||
if (function.getFunctions() != null) { | |||
if (!function.getFunctions().isEmpty()) { | |||
// if there are n functions, | |||
// there must be n-1 bounds. | |||
// so let each function handle an equal portion |
@@ -17,6 +17,7 @@ | |||
package org.apache.fop.render.shading; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import org.apache.fop.pdf.PDFDeviceColorSpace; | |||
@@ -37,18 +38,14 @@ public class PDFGradientFactory extends GradientFactory<PDFPattern> { | |||
public Function makeFunction(int functionType, List<Double> theDomain, | |||
List<Double> theRange, List<Function> theFunctions, | |||
List<Double> theBounds, List<Double> theEncode) { | |||
PDFFunction newFunction = new PDFFunction(functionType, theDomain, theRange, theFunctions, | |||
theBounds, theEncode); | |||
newFunction = graphics2D.registerFunction(newFunction); | |||
return newFunction; | |||
return new Function(functionType, theDomain, theRange, theFunctions, theBounds, theEncode); | |||
} | |||
public Function makeFunction(int functionType, List<Double> theDomain, | |||
List<Double> theRange, List<Double> theCZero, List<Double> theCOne, | |||
double theInterpolationExponentN) { | |||
PDFFunction newFunction = new PDFFunction(functionType, theDomain, theRange, theCZero, | |||
Function newFunction = new Function(functionType, theDomain, theRange, theCZero, | |||
theCOne, theInterpolationExponentN); | |||
newFunction = graphics2D.registerFunction(newFunction); | |||
return newFunction; | |||
} | |||
@@ -57,8 +54,13 @@ public class PDFGradientFactory extends GradientFactory<PDFPattern> { | |||
PDFDeviceColorSpace theColorSpace, List<Double> theBackground, List<Double> theBBox, | |||
boolean theAntiAlias, List<Double> theCoords, List<Double> theDomain, | |||
Function theFunction, List<Integer> theExtend) { | |||
List<PDFFunction> pdfFunctions = new ArrayList<PDFFunction>(theFunction.getFunctions().size()); | |||
for (Function f : theFunction.getFunctions()) { | |||
pdfFunctions.add(graphics2D.registerFunction(new PDFFunction(f))); | |||
} | |||
PDFFunction pdfFunction = graphics2D.registerFunction(new PDFFunction(theFunction, pdfFunctions)); | |||
PDFShading newShading = new PDFShading(theShadingType, theColorSpace, theBackground, | |||
theBBox, theAntiAlias, theCoords, theDomain, theFunction, theExtend); | |||
theBBox, theAntiAlias, theCoords, theDomain, pdfFunction, theExtend); | |||
newShading = graphics2D.registerShading(newShading); | |||
return newShading; | |||
} |