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