return pattern;
}
- /**
- * Make a smooth shading pattern
- *
- * @param res the PDF resource context to add the shading, may be null
- * @param thePatternType the type of the pattern, which is 2, smooth shading
- * @param theShading the PDF Shading object that comprises this pattern
- * @param theXUID optional:the extended unique Identifier if used.
- * @param theExtGState optional: the extended graphics state, if used.
- * @param theMatrix Optional:List of Doubles that specify the matrix.
- * @return the PDF pattern that was created
- */
- public PDFPattern makePattern(PDFResourceContext res,
- int thePatternType, PDFShading theShading,
- List theXUID, StringBuffer theExtGState,
- List theMatrix) {
- PDFPattern pattern = new PDFPattern(2, theShading,
- theXUID, theExtGState, theMatrix);
-
- PDFPattern oldpatt = getDocument().findPattern(pattern);
- if (oldpatt == null) {
- getDocument().registerObject(pattern);
- } else {
- pattern = oldpatt;
- }
-
- if (res != null) {
- res.getPDFResources().addPattern(pattern);
- } else {
- getDocument().getResources().addPattern(pattern);
- }
-
- return (pattern);
- }
-
/* ============= named destinations and the name dictionary ============ */
import java.util.List;
import org.apache.fop.render.shading.Pattern;
-import org.apache.fop.render.shading.Shading;
/**
* class representing a PDF Function.
* Create a type 2 pattern (smooth shading)
*
* @param thePatternType the type of the pattern, which is 2, smooth shading
- * @param theShading the PDF Shading object that comprises this pattern
+ * @param shading the Shading object that comprises this pattern
* @param theXUID optional:the extended unique Identifier if used.
* @param theExtGState optional: the extended graphics state, if used.
* @param theMatrix Optional:List of Doubles that specify the matrix.
*/
- public PDFPattern(int thePatternType, Shading theShading,
+ public PDFPattern(int thePatternType, PDFShading shading,
List theXUID, StringBuffer theExtGState,
List theMatrix) {
super();
this.patternType = 2; // thePatternType;
- assert theShading instanceof PDFShading;
- this.shading = (PDFShading)theShading;
+ this.shading = shading;
this.xUID = theXUID;
// this isn't really implemented, so it should always be null.
// I just don't want to have to add a new parameter once it is implemented.
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;
+import org.apache.fop.render.shading.ShadingPattern.ShadingRenderer;
+
/**
* class representing a PDF Smooth Shading object.
*
* All PDF Functions have a shadingType (0,2,3, or 4), a Domain, and a Range.
*/
-public class PDFShading extends PDFObject implements Shading {
+public class PDFShading extends PDFObject {
// Guts common to all function types
/**
*/
protected String shadingName = null;
- /**
- * Required: The Type of shading (1,2,3,4,5,6,7)
- */
- protected int shadingType = 3; // Default
-
- /**
- * A ColorSpace representing the colorspace. "DeviceRGB" is an example.
- */
- protected PDFDeviceColorSpace colorSpace = null;
-
- /**
- * The background color. Since shading is opaque,
- * this is very rarely used.
- */
- protected List background = null;
-
- /**
- * Optional: A List specifying the clipping rectangle
- */
- protected List bBox = null;
-
- /**
- * Optional: A flag whether or not to filter the shading function
- * to prevent aliasing artifacts. Default is false.
- */
- protected boolean antiAlias = false;
-
- /**
- * Optional for Type 1: Array of four numbers, xmin, xmax, ymin, ymax.
- * Default is [0 1 0 1]
- * Optional for Type 2: An array of two numbers between which the blend
- * varies between start and end points. Default is 0, 1.
- * Optional for Type 3: An array of two numbers between which the blend
- * varies between start and end points. Default is 0, 1.
- */
- protected List domain = null;
-
- /**
- * Optional for Type 1: A transformation matrix
- */
- protected List matrix = null;
-
- /**
- * Required for Type 1, 2, and 3:
- * The object of the color mapping function (usually type 2 or 3).
- * Optional for Type 4,5,6, and 7: When it's nearly the same thing.
- */
- protected PDFFunction function = null;
+ private final Shading shading;
- /**
- * Required for Type 2: An Array of four numbers specifying
- * the starting and ending coordinate pairs
- * Required for Type 3: An Array of six numbers [x0,y0,r0,x1,y1,r1]
- * specifying the centers and radii of
- * the starting and ending circles.
- */
- protected List coords = null;
-
- /**
- * Required for Type 2+3: An Array of two boolean values specifying
- * whether to extend the start and end colors past the start
- * and end points, respectively.
- * Default is false, false.
- */
- protected List extend = null;
-
- /**
- * Required for Type 4,5,6, and 7: Specifies the number of bits used
- * to represent each vertex coordinate.
- * Allowed to be 1,2,4,8,12,16,24, or 32.
- */
- protected int bitsPerCoordinate = 0;
-
- /**
- * Required for Type 4,5,6, and 7: Specifies the number of bits used
- * to represent the edge flag for each vertex.
- * Allowed to be 2,4,or 8, while the Edge flag itself is allowed to
- * be 0,1 or 2.
- */
- protected int bitsPerFlag = 0;
-
- /**
- * 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
- */
- protected List decode = null;
-
- /**
- * Required for Type 4,5,6, and 7: Specifies the number of bits used
- * to represent each color coordinate.
- * Allowed to be 1,2,4,8,12, or 16
- */
- protected int bitsPerComponent = 0;
-
- /**
- * Required for Type 5:The number of vertices in each "row" of
- * the lattice; it must be greater than or equal to 2.
- */
- protected int verticesPerRow = 0;
-
- /**
- * Constructor for type function based shading
- *
- * @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
- */
- public PDFShading(int theShadingType, PDFDeviceColorSpace theColorSpace,
- List theBackground, List theBBox,
- boolean theAntiAlias, List theDomain,
- List theMatrix, PDFFunction theFunction) {
- super();
- this.shadingType = theShadingType; // 1
- this.colorSpace = theColorSpace;
- this.background = theBackground;
- this.bBox = theBBox;
- this.antiAlias = theAntiAlias;
-
- this.domain = theDomain;
- this.matrix = theMatrix;
- this.function = theFunction;
-
- }
+ private final PDFFunction pdfFunction;
/**
* Constructor for Type 2 and 3
*
- * @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,
+ * @param shadingType 2 or 3 for axial or radial shading
+ * @param colorSpace "DeviceRGB" or similar.
+ * @param coords List of four (type 2) or 6 (type 3) Double
+ * @param pdfFunction 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]
- */
- public PDFShading(int theShadingType, PDFDeviceColorSpace theColorSpace,
- List theBackground, List theBBox,
- boolean theAntiAlias, List theCoords,
- List theDomain, PDFFunction theFunction,
- List theExtend) {
- super();
- this.shadingType = theShadingType; // 2 or 3
- this.colorSpace = theColorSpace;
- this.background = theBackground;
- this.bBox = theBBox;
- this.antiAlias = theAntiAlias;
-
- this.coords = theCoords;
- this.domain = theDomain;
- this.function = theFunction;
- this.extend = theExtend;
-
- }
-
- /**
- * Constructor for Type 4,6, or 7
- *
- * @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
- */
- public PDFShading(int theShadingType, PDFDeviceColorSpace theColorSpace,
- List theBackground, List theBBox,
- boolean theAntiAlias, int theBitsPerCoordinate,
- int theBitsPerComponent, int theBitsPerFlag,
- List theDecode, PDFFunction theFunction) {
- super();
-
- this.shadingType = theShadingType; // 4,6 or 7
- this.colorSpace = theColorSpace;
- this.background = theBackground;
- this.bBox = theBBox;
- this.antiAlias = theAntiAlias;
-
- this.bitsPerCoordinate = theBitsPerCoordinate;
- this.bitsPerComponent = theBitsPerComponent;
- this.bitsPerFlag = theBitsPerFlag;
- this.decode = theDecode;
- this.function = theFunction;
- }
-
- /**
- * Constructor for type 5
- *
- * @param theShadingType 5 for lattice-Form Gouraud shaded-triangle mesh
- * @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
*/
- public PDFShading(int theShadingType, PDFDeviceColorSpace theColorSpace,
- List theBackground, List theBBox,
- boolean theAntiAlias, int theBitsPerCoordinate,
- int theBitsPerComponent, List theDecode,
- int theVerticesPerRow, PDFFunction theFunction) {
- super();
- this.shadingType = theShadingType; // 5
- this.colorSpace = theColorSpace;
- this.background = theBackground;
- this.bBox = theBBox;
- this.antiAlias = theAntiAlias;
-
- this.bitsPerCoordinate = theBitsPerCoordinate;
- this.bitsPerComponent = theBitsPerComponent;
- this.decode = theDecode;
- this.verticesPerRow = theVerticesPerRow;
- this.function = theFunction;
-
+ public PDFShading(int shadingType, PDFDeviceColorSpace colorSpace,
+ List coords, PDFFunction pdfFunction) {
+ shading = new Shading(shadingType, colorSpace, coords, pdfFunction.getFunction());
+ this.pdfFunction = pdfFunction;
}
/**
* @return the PDF string.
*/
public String toPDFString() {
- ShadingPattern pattern = new ShadingPattern(this);
- return pattern.toString(colorSpace, shadingType, background, bBox, antiAlias);
+ final ShadingRenderer shadingRenderer = new ShadingRenderer() {
+
+ public void outputFunction(StringBuffer out) {
+ Function function = shading.getFunction();
+ if (function != null) {
+ out.append("/Function ");
+ out.append(pdfFunction.referencePDF() + " \n");
+ }
+ }
+ };
+ ShadingPattern pattern = new ShadingPattern(shading, shadingRenderer);
+ return pattern.toString(shading.getColorSpace(), shading.getShadingType(), shading.getBackground(),
+ shading.getBBox(), shading.isAntiAlias());
}
/** {@inheritDoc} */
if (!(obj instanceof PDFShading)) {
return false;
}
- PDFShading shad = (PDFShading)obj;
- if (shadingType != shad.shadingType) {
+ Shading other = ((PDFShading) obj).shading;
+ if (shading.getShadingType() != other.getShadingType()) {
return false;
}
- if (antiAlias != shad.antiAlias) {
+ if (shading.isAntiAlias() != other.isAntiAlias()) {
return false;
}
- if (bitsPerCoordinate != shad.bitsPerCoordinate) {
+ if (shading.getBitsPerCoordinate() != other.getBitsPerCoordinate()) {
return false;
}
- if (bitsPerFlag != shad.bitsPerFlag) {
+ if (shading.getBitsPerFlag() != other.getBitsPerFlag()) {
return false;
}
- if (bitsPerComponent != shad.bitsPerComponent) {
+ if (shading.getBitsPerComponent() != other.getBitsPerComponent()) {
return false;
}
- if (verticesPerRow != shad.verticesPerRow) {
+ if (shading.getVerticesPerRow() != other.getVerticesPerRow()) {
return false;
}
- if (colorSpace != null) {
- if (!colorSpace.equals(shad.colorSpace)) {
+ if (shading.getColorSpace() != null) {
+ if (!shading.getColorSpace().equals(other.getColorSpace())) {
return false;
}
- } else if (shad.colorSpace != null) {
+ } else if (other.getColorSpace() != null) {
return false;
}
- if (background != null) {
- if (!background.equals(shad.background)) {
+ if (shading.getBackground() != null) {
+ if (!shading.getBackground().equals(other.getBackground())) {
return false;
}
- } else if (shad.background != null) {
+ } else if (other.getBackground() != null) {
return false;
}
- if (bBox != null) {
- if (!bBox.equals(shad.bBox)) {
+ if (shading.getBBox() != null) {
+ if (!shading.getBBox().equals(other.getBBox())) {
return false;
}
- } else if (shad.bBox != null) {
+ } else if (other.getBBox() != null) {
return false;
}
- if (domain != null) {
- if (!domain.equals(shad.domain)) {
+ if (shading.getDomain() != null) {
+ if (!shading.getDomain().equals(other.getDomain())) {
return false;
}
- } else if (shad.domain != null) {
+ } else if (other.getDomain() != null) {
return false;
}
- if (matrix != null) {
- if (!matrix.equals(shad.matrix)) {
+ if (shading.getMatrix() != null) {
+ if (!shading.getMatrix().equals(other.getMatrix())) {
return false;
}
- } else if (shad.matrix != null) {
+ } else if (other.getMatrix() != null) {
return false;
}
- if (coords != null) {
- if (!coords.equals(shad.coords)) {
+ if (shading.getCoords() != null) {
+ if (!shading.getCoords().equals(other.getCoords())) {
return false;
}
- } else if (shad.coords != null) {
+ } else if (other.getCoords() != null) {
return false;
}
- if (extend != null) {
- if (!extend.equals(shad.extend)) {
+ if (shading.getExtend() != null) {
+ if (!shading.getExtend().equals(other.getExtend())) {
return false;
}
- } else if (shad.extend != null) {
+ } else if (other.getExtend() != null) {
return false;
}
- if (decode != null) {
- if (!decode.equals(shad.decode)) {
+ if (shading.getDecode() != null) {
+ if (!shading.getDecode().equals(other.getDecode())) {
return false;
}
- } else if (shad.decode != null) {
+ } else if (other.getDecode() != null) {
return false;
}
- if (function != null) {
- if (!function.equals(shad.function)) {
+ if (shading.getFunction() != null) {
+ if (!shading.getFunction().equals(other.getFunction())) {
return false;
}
- } else if (shad.function != null) {
+ } else if (other.getFunction() != null) {
return false;
}
return true;
}
- /**
- * A method to write a type 1 shading object
- * @param p The StringBuffer to write the shading object
- * @return Returns the StringBuffer to which the shading object was written
- */
- public StringBuffer handleShadingType1(StringBuffer p) {
- if (this.domain != null) {
- p.append("/Domain [ ");
- for (int domainIndex = 0; domainIndex < domain.size(); domainIndex++) {
- p.append(PDFNumber.doubleOut((Double)this.domain.get(domainIndex))
- + " ");
- }
- p.append("] \n");
- } else {
- p.append("/Domain [ 0 1 ] \n");
- }
-
- if (this.matrix != null) {
- p.append("/Matrix [ ");
- for (int matrixIndex = 0; matrixIndex < matrix.size(); matrixIndex++) {
- p.append(PDFNumber.doubleOut((Double)this.matrix.get(matrixIndex))
- + " ");
- }
- p.append("] \n");
- }
-
- if (this.function != null) {
- p.append("/Function ");
- p.append(this.function.referencePDF() + " \n");
- }
- return p;
- }
-
- /**
- * A method to write a type 2 or 3 shading object
- * @param p The StringBuffer to write the shading object
- * @return Returns the StringBuffer to which the shading object was written
- */
- public StringBuffer handleShadingType2or3(StringBuffer p) {
- // 3 is radial shading (circular gradient)
- if (this.coords != null) {
- p.append("/Coords [ ");
- for (int coordIndex = 0; coordIndex < coords.size(); coordIndex++) {
- p.append(PDFNumber.doubleOut((Double)this.coords.get(coordIndex))
- + " ");
- }
- p.append("] \n");
- }
-
- // DOMAIN
- if (this.domain != null) {
- p.append("/Domain [ ");
- for (int domainIndex = 0; domainIndex < domain.size(); domainIndex++) {
- p.append(PDFNumber.doubleOut((Double)this.domain.get(domainIndex))
- + " ");
- }
- p.append("] \n");
- } else {
- p.append("/Domain [ 0 1 ] \n");
- }
-
- if (this.extend != null) {
- p.append("/Extend [ ");
- for (int extendIndex = 0; extendIndex < extend.size(); extendIndex++) {
- p.append((this.extend.get(extendIndex)) + " ");
- }
-
- p.append("] \n");
- } else {
- p.append("/Extend [ true true ] \n");
- }
-
-
- if (this.function != null) {
- p.append("/Function ");
- p.append(this.function.referencePDF() + " \n");
- }
-
- return p;
- }
-
- /**
- * A method to write a type 4, 6 or 7 shading object
- * @param p The StringBuffer to write the shading object
- * @return Returns the StringBuffer to which the shading object was written
- */
- public StringBuffer handleShadingType4or6or7(StringBuffer p) {
- // 6:coons patch meshes
- // 7://tensor product patch meshes (which no one ever uses)
- if (this.bitsPerCoordinate > 0) {
- p.append("/BitsPerCoordinate " + this.bitsPerCoordinate
- + " \n");
- } else {
- p.append("/BitsPerCoordinate 1 \n");
- }
-
- if (this.bitsPerComponent > 0) {
- p.append("/BitsPerComponent " + this.bitsPerComponent
- + " \n");
- } else {
- p.append("/BitsPerComponent 1 \n");
- }
-
- if (this.bitsPerFlag > 0) {
- p.append("/BitsPerFlag " + this.bitsPerFlag + " \n");
- } else {
- p.append("/BitsPerFlag 2 \n");
- }
-
- if (this.decode != null) {
- p.append("/Decode [ ");
- for (int decodeIndex = 0; decodeIndex < decode.size(); decodeIndex++) {
- p.append((this.decode.get(decodeIndex)) + " ");
- }
-
- p.append("] \n");
- }
-
- if (this.function != null) {
- p.append("/Function ");
- p.append(this.function.referencePDF() + " \n");
- }
-
- return p;
- }
-
- /**
- * A method to write a type 5 shading object
- * @param p The StringBuffer to write the shading object
- * @return Returns the StringBuffer to which the shading object was written
- */
- public StringBuffer handleShadingType5(StringBuffer p) {
- if (this.bitsPerCoordinate > 0) {
- p.append("/BitsPerCoordinate " + this.bitsPerCoordinate
- + " \n");
- } else {
- p.append("/BitsPerCoordinate 1 \n");
- }
-
- if (this.bitsPerComponent > 0) {
- p.append("/BitsPerComponent " + this.bitsPerComponent
- + " \n");
- } else {
- p.append("/BitsPerComponent 1 \n");
- }
-
- if (this.decode != null) {
- p.append("/Decode [ ");
- for (int decodeIndex = 0; decodeIndex < decode.size(); decodeIndex++) {
- p.append((this.decode.get(decodeIndex)) + " ");
- }
-
- p.append("] \n");
- }
-
- if (this.function != null) {
- p.append("/Function ");
- p.append(this.function.referencePDF() + " \n");
- }
-
- if (this.verticesPerRow > 0) {
- p.append("/VerticesPerRow " + this.verticesPerRow + " \n");
- } else {
- p.append("/VerticesPerRow 2 \n");
- }
-
- return p;
- }
}
import java.util.ArrayList;
import java.util.List;
-import org.apache.fop.pdf.PDFDeviceColorSpace;
import org.apache.fop.pdf.PDFFunction;
import org.apache.fop.pdf.PDFPattern;
import org.apache.fop.pdf.PDFShading;
}
@Override
- protected Shading makeShading(int shadingType, PDFDeviceColorSpace colorSpace,
- List<Double> coords, Function function) {
+ protected PDFPattern makePattern(int patternType, Shading shading, List<Double> matrix) {
+ Function function = shading.getFunction();
List<PDFFunction> pdfFunctions = new ArrayList<PDFFunction>(function.getFunctions().size());
for (Function f : function.getFunctions()) {
pdfFunctions.add(graphics2D.registerFunction(new PDFFunction(f)));
}
PDFFunction pdfFunction = graphics2D.registerFunction(new PDFFunction(function, pdfFunctions));
- PDFShading shading = new PDFShading(shadingType, colorSpace, null, null, false,
- coords, null, pdfFunction, null);
- return graphics2D.registerShading(shading);
- }
-
- @Override
- protected PDFPattern makePattern(int patternType, Shading shading, List<Double> matrix) {
- PDFPattern pattern = new PDFPattern(patternType, shading, null, null, matrix);
+ PDFShading pdfShading = new PDFShading(shading.getShadingType(), shading.getColorSpace(), shading.getCoords(),
+ pdfFunction);
+ pdfShading = graphics2D.registerShading(pdfShading);
+ PDFPattern pattern = new PDFPattern(patternType, pdfShading, null, null, matrix);
return graphics2D.registerPattern(pattern);
}
import java.util.List;
-import org.apache.fop.pdf.PDFDeviceColorSpace;
-import org.apache.fop.render.shading.Function;
import org.apache.fop.render.shading.GradientMaker;
import org.apache.fop.render.shading.Shading;
public class PSGradientMaker extends GradientMaker<PSPattern> {
- @Override
- protected Shading makeShading(int shadingType,
- PDFDeviceColorSpace colorSpace, List<Double> coords, Function function) {
- return new PSShading(shadingType, colorSpace, null, null, false, coords, null, function, null);
- }
-
@Override
protected PSPattern makePattern(int patternType, Shading shading, List<Double> matrix) {
return new PSPattern(patternType, shading, null, null, matrix);
package org.apache.fop.render.ps.svg;
+import java.util.ArrayList;
import java.util.List;
+import org.apache.fop.render.shading.Function;
+import org.apache.fop.render.shading.FunctionPattern;
import org.apache.fop.render.shading.Pattern;
import org.apache.fop.render.shading.Shading;
+import org.apache.fop.render.shading.ShadingPattern;
+import org.apache.fop.render.shading.ShadingPattern.ShadingRenderer;
public class PSPattern implements Pattern {
/**
* The Shading object comprising the Type 2 pattern
*/
- protected PSShading shading = null;
+ protected Shading shading;
/**
* List of Integers represetning the Extended unique Identifier
public PSPattern(int thePatternType, Shading theShading, List theXUID,
StringBuffer theExtGState, List<Double> matrix) {
this.patternType = 2; // thePatternType;
- assert theShading instanceof PSShading;
- this.shading = (PSShading)theShading;
+ this.shading = theShading;
this.xUID = theXUID;
this.extGState = theExtGState; // always null
this.matrix = matrix;
p.append("/PatternType " + this.patternType + " \n");
if (this.shading != null) {
- p.append("/Shading " + this.shading.toString() + " \n");
+ p.append("/Shading ");
+ outputShading(p);
+ p.append(" \n");
}
if (this.xUID != null) {
return p.toString();
}
+
+ private void outputShading(StringBuffer out) {
+ final Function function = shading.getFunction();
+ final ShadingRenderer shadingRenderer = new ShadingRenderer() {
+
+ public void outputFunction(StringBuffer out) {
+ out.append("/Function ");
+ FunctionPattern pattern = new FunctionPattern(function);
+ List<String> functionsStrings = new ArrayList<String>(function.getFunctions().size());
+ for (Function f : function.getFunctions()) {
+ functionsStrings.add(functionToString(f));
+ }
+ out.append(pattern.toWriteableString(functionsStrings));
+ out.append("\n");
+ }
+ };
+ ShadingPattern pattern = new ShadingPattern(shading, shadingRenderer);
+ out.append(pattern.toString(shading.getColorSpace(), shading.getShadingType(), shading.getBackground(),
+ shading.getBBox(), shading.isAntiAlias()));
+ }
+
+ private String functionToString(Function function) {
+ FunctionPattern pattern = new FunctionPattern(function);
+ List<String> functionsStrings = new ArrayList<String>(function.getFunctions().size());
+ for (Function f : function.getFunctions()) {
+ functionsStrings.add(functionToString(f));
+ }
+ return pattern.toWriteableString(functionsStrings);
+ }
+
}
+++ /dev/null
-/*
- * 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.render.ps.svg;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.fop.pdf.PDFDeviceColorSpace;
-import org.apache.fop.pdf.PDFNumber;
-import org.apache.fop.render.shading.Function;
-import org.apache.fop.render.shading.FunctionPattern;
-import org.apache.fop.render.shading.Shading;
-import org.apache.fop.render.shading.ShadingPattern;
-
-public class PSShading implements Shading {
-
- /**
- * Required: The Type of shading (1,2,3,4,5,6,7)
- */
- protected int shadingType = 3; // Default
-
- /**
- * A ColorSpace representing the colorspace. "DeviceRGB" is an example.
- */
- protected PDFDeviceColorSpace colorSpace = null;
-
- /**
- * The background color. Since shading is opaque,
- * this is very rarely used.
- */
- protected List background = null;
-
- /**
- * Optional: A List specifying the clipping rectangle
- */
- protected List bBox = null;
-
- /**
- * Optional: A flag whether or not to filter the shading function
- * to prevent aliasing artifacts. Default is false.
- */
- protected boolean antiAlias = false;
-
- /**
- * Optional for Type 1: Array of four numbers, xmin, xmax, ymin, ymax.
- * Default is [0 1 0 1]
- * Optional for Type 2: An array of two numbers between which the blend
- * varies between start and end points. Default is 0, 1.
- * Optional for Type 3: An array of two numbers between which the blend
- * varies between start and end points. Default is 0, 1.
- */
- protected List domain = null;
-
- /**
- * Required for Type 1, 2, and 3:
- * The object of the color mapping function (usually type 2 or 3).
- * Optional for Type 4,5,6, and 7: When it's nearly the same thing.
- */
- protected Function function;
-
- /**
- * Required for Type 2: An Array of four numbers specifying
- * the starting and ending coordinate pairs
- * Required for Type 3: An Array of six numbers [x0,y0,r0,x1,y1,r1]
- * specifying the centers and radii of
- * the starting and ending circles.
- */
- protected List coords = null;
-
- /**
- * Required for Type 2+3: An Array of two boolean values specifying
- * whether to extend the start and end colors past the start
- * and end points, respectively.
- * Default is false, false.
- */
- protected List extend = null;
-
- /**
- * Constructor for Type 2 and 3
- *
- * @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]
- */
- public PSShading(int theShadingType, PDFDeviceColorSpace theColorSpace,
- List<Double> theBackground, List<Double> theBBox,
- boolean theAntiAlias, List<Double> theCoords,
- List<Double> theDomain, Function theFunction,
- List<Integer> theExtend) {
- this.shadingType = theShadingType; // 2 or 3
- this.colorSpace = theColorSpace;
- this.background = theBackground;
- this.bBox = theBBox;
- this.antiAlias = theAntiAlias;
-
- this.coords = theCoords;
- this.domain = theDomain;
- this.function = theFunction;
- this.extend = theExtend;
- }
-
- /**
- * represent as PS. Whatever the shadingType is, the correct
- * representation spits out. The sets of required and optional
- * attributes are different for each type, but if a required
- * attribute's object was constructed as null, then no error
- * is raised. Instead, the malformed PS that was requested
- * by the construction is dutifully output.
- * This policy should be reviewed.
- *
- * @return the PDF string.
- */
- public String toString() {
- ShadingPattern pattern = new ShadingPattern(this);
- return pattern.toString(colorSpace, shadingType, background, bBox, antiAlias);
- }
-
- /**
- * A method to write a type 2 or 3 shading object
- * @param p The StringBuffer to write the shading object
- * @return Returns the StringBuffer to which the shading object was written
- */
- public StringBuffer handleShadingType2or3(StringBuffer p) {
- if (this.coords != null) {
- p.append("\t/Coords [ ");
- for (int coordIndex = 0; coordIndex < coords.size(); coordIndex++) {
- p.append(PDFNumber.doubleOut((Double)this.coords.get(coordIndex))
- + " ");
- }
- p.append("] \n");
- }
-
- // DOMAIN
- if (this.domain != null) {
- p.append("\t/Domain [ ");
- for (int domainIndex = 0; domainIndex < domain.size(); domainIndex++) {
- p.append(PDFNumber.doubleOut((Double)this.domain.get(domainIndex))
- + " ");
- }
- p.append("] \n");
- } else {
- p.append("\t/Domain [ 0 1 ] \n");
- }
-
- if (this.extend != null) {
- p.append("\t/Extend [ ");
- for (int extendIndex = 0; extendIndex < extend.size(); extendIndex++) {
- p.append((this.extend.get(extendIndex)) + " ");
- }
-
- p.append("] \n");
- } else {
- p.append("\t/Extend [ true true ] \n");
- }
-
-
- if (this.function != null) {
- p.append("\t/Function ");
- p.append(functionToString(function) + " \n");
- }
- return p;
- }
-
- private String functionToString(Function function) {
- FunctionPattern pattern = new FunctionPattern(function);
- List<String> functionsStrings = new ArrayList<String>(function.getFunctions().size());
- for (Function f : function.getFunctions()) {
- functionsStrings.add(functionToString(f));
- }
- return pattern.toWriteableString(functionsStrings);
- }
-
- /**
- * A method to write a type 1 shading object
- * @param p The StringBuffer to write the shading object
- * @return Returns the StringBuffer to which the shading object was written
- */
- public StringBuffer handleShadingType1(StringBuffer p) {
- // TODO Auto-generated method stub
- return null;
- }
-
- /**
- * A method to write a type 4, 6 or 7 shading object
- * @param p The StringBuffer to write the shading object
- * @return Returns the StringBuffer to which the shading object was written
- */
- public StringBuffer handleShadingType4or6or7(StringBuffer p) {
- // TODO Auto-generated method stub
- return null;
- }
-
- /**
- * A method to write a type 5 shading object
- * @param p The StringBuffer to write the shading object
- * @return Returns the StringBuffer to which the shading object was written
- */
- public StringBuffer handleShadingType5(StringBuffer p) {
- // TODO Auto-generated method stub
- return null;
- }
-}
// Gradients are currently restricted to sRGB
PDFDeviceColorSpace colorSpace = new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_RGB);
Function function = new Function(3, null, null, functions, bounds, null);
- Shading shading = makeShading(gradient instanceof LinearGradientPaint ? 2 : 3, colorSpace,
- coords, function);
+ int shadingType = gradient instanceof LinearGradientPaint ? 2 : 3;
+ Shading shading = new Shading(shadingType, colorSpace, coords, function);
return makePattern(2, shading, matrix);
}
return gradientColors;
}
- protected abstract Shading makeShading(int shadingType, PDFDeviceColorSpace colorSpace,
- List<Double> coords, Function function);
-
protected abstract P makePattern(int patternType, Shading shading, List<Double> matrix);
}
package org.apache.fop.render.shading;
+import java.util.List;
+
+import org.apache.fop.pdf.PDFDeviceColorSpace;
+
+
+public class Shading {
+
+ /**
+ * Required: The Type of shading (1,2,3,4,5,6,7)
+ */
+ private final int shadingType;
+
+ /**
+ * A ColorSpace representing the colorspace. "DeviceRGB" is an example.
+ */
+ private final PDFDeviceColorSpace colorSpace;
+
+ /**
+ * Required for Type 2: An Array of four numbers specifying
+ * the starting and ending coordinate pairs
+ * Required for Type 3: An Array of six numbers [x0,y0,r0,x1,y1,r1]
+ * specifying the centers and radii of
+ * the starting and ending circles.
+ */
+ private final List<Double> coords;
+
+ /**
+ * Required for Type 1, 2, and 3:
+ * The object of the color mapping function (usually type 2 or 3).
+ * Optional for Type 4,5,6, and 7: When it's nearly the same thing.
+ */
+ 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;
+
+ /**
+ * Optional for Type 1: Array of four numbers, xmin, xmax, ymin, ymax.
+ * Default is [0 1 0 1]
+ * Optional for Type 2: An array of two numbers between which the blend
+ * varies between start and end points. Default is 0, 1.
+ * Optional for Type 3: An array of two numbers between which the blend
+ * varies between start and end points. Default is 0, 1.
+ */
+ private final List<Double> domain;
+
+ /**
+ * 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
+ * whether to extend the start and end colors past the start
+ * and end points, respectively.
+ * Default is false, false.
+ */
+ private final List<Boolean> extend;
+
+ /**
+ * Required for Type 4,5,6, and 7: Specifies the number of bits used
+ * to represent each vertex coordinate.
+ * Allowed to be 1,2,4,8,12,16,24, or 32.
+ */
+ private final int bitsPerCoordinate;
+
+ /**
+ * Required for Type 4,5,6, and 7: Specifies the number of bits used
+ * to represent the edge flag for each vertex.
+ * Allowed to be 2,4,or 8, while the Edge flag itself is allowed to
+ * be 0,1 or 2.
+ */
+ private final int bitsPerFlag;
+
+ /**
+ * Optional: A flag whether or not to filter the shading function
+ * to prevent aliasing artifacts. Default is false.
+ */
+ private final boolean antiAlias;
+
+ /**
+ * Required for Type 4,5,6, and 7: Specifies the number of bits used
+ * to represent each color coordinate.
+ * Allowed to be 1,2,4,8,12, or 16
+ */
+ private final int bitsPerComponent;
+
+ /**
+ * Required for Type 5:The number of vertices in each "row" of
+ * the lattice; it must be greater than or equal to 2.
+ */
+ private final int verticesPerRow;
+
+ public Shading(int shadingType, PDFDeviceColorSpace colorSpace,
+ List<Double> coords, Function function) {
+ this.shadingType = shadingType;
+ this.colorSpace = colorSpace;
+ this.background = null;
+ this.bbox = null;
+ this.antiAlias = false;
+ this.coords = coords;
+ this.domain = null;
+ this.function = function;
+ this.extend = null;
+ this.matrix = null;
+ this.decode = null;
+ this.bitsPerCoordinate = 0;
+ this.bitsPerFlag = 0;
+ this.bitsPerComponent = 0;
+ this.verticesPerRow = 0;
+ }
+
+ public int getShadingType() {
+ return shadingType;
+ }
+
+ public PDFDeviceColorSpace getColorSpace() {
+ return colorSpace;
+ }
+
+ public List<Double> getCoords() {
+ return coords;
+ }
+
+ public Function getFunction() {
+ return function;
+ }
+
+ public List<Double> getBBox() {
+ return bbox;
+ }
+
+ public List<Double> getMatrix() {
+ return matrix;
+ }
+
+ public List<Double> getBackground() {
+ return background;
+ }
+
+ public List<Double> getDomain() {
+ return domain;
+ }
+
+ public List<Double> getDecode() {
+ return decode;
+ }
+
+ public List<Boolean> getExtend() {
+ return extend;
+ }
+
+ public int getBitsPerCoordinate() {
+ return bitsPerCoordinate;
+ }
+
+ public int getBitsPerFlag() {
+ return bitsPerFlag;
+ }
+
+ public boolean isAntiAlias() {
+ return antiAlias;
+ }
+
+ public int getBitsPerComponent() {
+ return bitsPerComponent;
+ }
+
+ public int getVerticesPerRow() {
+ return verticesPerRow;
+ }
-public interface Shading {
- StringBuffer handleShadingType1(StringBuffer p);
- StringBuffer handleShadingType2or3(StringBuffer p);
- StringBuffer handleShadingType4or6or7(StringBuffer p);
- StringBuffer handleShadingType5(StringBuffer p);
}
*/
public class ShadingPattern {
+ public interface ShadingRenderer {
+
+ void outputFunction(StringBuffer out);
+ }
+
private Shading shading;
+ private final ShadingRenderer shadingRenderer;
+
/**
* Constructor
* @param shading The shading object from which to write the output
*/
- public ShadingPattern(Shading shading) {
+ public ShadingPattern(Shading shading, ShadingRenderer shadingRenderer) {
this.shading = shading;
+ this.shadingRenderer = shadingRenderer;
}
/**
// Here's where we differentiate based on what type it is.
switch (shadingType) {
//Function based shading
- case 1: p = shading.handleShadingType1(p); break;
+ case 1: p = handleShadingType1(p); break;
//Axial shading
case 2:
//Radial shading
- case 3: p = shading.handleShadingType2or3(p); break;
+ case 3: p = handleShadingType2or3(p); break;
//Free-form Gouraud-shaded triangle meshes
case 4:
//Coons patch meshes
case 6:
//Tensor product patch meshes
- case 7: p = shading.handleShadingType4or6or7(p); break;
+ case 7: p = handleShadingType4or6or7(p); break;
//Lattice Free form gouraud-shaded triangle mesh
- case 5: p = shading.handleShadingType5(p); break;
+ case 5: p = handleShadingType5(p); break;
default: //Shading pattern outside expecting values
break;
}
return (p.toString());
}
+
+
+ /**
+ * A method to write a type 1 shading object
+ * @param p The StringBuffer to write the shading object
+ * @return Returns the StringBuffer to which the shading object was written
+ */
+ public StringBuffer handleShadingType1(StringBuffer p) {
+ if (shading.getDomain() != null) {
+ p.append("/Domain [ ");
+ for (int domainIndex = 0; domainIndex < shading.getDomain().size(); domainIndex++) {
+ p.append(PDFNumber.doubleOut((Double)shading.getDomain().get(domainIndex))
+ + " ");
+ }
+ p.append("] \n");
+ } else {
+ p.append("/Domain [ 0 1 ] \n");
+ }
+
+ if (shading.getMatrix() != null) {
+ p.append("/Matrix [ ");
+ for (int matrixIndex = 0; matrixIndex < shading.getMatrix().size(); matrixIndex++) {
+ p.append(PDFNumber.doubleOut((Double)shading.getMatrix().get(matrixIndex))
+ + " ");
+ }
+ p.append("] \n");
+ }
+ shadingRenderer.outputFunction(p);
+ return p;
+ }
+
+ /**
+ * A method to write a type 2 or 3 shading object
+ * @param p The StringBuffer to write the shading object
+ * @return Returns the StringBuffer to which the shading object was written
+ */
+ public StringBuffer handleShadingType2or3(StringBuffer p) {
+ // 3 is radial shading (circular gradient)
+ if (shading.getCoords() != null) {
+ p.append("/Coords [ ");
+ for (int coordIndex = 0; coordIndex < shading.getCoords().size(); coordIndex++) {
+ p.append(PDFNumber.doubleOut((Double)shading.getCoords().get(coordIndex))
+ + " ");
+ }
+ p.append("] \n");
+ }
+
+ // DOMAIN
+ if (shading.getDomain() != null) {
+ p.append("/Domain [ ");
+ for (int domainIndex = 0; domainIndex < shading.getDomain().size(); domainIndex++) {
+ p.append(PDFNumber.doubleOut((Double)shading.getDomain().get(domainIndex))
+ + " ");
+ }
+ p.append("] \n");
+ } else {
+ p.append("/Domain [ 0 1 ] \n");
+ }
+
+ if (shading.getExtend() != null) {
+ p.append("/Extend [ ");
+ for (int extendIndex = 0; extendIndex < shading.getExtend().size(); extendIndex++) {
+ p.append((shading.getExtend().get(extendIndex)) + " ");
+ }
+
+ p.append("] \n");
+ } else {
+ p.append("/Extend [ true true ] \n");
+ }
+
+ shadingRenderer.outputFunction(p);
+
+ return p;
+ }
+
+ /**
+ * A method to write a type 4, 6 or 7 shading object
+ * @param p The StringBuffer to write the shading object
+ * @return Returns the StringBuffer to which the shading object was written
+ */
+ public StringBuffer handleShadingType4or6or7(StringBuffer p) {
+ // 6:coons patch meshes
+ // 7://tensor product patch meshes (which no one ever uses)
+ if (shading.getBitsPerCoordinate() > 0) {
+ p.append("/BitsPerCoordinate " + shading.getBitsPerCoordinate()
+ + " \n");
+ } else {
+ p.append("/BitsPerCoordinate 1 \n");
+ }
+
+ if (shading.getBitsPerComponent() > 0) {
+ p.append("/BitsPerComponent " + shading.getBitsPerComponent()
+ + " \n");
+ } else {
+ p.append("/BitsPerComponent 1 \n");
+ }
+
+ if (shading.getBitsPerFlag() > 0) {
+ p.append("/BitsPerFlag " + shading.getBitsPerFlag() + " \n");
+ } else {
+ p.append("/BitsPerFlag 2 \n");
+ }
+
+ if (shading.getDecode() != null) {
+ p.append("/Decode [ ");
+ for (int decodeIndex = 0; decodeIndex < shading.getDecode().size(); decodeIndex++) {
+ p.append((shading.getDecode().get(decodeIndex)) + " ");
+ }
+
+ p.append("] \n");
+ }
+
+ shadingRenderer.outputFunction(p);
+
+ return p;
+ }
+
+ /**
+ * A method to write a type 5 shading object
+ * @param p The StringBuffer to write the shading object
+ * @return Returns the StringBuffer to which the shading object was written
+ */
+ public StringBuffer handleShadingType5(StringBuffer p) {
+ if (shading.getBitsPerCoordinate() > 0) {
+ p.append("/BitsPerCoordinate " + shading.getBitsPerCoordinate()
+ + " \n");
+ } else {
+ p.append("/BitsPerCoordinate 1 \n");
+ }
+
+ if (shading.getBitsPerComponent() > 0) {
+ p.append("/BitsPerComponent " + shading.getBitsPerComponent()
+ + " \n");
+ } else {
+ p.append("/BitsPerComponent 1 \n");
+ }
+
+ if (shading.getDecode() != null) {
+ p.append("/Decode [ ");
+ for (int decodeIndex = 0; decodeIndex < shading.getDecode().size(); decodeIndex++) {
+ p.append((shading.getDecode().get(decodeIndex)) + " ");
+ }
+
+ p.append("] \n");
+ }
+
+ shadingRenderer.outputFunction(p);
+
+ if (shading.getVerticesPerRow() > 0) {
+ p.append("/VerticesPerRow " + shading.getVerticesPerRow() + " \n");
+ } else {
+ p.append("/VerticesPerRow 2 \n");
+ }
+
+ return p;
+ }
+
}