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 vh...@apache.org on 2014/07/18 21:48:02 UTC

svn commit: r1611783 [2/2] - in /xmlgraphics/fop/trunk: ./ src/java/org/apache/fop/pdf/ src/java/org/apache/fop/render/gradient/ src/java/org/apache/fop/render/ps/ src/java/org/apache/fop/render/ps/svg/ src/java/org/apache/fop/render/shading/ src/java/...

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=1611783&r1=1611782&r2=1611783&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 Fri Jul 18 19:48:02 2014
@@ -36,7 +36,6 @@ import java.awt.Stroke;
 import java.awt.color.ColorSpace;
 import java.awt.geom.AffineTransform;
 import java.awt.geom.PathIterator;
-import java.awt.geom.Point2D;
 import java.awt.geom.Rectangle2D;
 import java.awt.image.BufferedImage;
 import java.awt.image.ColorModel;
@@ -50,6 +49,7 @@ import java.awt.image.renderable.Rendera
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.StringWriter;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
@@ -93,15 +93,13 @@ 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.gradient.Function;
+import org.apache.fop.render.gradient.GradientMaker;
+import org.apache.fop.render.gradient.Pattern;
+import org.apache.fop.render.gradient.Shading;
 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.
@@ -112,7 +110,7 @@ import org.apache.fop.render.shading.Sha
  *
  * @see org.apache.batik.ext.awt.g2d.AbstractGraphics2D
  */
-public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHandler, GradientRegistrar {
+public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHandler {
     private static final AffineTransform IDENTITY_TRANSFORM = new AffineTransform();
 
     /** The number of decimal places. */
@@ -818,159 +816,18 @@ public class PDFGraphics2D extends Abstr
                     new Color[] {gpaint.getColor1(), gpaint.getColor2()},
                     gpaint.isCyclic() ? LinearGradientPaint.REPEAT : LinearGradientPaint.NO_CYCLE);
         }
-        if (paint instanceof LinearGradientPaint) {
-            LinearGradientPaint gp = (LinearGradientPaint)paint;
-
-            // This code currently doesn't support 'repeat'.
-            // For linear gradients it is possible to construct
-            // a 'tile' that is repeated with a PDF pattern, but
-            // it would be very tricky as you would have to rotate
-            // the coordinate system so the repeat was axially
-            // aligned.  At this point I'm just going to rasterize it.
-            MultipleGradientPaint.CycleMethodEnum cycle = gp.getCycleMethod();
-            if (cycle != MultipleGradientPaint.NO_CYCLE) {
-                return false;
-            }
-
-            Color[] cols = gp.getColors();
-            float[] fractions = gp.getFractions();
-
-            // Build proper transform from gradient space to page space
-            // ('Patterns' don't get userspace transform).
-            AffineTransform transform;
-            transform = new AffineTransform(getBaseTransform());
-            transform.concatenate(getTransform());
-            transform.concatenate(gp.getTransform());
-
-            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(new Double(mat[idx]));
-            }
-
-            Point2D p1 = gp.getStartPoint();
-            Point2D p2 = gp.getEndPoint();
-            List<Double> theCoords = new java.util.ArrayList<Double>();
-            theCoords.add(new Double(p1.getX()));
-            theCoords.add(new Double(p1.getY()));
-            theCoords.add(new Double(p2.getX()));
-            theCoords.add(new Double(p2.getY()));
-
-            List<Boolean> theExtend = new java.util.ArrayList<Boolean>();
-            theExtend.add(Boolean.TRUE);
-            theExtend.add(Boolean.TRUE);
-
-            List<Double> theDomain = new java.util.ArrayList<Double>();
-            theDomain.add(new Double(0));
-            theDomain.add(new Double(1));
-
-            List<Double> theEncode = new java.util.ArrayList<Double>();
-            theEncode.add(new Double(0));
-            theEncode.add(new Double(1));
-            theEncode.add(new Double(0));
-            theEncode.add(new Double(1));
-
-            List<Double> theBounds = new java.util.ArrayList<Double>();
-
-            List<Color> someColors = new java.util.ArrayList<Color>();
-
-            for (int count = 0; count < cols.length; count++) {
-                Color c1 = cols[count];
-                if (c1.getAlpha() != 255) {
-                    return false;  // PDF can't do alpha
-                }
-
-                //PDFColor color1 = new PDFColor(c1.getRed(), c1.getGreen(),
-                //                               c1.getBlue());
-                someColors.add(c1);
-                if (count > 0 && count < cols.length - 1) {
-                    theBounds.add(new Double(fractions[count]));
-                }
-            }
-
-            //Gradients are currently restricted to sRGB
-            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));
-
+        if (paint instanceof LinearGradientPaint && gradientSupported((LinearGradientPaint) paint)) {
+            Pattern pattern = GradientMaker.makeLinearGradient((LinearGradientPaint) paint,
+                    getBaseTransform(), getTransform());
+            PDFPattern pdfPattern = createPDFPattern(pattern);
+            currentStream.write(pdfPattern.getColorSpaceOut(fill));
             return true;
         }
-        if (paint instanceof RadialGradientPaint) {
-            RadialGradientPaint rgp = (RadialGradientPaint)paint;
-
-            // There is essentially no way to support repeats
-            // in PDF for radial gradients (the one option would
-            // be to 'grow' the outer circle until it fully covered
-            // the bounds and then grow the stops accordingly, the
-            // problem is that this may require an extremely large
-            // number of stops for cases where the focus is near
-            // the edge of the outer circle).  so we rasterize.
-            MultipleGradientPaint.CycleMethodEnum cycle = rgp.getCycleMethod();
-            if (cycle != MultipleGradientPaint.NO_CYCLE) {
-                return false;
-            }
-
-            AffineTransform transform;
-            transform = new AffineTransform(getBaseTransform());
-            transform.concatenate(getTransform());
-            transform.concatenate(rgp.getTransform());
-
-            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(new Double(mat[idx]));
-            }
-
-            double ar = rgp.getRadius();
-            Point2D ac = rgp.getCenterPoint();
-            Point2D af = rgp.getFocusPoint();
-
-            List<Double> theCoords = new java.util.ArrayList<Double>();
-            double dx = af.getX() - ac.getX();
-            double dy = af.getY() - ac.getY();
-            double d = Math.sqrt(dx * dx + dy * dy);
-            if (d > ar) {
-                // the center point af must be within the circle with
-                // radius ar centered at ac so limit it to that.
-                double scale = (ar * .9999) / d;
-                dx = dx * scale;
-                dy = dy * scale;
-            }
-
-            theCoords.add(new Double(ac.getX() + dx)); // Fx
-            theCoords.add(new Double(ac.getY() + dy)); // Fy
-            theCoords.add(new Double(0));
-            theCoords.add(new Double(ac.getX()));
-            theCoords.add(new Double(ac.getY()));
-            theCoords.add(new Double(ar));
-
-            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) {
-                    return false;  // PDF can't do alpha
-                }
-
-                someColors.add(cc);
-            }
-
-            float[] fractions = rgp.getFractions();
-            List<Double> theBounds = new java.util.ArrayList<Double>();
-            for (int count = 1; count < fractions.length - 1; count++) {
-                float offset = fractions[count];
-                theBounds.add(new Double(offset));
-            }
-            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));
-
+        if (paint instanceof RadialGradientPaint && gradientSupported((RadialGradientPaint) paint)) {
+            Pattern pattern = GradientMaker.makeRadialGradient((RadialGradientPaint) paint,
+                    getBaseTransform(), getTransform());
+            PDFPattern pdfPattern = createPDFPattern(pattern);
+            currentStream.write(pdfPattern.getColorSpaceOut(fill));
             return true;
         }
         if (paint instanceof PatternPaint) {
@@ -980,6 +837,47 @@ public class PDFGraphics2D extends Abstr
         return false; // unknown paint
     }
 
+    private PDFPattern createPDFPattern(Pattern pattern) {
+        Shading shading = pattern.getShading();
+        Function function = shading.getFunction();
+        List<PDFFunction> pdfFunctions = new ArrayList<PDFFunction>(function.getFunctions().size());
+        for (Function f : function.getFunctions()) {
+            pdfFunctions.add(registerFunction(new PDFFunction(f)));
+        }
+        PDFFunction pdfFunction = registerFunction(new PDFFunction(function, pdfFunctions));
+        PDFShading pdfShading = new PDFShading(shading.getShadingType(), shading.getColorSpace(), shading.getCoords(),
+                pdfFunction);
+        pdfShading = registerShading(pdfShading);
+        PDFPattern pdfPattern = new PDFPattern(pattern.getPatternType(), pdfShading, null, null, pattern.getMatrix());
+        return registerPattern(pdfPattern);
+    }
+
+    private boolean gradientSupported(MultipleGradientPaint gradient) {
+        return !(gradientContainsTransparency(gradient) || gradientIsRepeated(gradient));
+    }
+
+    private boolean gradientContainsTransparency(MultipleGradientPaint gradient) {
+        for (Color color : gradient.getColors()) {
+            if (color.getAlpha() != 255) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean gradientIsRepeated(MultipleGradientPaint gradient) {
+         // For linear gradients it is possible to construct a 'tile' that is repeated with
+         // a PDF pattern, but it would be very tricky as the coordinate system would have
+         // to be rotated so the repeat is axially aligned.
+
+         // For radial gradients there is essentially no way to support repeats in PDF (the
+         // one option would be to 'grow' the outer circle until it fully covers the
+         // bounds and then grow the stops accordingly, the problem is that this may
+         // require an extremely large number of stops for cases where the focus is near
+         // the edge of the outer circle).
+        return (gradient.getCycleMethod() != MultipleGradientPaint.NO_CYCLE);
+    }
+
     private boolean createPattern(PatternPaint pp, boolean fill) {
         preparePainting();
 
@@ -1883,8 +1781,8 @@ public class PDFGraphics2D extends Abstr
      * @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);
+    public PDFFunction registerFunction(PDFFunction function) {
+        return pdfDoc.getFactory().registerFunction(function);
     }
 
     /**
@@ -1893,9 +1791,8 @@ public class PDFGraphics2D extends Abstr
      * @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);
+    public PDFShading registerShading(PDFShading shading) {
+        return pdfDoc.getFactory().registerShading(resourceContext, shading);
     }
 
     /**
@@ -1904,9 +1801,8 @@ public class PDFGraphics2D extends Abstr
      * @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);
+    public PDFPattern registerPattern(PDFPattern pattern) {
+        return pdfDoc.getFactory().registerPattern(resourceContext, pattern);
     }
 
 }



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