org.apache.fop.render.pdf.pdfbox.PSPDFGraphics2D Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fop-pdf-images Show documentation
Show all versions of fop-pdf-images Show documentation
Apache FOP PDF Images plug-in extends FOP in order to add support for using PDF images in fo:external-graphic elements when generating PDF files.
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* $Id$ */
package org.apache.fop.render.pdf.pdfbox;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Paint;
import java.awt.PaintContext;
import java.awt.Rectangle;
import java.awt.TexturePaint;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DataBufferInt;
import java.awt.image.ImageObserver;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URI;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.io.IOUtils;
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSInteger;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSStream;
import org.apache.pdfbox.pdmodel.common.function.PDFunction;
import org.apache.pdfbox.pdmodel.common.function.PDFunctionType0;
import org.apache.pdfbox.pdmodel.common.function.PDFunctionType2;
import org.apache.pdfbox.pdmodel.common.function.PDFunctionType3;
import org.apache.pdfbox.pdmodel.graphics.shading.AxialShadingContext;
import org.apache.pdfbox.pdmodel.graphics.shading.AxialShadingPaint;
import org.apache.pdfbox.pdmodel.graphics.shading.RadialShadingContext;
import org.apache.pdfbox.pdmodel.graphics.shading.RadialShadingPaint;
import org.apache.pdfbox.pdmodel.graphics.shading.ShadingPaint;
import org.apache.pdfbox.util.Matrix;
import org.apache.xmlgraphics.image.loader.ImageInfo;
import org.apache.xmlgraphics.image.loader.ImageSize;
import org.apache.xmlgraphics.io.TempResourceURIGenerator;
import org.apache.xmlgraphics.java2d.ps.PSGraphics2D;
import org.apache.xmlgraphics.ps.PSGenerator;
import org.apache.xmlgraphics.ps.PSResource;
import org.apache.fop.pdf.PDFDeviceColorSpace;
import org.apache.fop.render.gradient.Function;
import org.apache.fop.render.gradient.GradientMaker;
import org.apache.fop.render.gradient.GradientMaker.DoubleFormatter;
import org.apache.fop.render.gradient.Pattern;
import org.apache.fop.render.gradient.Shading;
import org.apache.fop.render.ps.Gradient;
import org.apache.fop.render.ps.PSDocumentHandler;
import org.apache.fop.render.ps.PSImageUtils;
public class PSPDFGraphics2D extends PSGraphics2D {
private boolean clearRect;
public PSPDFGraphics2D(boolean textAsShapes) {
super(textAsShapes);
}
public PSPDFGraphics2D(PSGraphics2D g) {
super(g);
}
public PSPDFGraphics2D(boolean textAsShapes, PSGenerator gen) {
super(textAsShapes, gen);
}
public void clearRect(int x, int y, int width, int height) {
if (clearRect) {
super.clearRect(x, y, width, height);
}
clearRect = true;
}
private final GradientMaker.DoubleFormatter doubleFormatter = new DoubleFormatter() {
public String formatDouble(double d) {
return getPSGenerator().formatDouble(d);
}
};
protected void applyPaint(Paint paint, boolean fill) {
preparePainting();
if (paint instanceof AxialShadingPaint || paint instanceof RadialShadingPaint) {
PaintContext paintContext = paint.createContext(null, new Rectangle(), null, new AffineTransform(),
getRenderingHints());
int deviceColorSpace = PDFDeviceColorSpace.DEVICE_RGB;
if (paint instanceof AxialShadingPaint) {
try {
AxialShadingContext asc = (AxialShadingContext) paintContext;
float[] fCoords = asc.getCoords();
transformCoords(fCoords, (ShadingPaint) paint, true);
PDFunction function = asc.getFunction();
Function targetFT = getFunction(function);
if (targetFT != null) {
if (targetFT.getFunctions().size() == 5
&& targetFT.getFunctions().get(0).getFunctionType() == 0) {
return;
}
List dCoords = floatArrayToDoubleList(fCoords);
PDFDeviceColorSpace colSpace = new PDFDeviceColorSpace(deviceColorSpace);
Shading shading = new Shading(2, colSpace, dCoords, targetFT);
Pattern pattern = new Pattern(2, shading, null);
gen.write(Gradient.outputPattern(pattern, doubleFormatter));
}
} catch (IOException ioe) {
handleIOException(ioe);
}
} else if (paint instanceof RadialShadingPaint) {
try {
RadialShadingContext rsc = (RadialShadingContext) paintContext;
float[] fCoords = rsc.getCoords();
transformCoords(fCoords, (ShadingPaint) paint, false);
PDFunction function = rsc.getFunction();
Function targetFT3 = getFunction(function);
List dCoords = floatArrayToDoubleList(fCoords);
PDFDeviceColorSpace colSpace = new PDFDeviceColorSpace(deviceColorSpace);
Shading shading = new Shading(3, colSpace, dCoords, targetFT3);
Pattern pattern = new Pattern(2, shading, null);
gen.write(Gradient.outputPattern(pattern, doubleFormatter));
} catch (IOException ioe) {
handleIOException(ioe);
}
}
} else if (paint.getClass().getSimpleName().equals("TilingPaint")) {
TexturePaint texturePaint = (TexturePaint) getField(paint, "paint");
Matrix matrix = (Matrix) getField(paint, "patternMatrix");
Rectangle2D rect = getTransformedRect(matrix, texturePaint.getAnchorRect());
texturePaint = new TexturePaint(texturePaint.getImage(), rect);
super.applyPaint(texturePaint, fill);
}
}
private static Object getField(final Paint paint, final String field) {
return AccessController.doPrivileged(new PrivilegedAction