Author: ssteiner Date: Thu Dec 17 11:40:55 2015 New Revision: 1720524 URL: http://svn.apache.org/viewvc?rev=1720524&view=rev Log: FOP-2553: Support PDF shading to PS
Modified: xmlgraphics/fop-pdf-images/trunk/lib/fontbox-2.0.0-SNAPSHOT.jar xmlgraphics/fop-pdf-images/trunk/lib/fop.jar xmlgraphics/fop-pdf-images/trunk/lib/pdfbox-2.0.0-SNAPSHOT.jar xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/FOPPDFSingleByteFont.java xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/ImageConverterPDF2G2D.java xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/MergeFontsPDFWriter.java xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PDFWriter.java xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PSPDFGraphics2D.java Modified: xmlgraphics/fop-pdf-images/trunk/lib/fontbox-2.0.0-SNAPSHOT.jar URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/lib/fontbox-2.0.0-SNAPSHOT.jar?rev=1720524&r1=1720523&r2=1720524&view=diff ============================================================================== Binary files - no diff available. Modified: xmlgraphics/fop-pdf-images/trunk/lib/fop.jar URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/lib/fop.jar?rev=1720524&r1=1720523&r2=1720524&view=diff ============================================================================== Binary files - no diff available. Modified: xmlgraphics/fop-pdf-images/trunk/lib/pdfbox-2.0.0-SNAPSHOT.jar URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/lib/pdfbox-2.0.0-SNAPSHOT.jar?rev=1720524&r1=1720523&r2=1720524&view=diff ============================================================================== Binary files - no diff available. Modified: xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/FOPPDFSingleByteFont.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/FOPPDFSingleByteFont.java?rev=1720524&r1=1720523&r2=1720524&view=diff ============================================================================== --- xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/FOPPDFSingleByteFont.java (original) +++ xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/FOPPDFSingleByteFont.java Thu Dec 17 11:40:55 2015 @@ -38,7 +38,6 @@ import org.apache.pdfbox.cos.COSDictiona import org.apache.pdfbox.cos.COSName; import org.apache.pdfbox.cos.COSNumber; import org.apache.pdfbox.encoding.Encoding; -import org.apache.pdfbox.encoding.EncodingManager; import org.apache.pdfbox.pdmodel.common.PDStream; import org.apache.pdfbox.pdmodel.font.PDFont; import org.apache.pdfbox.pdmodel.font.PDFontDescriptorDictionary; @@ -117,7 +116,7 @@ public class FOPPDFSingleByteFont extend addEncoding(font); } - private Map<Integer, String> getCodeToName(Encoding encoding) { + private Map<Integer, String> getCodeToName(Encoding encoding) throws IOException { Map<Integer, String> codeToName = new HashMap<Integer, String>(); if (encoding != null) { COSBase cos = encoding.getCOSObject(); @@ -125,12 +124,8 @@ public class FOPPDFSingleByteFont extend COSDictionary enc = (COSDictionary) cos; COSName baseEncodingName = (COSName) enc.getDictionaryObject(COSName.BASE_ENCODING); if (baseEncodingName != null) { - try { - Encoding baseEncoding = EncodingManager.INSTANCE.getEncoding(baseEncodingName); - codeToName.putAll(baseEncoding.getCodeToNameMap()); - } catch (IOException e) { - throw new RuntimeException(e); - } + Encoding baseEncoding = Encoding.getInstance(baseEncodingName); + codeToName.putAll(baseEncoding.getCodeToNameMap()); } COSArray differences = (COSArray)enc.getDictionaryObject(COSName.DIFFERENCES); int currentIndex = -1; @@ -359,7 +354,7 @@ public class FOPPDFSingleByteFont extend return null; } - private void addEncoding(PDFont fontForEnc) { + private void addEncoding(PDFont fontForEnc) throws IOException { List<String> added = new ArrayList<String>(encodingMap.values()); Map<Integer, String> codeToName = getCodeToName(fontForEnc.getFontEncoding()); for (int i = fontForEnc.getFirstChar(); i <= fontForEnc.getLastChar(); i++) { Modified: xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/ImageConverterPDF2G2D.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/ImageConverterPDF2G2D.java?rev=1720524&r1=1720523&r2=1720524&view=diff ============================================================================== --- xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/ImageConverterPDF2G2D.java (original) +++ xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/ImageConverterPDF2G2D.java Thu Dec 17 11:40:55 2015 @@ -134,8 +134,8 @@ public class ImageConverterPDF2G2D exten area.getHeight() / pageDimension.height); g2d.transform(at); - PageDrawer drawer = new PageDrawer(null); - drawer.drawPage(g2d, page, mediaBox); + PageDrawer drawer = new PageDrawer(null, page); + drawer.drawPage(g2d, mediaBox); } catch (IOException ioe) { //TODO Better exception handling throw new RuntimeException("I/O error while painting PDF page", ioe); Modified: xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/MergeFontsPDFWriter.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/MergeFontsPDFWriter.java?rev=1720524&r1=1720523&r2=1720524&view=diff ============================================================================== --- xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/MergeFontsPDFWriter.java (original) +++ xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/MergeFontsPDFWriter.java Thu Dec 17 11:40:55 2015 @@ -48,7 +48,7 @@ import org.apache.pdfbox.pdmodel.font.PD import org.apache.pdfbox.pdmodel.font.PDTrueTypeFont; import org.apache.pdfbox.pdmodel.font.PDType0Font; import org.apache.pdfbox.pdmodel.font.PDType1Font; -import org.apache.pdfbox.util.operator.PDFOperator; +import org.apache.pdfbox.util.operator.Operator; import org.apache.fop.fonts.FontInfo; import org.apache.fop.fonts.SingleByteFont; @@ -85,7 +85,7 @@ public class MergeFontsPDFWriter extends return txt; } - protected void readPDFArguments(PDFOperator op, Collection<COSBase> arguments) throws IOException { + protected void readPDFArguments(Operator op, Collection<COSBase> arguments) throws IOException { for (COSBase c : arguments) { if (c instanceof COSName) { COSName cn = (COSName)c; Modified: xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PDFWriter.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PDFWriter.java?rev=1720524&r1=1720523&r2=1720524&view=diff ============================================================================== --- xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PDFWriter.java (original) +++ xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PDFWriter.java Thu Dec 17 11:40:55 2015 @@ -36,7 +36,7 @@ import org.apache.pdfbox.cos.COSName; import org.apache.pdfbox.cos.COSString; import org.apache.pdfbox.pdfparser.PDFStreamParser; import org.apache.pdfbox.pdmodel.common.PDStream; -import org.apache.pdfbox.util.operator.PDFOperator; +import org.apache.pdfbox.util.operator.Operator; public class PDFWriter { protected StringBuilder s = new StringBuilder(); @@ -55,8 +55,8 @@ public class PDFWriter { List<COSBase> arguments = new ArrayList<COSBase>(); while (it.hasNext()) { Object o = it.next(); - if (o instanceof PDFOperator) { - PDFOperator op = (PDFOperator)o; + if (o instanceof Operator) { + Operator op = (Operator)o; readPDFArguments(op, arguments); s.append(op.getOperation() + "\n"); arguments.clear(); @@ -77,13 +77,13 @@ public class PDFWriter { return s.toString(); } - protected void readPDFArguments(PDFOperator op, Collection<COSBase> arguments) throws IOException { + protected void readPDFArguments(Operator op, Collection<COSBase> arguments) throws IOException { for (COSBase c : arguments) { processArg(op, c); } } - protected void processArg(PDFOperator op, COSBase c) throws IOException { + protected void processArg(Operator op, COSBase c) throws IOException { if (c instanceof COSInteger) { s.append(((COSInteger) c).intValue()); s.append(" "); Modified: xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PSPDFGraphics2D.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PSPDFGraphics2D.java?rev=1720524&r1=1720523&r2=1720524&view=diff ============================================================================== --- xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PSPDFGraphics2D.java (original) +++ xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PSPDFGraphics2D.java Thu Dec 17 11:40:55 2015 @@ -24,7 +24,10 @@ 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.geom.AffineTransform; import java.awt.image.BufferedImage; import java.awt.image.DataBufferInt; import java.awt.image.ImageObserver; @@ -33,7 +36,28 @@ import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.URI; +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.color.PDColorSpace; +import org.apache.pdfbox.pdmodel.graphics.pattern.TilingPaint; +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.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageSize; @@ -42,6 +66,13 @@ import org.apache.xmlgraphics.java2d.ps. 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; @@ -59,6 +90,127 @@ public class PSPDFGraphics2D extends PSG super(textAsShapes, gen); } + 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, null, null, new AffineTransform(), + getRenderingHints()); + PDColorSpace pdcs; + int deviceColorSpace = PDFDeviceColorSpace.DEVICE_RGB; + if (paint instanceof AxialShadingPaint) { + try { + AxialShadingContext asc = (AxialShadingContext) paintContext; + float[] fCoords = asc.getCoords(); + PDFunction function = asc.getFunction(); + Function targetFT = getFunction(function); + if (targetFT != null) { + if (targetFT.getFunctions().size() == 5 + && targetFT.getFunctions().get(0).getFunctionType() == 0) { + return; + } + List<Double> 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(); + PDFunction function = rsc.getFunction(); + Function targetFT3 = getFunction(function); + List<Double> 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); + } + } + } + if (paint instanceof TilingPaint) { + super.applyPaint(paint, fill); + } + } + + private static Function getFunction(PDFunction f) throws IOException { + if (f instanceof PDFunctionType3) { + PDFunctionType3 sourceFT3 = (PDFunctionType3) f; + float[] bounds = sourceFT3.getBounds().toFloatArray(); + COSArray sourceFunctions = sourceFT3.getFunctions(); + List<Function> targetFunctions = new ArrayList<Function>(); + for (int j = 0; j < sourceFunctions.size(); j++) { + targetFunctions.add(getFunction(PDFunction.create(sourceFunctions.get(j)))); + } + return new Function(null, null, targetFunctions, toList(bounds), null); + } else if (f instanceof PDFunctionType2) { + PDFunctionType2 sourceFT2 = (PDFunctionType2) f; + double interpolation = (double)sourceFT2.getN(); + float[] c0 = sourceFT2.getC0().toFloatArray(); + float[] c1 = sourceFT2.getC1().toFloatArray(); + return new Function(null, null, c0, c1, interpolation); + } else if (f instanceof PDFunctionType0) { + COSDictionary s = f.getDictionary(); + assert s instanceof COSStream; + COSStream stream = (COSStream) s; + COSArray encode = (COSArray) s.getDictionaryObject(COSName.ENCODE); + COSArray domain = (COSArray) s.getDictionaryObject(COSName.DOMAIN); + COSArray range = (COSArray) s.getDictionaryObject(COSName.RANGE); + int bits = ((COSInteger)s.getDictionaryObject(COSName.BITS_PER_SAMPLE)).intValue(); + COSArray size = (COSArray) s.getDictionaryObject(COSName.SIZE); + byte[] x = IOUtils.toByteArray(stream.getUnfilteredStream()); + for (byte y : x) { + if (y != 0) { + return new Function(floatArrayToDoubleList(domain.toFloatArray()), + floatArrayToDoubleList(range.toFloatArray()), + floatArrayToDoubleList(encode.toFloatArray()), + x, + bits, + toList(size) + ); + } + } + return null; + } + throw new IOException("Unsupported " + f.toString()); + } + + private static List<Float> toList(float[] array) { + List<Float> list = new ArrayList<Float>(array.length); + for (float f : array) { + list.add(f); + } + return list; + } + + private static List<Integer> toList(COSArray array) { + List<Integer> list = new ArrayList<Integer>(); + for (COSBase i : array) { + list.add(((COSInteger)i).intValue()); + } + return list; + } + + private static List<Double> floatArrayToDoubleList(float[] floatArray) { + List<Double> doubleList = new ArrayList<Double>(); + for (float f : floatArray) { + doubleList.add((double) f); + } + return doubleList; + } + @Override public boolean drawImage(Image img, int x1, int y1, ImageObserver observer) { PSGenerator tmp = gen; --------------------------------------------------------------------- To unsubscribe, e-mail: fop-commits-unsubscr...@xmlgraphics.apache.org For additional commands, e-mail: fop-commits-h...@xmlgraphics.apache.org