xmlgraphics-fop-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From vhenneb...@apache.org
Subject svn commit: r1550851 [4/6] - in /xmlgraphics/fop/branches/Temp_WhitespaceManagement: ./ examples/fo/basic/ lib/ src/codegen/unicode/java/org/apache/fop/complexscripts/bidi/ src/documentation/intermediate-format-ng/ src/java/META-INF/services/ src/java/...
Date Fri, 13 Dec 2013 23:41:17 GMT
Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/pdf/PDFFunction.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/pdf/PDFFunction.java?rev=1550851&r1=1550850&r2=1550851&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/pdf/PDFFunction.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/pdf/PDFFunction.java Fri Dec 13 23:41:13 2013
@@ -22,6 +22,10 @@ package org.apache.fop.pdf;
 // Java...
 import java.util.List;
 
+import org.apache.fop.render.shading.Function;
+import org.apache.fop.render.shading.FunctionDelegate;
+import org.apache.fop.render.shading.FunctionPattern;
+
 /**
  * class representing a PDF Function.
  *
@@ -33,126 +37,9 @@ import java.util.List;
  *
  * All PDF Functions have a FunctionType (0,2,3, or 4), a Domain, and a Range.
  */
-public class PDFFunction extends PDFObject {
-    // Guts common to all function types
-
-    /**
-     * 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 domain = null;
-
-    /**
-     * Required: 2 * n Array of Double numbers which are possible outputs to the function
-     */
-    protected List 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 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 encode = null;
+public class PDFFunction extends PDFObject implements Function {
 
-    /**
-     * 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 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 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 cZero = null;
-
-    /**
-     * Required For Type 2: An Array of n Doubles defining
-     * the function result when x=1. Default is [1].
-     */
-    protected List 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 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 bounds = null;
-    // See encode above, as it's also part of Type 3 Functions.
-
-    /* *************************TYPE 4************************** */
-    // See 'data' above.
+    private FunctionDelegate delegate;
 
     /**
      * create an complete Function object of Type 0, A Sampled function.
@@ -211,26 +98,13 @@ public class PDFFunction extends PDFObje
      * @param theFunctionType This is the type of function (0,2,3, or 4).
      * It should be 0 as this is the constructor for sampled functions.
      */
-    public PDFFunction(int theFunctionType, List theDomain,
-            List theRange, List theSize, int theBitsPerSample,
-            int theOrder, List theEncode, List theDecode,
-            StringBuffer theFunctionDataStream, List theFilter) {
-        super();
-
-        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;
+    public PDFFunction(int theFunctionType, List<Double> theDomain,
+                       List<Double> theRange, List<Double> theSize, int theBitsPerSample,
+                       int theOrder, List<Double> theEncode, List<Double> theDecode,
+                       StringBuffer theFunctionDataStream, List<String> theFilter) {
+        delegate = new FunctionDelegate(this, theFunctionType, theDomain, theRange,
+                theSize, theBitsPerSample, theOrder, theEncode, theDecode,
+                theFunctionDataStream, theFilter);
     }
 
     /**
@@ -260,20 +134,11 @@ public class PDFFunction extends PDFObje
      * PDF Spec page 268
      * @param theFunctionType The type of the function, which should be 2.
      */
-    public PDFFunction(int theFunctionType, List theDomain,
-                       List theRange, List theCZero, List theCOne,
+    public PDFFunction(int theFunctionType, List<Double> theDomain,
+                       List<Double> theRange, List<Double> theCZero, List<Double> theCOne,
                        double theInterpolationExponentN) {
-        super();
-
-        this.functionType = 2;    // dang well better be 2;
-
-        this.cZero = theCZero;
-        this.cOne = theCOne;
-        this.interpolationExponentN = theInterpolationExponentN;
-
-
-        this.domain = theDomain;
-        this.range = theRange;
+        delegate = new FunctionDelegate(this, theFunctionType, theDomain, theRange,
+                theCZero, theCOne, theInterpolationExponentN);
 
     }
 
@@ -312,18 +177,11 @@ public class PDFFunction extends PDFObje
      * @param theFunctionType This is the function type. It should be 3,
      * for a stitching function.
      */
-    public PDFFunction(int theFunctionType, List theDomain,
-                       List theRange, List theFunctions,
-                       List theBounds, List theEncode) {
-        super();
-
-        this.functionType = 3;    // dang well better be 3;
-
-        this.functions = theFunctions;
-        this.bounds = theBounds;
-        this.encode = theEncode;
-        this.domain = theDomain;
-        this.range = theRange;
+    public PDFFunction(int theFunctionType, List<Double> theDomain,
+                       List<Double> theRange, List<Function> theFunctions,
+                       List<Double> theBounds, List<Double> theEncode) {
+        delegate = new FunctionDelegate(this, theFunctionType, theDomain, theRange,
+                theFunctions, theBounds, theEncode);
 
     }
 
@@ -349,20 +207,12 @@ public class PDFFunction extends PDFObje
      * @param theFunctionType The type of function which should be 4, as this is
      * a Postscript calculator function
      */
-    public PDFFunction(int theFunctionType, List theDomain,
-                       List theRange, StringBuffer theFunctionDataStream) {
-        super();
-
-        this.functionType = 4;    // dang well better be 4;
-        this.functionDataStream = theFunctionDataStream;
-
-        this.domain = theDomain;
-
-        this.range = theRange;
-
+    public PDFFunction(int theFunctionType, List<Double> theDomain,
+                       List<Double> theRange, StringBuffer theFunctionDataStream) {
+        delegate = new FunctionDelegate(this, theFunctionType, theDomain, theRange,
+                theFunctionDataStream);
     }
 
-
     /**
      * represent as PDF. Whatever the FunctionType is, the correct
      * representation spits out. The sets of required and optional
@@ -375,319 +225,13 @@ public class PDFFunction extends PDFObje
      * @return the PDF string.
      */
     public byte[] toPDF() {
-        int vectorSize = 0;
-        int numberOfFunctions = 0;
-        int tempInt = 0;
-        StringBuffer p = new StringBuffer(256);
-        p.append("<< \n/FunctionType " + this.functionType + " \n");
-
-        // FunctionType 0
-        if (this.functionType == 0) {
-            if (this.domain != null) {
-                // DOMAIN
-                p.append("/Domain [ ");
-                vectorSize = this.domain.size();
-                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
-                    p.append(PDFNumber.doubleOut((Double)this.domain.get(tempInt))
-                             + " ");
-                }
-
-                p.append("] \n");
-            } else {
-                p.append("/Domain [ 0 1 ] \n");
-            }
-
-            // SIZE
-            if (this.size != null) {
-                p.append("/Size [ ");
-                vectorSize = this.size.size();
-                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
-                    p.append(PDFNumber.doubleOut((Double)this.size.get(tempInt))
-                             + " ");
-                }
-                p.append("] \n");
-            }
-            // ENCODE
-            if (this.encode != null) {
-                p.append("/Encode [ ");
-                vectorSize = this.encode.size();
-                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
-                    p.append(PDFNumber.doubleOut((Double)this.encode.get(tempInt))
-                             + " ");
-                }
-                p.append("] \n");
-            } else {
-                p.append("/Encode [ ");
-                vectorSize = this.functions.size();
-                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
-                    p.append("0 1 ");
-                }
-                p.append("] \n");
-
-            }
-
-            // BITSPERSAMPLE
-            p.append("/BitsPerSample " + this.bitsPerSample);
-
-            // ORDER (optional)
-            if (this.order == 1 || this.order == 3) {
-                p.append(" \n/Order " + this.order + " \n");
-            }
-
-            // RANGE
-            if (this.range != null) {
-                p.append("/Range [ ");
-                vectorSize = this.range.size();
-                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
-                    p.append(PDFNumber.doubleOut((Double)this.range.get(tempInt))
-                             + " ");
-                }
-
-                p.append("] \n");
-            }
-
-            // DECODE
-            if (this.decode != null) {
-                p.append("/Decode [ ");
-                vectorSize = this.decode.size();
-                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
-                    p.append(PDFNumber.doubleOut((Double)this.decode.get(tempInt))
-                             + " ");
-                }
-
-                p.append("] \n");
-            }
-
-            // LENGTH
-            if (this.functionDataStream != null) {
-                p.append("/Length " + (this.functionDataStream.length() + 1)
-                         + " \n");
-            }
-
-            // FILTER?
-            if (this.filter != null) {           // if there's a filter
-                vectorSize = this.filter.size();
-                p.append("/Filter ");
-                if (vectorSize == 1) {
-                    p.append("/" + ((String)this.filter.get(0))
-                             + " \n");
-                } else {
-                    p.append("[ ");
-                    for (tempInt = 0; tempInt < vectorSize; tempInt++) {
-                        p.append("/" + ((String)this.filter.get(0))
-                                 + " ");
-                    }
-                    p.append("] \n");
-                }
-            }
-            p.append(">>");
-
-            // stream representing the function
-            if (this.functionDataStream != null) {
-                p.append("\nstream\n" + this.functionDataStream
-                         + "\nendstream");
-            }
-
-            // end of if FunctionType 0
-
-        } else if (this.functionType == 2) {
-            // DOMAIN
-            if (this.domain != null) {
-                p.append("/Domain [ ");
-                vectorSize = this.domain.size();
-                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
-                    p.append(PDFNumber.doubleOut((Double)this.domain.get(tempInt))
-                             + " ");
-                }
-
-                p.append("] \n");
-            } else {
-                p.append("/Domain [ 0 1 ] \n");
-            }
-
-
-            // RANGE
-            if (this.range != null) {
-                p.append("/Range [ ");
-                vectorSize = this.range.size();
-                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
-                    p.append(PDFNumber.doubleOut((Double)this.range.get(tempInt))
-                             + " ");
-                }
-
-                p.append("] \n");
-            }
-
-            // FunctionType, C0, C1, N are required in PDF
-
-            // C0
-            if (this.cZero != null) {
-                p.append("/C0 [ ");
-                vectorSize = this.cZero.size();
-                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
-                    p.append(PDFNumber.doubleOut((Double)this.cZero.get(tempInt))
-                             + " ");
-                }
-                p.append("] \n");
-            }
-
-            // C1
-            if (this.cOne != null) {
-                p.append("/C1 [ ");
-                vectorSize = this.cOne.size();
-                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
-                    p.append(PDFNumber.doubleOut((Double)this.cOne.get(tempInt))
-                             + " ");
-                }
-                p.append("] \n");
-            }
-
-            // N: The interpolation Exponent
-            p.append("/N "
-                     + PDFNumber.doubleOut(new Double(this.interpolationExponentN))
-                     + " \n");
-
-            p.append(">>");
-
-        } else if (this.functionType
-                   == 3) {                       // fix this up when my eyes uncross
-            // DOMAIN
-            if (this.domain != null) {
-                p.append("/Domain [ ");
-                vectorSize = this.domain.size();
-                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
-                    p.append(PDFNumber.doubleOut((Double)this.domain.get(tempInt))
-                             + " ");
-                }
-                p.append("] \n");
-            } else {
-                p.append("/Domain [ 0 1 ] \n");
-            }
-
-            // RANGE
-            if (this.range != null) {
-                p.append("/Range [ ");
-                vectorSize = this.range.size();
-                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
-                    p.append(PDFNumber.doubleOut((Double)this.range.get(tempInt))
-                             + " ");
-                }
-
-                p.append("] \n");
-            }
-
-            // FUNCTIONS
-            if (this.functions != null) {
-                p.append("/Functions [ ");
-                numberOfFunctions = this.functions.size();
-                for (tempInt = 0; tempInt < numberOfFunctions; tempInt++) {
-                    p.append(((PDFFunction)this.functions.get(tempInt)).referencePDF()
-                             + " ");
-
-                }
-                p.append("] \n");
-            }
-
-
-            // ENCODE
-            if (this.encode != null) {
-                p.append("/Encode [ ");
-                vectorSize = this.encode.size();
-                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
-                    p.append(PDFNumber.doubleOut((Double)this.encode.get(tempInt))
-                             + " ");
-                }
-
-                p.append("] \n");
-            } else {
-                p.append("/Encode [ ");
-                vectorSize = this.functions.size();
-                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
-                    p.append("0 1 ");
-                }
-                p.append("] \n");
-
-            }
-
-
-            // BOUNDS, required, but can be empty
-            p.append("/Bounds [ ");
-            if (this.bounds != null) {
-
-                vectorSize = this.bounds.size();
-                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
-                    p.append(PDFNumber.doubleOut((Double)this.bounds.get(tempInt))
-                             + " ");
-                }
-
-            } else {
-                if (this.functions != 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(new Double(1.0
-                            / ((double)numberOfFunctions)));
-
-                    for (tempInt = 0; tempInt + 1 < numberOfFunctions;
-                            tempInt++) {
-
-                        p.append(functionsFraction + " ");
-                    }
-                    functionsFraction = null;    // clean reference.
-
-                }
-
-            }
-            p.append("]\n>>");
-        } else if (this.functionType
-                   == 4) {                       // fix this up when my eyes uncross
-            // DOMAIN
-            if (this.domain != null) {
-                p.append("/Domain [ ");
-                vectorSize = this.domain.size();
-                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
-                    p.append(PDFNumber.doubleOut((Double)this.domain.get(tempInt))
-                             + " ");
-                }
-
-                p.append("] \n");
-            } else {
-                p.append("/Domain [ 0 1 ] \n");
-            }
-
-            // RANGE
-            if (this.range != null) {
-                p.append("/Range [ ");
-                vectorSize = this.range.size();
-                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
-                    p.append(PDFNumber.doubleOut((Double)this.range.get(tempInt))
-                             + " ");
-                }
-
-                p.append("] \n");
-            }
-
-            // LENGTH
-            if (this.functionDataStream != null) {
-                p.append("/Length " + (this.functionDataStream.length() + 1)
-                         + " \n");
-            }
-
-            p.append(">>");
-
-            // stream representing the function
-            if (this.functionDataStream != null) {
-                p.append("\nstream\n{ " + this.functionDataStream
-                         + " }\nendstream");
-            }
-
-
-        }
+        return toByteString();
+    }
 
-        return encode(p.toString());
 
+    public byte[] toByteString() {
+        FunctionPattern pattern = new FunctionPattern(this);
+        return encode(pattern.toWriteableString());
     }
 
     /** {@inheritDoc} */
@@ -702,96 +246,155 @@ public class PDFFunction extends PDFObje
             return false;
         }
         PDFFunction func = (PDFFunction)obj;
-        if (functionType != func.functionType) {
+        if (delegate.getFunctionType() != func.getFunctionType()) {
             return false;
         }
-        if (bitsPerSample != func.bitsPerSample) {
+        if (delegate.getBitsPerSample() != func.getBitsPerSample()) {
             return false;
         }
-        if (order != func.order) {
+        if (delegate.getOrder() != func.getOrder()) {
             return false;
         }
-        if (interpolationExponentN != func.interpolationExponentN) {
+        if (delegate.getInterpolationExponentN() != func.getInterpolationExponentN()) {
             return false;
         }
-        if (domain != null) {
-            if (!domain.equals(func.domain)) {
+        if (delegate.getDomain() != null) {
+            if (!delegate.getDomain().equals(func.getDomain())) {
                 return false;
             }
-        } else if (func.domain != null) {
+        } else if (func.getDomain() != null) {
             return false;
         }
-        if (range != null) {
-            if (!range.equals(func.range)) {
+        if (delegate.getRange() != null) {
+            if (!delegate.getRange().equals(func.getRange())) {
                 return false;
             }
-        } else if (func.range != null) {
+        } else if (func.getRange() != null) {
             return false;
         }
-        if (size != null) {
-            if (!size.equals(func.size)) {
+        if (delegate.getSize() != null) {
+            if (!delegate.getSize().equals(func.getSize())) {
                 return false;
             }
-        } else if (func.size != null) {
+        } else if (func.getSize() != null) {
             return false;
         }
-        if (encode != null) {
-            if (!encode.equals(func.encode)) {
+        if (delegate.getEncode() != null) {
+            if (!delegate.getEncode().equals(func.getEncode())) {
                 return false;
             }
-        } else if (func.encode != null) {
+        } else if (func.getEncode() != null) {
             return false;
         }
-        if (decode != null) {
-            if (!decode.equals(func.decode)) {
+        if (delegate.getDecode() != null) {
+            if (!delegate.getDecode().equals(func.getDecode())) {
                 return false;
             }
-        } else if (func.decode != null) {
+        } else if (func.getDecode() != null) {
             return false;
         }
-        if (functionDataStream != null) {
-            if (!functionDataStream.equals(func.functionDataStream)) {
+        if (delegate.getDataStream() != null) {
+            if (!delegate.getDataStream().equals(func.getDataStream())) {
                 return false;
             }
-        } else if (func.functionDataStream != null) {
+        } else if (func.getDataStream() != null) {
             return false;
         }
-        if (filter != null) {
-            if (!filter.equals(func.filter)) {
+        if (delegate.getFilter() != null) {
+            if (!delegate.getFilter().equals(func.getFilter())) {
                 return false;
             }
-        } else if (func.filter != null) {
+        } else if (func.getFilter() != null) {
             return false;
         }
-        if (cZero != null) {
-            if (!cZero.equals(func.cZero)) {
+        if (delegate.getCZero() != null) {
+            if (!delegate.getCZero().equals(func.getCZero())) {
                 return false;
             }
-        } else if (func.cZero != null) {
+        } else if (func.getCZero() != null) {
             return false;
         }
-        if (cOne != null) {
-            if (!cOne.equals(func.cOne)) {
+        if (delegate.getCOne() != null) {
+            if (!delegate.getCOne().equals(func.getCOne())) {
                 return false;
             }
-        } else if (func.cOne != null) {
+        } else if (func.getCOne() != null) {
             return false;
         }
-        if (functions != null) {
-            if (!functions.equals(func.functions)) {
+        if (delegate.getFunctions() != null) {
+            if (!delegate.getFunctions().equals(func.getFunctions())) {
                 return false;
             }
-        } else if (func.functions != null) {
+        } else if (func.getFunctions() != null) {
             return false;
         }
-        if (bounds != null) {
-            if (!bounds.equals(func.bounds)) {
+        if (delegate.getBounds() != null) {
+            if (!delegate.getBounds().equals(func.getBounds())) {
                 return false;
             }
-        } else if (func.bounds != null) {
+        } else if (func.getBounds() != null) {
             return false;
         }
         return true;
     }
 
+    public int getFunctionType() {
+        return delegate.getFunctionType();
+    }
+
+    public List<Double> getBounds() {
+        return delegate.getBounds();
+    }
+
+    public List<Double> getDomain() {
+        return delegate.getDomain();
+    }
+
+    public List<Double> getSize() {
+        return delegate.getSize();
+    }
+
+    public List<String> getFilter() {
+        return delegate.getFilter();
+    }
+
+    public List<Double> getEncode() {
+        return delegate.getEncode();
+    }
+
+    public List<Function> getFunctions() {
+        return delegate.getFunctions();
+    }
+
+    public int getBitsPerSample() {
+        return delegate.getBitsPerSample();
+    }
+
+    public double getInterpolationExponentN() {
+        return delegate.getInterpolationExponentN();
+    }
+
+    public int getOrder() {
+        return delegate.getOrder();
+    }
+
+    public List<Double> getRange() {
+        return delegate.getRange();
+    }
+
+    public List<Double> getDecode() {
+        return delegate.getDecode();
+    }
+
+    public StringBuffer getDataStream() {
+        return delegate.getDataStream();
+    }
+
+    public List<Double> getCZero() {
+        return delegate.getCZero();
+    }
+
+    public List<Double> getCOne() {
+        return delegate.getCOne();
+    }
 }

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/pdf/PDFNumber.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/pdf/PDFNumber.java?rev=1550851&r1=1550850&r2=1550851&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/pdf/PDFNumber.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/pdf/PDFNumber.java Fri Dec 13 23:41:13 2013
@@ -29,6 +29,14 @@ public class PDFNumber extends PDFObject
 
     private Number number;
 
+    public PDFNumber() {
+        this.number = Integer.valueOf(0);
+    }
+
+    public PDFNumber(Number number) {
+        this.number = number;
+    }
+
     /**
      * Returns the number.
      * @return the number

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/pdf/PDFPaintingState.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/pdf/PDFPaintingState.java?rev=1550851&r1=1550850&r2=1550851&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/pdf/PDFPaintingState.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/pdf/PDFPaintingState.java Fri Dec 13 23:41:13 2013
@@ -44,8 +44,6 @@ import org.apache.fop.util.AbstractPaint
  * previous state then the necessary values can be overridden.
  * The current transform behaves differently to other values as the
  * matrix is combined with the current resolved value.
- * It is impossible to optimise the result without analysing the all
- * the possible combinations after completing.
  */
 public class PDFPaintingState extends org.apache.fop.util.AbstractPaintingState {
 
@@ -187,6 +185,36 @@ public class PDFPaintingState extends or
         return newState;
     }
 
+    public void setLayer(String layer) {
+        getPDFData().setLayer(layer);
+    }
+
+    public String getLayer() {
+        return getPDFData().getLayer();
+    }
+
+    public boolean getLayerChanged() {
+        String layerCurrent = getLayer();
+        if (layerCurrent == null) {
+            return false;
+        } else if (getStateStack().isEmpty()) {
+            return true;
+        } else {
+            for (int i = getStackLevel(); i > 0; --i) {
+                String layerPrev = ((PDFData) getStateStack().get(i - 1)).getLayer();
+                if (layerPrev == null) {
+                    continue;
+                } else {
+                    // Both current and prior are set, so, if same, then we know layer
+                    // didn't change (and can stop search), otherwise it did change.
+                    return !layerCurrent.equals(layerPrev);
+                }
+            }
+            // Current layer set, but no prior saved layer set, so must have changed.
+            return true;
+        }
+    }
+
     /** {@inheritDoc} */
     @Override
     protected AbstractData instantiateData() {
@@ -209,7 +237,7 @@ public class PDFPaintingState extends or
         AbstractData data = getData();
         AbstractData copy = (AbstractData)data.clone();
         data.clearTransform();
-        getStateStack().add(copy);
+        getStateStack().push(copy);
     }
 
     private PDFData getPDFData() {

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/pdf/PDFPattern.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/pdf/PDFPattern.java?rev=1550851&r1=1550850&r2=1550851&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/pdf/PDFPattern.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/pdf/PDFPattern.java Fri Dec 13 23:41:13 2013
@@ -23,6 +23,9 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.util.List;
 
+import org.apache.fop.render.shading.Pattern;
+import org.apache.fop.render.shading.Shading;
+
 /**
  * class representing a PDF Function.
  *
@@ -33,7 +36,7 @@ import java.util.List;
  *
  * All PDF Functions have a FunctionType (0,2,3, or 4), a Domain, and a Range.
  */
-public class PDFPattern extends PDFPathPaint {
+public class PDFPattern extends PDFPathPaint implements Pattern {
 
     /**
      * The resources associated with this pattern
@@ -146,13 +149,14 @@ public class PDFPattern extends PDFPathP
      * @param theExtGState optional: the extended graphics state, if used.
      * @param theMatrix Optional:List of Doubles that specify the matrix.
      */
-    public PDFPattern(int thePatternType, PDFShading theShading,
+    public PDFPattern(int thePatternType, Shading theShading,
                       List theXUID, StringBuffer theExtGState,
                       List theMatrix) {
         super();
 
         this.patternType = 2;             // thePatternType;
-        this.shading = theShading;
+        assert theShading instanceof PDFShading;
+        this.shading = (PDFShading)theShading;
         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.
@@ -259,7 +263,7 @@ public class PDFPattern extends PDFPathP
                 vectorSize = this.xUID.size();
                 p.append("/XUID [ ");
                 for (tempInt = 0; tempInt < vectorSize; tempInt++) {
-                    p.append(((Integer)this.xUID.get(tempInt)) + " ");
+                    p.append((this.xUID.get(tempInt)) + " ");
                 }
                 p.append("] \n");
             }
@@ -269,13 +273,14 @@ public class PDFPattern extends PDFPathP
                 pdfStream = new PDFStream();
                 pdfStream.setDocument(getDocumentSafely());
                 pdfStream.add(this.patternDataStream.toString());
+                pdfStream.setObjectNumber(getObjectNumber());
                 pdfStream.getFilterList().addDefaultFilters(
                         getDocument().getFilterMap(),
                         PDFFilterList.CONTENT_FILTER);
+                getDocument().applyEncryption(pdfStream);
                 encodedStream = pdfStream.encodeStream();
                 p.append(pdfStream.getFilterList().buildFilterDictEntries());
-                p.append("/Length " + (encodedStream.getSize() + 1)
-                         + " \n");
+                p.append("/Length " + encodedStream.getSize() + " \n");
             }
 
         } else {
@@ -289,7 +294,7 @@ public class PDFPattern extends PDFPathP
                 vectorSize = this.xUID.size();
                 p.append("/XUID [ ");
                 for (tempInt = 0; tempInt < vectorSize; tempInt++) {
-                    p.append(((Integer)this.xUID.get(tempInt)) + " ");
+                    p.append((this.xUID.get(tempInt)) + " ");
                 }
                 p.append("] \n");
             }

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/pdf/PDFResources.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/pdf/PDFResources.java?rev=1550851&r1=1550850&r2=1550851&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/pdf/PDFResources.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/pdf/PDFResources.java Fri Dec 13 23:41:13 2013
@@ -37,8 +37,8 @@ import org.apache.fop.fonts.base14.ZapfD
 /**
  * Class representing a /Resources object.
  *
- * /Resources object contain a list of references to the fonts for the
- * document
+ * /Resources object contain a list of references to the fonts, patterns,
+ * shadings, etc.,  for the document.
  */
 public class PDFResources extends PDFDictionary {
 
@@ -73,6 +73,9 @@ public class PDFResources extends PDFDic
     /** Map of ICC color spaces (key: ICC profile description) */
     protected Map<String, PDFICCBasedColorSpace> iccColorSpaces = new LinkedHashMap<String, PDFICCBasedColorSpace>();
 
+    /** Named properties */
+    protected Map<String, PDFReference> properties = new LinkedHashMap<String, PDFReference>();
+
     /**
      * create a /Resources object.
      *
@@ -191,6 +194,25 @@ public class PDFResources extends PDFDic
         return cs;
     }
 
+    /**
+     * Add a named property.
+     *
+     * @param name name of property
+     * @param property reference to property value
+     */
+    public void addProperty(String name, PDFReference property) {
+        this.properties.put(name, property);
+    }
+
+    /**
+     * Get a named property.
+     *
+     * @param name name of property
+     */
+    public PDFReference getProperty(String name) {
+        return this.properties.get(name);
+    }
+
     @Override
     public int output(OutputStream stream) throws IOException {
         populateDictionary();
@@ -253,6 +275,14 @@ public class PDFResources extends PDFDic
             }
             put("ColorSpace", dict);
         }
+
+        if (!properties.isEmpty()) {
+            PDFDictionary dict = new PDFDictionary(this);
+            for (String name : properties.keySet()) {
+                dict.put(name, properties.get(name));
+            }
+            put("Properties", dict);
+        }
     }
 
 }

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/pdf/PDFShading.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/pdf/PDFShading.java?rev=1550851&r1=1550850&r2=1550851&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/pdf/PDFShading.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/pdf/PDFShading.java Fri Dec 13 23:41:13 2013
@@ -22,6 +22,10 @@ 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;
+
 /**
  * class representing a PDF Smooth Shading object.
  *
@@ -32,7 +36,7 @@ import java.util.List;
  *
  * All PDF Functions have a shadingType (0,2,3, or 4), a Domain, and a Range.
  */
-public class PDFShading extends PDFObject {
+public class PDFShading extends PDFObject implements Shading {
     // Guts common to all function types
 
     /**
@@ -205,7 +209,7 @@ public class PDFShading extends PDFObjec
     public PDFShading(int theShadingType, PDFDeviceColorSpace theColorSpace,
             List theBackground, List theBBox,
             boolean theAntiAlias, List theCoords,
-            List theDomain, PDFFunction theFunction,
+            List theDomain, Function theFunction,
             List theExtend) {
         super();
         this.shadingType = theShadingType;    // 2 or 3
@@ -216,7 +220,8 @@ public class PDFShading extends PDFObjec
 
         this.coords = theCoords;
         this.domain = theDomain;
-        this.function = theFunction;
+        assert theFunction instanceof PDFFunction;
+        this.function = (PDFFunction)theFunction;
         this.extend = theExtend;
 
     }
@@ -335,197 +340,8 @@ public class PDFShading extends PDFObjec
      * @return the PDF string.
      */
     public String toPDFString() {
-        int vectorSize;
-        int tempInt;
-        StringBuffer p = new StringBuffer(128);
-        p.append("<<\n/ShadingType " + this.shadingType + " \n");
-        if (this.colorSpace != null) {
-            p.append("/ColorSpace /"
-                     + this.colorSpace.getName() + " \n");
-        }
-
-        if (this.background != null) {
-            p.append("/Background [ ");
-            vectorSize = this.background.size();
-            for (tempInt = 0; tempInt < vectorSize; tempInt++) {
-                p.append(PDFNumber.doubleOut((Double)this.background.get(tempInt))
-                         + " ");
-            }
-            p.append("] \n");
-        }
-
-        if (this.bBox
-                != null) {    // I've never seen an example, so I guess this is right.
-            p.append("/BBox [ ");
-            vectorSize = this.bBox.size();
-            for (tempInt = 0; tempInt < vectorSize; tempInt++) {
-                p.append(PDFNumber.doubleOut((Double)this.bBox.get(tempInt))
-                         + " ");
-            }
-            p.append("] \n");
-        }
-
-        if (this.antiAlias) {
-            p.append("/AntiAlias " + this.antiAlias + " \n");
-        }
-
-        // Here's where we differentiate based on what type it is.
-        if (this.shadingType == 1) {    // function based shading
-            if (this.domain != null) {
-                p.append("/Domain [ ");
-                vectorSize = this.domain.size();
-                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
-                    p.append(PDFNumber.doubleOut((Double)this.domain.get(tempInt))
-                             + " ");
-                }
-                p.append("] \n");
-            } else {
-                p.append("/Domain [ 0 1 ] \n");
-            }
-
-            if (this.matrix != null) {
-                p.append("/Matrix [ ");
-                vectorSize = this.matrix.size();
-                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
-                    p.append(PDFNumber.doubleOut((Double)this.matrix.get(tempInt))
-                             + " ");
-                }
-                p.append("] \n");
-            }
-
-            if (this.function != null) {
-                p.append("/Function ");
-                p.append(this.function.referencePDF() + " \n");
-            }
-        } else if ((this.shadingType == 2)
-                   || (this.shadingType
-                       == 3)) {         // 2 is axial shading (linear gradient)
-            // 3 is radial shading (circular gradient)
-            if (this.coords != null) {
-                p.append("/Coords [ ");
-                vectorSize = this.coords.size();
-                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
-                    p.append(PDFNumber.doubleOut((Double)this.coords.get(tempInt))
-                             + " ");
-                }
-                p.append("] \n");
-            }
-
-            // DOMAIN
-            if (this.domain != null) {
-                p.append("/Domain [ ");
-                vectorSize = this.domain.size();
-                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
-                    p.append(PDFNumber.doubleOut((Double)this.domain.get(tempInt))
-                             + " ");
-                }
-                p.append("] \n");
-            } else {
-                p.append("/Domain [ 0 1 ] \n");
-            }
-
-            if (this.extend != null) {
-                p.append("/Extend [ ");
-                vectorSize = this.extend.size();
-                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
-                    p.append(((Boolean)this.extend.get(tempInt)) + " ");
-                }
-
-                p.append("] \n");
-            } else {
-                p.append("/Extend [ true true ] \n");
-            }
-
-
-            if (this.function != null) {
-                p.append("/Function ");
-                p.append(this.function.referencePDF() + " \n");
-            }
-
-
-        } else if ((this.shadingType == 4) || (this.shadingType == 6)
-                   || (this.shadingType
-                       == 7)) {    // 4:Free-form Gouraud-shaded triangle meshes
-            // 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 [ ");
-                vectorSize = this.decode.size();
-                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
-                    p.append(((Boolean)this.decode.get(tempInt)) + " ");
-                }
-
-                p.append("] \n");
-            }
-
-            if (this.function != null) {
-                p.append("/Function ");
-                p.append(this.function.referencePDF() + " \n");
-            }
-
-        } else if (this.shadingType
-                   == 5) {    // Lattice Free form gouraud-shaded triangle mesh
-
-            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 [ ");
-                vectorSize = this.decode.size();
-                for (tempInt = 0; tempInt < vectorSize; tempInt++) {
-                    p.append(((Boolean)this.decode.get(tempInt)) + " ");
-                }
-
-                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");
-            }
-
-        }
-
-        p.append(">>");
-
-        return (p.toString());
+        ShadingPattern pattern = new ShadingPattern(this);
+        return pattern.toString(colorSpace, shadingType, background, bBox, antiAlias);
     }
 
     /** {@inheritDoc} */
@@ -623,4 +439,173 @@ public class PDFShading extends PDFObjec
         }
         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;
+    }
 }

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/AbstractRenderer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/AbstractRenderer.java?rev=1550851&r1=1550850&r2=1550851&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/AbstractRenderer.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/AbstractRenderer.java Fri Dec 13 23:41:13 2013
@@ -28,6 +28,7 @@ import java.io.OutputStream;
 import java.util.List;
 import java.util.Locale;
 import java.util.Set;
+import java.util.Stack;
 
 import org.w3c.dom.Document;
 
@@ -112,8 +113,12 @@ public abstract class AbstractRenderer
     /** the currently active PageViewport */
     protected PageViewport currentPageViewport;
 
+    /* warned XML handlers */
     private Set warnedXMLHandlers;
 
+    /* layers stack */
+    private Stack<String> layers;
+
     /** {@inheritDoc} */
     public abstract void setupFontInfo(FontInfo fontInfo) throws FOPException;
 
@@ -471,6 +476,10 @@ public abstract class AbstractRenderer
      * @param children  The children to render within the block viewport
      */
     protected void renderBlockViewport(BlockViewport bv, List children) {
+        boolean inNewLayer = false;
+        if (maybeStartLayer(bv)) {
+            inNewLayer = true;
+        }
         // clip and position viewport if necessary
         if (bv.getPositioning() == Block.ABSOLUTE) {
             // save positions
@@ -506,6 +515,7 @@ public abstract class AbstractRenderer
             currentIPPosition = saveIP;
             currentBPPosition = saveBP + bv.getAllocBPD();
         }
+        maybeEndLayer(bv, inNewLayer);
     }
 
     /**
@@ -573,6 +583,10 @@ public abstract class AbstractRenderer
     protected void renderBlock(Block block) {
         assert block != null;
         List children = block.getChildAreas();
+        boolean inNewLayer = false;
+        if (maybeStartLayer(block)) {
+            inNewLayer = true;
+        }
         if (block instanceof BlockViewport) {
             if (children != null) {
                 renderBlockViewport((BlockViewport) block, children);
@@ -607,6 +621,45 @@ public abstract class AbstractRenderer
                 currentBPPosition = saveBP + block.getAllocBPD();
             }
         }
+        maybeEndLayer(block, inNewLayer);
+    }
+
+    /**
+     * Establish new optional content group layer.
+     * @param layer name of layer
+     */
+    protected abstract void startLayer(String layer);
+
+    /**
+     * Finish current optional content group layer.
+     */
+    protected abstract void endLayer();
+
+    protected boolean maybeStartLayer(Area area) {
+        String layer = (String) area.getTrait(Trait.LAYER);
+        if (layer != null) {
+            if (layers == null) {
+                layers = new Stack<String>();
+            }
+            if (layers.empty() || !layers.peek().equals(layer)) {
+                layers.push(layer);
+                startLayer(layer);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    protected void maybeEndLayer(Area area, boolean inNewLayer) {
+        if (inNewLayer) {
+            assert layers != null;
+            assert !layers.empty();
+            String layer = (String) area.getTrait(Trait.LAYER);
+            assert layer != null;
+            assert layers.peek().equals(layer);
+            endLayer();
+            layers.pop();
+        }
     }
 
     /**
@@ -746,6 +799,10 @@ public abstract class AbstractRenderer
      * @param ip the inline parent to render
      */
     protected void renderInlineParent(InlineParent ip) {
+        boolean inNewLayer = false;
+        if (maybeStartLayer(ip)) {
+            inNewLayer = true;
+        }
         int level = ip.getBidiLevel();
         List children = ip.getChildAreas();
         renderInlineAreaBackAndBorders(ip);
@@ -782,6 +839,7 @@ public abstract class AbstractRenderer
         }
         currentIPPosition = saveIP + ip.getAllocIPD();
         currentBPPosition = saveBP;
+        maybeEndLayer(ip, inNewLayer);
     }
 
     /**

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/afp/AFPFontConfig.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/afp/AFPFontConfig.java?rev=1550851&r1=1550850&r2=1550851&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/afp/AFPFontConfig.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/afp/AFPFontConfig.java Fri Dec 13 23:41:13 2013
@@ -316,8 +316,8 @@ public final class AFPFontConfig impleme
 
         private final String characterset;
 
-        private CIDKeyedFontConfig(List<FontTriplet> triplets, String type, String codePage,
-                String encoding, String characterset, String name, CharacterSetType charsetType, boolean embeddable, String uri) {
+        private CIDKeyedFontConfig(List<FontTriplet> triplets, String type, String codePage, String encoding,
+                String characterset, String name, CharacterSetType charsetType, boolean embeddable, String uri) {
             super(triplets, type, codePage, encoding, name, embeddable, uri);
             this.characterset = characterset;
             this.charsetType = charsetType;

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/afp/AFPPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/afp/AFPPainter.java?rev=1550851&r1=1550850&r2=1550851&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/afp/AFPPainter.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/afp/AFPPainter.java Fri Dec 13 23:41:13 2013
@@ -164,7 +164,7 @@ public class AFPPainter extends Abstract
     }
 
     /** {@inheritDoc} */
-    public void startGroup(AffineTransform transform) throws IFException {
+    public void startGroup(AffineTransform transform, String layer) throws IFException {
         try {
             saveGraphicsState();
             concatenateTransformationMatrix(transform);

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/afp/AFPRendererConfig.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/afp/AFPRendererConfig.java?rev=1550851&r1=1550850&r2=1550851&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/afp/AFPRendererConfig.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/afp/AFPRendererConfig.java Fri Dec 13 23:41:13 2013
@@ -103,7 +103,8 @@ public final class AFPRendererConfig imp
         }
     }
 
-    private final EnumMap<AFPRendererOption, Object> params = new EnumMap<AFPRendererOption, Object>(AFPRendererOption.class);
+    private final EnumMap<AFPRendererOption, Object> params
+            = new EnumMap<AFPRendererOption, Object>(AFPRendererOption.class);
 
     private final EnumMap<ImagesModeOptions, Object> imageModeParams
     = new EnumMap<ImagesModeOptions, Object>(ImagesModeOptions.class);

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java?rev=1550851&r1=1550850&r2=1550851&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java Fri Dec 13 23:41:13 2013
@@ -126,8 +126,8 @@ public abstract class AbstractIFPainter<
     }
 
     /** {@inheritDoc} */
-    public void startGroup(AffineTransform[] transforms) throws IFException {
-        startGroup(combine(transforms));
+    public void startGroup(AffineTransform[] transforms, String layer) throws IFException {
+        startGroup(combine(transforms), layer);
     }
 
     /**

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/AbstractXMLWritingIFDocumentHandler.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/AbstractXMLWritingIFDocumentHandler.java?rev=1550851&r1=1550850&r2=1550851&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/AbstractXMLWritingIFDocumentHandler.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/AbstractXMLWritingIFDocumentHandler.java Fri Dec 13 23:41:13 2013
@@ -54,10 +54,10 @@ public abstract class AbstractXMLWriting
         if (result instanceof SAXResult) {
             SAXResult saxResult = (SAXResult)result;
             this.handler = new GenerationHelperContentHandler(
-                    saxResult.getHandler(), getMainNamespace());
+                    saxResult.getHandler(), getMainNamespace(), getContext());
         } else {
             this.handler = new GenerationHelperContentHandler(
-                    createContentHandler(result), getMainNamespace());
+                    createContentHandler(result), getMainNamespace(), getContext());
         }
     }
 

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/IFContext.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/IFContext.java?rev=1550851&r1=1550850&r2=1550851&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/IFContext.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/IFContext.java Fri Dec 13 23:41:13 2013
@@ -55,6 +55,8 @@ public class IFContext {
 
     private boolean hyphenated;
 
+    private int pageIndex = -1;
+
     /**
      * Main constructor.
      * @param ua the user agent
@@ -216,4 +218,20 @@ public class IFContext {
         return hyphenated;
     }
 
+    /**
+     * Record current page index.
+     * @param pageIndex a zero based page index or -1 (no page)
+     */
+    public void setPageIndex(int pageIndex) {
+        this.pageIndex = pageIndex;
+    }
+
+    /**
+     * Obtain current page index.
+     * @return a zero based page index or -1 (no page)
+     */
+    public int getPageIndex() {
+        return this.pageIndex;
+    }
+
 }

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/IFGraphicContext.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/IFGraphicContext.java?rev=1550851&r1=1550850&r2=1550851&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/IFGraphicContext.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/IFGraphicContext.java Fri Dec 13 23:41:13 2013
@@ -89,6 +89,7 @@ public class IFGraphicContext extends Gr
     public static class Group {
 
         private AffineTransform[] transforms;
+        private String layer;
 
         /**
          * Construct a Group.
@@ -106,6 +107,16 @@ public class IFGraphicContext extends Gr
             this(new AffineTransform[] {transform});
         }
 
+        /**
+         * Construct a layer Group, i.e., a Group with no transforms
+         * but with a optional content group layer label.
+         * @param layer a layer label
+         */
+        public Group(String layer) {
+            this();
+            this.layer = layer;
+        }
+
         /** Default constructor. */
         public Group() {
             this(EMPTY_TRANSFORM_ARRAY);
@@ -116,12 +127,17 @@ public class IFGraphicContext extends Gr
             return this.transforms;
         }
 
+        /** @return layer */
+        public String getLayer() {
+            return this.layer;
+        }
+
         /**
          * @param painter a painter
          * @throws IFException in not caught
          */
         public void start(IFPainter painter) throws IFException {
-            painter.startGroup(transforms);
+            painter.startGroup(transforms, layer);
         }
 
         /**
@@ -136,6 +152,11 @@ public class IFGraphicContext extends Gr
         public String toString() {
             StringBuffer sb = new StringBuffer("group: ");
             IFUtil.toString(getTransforms(), sb);
+            if ((layer != null) && (layer.length() > 0)) {
+                sb.append(" layer(");
+                sb.append(layer);
+                sb.append(')');
+            }
             return sb.toString();
         }
 

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/IFPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/IFPainter.java?rev=1550851&r1=1550850&r2=1550851&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/IFPainter.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/IFPainter.java Fri Dec 13 23:41:13 2013
@@ -113,19 +113,21 @@ public interface IFPainter {
     /**
      * Starts a new group of graphical elements. Corresponds to SVG's g element.
      * @param transforms a series of transformation matrices establishing the new coordinate system
+     * @param layer an optional layer label (or null if none)
      * @throws IFException if an error occurs while handling this element
      */
-    void startGroup(AffineTransform[] transforms) throws IFException;
+    void startGroup(AffineTransform[] transforms, String layer) throws IFException;
 
     /**
      * Starts a new group of graphical elements. Corresponds to SVG's g element.
      * @param transform the transformation matrix establishing the new coordinate system
+     * @param layer an optional layer label (or null if none)
      * @throws IFException if an error occurs while handling this element
      */
-    void startGroup(AffineTransform transform) throws IFException;
+    void startGroup(AffineTransform transform, String layer) throws IFException;
 
     /**
-     * Ends the current group and restores the previous coordinate system.
+     * Ends the current group and restores the previous coordinate system (and layer).
      * @throws IFException if an error occurs while handling this element
      */
     void endGroup() throws IFException;

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/IFParser.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/IFParser.java?rev=1550851&r1=1550850&r2=1550851&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/IFParser.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/IFParser.java Fri Dec 13 23:41:13 2013
@@ -592,7 +592,8 @@ public class IFParser implements IFConst
                 String transform = attributes.getValue("transform");
                 AffineTransform[] transforms
                     = AffineTransformArrayParser.createAffineTransform(transform);
-                painter.startGroup(transforms);
+                String layer = attributes.getValue("layer");
+                painter.startGroup(transforms, layer);
             }
 
             public void endElement() throws IFException {
@@ -800,8 +801,8 @@ public class IFParser implements IFConst
                     }
                     painter.drawImage(uri, new Rectangle(x, y, width, height));
                 }
-                resetForeignAttributes();
                 resetStructureTreeElement();
+                resetForeignAttributes();
                 inForeignObject = false;
             }
 

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/IFRenderer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/IFRenderer.java?rev=1550851&r1=1550850&r2=1550851&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/IFRenderer.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/IFRenderer.java Fri Dec 13 23:41:13 2013
@@ -571,6 +571,7 @@ public class IFRenderer extends Abstract
             Dimension dim = new Dimension(viewArea.width, viewArea.height);
 
             establishForeignAttributes(page.getForeignAttributes());
+            documentHandler.getContext().setPageIndex(page.getPageIndex());
             documentHandler.startPage(page.getPageIndex(), page.getPageNumberString(),
                     page.getSimplePageMasterName(), dim);
             resetForeignAttributes();
@@ -598,6 +599,7 @@ public class IFRenderer extends Abstract
 
             establishForeignAttributes(page.getForeignAttributes());
             documentHandler.endPage();
+            documentHandler.getContext().setPageIndex(-1);
             resetForeignAttributes();
         } catch (IFException e) {
             handleIFException(e);
@@ -740,6 +742,12 @@ public class IFRenderer extends Abstract
     protected void renderBlockViewport(BlockViewport bv, List children) {
         //Essentially the same code as in the super class but optimized for the IF
 
+        // Handle new layer.
+        boolean inNewLayer = false;
+        if (maybeStartLayer(bv)) {
+            inNewLayer = true;
+        }
+
         //This is the content-rect
         Dimension dim = new Dimension(bv.getIPD(), bv.getBPD());
         viewportDimensionStack.push(dim);
@@ -840,6 +848,7 @@ public class IFRenderer extends Abstract
             currentBPPosition += bv.getAllocBPD();
         }
         viewportDimensionStack.pop();
+        maybeEndLayer(bv, inNewLayer);
     }
 
     /** {@inheritDoc} */
@@ -847,7 +856,7 @@ public class IFRenderer extends Abstract
         StructureTreeElement structElem
                 = (StructureTreeElement) viewport.getTrait(Trait.STRUCTURE_TREE_ELEMENT);
         establishStructureTreeElement(structElem);
-        pushdID(viewport);
+        pushID(viewport);
         Dimension dim = new Dimension(viewport.getIPD(), viewport.getBPD());
         viewportDimensionStack.push(dim);
         super.renderInlineViewport(viewport);
@@ -894,9 +903,26 @@ public class IFRenderer extends Abstract
     }
 
     /** {@inheritDoc} */
+    protected void startLayer(String layer) {
+        if (log.isTraceEnabled()) {
+            log.trace("startLayer() layer=" + layer);
+        }
+        saveGraphicsState();
+        pushGroup(new IFGraphicContext.Group(layer));
+    }
+
+    /** {@inheritDoc} */
+    protected void endLayer() {
+        if (log.isTraceEnabled()) {
+            log.trace("endLayer()");
+        }
+        restoreGraphicsState();
+    }
+
+    /** {@inheritDoc} */
     protected void renderInlineArea(InlineArea inlineArea) {
         saveInlinePosIfTargetable(inlineArea);
-        pushdID(inlineArea);
+        pushID(inlineArea);
         super.renderInlineArea(inlineArea);
         popID(inlineArea);
     }
@@ -963,7 +989,7 @@ public class IFRenderer extends Abstract
             log.trace("renderBlock() " + block);
         }
         saveBlockPosIfTargetable(block);
-        pushdID(block);
+        pushID(block);
         IFContext context = documentHandler.getContext();
         Locale oldLocale = context.getLanguage();
         context.setLanguage(block.getLocale());
@@ -975,7 +1001,7 @@ public class IFRenderer extends Abstract
         popID(block);
     }
 
-    private void pushdID(Area area) {
+    private void pushID(Area area) {
         String prodID = (String) area.getTrait(Trait.PROD_ID);
         if (prodID != null) {
             ids.push(prodID);

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/IFSerializer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/IFSerializer.java?rev=1550851&r1=1550850&r2=1550851&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/IFSerializer.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/intermediate/IFSerializer.java Fri Dec 13 23:41:13 2013
@@ -303,6 +303,7 @@ implements IFConstants, IFPainter, IFDoc
             addAttribute(atts, "width", Integer.toString(size.width));
             addAttribute(atts, "height", Integer.toString(size.height));
             addForeignAttributes(atts);
+            getContext().setPageIndex(index);
             handler.startElement(EL_PAGE, atts);
         } catch (SAXException e) {
             throw new IFException("SAX error in startPage()", e);
@@ -379,6 +380,7 @@ implements IFConstants, IFPainter, IFDoc
     public void endPage() throws IFException {
         try {
             handler.endElement(EL_PAGE);
+            getContext().setPageIndex(-1);
         } catch (SAXException e) {
             throw new IFException("SAX error in endPage()", e);
         }
@@ -426,21 +428,24 @@ implements IFConstants, IFPainter, IFDoc
     }
 
     /** {@inheritDoc} */
-    public void startGroup(AffineTransform[] transforms) throws IFException {
-        startGroup(IFUtil.toString(transforms));
+    public void startGroup(AffineTransform[] transforms, String layer) throws IFException {
+        startGroup(IFUtil.toString(transforms), layer);
     }
 
     /** {@inheritDoc} */
-    public void startGroup(AffineTransform transform) throws IFException {
-        startGroup(IFUtil.toString(transform));
+    public void startGroup(AffineTransform transform, String layer) throws IFException {
+        startGroup(IFUtil.toString(transform), layer);
     }
 
-    private void startGroup(String transform) throws IFException {
+    private void startGroup(String transform, String layer) throws IFException {
         try {
             AttributesImpl atts = new AttributesImpl();
             if (transform != null && transform.length() > 0) {
                 addAttribute(atts, "transform", transform);
             }
+            if (layer != null && layer.length() > 0) {
+                addAttribute(atts, "layer", layer);
+            }
             handler.startElement(EL_GROUP, atts);
         } catch (SAXException e) {
             throw new IFException("SAX error in startGroup()", e);

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/java2d/Java2DPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/java2d/Java2DPainter.java?rev=1550851&r1=1550850&r2=1550851&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/java2d/Java2DPainter.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/java2d/Java2DPainter.java Fri Dec 13 23:41:13 2013
@@ -143,7 +143,7 @@ public class Java2DPainter extends Abstr
     }
 
     /** {@inheritDoc} */
-    public void startGroup(AffineTransform transform) throws IFException {
+    public void startGroup(AffineTransform transform, String layer) throws IFException {
         saveGraphicsState();
         try {
             concatenateTransformationMatrix(transform);

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/java2d/Java2DRenderer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/java2d/Java2DRenderer.java?rev=1550851&r1=1550850&r2=1550851&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/java2d/Java2DRenderer.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/java2d/Java2DRenderer.java Fri Dec 13 23:41:13 2013
@@ -476,6 +476,14 @@ public abstract class Java2DRenderer ext
     }
 
     /** {@inheritDoc} */
+    protected void startLayer(String layer) {
+    }
+
+    /** {@inheritDoc} */
+    protected void endLayer() {
+    }
+
+    /** {@inheritDoc} */
     protected List breakOutOfStateStack() {
         log.debug("Block.FIXED --> break out");
         List breakOutList;

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/pcl/PCLPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/pcl/PCLPainter.java?rev=1550851&r1=1550850&r2=1550851&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/pcl/PCLPainter.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/pcl/PCLPainter.java Fri Dec 13 23:41:13 2013
@@ -126,7 +126,7 @@ public class PCLPainter extends Abstract
     }
 
     /** {@inheritDoc} */
-    public void startGroup(AffineTransform transform) throws IFException {
+    public void startGroup(AffineTransform transform, String layer) throws IFException {
         saveGraphicsState();
         try {
             concatenateTransformationMatrix(transform);

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/pdf/PDFContentGenerator.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/pdf/PDFContentGenerator.java?rev=1550851&r1=1550850&r2=1550851&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/pdf/PDFContentGenerator.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/pdf/PDFContentGenerator.java Fri Dec 13 23:41:13 2013
@@ -30,6 +30,7 @@ import org.apache.fop.pdf.PDFDocument;
 import org.apache.fop.pdf.PDFFilterList;
 import org.apache.fop.pdf.PDFNumber;
 import org.apache.fop.pdf.PDFPaintingState;
+import org.apache.fop.pdf.PDFReference;
 import org.apache.fop.pdf.PDFResourceContext;
 import org.apache.fop.pdf.PDFStream;
 import org.apache.fop.pdf.PDFText;
@@ -55,7 +56,7 @@ public class PDFContentGenerator {
     private PDFColorHandler colorHandler;
 
     /** drawing state */
-    protected PDFPaintingState currentState = null;
+    protected PDFPaintingState currentState;
     /** Text generation utility holding the current font status */
     protected PDFTextUtil textutil;
 
@@ -156,15 +157,23 @@ public class PDFContentGenerator {
      */
     protected void comment(String text) {
         if (WRITE_COMMENTS) {
-            currentStream.add("% " + text + "\n");
+            getStream().add("% " + text + "\n");
         }
     }
 
     /** Save graphics state. */
     protected void saveGraphicsState() {
         endTextObject();
-        currentState.save();
-        currentStream.add("q\n");
+        getState().save();
+        getStream().add("q\n");
+    }
+
+    /** Save graphics state with optional layer. */
+    protected void saveGraphicsState(String layer) {
+        endTextObject();
+        getState().save();
+        maybeBeginLayer(layer);
+        getStream().add("q\n");
     }
 
     /**
@@ -174,9 +183,9 @@ public class PDFContentGenerator {
      */
     protected void saveGraphicsState(String structElemType, int sequenceNum) {
         endTextObject();
-        currentState.save();
+        getState().save();
         beginMarkedContentSequence(structElemType, sequenceNum);
-        currentStream.add("q\n");
+        getStream().add("q\n");
     }
 
     /**
@@ -208,18 +217,18 @@ public class PDFContentGenerator {
         if (structElemType != null) {
             String actualTextProperty = actualText == null ? ""
                     : " /ActualText " + PDFText.escapeText(actualText);
-            currentStream.add(structElemType + " <</MCID " + String.valueOf(mcid)
+            getStream().add(structElemType + " <</MCID " + String.valueOf(mcid)
                     + actualTextProperty + ">>\n"
                     + "BDC\n");
         } else {
-            currentStream.add("/Artifact\nBMC\n");
+            getStream().add("/Artifact\nBMC\n");
             this.inArtifactMode = true;
         }
         this.inMarkedContentSequence = true;
     }
 
     void endMarkedContentSequence() {
-        currentStream.add("EMC\n");
+        getStream().add("EMC\n");
         this.inMarkedContentSequence = false;
         this.inArtifactMode = false;
     }
@@ -231,9 +240,10 @@ public class PDFContentGenerator {
      */
     protected void restoreGraphicsState(boolean popState) {
         endTextObject();
-        currentStream.add("Q\n");
+        getStream().add("Q\n");
+        maybeEndLayer();
         if (popState) {
-            currentState.restore();
+            getState().restore();
         }
     }
 
@@ -251,11 +261,42 @@ public class PDFContentGenerator {
      */
     protected void restoreGraphicsStateAccess() {
         endTextObject();
-        currentStream.add("Q\n");
+        getStream().add("Q\n");
         if (this.inMarkedContentSequence) {
             endMarkedContentSequence();
         }
-        currentState.restore();
+        getState().restore();
+    }
+
+    private void maybeBeginLayer(String layer) {
+        if ((layer != null) && (layer.length() > 0)) {
+            getState().setLayer(layer);
+            beginOptionalContent(layer);
+        }
+    }
+
+    private void maybeEndLayer() {
+        if (getState().getLayerChanged()) {
+            endOptionalContent();
+        }
+    }
+
+    private int ocNameIndex = 0;
+
+    private void beginOptionalContent(String layerId) {
+        String name;
+        PDFReference layer = document.resolveExtensionReference(layerId);
+        if (layer != null) {
+            name = "oc" + ++ocNameIndex;
+            document.getResources().addProperty(name, layer);
+        } else {
+            name = "unknown";
+        }
+        getStream().add("/OC /" + name + " BDC\n");
+    }
+
+    private void endOptionalContent() {
+        getStream().add("EMC\n");
     }
 
     /** Indicates the beginning of a text object. */
@@ -310,8 +351,8 @@ public class PDFContentGenerator {
     public void concatenate(AffineTransform transform) {
         this.transform = transform;
         if (!transform.isIdentity()) {
-            currentState.concatenate(transform);
-            currentStream.add(CTMHelper.toPDFString(transform, false) + " cm\n");
+            getState().concatenate(transform);
+            getStream().add(CTMHelper.toPDFString(transform, false) + " cm\n");
         }
     }
 
@@ -333,7 +374,7 @@ public class PDFContentGenerator {
      * @param content the PDF content
      */
     public void add(String content) {
-        currentStream.add(content);
+        getStream().add(content);
     }
 
     /**
@@ -350,9 +391,9 @@ public class PDFContentGenerator {
      * @param width line width in points
      */
     public void updateLineWidth(float width) {
-        if (currentState.setLineWidth(width)) {
+        if (getState().setLineWidth(width)) {
             //Only write if value has changed WRT the current line width
-            currentStream.add(format(width) + " w\n");
+            getStream().add(format(width) + " w\n");
         }
     }
 
@@ -362,7 +403,7 @@ public class PDFContentGenerator {
      */
     public void updateCharacterSpacing(float value) {
         if (getState().setCharacterSpacing(value)) {
-            currentStream.add(format(value) + " Tc\n");
+            getStream().add(format(value) + " Tc\n");
         }
     }
 
@@ -400,7 +441,7 @@ public class PDFContentGenerator {
         if (pdf != null) {
             colorHandler.establishColor(pdf, col, fill);
         } else {
-            setColor(col, fill, this.currentStream);
+            setColor(col, fill, getStream());
         }
     }
 

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java?rev=1550851&r1=1550850&r2=1550851&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java Fri Dec 13 23:41:13 2013
@@ -50,7 +50,8 @@ import org.apache.fop.render.intermediat
 import org.apache.fop.render.intermediate.IFException;
 import org.apache.fop.render.intermediate.IFPainter;
 import org.apache.fop.render.pdf.PDFRendererConfig.PDFRendererConfigParser;
-import org.apache.fop.render.pdf.extensions.PDFEmbeddedFileExtensionAttachment;
+import org.apache.fop.render.pdf.extensions.PDFDictionaryAttachment;
+import org.apache.fop.render.pdf.extensions.PDFEmbeddedFileAttachment;
 
 /**
  * {@link org.apache.fop.render.intermediate.IFDocumentHandler} implementation that produces PDF.
@@ -296,17 +297,21 @@ public class PDFDocumentHandler extends 
         } else if (extension instanceof Metadata) {
             XMPMetadata wrapper = new XMPMetadata(((Metadata) extension));
             pdfUtil.renderXMPMetadata(wrapper);
-        } else if (extension instanceof PDFEmbeddedFileExtensionAttachment) {
-            PDFEmbeddedFileExtensionAttachment embeddedFile
-                = (PDFEmbeddedFileExtensionAttachment)extension;
+        } else if (extension instanceof PDFEmbeddedFileAttachment) {
+            PDFEmbeddedFileAttachment embeddedFile
+                = (PDFEmbeddedFileAttachment)extension;
             try {
                 pdfUtil.addEmbeddedFile(embeddedFile);
             } catch (IOException ioe) {
                 throw new IFException("Error adding embedded file: " + embeddedFile.getSrc(), ioe);
             }
-        } else {
+        } else if (extension instanceof PDFDictionaryAttachment) {
+            pdfUtil.renderDictionaryExtension((PDFDictionaryAttachment) extension, currentPage);
+        } else if (extension != null) {
             log.debug("Don't know how to handle extension object. Ignoring: "
                     + extension + " (" + extension.getClass().getName() + ")");
+        } else {
+            log.debug("Ignoring null extension object.");
         }
     }
 



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


Mime
View raw message