You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by lb...@apache.org on 2013/11/13 16:24:27 UTC

svn commit: r1541551 [2/3] - in /xmlgraphics/fop/trunk: ./ lib/ src/java/org/apache/fop/pdf/ src/java/org/apache/fop/render/ps/ src/java/org/apache/fop/render/ps/svg/ src/java/org/apache/fop/render/shading/ src/java/org/apache/fop/svg/ test/java/org/ap...

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/svg/PSSVGGraphics2D.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/svg/PSSVGGraphics2D.java?rev=1541551&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/svg/PSSVGGraphics2D.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/svg/PSSVGGraphics2D.java Wed Nov 13 15:24:26 2013
@@ -0,0 +1,291 @@
+/*
+ * 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.awt.Color;
+import java.awt.Graphics;
+import java.awt.Paint;
+import java.awt.geom.AffineTransform;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.batik.ext.awt.LinearGradientPaint;
+import org.apache.batik.ext.awt.MultipleGradientPaint;
+import org.apache.batik.ext.awt.RadialGradientPaint;
+
+import org.apache.xmlgraphics.java2d.ps.PSGraphics2D;
+import org.apache.xmlgraphics.ps.PSGenerator;
+
+import org.apache.fop.pdf.PDFDeviceColorSpace;
+import org.apache.fop.render.shading.Function;
+import org.apache.fop.render.shading.GradientFactory;
+import org.apache.fop.render.shading.GradientRegistrar;
+import org.apache.fop.render.shading.PSGradientFactory;
+import org.apache.fop.render.shading.Pattern;
+import org.apache.fop.render.shading.Shading;
+
+
+public class PSSVGGraphics2D extends PSGraphics2D implements GradientRegistrar {
+
+    private static final Log LOG = LogFactory.getLog(PSSVGGraphics2D.class);
+
+    /**
+     * Create a new Graphics2D that generates PostScript code.
+     * @param textAsShapes True if text should be rendered as graphics
+     * @see org.apache.xmlgraphics.java2d.AbstractGraphics2D#AbstractGraphics2D(boolean)
+     */
+    public PSSVGGraphics2D(boolean textAsShapes) {
+        super(textAsShapes);
+    }
+
+    /**
+     * Create a new Graphics2D that generates PostScript code.
+     * @param textAsShapes True if text should be rendered as graphics
+     * @param gen PostScript generator to use for output
+     * @see org.apache.xmlgraphics.java2d.AbstractGraphics2D#AbstractGraphics2D(boolean)
+     */
+    public PSSVGGraphics2D(boolean textAsShapes, PSGenerator gen) {
+        super(textAsShapes, gen);
+    }
+
+    /**
+     * Constructor for creating copies
+     * @param g parent PostScript Graphics2D
+     */
+    public PSSVGGraphics2D(PSGraphics2D g) {
+        super(g);
+    }
+
+    protected void applyPaint(Paint paint, boolean fill) {
+        super.applyPaint(paint, fill);
+        if (paint instanceof RadialGradientPaint) {
+            RadialGradientPaint rgp = (RadialGradientPaint)paint;
+            try {
+                handleRadialGradient(rgp, gen);
+            } catch (IOException ioe) {
+                handleIOException(ioe);
+            }
+        } else if (paint instanceof LinearGradientPaint) {
+            LinearGradientPaint lgp = (LinearGradientPaint)paint;
+            try {
+                handleLinearGradient(lgp, gen);
+            } catch (IOException ioe) {
+                handleIOException(ioe);
+            }
+        }
+    }
+
+    private void handleLinearGradient(LinearGradientPaint lgp, PSGenerator gen) throws IOException {
+        MultipleGradientPaint.CycleMethodEnum cycle = lgp.getCycleMethod();
+        if (cycle != MultipleGradientPaint.NO_CYCLE) {
+            return;
+        }
+        float[] fractions = lgp.getFractions();
+        Color[] cols = lgp.getColors();
+
+        AffineTransform transform = new AffineTransform(getBaseTransform());
+        transform.concatenate(getTransform());
+        transform.concatenate(lgp.getTransform());
+
+        List theMatrix = new ArrayList();
+        double [] mat = new double[6];
+        transform.getMatrix(mat);
+        for (int idx = 0; idx < mat.length; idx++) {
+            theMatrix.add(Double.valueOf(mat[idx]));
+        }
+
+
+        List<Double> theCoords = new java.util.ArrayList<Double>();
+
+
+        AffineTransform start = applyTransform(lgp.getTransform(), lgp.getStartPoint().getX(), lgp.getStartPoint().getY());
+        AffineTransform end = applyTransform(lgp.getTransform(), lgp.getEndPoint().getX(), lgp.getEndPoint().getY());
+        double startX = start.getTranslateX();
+        double startY = start.getTranslateY();
+        double endX = end.getTranslateX();
+        double endY = end.getTranslateY();
+
+        double width = endX - startX;
+        double height = endY - startY;
+
+        startX = startX + width * fractions[0];
+        endX = endX - width * (1 - fractions[fractions.length - 1]);
+        startY = startY + (height * fractions[0]);
+        endY =  endY - height * (1 - fractions[fractions.length - 1]);
+
+        theCoords.add(startX);
+        theCoords.add(startY);
+        theCoords.add(endX);
+        theCoords.add(endY);
+
+
+        List<Color> someColors = new java.util.ArrayList<Color>();
+        for (int count = 0; count < cols.length; count++) {
+            Color c1 = cols[count];
+            if (c1.getAlpha() != 255) {
+                LOG.warn("Opacity is not currently supported for Postscript output");
+            }
+            someColors.add(c1);
+        }
+        List<Double> theBounds = new java.util.ArrayList<Double>();
+        for (int count = 1; count < fractions.length - 1; count++) {
+            float offset = fractions[count];
+            theBounds.add(Double.valueOf(offset));
+        }
+        PDFDeviceColorSpace colSpace;
+        colSpace = new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_RGB);
+
+        PSGradientFactory gradientFactory = (PSGradientFactory)GradientFactory.newInstance(this);
+        PSPattern myPattern = gradientFactory.createGradient(false, colSpace,
+                someColors, theBounds, theCoords, theMatrix);
+
+        gen.write(myPattern.toString());
+
+    }
+
+
+
+    private void handleRadialGradient(RadialGradientPaint rgp, PSGenerator gen) throws IOException {
+        MultipleGradientPaint.CycleMethodEnum cycle = rgp.getCycleMethod();
+        if (cycle != MultipleGradientPaint.NO_CYCLE) {
+            return;
+        }
+
+        AffineTransform transform;
+        transform = new AffineTransform(getBaseTransform());
+        transform.concatenate(getTransform());
+        transform.concatenate(rgp.getTransform());
+
+        AffineTransform resultCentre = applyTransform(rgp.getTransform(), rgp.getCenterPoint().getX(), rgp.getCenterPoint().getY());
+        AffineTransform resultFocus = applyTransform(rgp.getTransform(), rgp.getFocusPoint().getX(), rgp.getFocusPoint().getY());
+        double scale = Math.sqrt(rgp.getTransform().getDeterminant());
+        double radius = rgp.getRadius() * scale;
+        double centreX = resultCentre.getTranslateX();
+        double centreY = resultCentre.getTranslateY();
+        double focusX = resultFocus.getTranslateX();
+        double focusY = resultFocus.getTranslateY();
+
+        List<Double> theMatrix = new java.util.ArrayList<Double>();
+        double [] mat = new double[6];
+        transform.getMatrix(mat);
+        for (int idx = 0; idx < mat.length; idx++) {
+            theMatrix.add(Double.valueOf(mat[idx]));
+        }
+
+        List<Double> theCoords = new java.util.ArrayList<Double>();
+        float[] fractions = rgp.getFractions();
+
+        theCoords.add(centreX);
+        theCoords.add(centreY);
+        theCoords.add(radius * rgp.getFractions()[0]);
+        theCoords.add(focusX);
+        theCoords.add(focusY);
+        theCoords.add(radius * fractions[fractions.length - 1]);
+
+        Color[] cols = rgp.getColors();
+        List<Color> someColors = new java.util.ArrayList<Color>();
+        for (int count = 0; count < cols.length; count++) {
+            Color cc = cols[count];
+            if (cc.getAlpha() != 255) {
+                /* This should never happen because radial gradients with opacity should now
+                 * be rasterized in the PSImageHandlerSVG class. Please see the shouldRaster()
+                 * method for more information. */
+                LOG.warn("Opacity is not currently supported for Postscript output");
+            }
+
+            someColors.add(cc);
+        }
+
+        List<Double> theBounds = new java.util.ArrayList<Double>();
+        for (int count = 1; count < fractions.length - 1; count++) {
+            float offset = fractions[count];
+            theBounds.add(Double.valueOf(offset));
+        }
+        PDFDeviceColorSpace colSpace;
+        colSpace = new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_RGB);
+
+        PSGradientFactory gradientFactory = (PSGradientFactory)GradientFactory.newInstance(this);
+        PSPattern myPattern = gradientFactory.createGradient(true, colSpace,
+                someColors, theBounds, theCoords, theMatrix);
+
+        gen.write(myPattern.toString());
+    }
+
+    private AffineTransform applyTransform(AffineTransform base, double posX, double posY) {
+        AffineTransform result = AffineTransform.getTranslateInstance(posX, posY);
+        AffineTransform orig = base;
+        orig.concatenate(result);
+        return orig;
+    }
+
+    protected AffineTransform getBaseTransform() {
+        AffineTransform at = new AffineTransform(this.getTransform());
+        return at;
+    }
+
+    /**
+     * Creates a new <code>Graphics</code> object that is
+     * a copy of this <code>Graphics</code> object.
+     * @return     a new graphics context that is a copy of
+     * this graphics context.
+     */
+    @Override
+    public Graphics create() {
+        preparePainting();
+        return new PSSVGGraphics2D(this);
+    }
+
+    /**
+     * Registers a function object against the output format document
+     * @param function The function object to register
+     * @return Returns either the function which has already been registered
+     * or the current new registered object.
+     */
+    public Function registerFunction(Function function) {
+        //Objects aren't needed to be registered in Postscript
+        return function;
+    }
+
+    /**
+     * Registers a shading object against the otuput format document
+     * @param shading The shading object to register
+     * @return Returs either the shading which has already been registered
+     * or the current new registered object
+     */
+    public Shading registerShading(Shading shading) {
+        //Objects aren't needed to be registered in Postscript
+        return shading;
+    }
+
+    /**
+     * Registers a pattern object against the output format document
+     * @param pattern The pattern object to register
+     * @return Returns either the pattern which has already been registered
+     * or the current new registered object
+     */
+    public Pattern registerPattern(Pattern pattern) {
+        // TODO Auto-generated method stub
+        return pattern;
+    }
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/svg/PSSVGGraphics2D.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/svg/PSShading.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/svg/PSShading.java?rev=1541551&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/svg/PSShading.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/svg/PSShading.java Wed Nov 13 15:24:26 2013
@@ -0,0 +1,228 @@
+/*
+ * 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.io.UnsupportedEncodingException;
+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.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 PSFunction function = null;
+
+    /**
+     * 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;
+        assert theFunction instanceof PSFunction;
+        this.function = (PSFunction)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 ");
+            try {
+                p.append(new String(this.function.toByteString(), "UTF-8") + " \n");
+            } catch (UnsupportedEncodingException ex) {
+                //This should have been made an enum type to avoid throwing exceptions.
+            }
+        }
+        return p;
+    }
+
+    /**
+     * 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;
+    }
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/svg/PSShading.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/Function.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/Function.java?rev=1541551&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/Function.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/Function.java Wed Nov 13 15:24:26 2013
@@ -0,0 +1,39 @@
+/*
+ * 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 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();
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/Function.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/FunctionDelegate.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/FunctionDelegate.java?rev=1541551&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/FunctionDelegate.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/FunctionDelegate.java Wed Nov 13 15:24:26 2013
@@ -0,0 +1,451 @@
+/*
+ * 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();
+    }
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/FunctionDelegate.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/FunctionPattern.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/FunctionPattern.java?rev=1541551&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/FunctionPattern.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/FunctionPattern.java Wed Nov 13 15:24:26 2013
@@ -0,0 +1,363 @@
+/*
+ * 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.shading;
+
+import java.io.UnsupportedEncodingException;
+
+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
+ */
+public class FunctionPattern {
+
+    private Function function;
+
+    /**
+     * Constructor
+     * @param function The function from which to write the output
+     */
+    public FunctionPattern(Function function) {
+        this.function = function;
+    }
+
+    /**
+     * Outputs the function to a byte array
+     */
+    public String toWriteableString() {
+        int vectorSize = 0;
+        int numberOfFunctions = 0;
+        int tempInt = 0;
+        StringBuffer p = new StringBuffer(256);
+        p.append("<< \n/FunctionType " + function.getFunctionType() + " \n");
+
+        // FunctionType 0
+        if (this.function.getFunctionType() == 0) {
+            if (function.getDomain() != null) {
+                // DOMAIN
+                p.append("/Domain [ ");
+                vectorSize = function.getDomain().size();
+                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
+                    p.append(PDFNumber.doubleOut(function.getDomain().get(tempInt))
+                             + " ");
+                }
+
+                p.append("] \n");
+            } else {
+                p.append("/Domain [ 0 1 ] \n");
+            }
+
+            // SIZE
+            if (function.getSize() != null) {
+                p.append("/Size [ ");
+                vectorSize = function.getSize().size();
+                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
+                    p.append(PDFNumber.doubleOut(function.getSize().get(tempInt))
+                             + " ");
+                }
+                p.append("] \n");
+            }
+            // ENCODE
+            if (function.getEncode() != null) {
+                p.append("/Encode [ ");
+                vectorSize = function.getEncode().size();
+                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
+                    p.append(PDFNumber.doubleOut(function.getEncode().get(tempInt))
+                             + " ");
+                }
+                p.append("] \n");
+            } else {
+                p.append("/Encode [ ");
+                vectorSize = function.getFunctions().size();
+                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
+                    p.append("0 1 ");
+                }
+                p.append("] \n");
+
+            }
+
+            // BITSPERSAMPLE
+            p.append("/BitsPerSample " + function.getBitsPerSample());
+
+            // ORDER (optional)
+            if (function.getOrder() == 1 || function.getOrder() == 3) {
+                p.append(" \n/Order " + function.getOrder() + " \n");
+            }
+
+            // RANGE
+            if (function.getRange() != null) {
+                p.append("/Range [ ");
+                vectorSize = function.getRange().size();
+                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
+                    p.append(PDFNumber.doubleOut(function.getRange().get(tempInt))
+                             + " ");
+                }
+
+                p.append("] \n");
+            }
+
+            // DECODE
+            if (function.getDecode() != null) {
+                p.append("/Decode [ ");
+                vectorSize = function.getDecode().size();
+                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
+                    p.append(PDFNumber.doubleOut(function.getDecode().get(tempInt))
+                             + " ");
+                }
+
+                p.append("] \n");
+            }
+
+            // LENGTH
+            if (function.getDataStream() != null) {
+                p.append("/Length " + (function.getDataStream().length() + 1)
+                         + " \n");
+            }
+
+            // FILTER?
+            if (function.getFilter() != null) {           // if there's a filter
+                vectorSize = function.getFilter().size();
+                p.append("/Filter ");
+                if (vectorSize == 1) {
+                    p.append("/" + (function.getFilter().get(0))
+                             + " \n");
+                } else {
+                    p.append("[ ");
+                    for (tempInt = 0; tempInt < vectorSize; tempInt++) {
+                        p.append("/" + (function.getFilter().get(0))
+                                 + " ");
+                    }
+                    p.append("] \n");
+                }
+            }
+            p.append(">>");
+
+            // stream representing the function
+            if (function.getDataStream() != null) {
+                p.append("\nstream\n" + function.getDataStream()
+                         + "\nendstream");
+            }
+
+            // end of if FunctionType 0
+
+        } else if (function.getFunctionType() == 2) {
+            // DOMAIN
+            if (function.getDomain() != null) {
+                p.append("/Domain [ ");
+                vectorSize = function.getDomain().size();
+                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
+                    p.append(PDFNumber.doubleOut(function.getDomain().get(tempInt))
+                             + " ");
+                }
+
+                p.append("] \n");
+            } else {
+                p.append("/Domain [ 0 1 ] \n");
+            }
+
+
+            // RANGE
+            if (function.getRange() != null) {
+                p.append("/Range [ ");
+                vectorSize = function.getRange().size();
+                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
+                    p.append(PDFNumber.doubleOut(function.getRange().get(tempInt))
+                             + " ");
+                }
+
+                p.append("] \n");
+            }
+
+            // FunctionType, C0, C1, N are required in PDF
+
+            // C0
+            if (function.getCZero() != null) {
+                p.append("/C0 [ ");
+                vectorSize = function.getCZero().size();
+                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
+                    p.append(PDFNumber.doubleOut(function.getCZero().get(tempInt))
+                             + " ");
+                }
+                p.append("] \n");
+            }
+
+            // C1
+            if (function.getCOne() != null) {
+                p.append("/C1 [ ");
+                vectorSize = function.getCOne().size();
+                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
+                    p.append(PDFNumber.doubleOut(function.getCOne().get(tempInt))
+                             + " ");
+                }
+                p.append("] \n");
+            }
+
+            // N: The interpolation Exponent
+            p.append("/N "
+                     + PDFNumber.doubleOut(Double.valueOf(function.getInterpolationExponentN()))
+                     + " \n");
+
+            p.append(">>");
+
+        } else if (function.getFunctionType()
+                   == 3) {                       // fix this up when my eyes uncross
+            // DOMAIN
+            if (function.getDomain() != null) {
+                p.append("/Domain [ ");
+                vectorSize = function.getDomain().size();
+                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
+                    p.append(PDFNumber.doubleOut(function.getDomain().get(tempInt))
+                             + " ");
+                }
+                p.append("] \n");
+            } else {
+                p.append("/Domain [ 0 1 ] \n");
+            }
+
+            // RANGE
+            if (function.getRange() != null) {
+                p.append("/Range [ ");
+                vectorSize = function.getRange().size();
+                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
+                    p.append(PDFNumber.doubleOut(function.getRange().get(tempInt))
+                             + " ");
+                }
+
+                p.append("] \n");
+            }
+
+            // FUNCTIONS
+            if (function.getFunctions() != null) {
+                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.
+                    }
+                }
+                p.append("] \n");
+            }
+
+
+            // ENCODE
+            if (function.getEncode() != null) {
+                p.append("/Encode [ ");
+                vectorSize = function.getEncode().size();
+                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
+                    p.append(PDFNumber.doubleOut(function.getEncode().get(tempInt))
+                             + " ");
+                }
+
+                p.append("] \n");
+            } else {
+                p.append("/Encode [ ");
+                vectorSize = function.getFunctions().size();
+                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
+                    p.append("0 1 ");
+                }
+                p.append("] \n");
+
+            }
+
+
+            // BOUNDS, required, but can be empty
+            p.append("/Bounds [ ");
+            if (function.getBounds() != null) {
+
+                vectorSize = function.getBounds().size();
+                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
+                    p.append(PDFNumber.doubleOut(function.getBounds().get(tempInt))
+                             + " ");
+                }
+
+            } else {
+                if (function.getFunctions() != null) {
+                    // if there are n functions,
+                    // there must be n-1 bounds.
+                    // so let each function handle an equal portion
+                    // of the whole. e.g. if there are 4, then [ 0.25 0.25 0.25 ]
+
+                    String functionsFraction = PDFNumber.doubleOut(Double.valueOf(1.0
+                            / (numberOfFunctions)));
+
+                    for (tempInt = 0; tempInt + 1 < numberOfFunctions;
+                            tempInt++) {
+
+                        p.append(functionsFraction + " ");
+                    }
+                }
+
+            }
+            p.append("]\n>>");
+        } else if (function.getFunctionType()
+                   == 4) {                       // fix this up when my eyes uncross
+            // DOMAIN
+            if (function.getDomain() != null) {
+                p.append("/Domain [ ");
+                vectorSize = function.getDomain().size();
+                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
+                    p.append(PDFNumber.doubleOut(function.getDomain().get(tempInt))
+                             + " ");
+                }
+
+                p.append("] \n");
+            } else {
+                p.append("/Domain [ 0 1 ] \n");
+            }
+
+            // RANGE
+            if (function.getRange() != null) {
+                p.append("/Range [ ");
+                vectorSize = function.getRange().size();
+                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
+                    p.append(PDFNumber.doubleOut(function.getRange().get(tempInt))
+                             + " ");
+                }
+
+                p.append("] \n");
+            }
+
+            // LENGTH
+            if (function.getDataStream() != null) {
+                p.append("/Length " + (function.getDataStream().length() + 1)
+                         + " \n");
+            }
+
+            p.append(">>");
+
+            // stream representing the function
+            if (function.getDataStream() != null) {
+                p.append("\nstream\n{ " + function.getDataStream()
+                         + " }\nendstream");
+            }
+        }
+        return p.toString();
+    }
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/FunctionPattern.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/GradientFactory.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/GradientFactory.java?rev=1541551&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/GradientFactory.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/GradientFactory.java Wed Nov 13 15:24:26 2013
@@ -0,0 +1,162 @@
+/*
+ * 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.shading;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.xmlgraphics.java2d.color.ColorUtil;
+
+import org.apache.fop.pdf.PDFDeviceColorSpace;
+import org.apache.fop.render.ps.svg.PSSVGGraphics2D;
+
+public abstract class GradientFactory {
+
+    static GradientRegistrar registrar;
+
+    /**
+     * Constructor
+     * @param registrar The object used to register new embedded objects in the
+     * output format.
+     */
+    public static GradientFactory newInstance(GradientRegistrar theRegistrar) {
+        registrar = theRegistrar;
+        if (registrar instanceof PSSVGGraphics2D) {
+            return new PSGradientFactory();
+        } else {
+            return new PDFGradientFactory();
+        }
+    }
+
+    /**
+     * Creates a new gradient
+     * @param radial Determines whether the gradient is radial
+     * @param theColorspace The colorspace used in PDF and Postscript
+     * @param theColors The colors to be used in the gradient
+     * @param theBounds The bounds of each color
+     * @param theCoords The co-ordinates of the gradient
+     * @param theMatrix The matrix for any transformations
+     * @return Returns the Pattern object of the gradient
+     */
+    public abstract Pattern createGradient(boolean radial,
+            PDFDeviceColorSpace theColorspace, List<Color> theColors, List<Double> theBounds,
+            List<Double> theCoords, List<Double> theMatrix);
+
+    protected Pattern makeGradient(boolean radial, PDFDeviceColorSpace theColorspace,
+                                   List<Color> theColors, List<Double> theBounds,
+                                   List<Double> theCoords, List<Double> theMatrix) {
+        Shading myShad;
+        Function myfunky;
+        Function myfunc;
+        List<Double> theCzero;
+        List<Double> theCone;
+        double interpolation = 1.000;
+        List<Function> theFunctions = new ArrayList<Function>();
+
+        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 = theColors.get(currentPosition);
+            Color nextColor = 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) {
+                // make Shading of Type 2 or 3
+                myShad = makeShading(3, theColorspace, 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<Double> newCoords = new ArrayList<Double>();
+                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(Double.valueOf(0.0));
+
+                myShad = makeShading(3, theColorspace, null, null, false, newCoords,
+                        null, myfunky, null);
+            }
+        } else {
+            myShad = makeShading(2, theColorspace, null, null, false, theCoords,
+                    null, myfunky, null);
+        }
+        return makePattern(2, myShad, null, null, theMatrix);
+    }
+
+    public abstract Function makeFunction(int functionType, List<Double> theDomain,
+            List<Double> theRange, List<Function> theFunctions,
+            List<Double> theBounds, List<Double> theEncode);
+
+    public abstract Function makeFunction(int functionType, List<Double> theDomain,
+            List<Double> theRange, List<Double> theCZero, List<Double> theCOne,
+            double theInterpolationExponentN);
+
+    public abstract Shading makeShading(int theShadingType,
+            PDFDeviceColorSpace theColorSpace, List<Double> theBackground, List<Double> theBBox,
+            boolean theAntiAlias, List<Double> theCoords, List<Double> theDomain,
+            Function theFunction, List<Integer> theExtend);
+
+    public abstract Pattern makePattern(int thePatternType, Shading theShading, List theXUID,
+            StringBuffer theExtGState, List<Double> theMatrix);
+
+    private List<Double> toColorVector(Color nextColor) {
+        List<Double> vector = new java.util.ArrayList<Double>();
+        float[] comps = nextColor.getColorComponents(null);
+        for (int i = 0, c = comps.length; i < c; i++) {
+            vector.add(Double.valueOf(comps[i]));
+        }
+        return vector;
+    }
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/GradientFactory.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/GradientRegistrar.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/GradientRegistrar.java?rev=1541551&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/GradientRegistrar.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/GradientRegistrar.java Wed Nov 13 15:24:26 2013
@@ -0,0 +1,45 @@
+/*
+ * 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;
+
+public interface GradientRegistrar {
+
+    /**
+     * Registers a function object against the output format document
+     * @param function The function object to register
+     * @return Returns either the function which has already been registered
+     * or the current new registered object.
+     */
+    Function registerFunction(Function function);
+
+    /**
+     * Registers a shading object against the output format document
+     * @param shading The shading object to register
+     * @return Returns either the shading which has already been registered
+     * or the current new registered object
+     */
+    Shading registerShading(Shading shading);
+
+    /**
+     * Registers a pattern object against the output format document
+     * @param pattern The pattern object to register
+     * @return Returns either the pattern which has already been registered
+     * or the current new registered object
+     */
+    Pattern registerPattern(Pattern pattern);
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/GradientRegistrar.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/PDFGradientFactory.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/PDFGradientFactory.java?rev=1541551&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/PDFGradientFactory.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/PDFGradientFactory.java Wed Nov 13 15:24:26 2013
@@ -0,0 +1,76 @@
+/*
+ * 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.awt.Color;
+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;
+
+public class PDFGradientFactory extends GradientFactory {
+
+    @Override
+    public PDFPattern createGradient(boolean radial, PDFDeviceColorSpace theColorspace, List<Color> theColors,
+            List<Double> theBounds, List<Double> theCoords, List<Double> theMatrix) {
+        return (PDFPattern)makeGradient(radial, theColorspace, theColors, theBounds,
+                theCoords, theMatrix);
+    }
+
+    @Override
+    public Function makeFunction(int functionType, List<Double> theDomain,
+            List<Double> theRange, List<Function> theFunctions,
+            List<Double> theBounds, List<Double> theEncode) {
+        Function newFunction = new PDFFunction(functionType, theDomain, theRange, theFunctions,
+                    theBounds, theEncode);
+        newFunction = registrar.registerFunction(newFunction);
+        return newFunction;
+    }
+
+    public Function makeFunction(int functionType, List<Double> theDomain,
+            List<Double> theRange, List<Double> theCZero, List<Double> theCOne,
+            double theInterpolationExponentN) {
+        Function newFunction = new PDFFunction(functionType, theDomain, theRange, theCZero,
+                    theCOne, theInterpolationExponentN);
+        newFunction = registrar.registerFunction(newFunction);
+        return newFunction;
+    }
+
+    @Override
+    public Shading makeShading(int theShadingType,
+            PDFDeviceColorSpace theColorSpace, List<Double> theBackground, List<Double> theBBox,
+            boolean theAntiAlias, List<Double> theCoords, List<Double> theDomain,
+            Function theFunction, List<Integer> theExtend) {
+        Shading newShading = new PDFShading(theShadingType, theColorSpace, theBackground,
+                    theBBox, theAntiAlias, theCoords, theDomain, theFunction, theExtend);
+        newShading = registrar.registerShading(newShading);
+        return newShading;
+    }
+
+    @Override
+    public Pattern makePattern(int thePatternType, Shading theShading, List theXUID,
+            StringBuffer theExtGState, List<Double> theMatrix) {
+        Pattern newPattern = new PDFPattern(thePatternType, theShading, theXUID, theExtGState,
+                    theMatrix);
+        newPattern = registrar.registerPattern(newPattern);
+        return newPattern;
+    }
+
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/PDFGradientFactory.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/PSGradientFactory.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/PSGradientFactory.java?rev=1541551&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/PSGradientFactory.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/PSGradientFactory.java Wed Nov 13 15:24:26 2013
@@ -0,0 +1,70 @@
+/*
+ * 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.awt.Color;
+import java.util.List;
+
+import org.apache.fop.pdf.PDFDeviceColorSpace;
+import org.apache.fop.render.ps.svg.PSFunction;
+import org.apache.fop.render.ps.svg.PSPattern;
+import org.apache.fop.render.ps.svg.PSShading;
+
+public class PSGradientFactory extends GradientFactory {
+
+    @Override
+    public PSPattern createGradient(boolean radial, PDFDeviceColorSpace theColorspace,
+            List<Color> theColors, List<Double> theBounds, List<Double> theCoords,
+            List<Double> theMatrix) {
+        return (PSPattern)makeGradient(radial, theColorspace, theColors, theBounds,
+                theCoords, theMatrix);
+    }
+
+    public Function makeFunction(int functionType, List<Double> theDomain,
+            List<Double> theRange, List<Function> theFunctions,
+            List<Double> theBounds, List<Double> theEncode) {
+        Function newFunction = new PSFunction(functionType, theDomain, theRange, theFunctions,
+                    theBounds, theEncode);
+        return newFunction;
+    }
+
+    @Override
+    public Function makeFunction(int functionType, List<Double> theDomain,
+            List<Double> theRange, List<Double> theCZero, List<Double> theCOne,
+            double theInterpolationExponentN) {
+        Function newFunction = new PSFunction(functionType, theDomain, theRange, theCZero,
+                    theCOne, theInterpolationExponentN);
+        return newFunction;
+    }
+
+    @Override
+    public Shading makeShading(int theShadingType,
+            PDFDeviceColorSpace theColorSpace, List<Double> theBackground, List<Double> theBBox,
+            boolean theAntiAlias, List<Double> theCoords, List<Double> theDomain,
+            Function theFunction, List<Integer> theExtend) {
+        Shading newShading = new PSShading(theShadingType, theColorSpace, theBackground, theBBox,
+                    theAntiAlias, theCoords, theDomain, theFunction, theExtend);
+        return newShading;
+    }
+
+    @Override
+    public Pattern makePattern(int thePatternType, Shading theShading, List theXUID,
+            StringBuffer theExtGState, List<Double> theMatrix) {
+        return new PSPattern(thePatternType, theShading, theXUID, theExtGState);
+    }
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/PSGradientFactory.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/Pattern.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/Pattern.java?rev=1541551&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/Pattern.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/Pattern.java Wed Nov 13 15:24:26 2013
@@ -0,0 +1,22 @@
+/*
+ * 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;
+
+public interface Pattern {
+
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/Pattern.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/Shading.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/Shading.java?rev=1541551&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/Shading.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/Shading.java Wed Nov 13 15:24:26 2013
@@ -0,0 +1,26 @@
+/*
+ * 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;
+
+
+public interface Shading {
+    StringBuffer handleShadingType1(StringBuffer p);
+    StringBuffer handleShadingType2or3(StringBuffer p);
+    StringBuffer handleShadingType4or6or7(StringBuffer p);
+    StringBuffer handleShadingType5(StringBuffer p);
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/Shading.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/ShadingPattern.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/ShadingPattern.java?rev=1541551&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/ShadingPattern.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/ShadingPattern.java Wed Nov 13 15:24:26 2013
@@ -0,0 +1,105 @@
+/*
+ * 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;
+
+import org.apache.fop.pdf.PDFDeviceColorSpace;
+import org.apache.fop.pdf.PDFNumber;
+
+/**
+ * A class for writing shading objects for different output formats
+ */
+public class ShadingPattern {
+
+    private Shading shading;
+
+    /**
+     * Constructor
+     * @param shading The shading object from which to write the output
+     */
+    public ShadingPattern(Shading shading) {
+        this.shading = shading;
+    }
+
+    /**
+     * Outputs the given shading object to a String
+     * @param colorSpace The Colospace (PDF and Postscript)
+     * @param shadingType The shading type
+     * @param background The background
+     * @param bBox The bounding box
+     * @param antiAlias Anti-aliasing
+     * @return Returns the output string
+     */
+    public String toString(PDFDeviceColorSpace colorSpace, int shadingType, List background,
+            List bBox, boolean antiAlias) {
+        StringBuffer p = new StringBuffer(128);
+        p.append("<<\n/ShadingType " + shadingType + " \n");
+        if (colorSpace != null) {
+            p.append("/ColorSpace /"
+                     + colorSpace.getName() + " \n");
+        }
+
+        if (background != null) {
+            p.append("/Background [ ");
+            for (int bgIndex = 0; bgIndex < background.size(); bgIndex++) {
+                p.append(PDFNumber.doubleOut((Double)background.get(bgIndex))
+                         + " ");
+            }
+            p.append("] \n");
+        }
+
+        if (bBox
+                != null) {    // I've never seen an example, so I guess this is right.
+            p.append("/BBox [ ");
+            for (int bboxIndex = 0; bboxIndex < bBox.size(); bboxIndex++) {
+                p.append(PDFNumber.doubleOut((Double)bBox.get(bboxIndex))
+                         + " ");
+            }
+            p.append("] \n");
+        }
+
+        if (antiAlias) {
+            p.append("/AntiAlias " + antiAlias + " \n");
+        }
+
+        // Here's where we differentiate based on what type it is.
+        switch (shadingType) {
+        //Function based shading
+        case 1: p = shading.handleShadingType1(p); break;
+        //Axial shading
+        case 2:
+        //Radial shading
+        case 3: p = shading.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;
+        //Lattice Free form gouraud-shaded triangle mesh
+        case 5: p = shading.handleShadingType5(p); break;
+        default: //Shading pattern outside expecting values
+            break;
+        }
+
+        p.append(">>");
+
+        return (p.toString());
+    }
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/shading/ShadingPattern.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFGraphics2D.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFGraphics2D.java?rev=1541551&r1=1541550&r2=1541551&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFGraphics2D.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFGraphics2D.java Wed Nov 13 15:24:26 2013
@@ -80,6 +80,7 @@ import org.apache.fop.pdf.PDFColorHandle
 import org.apache.fop.pdf.PDFConformanceException;
 import org.apache.fop.pdf.PDFDeviceColorSpace;
 import org.apache.fop.pdf.PDFDocument;
+import org.apache.fop.pdf.PDFFunction;
 import org.apache.fop.pdf.PDFGState;
 import org.apache.fop.pdf.PDFImage;
 import org.apache.fop.pdf.PDFImageXObject;
@@ -89,11 +90,18 @@ import org.apache.fop.pdf.PDFPaintingSta
 import org.apache.fop.pdf.PDFPattern;
 import org.apache.fop.pdf.PDFResourceContext;
 import org.apache.fop.pdf.PDFResources;
+import org.apache.fop.pdf.PDFShading;
 import org.apache.fop.pdf.PDFText;
 import org.apache.fop.pdf.PDFXObject;
 import org.apache.fop.render.pdf.ImageRawCCITTFaxAdapter;
 import org.apache.fop.render.pdf.ImageRawJPEGAdapter;
 import org.apache.fop.render.pdf.ImageRenderedAdapter;
+import org.apache.fop.render.shading.Function;
+import org.apache.fop.render.shading.GradientFactory;
+import org.apache.fop.render.shading.GradientRegistrar;
+import org.apache.fop.render.shading.PDFGradientFactory;
+import org.apache.fop.render.shading.Pattern;
+import org.apache.fop.render.shading.Shading;
 
 /**
  * <p>PDF Graphics 2D.
@@ -104,7 +112,7 @@ import org.apache.fop.render.pdf.ImageRe
  *
  * @see org.apache.batik.ext.awt.g2d.AbstractGraphics2D
  */
-public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHandler {
+public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHandler, GradientRegistrar {
     private static final AffineTransform IDENTITY_TRANSFORM = new AffineTransform();
 
     /** The number of decimal places. */
@@ -868,11 +876,10 @@ public class PDFGraphics2D extends Abstr
             }
 
             //Gradients are currently restricted to sRGB
-            PDFDeviceColorSpace aColorSpace;
-            aColorSpace = new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_RGB);
-            PDFPattern myPat = pdfDoc.getFactory().makeGradient(
-                    resourceContext, false, aColorSpace,
-                    someColors, theBounds, theCoords, theMatrix);
+            PDFDeviceColorSpace colSpace = new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_RGB);
+            PDFGradientFactory gradientFactory = (PDFGradientFactory)GradientFactory.newInstance(this);
+            PDFPattern myPat = gradientFactory.createGradient(false, colSpace, someColors, theBounds,
+                    theCoords, theMatrix);
             currentStream.write(myPat.getColorSpaceOut(fill));
 
             return true;
@@ -944,13 +951,10 @@ public class PDFGraphics2D extends Abstr
                 float offset = fractions[count];
                 theBounds.add(new Double(offset));
             }
-            PDFDeviceColorSpace colSpace;
-            colSpace = new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_RGB);
-
-            PDFPattern myPat = pdfDoc.getFactory().makeGradient(
-                resourceContext, true, colSpace,
-                 someColors, theBounds, theCoords, theMatrix);
-
+            PDFDeviceColorSpace colSpace = new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_RGB);
+            PDFGradientFactory gradientFactory = (PDFGradientFactory) GradientFactory.newInstance(this);
+            PDFPattern myPat = gradientFactory.createGradient(true, colSpace, someColors, theBounds,
+                    theCoords, theMatrix);
             currentStream.write(myPat.getColorSpaceOut(fill));
 
             return true;
@@ -1856,4 +1860,36 @@ public class PDFGraphics2D extends Abstr
         //NYI
     }
 
+    /**
+     * Registers a function object against the output format document
+     * @param function The function object to register
+     * @return Returns either the function which has already been registered
+     * or the current new registered object.
+     */
+    public Function registerFunction(Function function) {
+        return pdfDoc.getFactory().registerFunction((PDFFunction)function);
+    }
+
+    /**
+     * Registers a shading object against the otuput format document
+     * @param shading The shading object to register
+     * @return Returs either the shading which has already been registered
+     * or the current new registered object
+     */
+    public Shading registerShading(Shading shading) {
+        assert shading instanceof PDFShading;
+        return pdfDoc.getFactory().registerShading(resourceContext, (PDFShading)shading);
+    }
+
+    /**
+     * Registers a pattern object against the output format document
+     * @param pattern The pattern object to register
+     * @return Returns either the pattern which has already been registered
+     * or the current new registered object
+     */
+    public Pattern registerPattern(Pattern pattern) {
+        assert pattern instanceof PDFPattern;
+        return pdfDoc.getFactory().registerPattern(resourceContext, (PDFPattern)pattern);
+    }
+
 }

Added: xmlgraphics/fop/trunk/test/java/org/apache/fop/render/ps/svg/PSSVGGraphics2DTestCase.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/java/org/apache/fop/render/ps/svg/PSSVGGraphics2DTestCase.java?rev=1541551&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/test/java/org/apache/fop/render/ps/svg/PSSVGGraphics2DTestCase.java (added)
+++ xmlgraphics/fop/trunk/test/java/org/apache/fop/render/ps/svg/PSSVGGraphics2DTestCase.java Wed Nov 13 15:24:26 2013
@@ -0,0 +1,71 @@
+/*
+ * 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.awt.Color;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.Rectangle2D.Float;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+
+import org.junit.Test;
+
+import org.apache.commons.io.FileUtils;
+
+import org.apache.batik.ext.awt.RadialGradientPaint;
+
+import org.apache.xmlgraphics.java2d.GraphicContext;
+import org.apache.xmlgraphics.ps.PSGenerator;
+
+import static org.junit.Assert.assertEquals;
+
+public class PSSVGGraphics2DTestCase {
+
+    float cx = 841.891f;
+    float cy = 178.583f;
+    float r = 16.4331f;
+    float[] fractions = {0.2f, 0.6012f, 0.8094f, 1.0f};
+
+    /**
+     * Tests a radial gradient generated pattern with certain inputs against
+     * an expected output.
+     * @throws IOException
+     */
+    @Test
+    public void testApplyPaint() throws IOException {
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        PSGenerator gen = new PSGenerator(os);
+        PSSVGGraphics2D svgGraphics2D = new PSSVGGraphics2D(false, gen);
+        svgGraphics2D.setGraphicContext(new GraphicContext());
+        svgGraphics2D.setTransform(new AffineTransform());
+        Color[] colors = {new Color(255, 255, 255), new Color(200, 200, 200),
+                new Color(170, 170, 170), new Color(140, 140, 140)};
+        RadialGradientPaint paint = new RadialGradientPaint(cx, cy, r, fractions, colors);
+        Float s = new Rectangle2D.Float(7.0f, 3.0f, 841.891f, 178.583f);
+        svgGraphics2D.applyPaint(paint, true);
+        byte[] test = os.toByteArray();
+
+        byte[] expected = FileUtils.readFileToByteArray(
+                new File("test/java/org/apache/fop/render/ps/svg/expected.ps"));
+        assertEquals(new String(test), new String(expected));
+    }
+}

Propchange: xmlgraphics/fop/trunk/test/java/org/apache/fop/render/ps/svg/PSSVGGraphics2DTestCase.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain



---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org