diff options
author | Keiron Liddle <keiron@apache.org> | 2002-06-27 11:45:55 +0000 |
---|---|---|
committer | Keiron Liddle <keiron@apache.org> | 2002-06-27 11:45:55 +0000 |
commit | d3b6621df5e65468d8fa65ad35e07e316635e97c (patch) | |
tree | 2e884f12b1b33cbb472a8cb8be218de5e5fbd95e /src/org | |
parent | e86556e4f1a88428e437e805774090f40ca14ccb (diff) | |
download | xmlgraphics-fop-d3b6621df5e65468d8fa65ad35e07e316635e97c.tar.gz xmlgraphics-fop-d3b6621df5e65468d8fa65ad35e07e316635e97c.zip |
added transparency for images
made pdf package more self contained
started on patterns/gradients for svg
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@194926 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/org')
27 files changed, 747 insertions, 480 deletions
diff --git a/src/org/apache/fop/image/AbstractFopImage.java b/src/org/apache/fop/image/AbstractFopImage.java index 9b3a91d73..2b1dec82d 100644 --- a/src/org/apache/fop/image/AbstractFopImage.java +++ b/src/org/apache/fop/image/AbstractFopImage.java @@ -9,9 +9,10 @@ package org.apache.fop.image; // Java import java.net.URL; +import java.awt.color.ColorSpace; +import java.awt.color.ICC_Profile; // FOP -import org.apache.fop.datatypes.ColorSpace; import org.apache.fop.pdf.PDFColor; import org.apache.fop.pdf.PDFFilter; import org.apache.fop.image.analyser.ImageReaderFactory; @@ -78,12 +79,6 @@ public abstract class AbstractFopImage implements FopImage { protected PDFColor m_transparentColor = null; /** - * Image compression type. - * Added by Eric Dalquist - */ - protected PDFFilter m_compressionType = null; - - /** * Constructor. * Construct a new FopImage object and initialize its default properties: * <UL> @@ -172,6 +167,10 @@ public abstract class AbstractFopImage implements FopImage { return this.m_colorSpace; } + public ICC_Profile getICCProfile() { + return null; + } + /** * Return the number of bits per pixel. * @return number of bits per pixel @@ -188,6 +187,14 @@ public abstract class AbstractFopImage implements FopImage { return this.m_isTransparent; } + public boolean hasSoftMask() { + return false; + } + + public byte[] getSoftMask() { + return null; + } + /** * Return the transparent color. * @return the transparent color (org.apache.fop.pdf.PDFColor) @@ -228,19 +235,5 @@ public abstract class AbstractFopImage implements FopImage { return 0; } - /** - * Return the original image compression type. - * @return the original image compression type (org.apache.fop.pdf.PDFFilter) - */ - public PDFFilter getPDFFilter() { - - /* - * Added by Eric Dalquist - * Using the bitsPerPixel var as our flag since many imges will - * have a null m_compressionType even after being loaded - */ - return m_compressionType; - } - } diff --git a/src/org/apache/fop/image/BmpImage.java b/src/org/apache/fop/image/BmpImage.java index d58fe94e9..26cd3c5a5 100644 --- a/src/org/apache/fop/image/BmpImage.java +++ b/src/org/apache/fop/image/BmpImage.java @@ -18,9 +18,9 @@ package org.apache.fop.image; import java.net.URL; import java.io.InputStream; import java.io.IOException; +import java.awt.color.ColorSpace; // FOP -import org.apache.fop.datatypes.ColorSpace; import org.apache.fop.pdf.PDFColor; import org.apache.fop.image.analyser.ImageReader; import org.apache.fop.fo.FOUserAgent; @@ -86,7 +86,7 @@ public class BmpImage extends AbstractFopImage { int imagestart = headermap[10] + headermap[11] * 256 + headermap[12] * 256 * 256 + headermap[13] * 256 * 256 * 256; this.m_bitsPerPixel = headermap[28]; - this.m_colorSpace = new ColorSpace(ColorSpace.DEVICE_RGB); + this.m_colorSpace = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB); int bytes = 0; if (this.m_bitsPerPixel == 1) bytes = (this.m_width + 7) / 8; diff --git a/src/org/apache/fop/image/EPSImage.java b/src/org/apache/fop/image/EPSImage.java index bb66eb116..3867d2a20 100644 --- a/src/org/apache/fop/image/EPSImage.java +++ b/src/org/apache/fop/image/EPSImage.java @@ -15,7 +15,6 @@ import java.io.IOException; // FOP import org.apache.fop.apps.Driver; -import org.apache.fop.datatypes.ColorSpace; import org.apache.fop.pdf.PDFColor; import org.apache.fop.image.analyser.ImageReader; import org.apache.fop.image.analyser.EPSReader; diff --git a/src/org/apache/fop/image/FopImage.java b/src/org/apache/fop/image/FopImage.java index d7b60a62c..a09272a2a 100644 --- a/src/org/apache/fop/image/FopImage.java +++ b/src/org/apache/fop/image/FopImage.java @@ -11,10 +11,10 @@ package org.apache.fop.image; import java.io.InputStream; +import java.awt.color.ColorSpace; +import java.awt.color.ICC_Profile; -import org.apache.fop.datatypes.ColorSpace; import org.apache.fop.pdf.PDFColor; -import org.apache.fop.pdf.PDFFilter; import org.apache.fop.fo.FOUserAgent; public interface FopImage { @@ -39,8 +39,8 @@ public interface FopImage { public int getWidth(); public int getHeight(); - // DeviceGray, DeviceRGB, or DeviceCMYK public ColorSpace getColorSpace(); + public ICC_Profile getICCProfile(); // bits per pixel public int getBitsPerPixel(); @@ -48,6 +48,8 @@ public interface FopImage { // For transparent images public boolean isTransparent(); public PDFColor getTransparentColor(); + public boolean hasSoftMask(); + public byte[] getSoftMask(); // get the image bytes, and bytes properties @@ -61,8 +63,6 @@ public interface FopImage { // should be changed... public byte[] getRessourceBytes(); public int getRessourceBytesSize(); - // return null if no corresponding PDFFilter - public PDFFilter getPDFFilter(); public static class ImageInfo { public InputStream stream; diff --git a/src/org/apache/fop/image/GifImage.java b/src/org/apache/fop/image/GifImage.java index dc27dbe21..32495c0e0 100644 --- a/src/org/apache/fop/image/GifImage.java +++ b/src/org/apache/fop/image/GifImage.java @@ -12,9 +12,9 @@ import java.net.URL; import java.awt.image.ImageProducer; import java.awt.image.ColorModel; import java.awt.image.IndexColorModel; +import java.awt.color.ColorSpace; // FOP -import org.apache.fop.datatypes.ColorSpace; import org.apache.fop.pdf.PDFColor; import org.apache.fop.image.analyser.ImageReader; import org.apache.fop.fo.FOUserAgent; @@ -58,7 +58,7 @@ public class GifImage extends AbstractFopImage { ColorModel cm = consumer.getColorModel(); this.m_bitsPerPixel = 8; // this.m_bitsPerPixel = cm.getPixelSize(); - this.m_colorSpace = new ColorSpace(ColorSpace.DEVICE_RGB); + this.m_colorSpace = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB); if (cm.hasAlpha()) { int transparencyType = cm.getTransparency(); // java.awt.Transparency. BITMASK or OPAQUE or TRANSLUCENT if (transparencyType == java.awt.Transparency.OPAQUE) { diff --git a/src/org/apache/fop/image/JAIImage.java b/src/org/apache/fop/image/JAIImage.java index 54c288e2f..4d2f25561 100644 --- a/src/org/apache/fop/image/JAIImage.java +++ b/src/org/apache/fop/image/JAIImage.java @@ -16,14 +16,15 @@ import java.io.BufferedInputStream; import java.awt.image.ColorModel; import java.awt.image.IndexColorModel; import java.awt.image.BufferedImage; +import java.awt.color.ColorSpace; // JAI import javax.media.jai.JAI; import javax.media.jai.RenderedOp; // Sun codec import com.sun.media.jai.codec.FileCacheSeekableStream; + // FOP -import org.apache.fop.datatypes.ColorSpace; import org.apache.fop.pdf.PDFColor; import org.apache.fop.image.analyser.ImageReader; @@ -59,7 +60,7 @@ public class JAIImage extends AbstractFopImage { ColorModel cm = imageOp.getColorModel(); this.m_bitsPerPixel = 8; // this.m_bitsPerPixel = cm.getPixelSize(); - this.m_colorSpace = new ColorSpace(ColorSpace.DEVICE_RGB); + this.m_colorSpace = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB); BufferedImage imageData = imageOp.getAsBufferedImage(); int[] tmpMap = imageData.getRGB(0, 0, this.m_width, diff --git a/src/org/apache/fop/image/JimiImage.java b/src/org/apache/fop/image/JimiImage.java index 6c6eb6b64..a4b3113b5 100644 --- a/src/org/apache/fop/image/JimiImage.java +++ b/src/org/apache/fop/image/JimiImage.java @@ -12,12 +12,12 @@ import java.net.URL; import java.awt.image.ImageProducer; import java.awt.image.ColorModel; import java.awt.image.IndexColorModel; +import java.awt.color.ColorSpace; // Jimi import com.sun.jimi.core.*; // FOP -import org.apache.fop.datatypes.ColorSpace; import org.apache.fop.pdf.PDFColor; import org.apache.fop.image.analyser.ImageReader; @@ -63,7 +63,7 @@ public class JimiImage extends AbstractFopImage { ColorModel cm = consumer.getColorModel(); this.m_bitsPerPixel = 8; // this.m_bitsPerPixel = cm.getPixelSize(); - this.m_colorSpace = new ColorSpace(ColorSpace.DEVICE_RGB); + this.m_colorSpace = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB); if (cm.hasAlpha()) { int transparencyType = cm.getTransparency(); // java.awt.Transparency. BITMASK or OPAQUE or TRANSLUCENT if (transparencyType == java.awt.Transparency.OPAQUE) { diff --git a/src/org/apache/fop/image/JpegImage.java b/src/org/apache/fop/image/JpegImage.java index 7e3b756dd..f1f64919e 100644 --- a/src/org/apache/fop/image/JpegImage.java +++ b/src/org/apache/fop/image/JpegImage.java @@ -14,9 +14,11 @@ import java.awt.image.ColorModel; import java.awt.image.IndexColorModel; import java.io.ByteArrayOutputStream; import java.io.InputStream; +import java.awt.color.ColorSpace; +import java.awt.color.ICC_Profile; +import java.awt.color.ICC_ColorSpace; // FOP -import org.apache.fop.datatypes.ColorSpace; import org.apache.fop.pdf.PDFColor; import org.apache.fop.pdf.DCTFilter; import org.apache.fop.image.analyser.ImageReader; @@ -29,6 +31,7 @@ import org.apache.fop.fo.FOUserAgent; * @see FopImage */ public class JpegImage extends AbstractFopImage { + ICC_Profile iccProfile = null; boolean found_icc_profile = false; boolean found_dimensions = false; @@ -40,15 +43,11 @@ public class JpegImage extends AbstractFopImage { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream iccStream = new ByteArrayOutputStream(); InputStream inStream; - this.m_colorSpace = new ColorSpace(ColorSpace.DEVICE_UNKNOWN); byte[] readBuf = new byte[4096]; int bytes_read; int index = 0; boolean cont = true; - this.m_compressionType = new DCTFilter(); - this.m_compressionType.setApplied(true); - try { inStream = this.m_href.openStream(); @@ -86,14 +85,15 @@ public class JpegImage extends AbstractFopImage { this.m_bitmaps[index + 8]); if (this.m_bitmaps[index + 9] == 1) { - this.m_colorSpace.setColorSpace( - ColorSpace.DEVICE_GRAY); + this.m_colorSpace = ColorSpace.getInstance( + ColorSpace.CS_GRAY); } else if (this.m_bitmaps[index + 9] == 3) { - this.m_colorSpace.setColorSpace( - ColorSpace.DEVICE_RGB); + this.m_colorSpace = ColorSpace.getInstance( + ColorSpace.CS_LINEAR_RGB); } else if (this.m_bitmaps[index + 9] == 4) { - this.m_colorSpace.setColorSpace( - ColorSpace.DEVICE_CMYK); + // howto create CMYK color space + this.m_colorSpace = ColorSpace.getInstance( + ColorSpace.CS_CIEXYZ); } found_dimensions = true; @@ -152,11 +152,15 @@ public class JpegImage extends AbstractFopImage { e.getMessage(), e); return false; } - this.m_colorSpace.setICCProfile(iccStream.toByteArray()); + iccProfile = ICC_Profile.getInstance(iccStream.toByteArray()); } return true; } + public ICC_Profile getICCProfile() { + return iccProfile; + } + private int calcBytes(byte bOne, byte bTwo) { return (uByte(bOne) * 256) + uByte(bTwo); } diff --git a/src/org/apache/fop/layout/FontState.java b/src/org/apache/fop/layout/FontState.java index b63143d13..fddd71087 100644 --- a/src/org/apache/fop/layout/FontState.java +++ b/src/org/apache/fop/layout/FontState.java @@ -24,7 +24,7 @@ public class FontState { private FontMetric _metric; - private static HashMap EMPTY_HASHTABLE = new HashMap(); + private static HashMap EMPTY_HASHMAP = new HashMap(); public FontState(FontInfo fontInfo, String fontFamily, String fontStyle, @@ -90,7 +90,7 @@ public class FontState { if (ret != null) return ret; } - return EMPTY_HASHTABLE; + return EMPTY_HASHMAP; } public int width(int charnum) { diff --git a/src/org/apache/fop/pdf/BitmapImage.java b/src/org/apache/fop/pdf/BitmapImage.java new file mode 100644 index 000000000..dd11de8bb --- /dev/null +++ b/src/org/apache/fop/pdf/BitmapImage.java @@ -0,0 +1,102 @@ +/* + * $Id$ + * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. + * For details on use and redistribution please refer to the + * LICENSE file included with these sources. + */ + +package org.apache.fop.pdf; + +import java.io.IOException; + +public class BitmapImage implements PDFImage { + int m_height; + int m_width; + int m_bitsPerPixel; + PDFColorSpace m_colorSpace; + byte[] m_bitmaps; + String maskRef; + PDFColor transparent = null; + String key; + + public BitmapImage(String k, int width, int height, byte[] result, + String mask) { + this.key = k; + this.m_height = height; + this.m_width = width; + this.m_bitsPerPixel = 8; + this.m_colorSpace = new PDFColorSpace(PDFColorSpace.DEVICE_RGB); + this.m_bitmaps = result; + maskRef = mask; + } + + public void setup(PDFDocument doc) { + } + + public String getKey() { + return key; + } + + // image size + public int getWidth() { + return m_width; + } + + public int getHeight() { + return m_height; + } + + public void setColorSpace(PDFColorSpace cs) { + m_colorSpace = cs; + } + + // DeviceGray, DeviceRGB, or DeviceCMYK + public PDFColorSpace getColorSpace() { + return m_colorSpace; + } + + // bits per pixel + public int getBitsPerPixel() { + return m_bitsPerPixel; + } + + public void setTransparent(PDFColor t) { + transparent = t; + } + + // For transparent images + public boolean isTransparent() { + return transparent != null; + } + + public PDFColor getTransparentColor() { + return transparent; + } + + public String getMask() { + return null; + } + + public String getSoftMask() { + return maskRef; + } + + public PDFStream getDataStream() throws IOException { + // delegate the stream work to PDFStream + PDFStream imgStream = new PDFStream(0); + + imgStream.setData(m_bitmaps); + + imgStream.addDefaultFilters(); + return imgStream; + } + + public PDFICCStream getICCStream() { + return null; + } + + public boolean isPS() { + return false; + } + } + diff --git a/src/org/apache/fop/pdf/PDFColor.java b/src/org/apache/fop/pdf/PDFColor.java index 379b1e2d8..b1f589be6 100644 --- a/src/org/apache/fop/pdf/PDFColor.java +++ b/src/org/apache/fop/pdf/PDFColor.java @@ -12,10 +12,6 @@ import java.util.ArrayList; import java.io.IOException; import java.io.PrintWriter; -// FOP -import org.apache.fop.datatypes.ColorType; -import org.apache.fop.datatypes.ColorSpace; - public class PDFColor extends PDFPathPaint { protected static double blackFactor = 2.0; // could be 3.0 as well. protected double red = -1.0; @@ -27,18 +23,9 @@ public class PDFColor extends PDFPathPaint { protected double yellow = -1.0; protected double black = -1.0; - public PDFColor(org.apache.fop.datatypes.ColorType theColor) { - this.colorSpace = new ColorSpace(ColorSpace.DEVICE_RGB); - // super(theNumber) - this.red = (double)theColor.red(); - this.green = (double)theColor.green(); - this.blue = (double)theColor.blue(); - - } - public PDFColor(double theRed, double theGreen, double theBlue) { // super(theNumber); - this.colorSpace = new ColorSpace(ColorSpace.DEVICE_RGB); + this.colorSpace = new PDFColorSpace(PDFColorSpace.DEVICE_RGB); this.red = theRed; this.green = theGreen; @@ -56,7 +43,7 @@ public class PDFColor extends PDFPathPaint { double theBlack) { // super(theNumber);//? - this.colorSpace = new ColorSpace(ColorSpace.DEVICE_CMYK); + this.colorSpace = new PDFColorSpace(PDFColorSpace.DEVICE_CMYK); this.cyan = theCyan; this.magenta = theMagenta; @@ -68,12 +55,12 @@ public class PDFColor extends PDFPathPaint { public ArrayList getVector() { // return a vector representation of the color // in the appropriate colorspace. ArrayList theColorVector = new ArrayList(); - if (this.colorSpace.getColorSpace() == ColorSpace.DEVICE_RGB) { // RGB + if (this.colorSpace.getColorSpace() == PDFColorSpace.DEVICE_RGB) { // RGB theColorVector.add(new Double(this.red)); theColorVector.add(new Double(this.green)); theColorVector.add(new Double(this.blue)); } else if (this.colorSpace.getColorSpace() - == ColorSpace.DEVICE_CMYK) { // CMYK + == PDFColorSpace.DEVICE_CMYK) { // CMYK theColorVector.add(new Double(this.cyan)); theColorVector.add(new Double(this.magenta)); theColorVector.add(new Double(this.yellow)); @@ -127,16 +114,16 @@ public class PDFColor extends PDFPathPaint { public void setColorSpace(int theColorSpace) { int theOldColorSpace = this.colorSpace.getColorSpace(); if (theOldColorSpace != theColorSpace) { - if (theOldColorSpace == ColorSpace.DEVICE_RGB) { - if (theColorSpace == ColorSpace.DEVICE_CMYK) { + if (theOldColorSpace == PDFColorSpace.DEVICE_RGB) { + if (theColorSpace == PDFColorSpace.DEVICE_CMYK) { this.convertRGBtoCMYK(); } else // convert to Gray? { this.convertRGBtoGRAY(); } - } else if (theOldColorSpace == ColorSpace.DEVICE_CMYK) { - if (theColorSpace == ColorSpace.DEVICE_RGB) { + } else if (theOldColorSpace == PDFColorSpace.DEVICE_CMYK) { + if (theColorSpace == PDFColorSpace.DEVICE_RGB) { this.convertCMYKtoRGB(); } else // convert to Gray? { @@ -144,7 +131,7 @@ public class PDFColor extends PDFPathPaint { } } else // used to be Gray { - if (theColorSpace == ColorSpace.DEVICE_RGB) { + if (theColorSpace == PDFColorSpace.DEVICE_RGB) { this.convertGRAYtoRGB(); } else // convert to CMYK? { @@ -161,7 +148,7 @@ public class PDFColor extends PDFPathPaint { double tempDouble; if (this.colorSpace.getColorSpace() - == ColorSpace.DEVICE_RGB) { // colorspace is RGB + == PDFColorSpace.DEVICE_RGB) { // colorspace is RGB // according to pdfspec 12.1 p.399 // if the colors are the same then just use the g or G operator boolean same = false; @@ -190,7 +177,7 @@ public class PDFColor extends PDFPathPaint { } } // end of output RGB else if (this.colorSpace.getColorSpace() - == ColorSpace.DEVICE_CMYK) { // colorspace is CMYK + == PDFColorSpace.DEVICE_CMYK) { // colorspace is CMYK if (fillNotStroke) { // fill p.append(PDFNumber.doubleOut(this.cyan) + " " diff --git a/src/org/apache/fop/datatypes/ColorSpace.java b/src/org/apache/fop/pdf/PDFColorSpace.java index 35a6987e6..62992b4af 100644 --- a/src/org/apache/fop/datatypes/ColorSpace.java +++ b/src/org/apache/fop/pdf/PDFColorSpace.java @@ -5,9 +5,9 @@ * LICENSE file included with these sources. */ -package org.apache.fop.datatypes; +package org.apache.fop.pdf; -public class ColorSpace { +public class PDFColorSpace { private boolean hasICCProfile; private byte[] iccProfile; private int numComponents; @@ -21,18 +21,17 @@ public class ColorSpace { // public static int DEVICE_GREY = 1; public static int DEVICE_RGB = 2; public static int DEVICE_CMYK = 3; - - + // Are there any others? - protected int currentColorSpace = -1; + protected int currentColorSpace = DEVICE_UNKNOWN; - public ColorSpace(int theColorSpace) { + public PDFColorSpace(int theColorSpace) { this.currentColorSpace = theColorSpace; hasICCProfile = false; numComponents = calculateNumComponents(); } - + private int calculateNumComponents() { if (currentColorSpace == DEVICE_GRAY) return 1; @@ -48,34 +47,32 @@ public class ColorSpace { this.currentColorSpace = theColorSpace; numComponents = calculateNumComponents(); } - + public boolean hasICCProfile() { return hasICCProfile; } - + public byte[] getICCProfile() { if (hasICCProfile) return iccProfile; else return new byte[0]; } - + public void setICCProfile(byte[] iccProfile) { this.iccProfile = iccProfile; hasICCProfile = true; } - + public int getColorSpace() { return (this.currentColorSpace); } - + public int getNumComponents() { return numComponents; } - - public String getColorSpacePDFString() { // this is for PDF Output. Does anyone else need a string representation? - - + + public String getColorSpacePDFString() { // shouldn't this be a select-case? I can never remember // the syntax for that. if (this.currentColorSpace == this.DEVICE_RGB) { @@ -88,5 +85,5 @@ public class ColorSpace { return ("DeviceRGB"); } } - + } diff --git a/src/org/apache/fop/pdf/PDFDocument.java b/src/org/apache/fop/pdf/PDFDocument.java index b2547e975..79d7dde7b 100644 --- a/src/org/apache/fop/pdf/PDFDocument.java +++ b/src/org/apache/fop/pdf/PDFDocument.java @@ -10,16 +10,9 @@ package org.apache.fop.pdf; -// images are the one place that FOP classes outside this package get -// referenced and I'd rather not do it -import org.apache.fop.image.FopImage; - -import org.apache.fop.datatypes.ColorSpace; - import org.apache.fop.render.pdf.CIDFont; import org.apache.fop.render.pdf.fonts.LazyFont; -import org.apache.fop.datatypes.IDReferences; import org.apache.fop.layout.FontMetric; import org.apache.fop.layout.FontDescriptor; // Java @@ -111,15 +104,10 @@ public class PDFDocument { protected PDFResources resources; /** - * the documents idReferences - */ - protected IDReferences idReferences; - - /** * the colorspace (0=RGB, 1=CMYK) */ // protected int colorspace = 0; - protected ColorSpace colorspace = new ColorSpace(ColorSpace.DEVICE_RGB); + protected PDFColorSpace colorspace = new PDFColorSpace(PDFColorSpace.DEVICE_RGB); /** * the counter for Pattern name numbering (e.g. 'Pattern1') @@ -439,7 +427,7 @@ public class PDFDocument { * @param theFunction The PDF Function that maps an (x,y) location to a color */ public PDFShading makeShading(int theShadingType, - ColorSpace theColorSpace, + PDFColorSpace theColorSpace, ArrayList theBackground, ArrayList theBBox, boolean theAntiAlias, ArrayList theDomain, ArrayList theMatrix, @@ -479,7 +467,7 @@ public class PDFDocument { * The default is [false, false] */ public PDFShading makeShading(int theShadingType, - ColorSpace theColorSpace, + PDFColorSpace theColorSpace, ArrayList theBackground, ArrayList theBBox, boolean theAntiAlias, ArrayList theCoords, ArrayList theDomain, PDFFunction theFunction, @@ -522,7 +510,7 @@ public class PDFDocument { * @param theFunction the PDFFunction */ public PDFShading makeShading(int theShadingType, - ColorSpace theColorSpace, + PDFColorSpace theColorSpace, ArrayList theBackground, ArrayList theBBox, boolean theAntiAlias, int theBitsPerCoordinate, @@ -567,7 +555,7 @@ public class PDFDocument { * @param theFunction The PDFFunction that's mapped on to this shape */ public PDFShading makeShading(int theShadingType, - ColorSpace theColorSpace, + PDFColorSpace theColorSpace, ArrayList theBackground, ArrayList theBBox, boolean theAntiAlias, int theBitsPerCoordinate, @@ -659,7 +647,7 @@ public class PDFDocument { } public PDFPattern createGradient(boolean radial, - ColorSpace theColorspace, + PDFColorSpace theColorspace, ArrayList theColors, ArrayList theBounds, ArrayList theCoords) { PDFShading myShad; @@ -668,7 +656,7 @@ public class PDFDocument { ArrayList theCzero; ArrayList theCone; PDFPattern myPattern; - ColorSpace theColorSpace; + PDFColorSpace theColorSpace; double interpolation = (double)1.000; ArrayList theFunctions = new ArrayList(); @@ -930,19 +918,22 @@ public class PDFDocument { return gstate; } - public int addImage(FopImage img) { + public PDFXObject addImage(PDFImage img) { // check if already created - String url = img.getURL(); - PDFXObject xObject = (PDFXObject)this.xObjectsMap.get(url); + String key = img.getKey(); + PDFXObject xObject = (PDFXObject)xObjectsMap.get(key); if (xObject != null) - return xObject.getXNumber(); - // else, create a new one + return xObject; + + // setup image + img.setup(this); + // create a new XObject xObject = new PDFXObject(++this.objectcount, ++this.xObjectCount, - img, this); + img); this.objects.add(xObject); this.xObjects.add(xObject); - this.xObjectsMap.put(url, xObject); - return xObjectCount; + this.xObjectsMap.put(key, xObject); + return xObject; } /** @@ -1029,8 +1020,8 @@ public class PDFDocument { } private String getGoToReference(String destination) { - String goToReference; - if (idReferences.doesIDExist(destination)) { + String goToReference = null; + /*if (idReferences.doesIDExist(destination)) { if (idReferences.doesGoToReferenceExist(destination)) { goToReference = idReferences.getInternalLinkGoToReference(destination); @@ -1042,16 +1033,12 @@ public class PDFDocument { } } else { // id was not found, so create it - //next line by lmckenzi@ca.ibm.com - //solves when IDNode made before IDReferences.createID called - //idReferences.createNewId(destination); - idReferences.createUnvalidatedID(destination); idReferences.addToIdValidationList(destination); goToReference = idReferences.createInternalLinkGoTo(destination, ++this.objectcount); addTrailerObject(idReferences.getPDFGoTo(destination)); - } + }*/ return goToReference; } @@ -1306,8 +1293,4 @@ public class PDFDocument { return pdfBytes.length; } - public void setIDReferences(IDReferences idReferences) { - this.idReferences = idReferences; - } - } diff --git a/src/org/apache/fop/pdf/PDFGState.java b/src/org/apache/fop/pdf/PDFGState.java index cf8d32c2a..99c21f85e 100644 --- a/src/org/apache/fop/pdf/PDFGState.java +++ b/src/org/apache/fop/pdf/PDFGState.java @@ -12,6 +12,33 @@ package org.apache.fop.pdf; * */ public class PDFGState extends PDFObject { + public static final String LW = "lw"; + public static final String LC = "lc"; + public static final String LJ = "lj"; + public static final String ML = "ml"; + public static final String D = "d"; + public static final String RI = "ri"; + public static final String OP = "OP"; + public static final String op = "op"; + public static final String OPM = "opm"; + public static final String Font = "font"; + public static final String BG = "bg"; + public static final String BG2 = "bg2"; + public static final String UCR = "ucr"; + public static final String UCR2 = "ucr2"; + public static final String TR = "tr"; + public static final String TR2 = "tr2"; + public static final String HT = "ht"; + public static final String FL = "fl"; + public static final String SM = "sm"; + public static final String SA = "sa"; + public static final String BM = "bm"; + public static final String SMask = "smask"; + public static final String CA = "CA"; + public static final String ca = "ca"; + public static final String AIS = "ais"; + public static final String TK = "tk"; + float alphaFill = 1; float alphaStroke = 1; diff --git a/src/org/apache/fop/pdf/PDFICCStream.java b/src/org/apache/fop/pdf/PDFICCStream.java index 55d444aca..b3d6cf875 100644 --- a/src/org/apache/fop/pdf/PDFICCStream.java +++ b/src/org/apache/fop/pdf/PDFICCStream.java @@ -6,41 +6,41 @@ */ package org.apache.fop.pdf; -import org.apache.fop.datatypes.ColorSpace; + +import java.awt.color.ICC_Profile; public class PDFICCStream extends PDFStream { private int origLength; private int len1, len3; - private ColorSpace cs; - - public void setColorSpace(ColorSpace cs) throws java.io.IOException { - this.cs = cs; - setData(cs.getICCProfile()); + private ICC_Profile cp; + private PDFColorSpace pdfColorSpace; + + public void setColorSpace(ICC_Profile cp, PDFColorSpace alt) { + this.cp = cp; + pdfColorSpace = alt; } public PDFICCStream(int num) { super(num); - cs = null; - } - - public PDFICCStream(int num, ColorSpace cs) throws java.io.IOException { - super(num); - setColorSpace(cs); + cp = null; } // overload the base object method so we don't have to copy // byte arrays around so much protected int output(java.io.OutputStream stream) throws java.io.IOException { + + setData(cp.getData()); + int length = 0; String filterEntry = applyFilters(); StringBuffer pb = new StringBuffer(); pb.append(this.number).append(" ").append(this.generation).append(" obj\n<< "); - pb.append("/N ").append(cs.getNumComponents()).append(" "); + pb.append("/N ").append(cp.getNumComponents()).append(" "); - if (cs.getColorSpace() > 0) - pb.append("/Alternate /").append(cs.getColorSpacePDFString()).append(" "); + if (pdfColorSpace != null) + pb.append("/Alternate /").append(pdfColorSpace.getColorSpacePDFString()).append(" "); pb.append("/Length ").append((_data.getSize() + 1)).append(" ").append(filterEntry); pb.append(" >>\n"); diff --git a/src/org/apache/fop/pdf/PDFImage.java b/src/org/apache/fop/pdf/PDFImage.java new file mode 100644 index 000000000..05cedf753 --- /dev/null +++ b/src/org/apache/fop/pdf/PDFImage.java @@ -0,0 +1,44 @@ +/* + * $Id$ + * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. + * For details on use and redistribution please refer to the + * LICENSE file included with these sources. + */ + +package org.apache.fop.pdf; + +import java.io.IOException; + +public interface PDFImage { + + // key to look up XObject + public String getKey(); + + public void setup(PDFDocument doc); + + // image size + public int getWidth(); + public int getHeight(); + + // DeviceGray, DeviceRGB, or DeviceCMYK + public PDFColorSpace getColorSpace(); + + // bits per pixel + public int getBitsPerPixel(); + + public boolean isPS(); + + // For transparent images + public boolean isTransparent(); + public PDFColor getTransparentColor(); + public String getMask(); + public String getSoftMask(); + + // get the image bytes, and bytes properties + + public PDFStream getDataStream() throws IOException; + + public PDFICCStream getICCStream(); + +} + diff --git a/src/org/apache/fop/pdf/PDFPathPaint.java b/src/org/apache/fop/pdf/PDFPathPaint.java index 2c2292823..2f0c0ab96 100644 --- a/src/org/apache/fop/pdf/PDFPathPaint.java +++ b/src/org/apache/fop/pdf/PDFPathPaint.java @@ -7,12 +7,10 @@ package org.apache.fop.pdf; -import org.apache.fop.datatypes.ColorSpace; - public abstract class PDFPathPaint extends PDFObject { // protected int colorspace = 0; //default is 0:RGB, not 1:CMYK - protected ColorSpace colorSpace; + protected PDFColorSpace colorSpace; public PDFPathPaint(int theNumber) { super(theNumber); diff --git a/src/org/apache/fop/pdf/PDFPattern.java b/src/org/apache/fop/pdf/PDFPattern.java index 412c923bd..ab9c0b645 100644 --- a/src/org/apache/fop/pdf/PDFPattern.java +++ b/src/org/apache/fop/pdf/PDFPattern.java @@ -10,9 +10,6 @@ package org.apache.fop.pdf; // Java... import java.util.ArrayList; -// FOP... -import org.apache.fop.datatypes.ColorSpace; - /** * class representing a PDF Function. * @@ -131,6 +128,7 @@ public class PDFPattern extends PDFPathPaint { this.yStep = theYStep; this.matrix = theMatrix; this.xUID = theXUID; + // TODO filter this stream this.patternDataStream = thePatternDataStream; } diff --git a/src/org/apache/fop/pdf/PDFShading.java b/src/org/apache/fop/pdf/PDFShading.java index 3bb284675..d4521e7ae 100644 --- a/src/org/apache/fop/pdf/PDFShading.java +++ b/src/org/apache/fop/pdf/PDFShading.java @@ -10,9 +10,6 @@ package org.apache.fop.pdf; // Java... import java.util.ArrayList; -// FOP -import org.apache.fop.datatypes.ColorSpace; - /** * class representing a PDF Smooth Shading object. * @@ -40,7 +37,7 @@ public class PDFShading extends PDFObject { * A ColorSpace representing the colorspace. "DeviceRGB" is an example. */ // protected StringBuffer colorSpace = null; - protected ColorSpace colorSpace = null; + protected PDFColorSpace colorSpace = null; /** * The background color. Since shading is opaque, @@ -148,7 +145,7 @@ public class PDFShading extends PDFObject { * @param theFunction The PDF Function that maps an (x,y) location to a color */ public PDFShading(int theNumber, String theShadingName, - int theShadingType, ColorSpace theColorSpace, + int theShadingType, PDFColorSpace theColorSpace, ArrayList theBackground, ArrayList theBBox, boolean theAntiAlias, ArrayList theDomain, ArrayList theMatrix, PDFFunction theFunction) { @@ -189,7 +186,7 @@ public class PDFShading extends PDFObject { * The default is [false, false] */ public PDFShading(int theNumber, String theShadingName, - int theShadingType, ColorSpace theColorSpace, + int theShadingType, PDFColorSpace theColorSpace, ArrayList theBackground, ArrayList theBBox, boolean theAntiAlias, ArrayList theCoords, ArrayList theDomain, PDFFunction theFunction, @@ -234,7 +231,7 @@ public class PDFShading extends PDFObject { * @param theFunction the PDFFunction */ public PDFShading(int theNumber, String theShadingName, - int theShadingType, ColorSpace theColorSpace, + int theShadingType, PDFColorSpace theColorSpace, ArrayList theBackground, ArrayList theBBox, boolean theAntiAlias, int theBitsPerCoordinate, int theBitsPerComponent, int theBitsPerFlag, @@ -277,7 +274,7 @@ public class PDFShading extends PDFObject { * @param theNumber the object number of this PDF object. */ public PDFShading(int theNumber, String theShadingName, - int theShadingType, ColorSpace theColorSpace, + int theShadingType, PDFColorSpace theColorSpace, ArrayList theBackground, ArrayList theBBox, boolean theAntiAlias, int theBitsPerCoordinate, int theBitsPerComponent, ArrayList theDecode, diff --git a/src/org/apache/fop/pdf/PDFState.java b/src/org/apache/fop/pdf/PDFState.java index 45d91c5fb..036a00fed 100644 --- a/src/org/apache/fop/pdf/PDFState.java +++ b/src/org/apache/fop/pdf/PDFState.java @@ -47,6 +47,7 @@ public class PDFState { private final static String FONTSIZE = "fontSize"; private final static String FONTNAME = "fontName"; private final static String CLIP = "clip"; + private final static String GSTATE = "gstate"; Color color = Color.black; Color backcolor = Color.white; @@ -63,6 +64,7 @@ public class PDFState { float fontSize = 0; String fontName = ""; Shape clip = null; + PDFGState gstate = null; ArrayList stateStack = new ArrayList(); @@ -89,6 +91,7 @@ public class PDFState { saveMap.put(FONTSIZE, new Float(fontSize)); saveMap.put(FONTNAME, fontName); saveMap.put(CLIP, clip); + saveMap.put(GSTATE, gstate); stateStack.add(saveMap); @@ -114,6 +117,7 @@ public class PDFState { fontSize = ((Float)saveMap.get(FONTSIZE)).floatValue(); fontName = (String)saveMap.get(FONTNAME); clip = (Shape)saveMap.get(CLIP); + gstate = (PDFGState)saveMap.get(GSTATE); } } diff --git a/src/org/apache/fop/pdf/PDFStream.java b/src/org/apache/fop/pdf/PDFStream.java index 20c3ef0cc..76f2e6719 100644 --- a/src/org/apache/fop/pdf/PDFStream.java +++ b/src/org/apache/fop/pdf/PDFStream.java @@ -96,7 +96,7 @@ public class PDFStream extends PDFObject { } - protected void addDefaultFilters() { + public void addDefaultFilters() { ArrayList filters = Configuration.getListValue("stream-filter-list", Configuration.PDF); if (filters == null) { diff --git a/src/org/apache/fop/pdf/PDFXObject.java b/src/org/apache/fop/pdf/PDFXObject.java index 6b97e43c7..8a3b9ad46 100644 --- a/src/org/apache/fop/pdf/PDFXObject.java +++ b/src/org/apache/fop/pdf/PDFXObject.java @@ -13,14 +13,7 @@ package org.apache.fop.pdf; // Java import java.io.IOException; import java.io.OutputStream; - -// FOP -import org.apache.fop.datatypes.ColorSpace; -import org.apache.fop.pdf.PDFDocument; -import org.apache.fop.pdf.PDFICCStream; -import org.apache.fop.image.FopImage; -import org.apache.fop.image.EPSImage; -import org.apache.fop.image.JpegImage; +import java.io.ByteArrayOutputStream; /** * PDF XObject @@ -30,52 +23,19 @@ import org.apache.fop.image.JpegImage; * the dictionary just provides information like the stream length */ public class PDFXObject extends PDFObject { - private boolean isPS; - private PDFDocument pdfDoc; - private PDFICCStream pdfICCStream; - - FopImage fopimage; + PDFImage pdfimage; int Xnum; /** - * create an Xobject with the given number and name and load the + * create an XObject with the given number and name and load the * image in the object */ - public PDFXObject(int number, int Xnumber, FopImage img) { - this(number, Xnumber, img, null); - } - - public PDFXObject(int number, int Xnumber, FopImage img, PDFDocument pdfdoc) { + public PDFXObject(int number, int Xnumber, PDFImage img) { super(number); - isPS = false; this.Xnum = Xnumber; - if (img == null) { - //log.error("FISH"); - } - fopimage = img; - this.pdfDoc = pdfdoc; - pdfICCStream = null; - try { - if (fopimage instanceof JpegImage) { - /* hasICCProfile is not initialized before - the bitmaps is read - should maybe fix this in - the JpegImage instead... - */ - fopimage.getBitmaps(); - JpegImage jpegimage = (JpegImage)fopimage; - if (jpegimage.getColorSpace().hasICCProfile()) { - pdfICCStream = pdfDoc.makePDFICCStream(); - pdfICCStream.setColorSpace(jpegimage.getColorSpace()); - pdfICCStream.addDefaultFilters(); - } - } - } catch (Exception e) { - //log.error("Error while reading image " + - // fopimage.getURL() + - // ": " + e.getMessage()); - } + pdfimage = img; } - + /** * @return the PDF XObject number */ @@ -89,143 +49,107 @@ public class PDFXObject extends PDFObject { protected int output(OutputStream stream) throws IOException { int length = 0; int i = 0; - - try { - if (fopimage instanceof EPSImage) { - isPS = true; - EPSImage epsImage = (EPSImage)fopimage; - int[] bbox = epsImage.getBBox(); - int bboxw = bbox[2] - bbox[0]; - int bboxh = bbox[3] - bbox[1]; - - // delegate the stream work to PDFStream - PDFStream imgStream = new PDFStream(0); - - StringBuffer preamble = new StringBuffer(); - preamble.append("%%BeginDocument: " + epsImage.getDocName() + "\n"); - - preamble.append("userdict begin % Push userdict on dict stack\n"); - preamble.append("/PreEPS_state save def\n"); - preamble.append("/dict_stack countdictstack def\n"); - preamble.append("/ops_count count 1 sub def\n"); - preamble.append("/showpage {} def\n"); - - - preamble.append((double)(1f/(double)bboxw) + " " + (double)(1f/(double)bboxh) + " scale\n"); - preamble.append(-bbox[0] + " " + (-bbox[1]) + " translate\n"); - preamble.append(bbox[0] + " " + bbox[1] + " " + bboxw + " " + bboxh + " rectclip\n"); - preamble.append("newpath\n"); - - StringBuffer post = new StringBuffer(); - post.append("%%EndDocument\n"); - post.append("count ops_count sub {pop} repeat\n"); - post.append("countdictstack dict_stack sub {end} repeat\n"); - post.append("PreEPS_state restore\n"); - post.append("end % userdict\n"); - - byte[] preBytes = preamble.toString().getBytes(); - byte[] postBytes = post.toString().getBytes(); - byte[] imgData = new byte[preBytes.length + postBytes.length + fopimage.getBitmaps().length]; - - System.arraycopy (preBytes, 0, imgData, 0, preBytes.length); - System.arraycopy (fopimage.getBitmaps(), 0, imgData, preBytes.length, fopimage.getBitmaps().length); - System.arraycopy (postBytes, 0, imgData, preBytes.length + fopimage.getBitmaps().length, postBytes.length); - - - imgStream.setData(imgData); - imgStream.addDefaultFilters(); - - String dictEntries = imgStream.applyFilters(); - - String p = this.number + " " + this.generation + " obj\n"; - p = p + "<</Type /XObject\n"; - p = p + "/Subtype /PS\n"; - p = p + "/Length " + imgStream.getDataLength(); - - p = p + dictEntries; - p = p + ">>\n"; - - // push the pdf dictionary on the writer - byte[] pdfBytes = p.getBytes(); - stream.write(pdfBytes); - length += pdfBytes.length; - // push all the image data on the writer and takes care of length for trailer - length += imgStream.outputStreamData(stream); - - pdfBytes = ("endobj\n").getBytes(); - stream.write(pdfBytes); - length += pdfBytes.length; - + + if (pdfimage.isPS()) { + length = outputEPSImage(stream); + } else { + + PDFStream imgStream = pdfimage.getDataStream(); + + String dictEntries = imgStream.applyFilters(); + + String p = this.number + " " + this.generation + " obj\n"; + p = p + "<</Type /XObject\n"; + p = p + "/Subtype /Image\n"; + p = p + "/Name /Im" + Xnum + "\n"; + p = p + "/Length " + imgStream.getDataLength() + "\n"; + p = p + "/Width " + pdfimage.getWidth() + "\n"; + p = p + "/Height " + pdfimage.getHeight() + "\n"; + p = p + "/BitsPerComponent " + pdfimage.getBitsPerPixel() + + "\n"; + + PDFICCStream pdfICCStream = pdfimage.getICCStream(); + if (pdfICCStream != null) { + p = p + "/ColorSpace [/ICCBased " + + pdfICCStream.referencePDF() + "]\n"; } else { + PDFColorSpace cs = pdfimage.getColorSpace(); + p = p + "/ColorSpace /" + cs.getColorSpacePDFString() + + "\n"; + } + + /* PhotoShop generates CMYK values that's inverse, + this will invert the values - too bad if it's not + a PhotoShop image... + */ + if (pdfimage.getColorSpace().getColorSpace() == + PDFColorSpace.DEVICE_CMYK) { + p = p + "/Decode [ 1.0 0.0 1.0 0.0 1.0 0.0 1.1 0.0 ]\n"; + } - // delegate the stream work to PDFStream - PDFStream imgStream = new PDFStream(0); - - imgStream.setData(fopimage.getBitmaps()); - - /* - * Added by Eric Dalquist - * If the DCT filter hasn't been added to the object we add it here - */ - if (fopimage.getPDFFilter() != null) { - imgStream.addFilter(fopimage.getPDFFilter()); - } - - imgStream.addDefaultFilters(); - - String dictEntries = imgStream.applyFilters(); - - String p = this.number + " " + this.generation + " obj\n"; - p = p + "<</Type /XObject\n"; - p = p + "/Subtype /Image\n"; - p = p + "/Name /Im" + Xnum + "\n"; - p = p + "/Length " + imgStream.getDataLength() + "\n"; - p = p + "/Width " + fopimage.getWidth() + "\n"; - p = p + "/Height " + fopimage.getHeight() + "\n"; - p = p + "/BitsPerComponent " + fopimage.getBitsPerPixel() + "\n"; - - if (pdfICCStream != null ) { - p = p + "/ColorSpace [/ICCBased " + pdfICCStream.referencePDF() + "]\n"; - } else { - ColorSpace cs = fopimage.getColorSpace(); - p = p + "/ColorSpace /" + cs.getColorSpacePDFString() + "\n"; - } - - /* PhotoShop generates CMYK values that's inverse, - this will invert the values - too bad if it's not a PhotoShop image...*/ - if (fopimage.getColorSpace().getColorSpace() == ColorSpace.DEVICE_CMYK) { - p = p + "/Decode [ 1.0 0.0 1.0 0.0 1.0 0.0 1.1 0.0 ]\n"; - } - - if (fopimage.isTransparent()) { - PDFColor transp = fopimage.getTransparentColor(); - p = p + "/Mask [" + transp.red255() + " " + transp.red255() - + " " + transp.green255() + " " + transp.green255() + " " - + transp.blue255() + " " + transp.blue255() + "]\n"; - } - p = p + dictEntries; - p = p + ">>\n"; - - // push the pdf dictionary on the writer - byte[] pdfBytes = p.getBytes(); - stream.write(pdfBytes); - length += pdfBytes.length; - // push all the image data on the writer and takes care of length for trailer - length += imgStream.outputStreamData(stream); - - pdfBytes = ("endobj\n").getBytes(); - stream.write(pdfBytes); - length += pdfBytes.length; + if (pdfimage.isTransparent()) { + PDFColor transp = pdfimage.getTransparentColor(); + p = p + "/Mask [" + transp.red255() + " " + + transp.red255() + " " + transp.green255() + + " " + transp.green255() + " " + + transp.blue255() + " " + transp.blue255() + "]\n"; + } + String ref = pdfimage.getSoftMask(); + if (ref != null) { + p = p + "/SMask " + ref + "\n"; } - } catch (Exception imgex) { - //log.error("Error in XObject : " - // + imgex.getMessage()); + + p = p + dictEntries; + p = p + ">>\n"; + + // push the pdf dictionary on the writer + byte[] pdfBytes = p.getBytes(); + stream.write(pdfBytes); + length += pdfBytes.length; + // push all the image data on the writer + // and takes care of length for trailer + length += imgStream.outputStreamData(stream); + + pdfBytes = ("endobj\n").getBytes(); + stream.write(pdfBytes); + length += pdfBytes.length; } - + // let it gc + pdfimage = null; return length; } - + byte[] toPDF() { return null; } + + private int outputEPSImage(OutputStream stream) throws IOException { + int length = 0; + int i = 0; + + PDFStream imgStream = pdfimage.getDataStream(); + String dictEntries = imgStream.applyFilters(); + + String p = this.number + " " + this.generation + " obj\n"; + p = p + "<</Type /XObject\n"; + p = p + "/Subtype /PS\n"; + p = p + "/Length " + imgStream.getDataLength(); + + p = p + dictEntries; + p = p + ">>\n"; + + // push the pdf dictionary on the writer + byte[] pdfBytes = p.getBytes(); + stream.write(pdfBytes); + length += pdfBytes.length; + // push all the image data on the writer and takes care of length for trailer + length += imgStream.outputStreamData(stream); + + pdfBytes = ("endobj\n").getBytes(); + stream.write(pdfBytes); + length += pdfBytes.length; + + return length; + } + } diff --git a/src/org/apache/fop/render/pdf/FopPDFImage.java b/src/org/apache/fop/render/pdf/FopPDFImage.java new file mode 100644 index 000000000..ca248b010 --- /dev/null +++ b/src/org/apache/fop/render/pdf/FopPDFImage.java @@ -0,0 +1,200 @@ +/* + * $Id$ + * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. + * For details on use and redistribution please refer to the + * LICENSE file included with these sources. + */ + +package org.apache.fop.render.pdf; + +import org.apache.fop.pdf.PDFImage; +import org.apache.fop.pdf.PDFFilter; +import org.apache.fop.pdf.PDFICCStream; +import org.apache.fop.pdf.PDFColor; +import org.apache.fop.pdf.PDFStream; +import org.apache.fop.pdf.PDFDocument; +import org.apache.fop.pdf.DCTFilter; +import org.apache.fop.pdf.PDFColorSpace; + +import org.apache.fop.image.FopImage; +import org.apache.fop.image.JpegImage; +import org.apache.fop.image.EPSImage; + +import java.io.IOException; +import java.awt.color.ColorSpace; +import java.awt.color.ICC_ColorSpace; +import java.awt.color.ICC_Profile; + +public class FopPDFImage implements PDFImage { + FopImage fopImage; + PDFICCStream pdfICCStream = null; + PDFFilter pdfFilter = null; + String maskRef; + String softMaskRef; + boolean isPS = false; + + public FopPDFImage(FopImage im) { + fopImage = im; + isPS = (fopImage instanceof EPSImage); + } + + // key to look up XObject + public String getKey() { + return fopImage.getURL(); + } + + public void setup(PDFDocument doc) { + + if ("image/jpeg".equals(fopImage.getMimeType())) { + pdfFilter = new DCTFilter(); + pdfFilter.setApplied(true); + + JpegImage jpegimage = (JpegImage) fopImage; + ICC_Profile prof = jpegimage.getICCProfile(); + PDFColorSpace pdfCS = toPDFColorSpace(jpegimage.getColorSpace()); + if (prof != null) { + pdfICCStream = doc.makePDFICCStream(); + pdfICCStream.setColorSpace(prof, pdfCS); + pdfICCStream.addDefaultFilters(); + } + } + } + + public boolean isPS() { + return isPS; + } + + // image size + public int getWidth() { + return fopImage.getWidth(); + } + + public int getHeight() { + return fopImage.getHeight(); + } + + // DeviceGray, DeviceRGB, or DeviceCMYK + public PDFColorSpace getColorSpace() { + return toPDFColorSpace(fopImage.getColorSpace()); + } + + public int getBitsPerPixel() { + return fopImage.getBitsPerPixel(); + } + + // For transparent images + public boolean isTransparent() { + return fopImage.isTransparent(); + } + + public PDFColor getTransparentColor() { + return fopImage.getTransparentColor(); + } + + public String getMask() { + return maskRef; + } + + public String getSoftMask() { + return softMaskRef; + } + + public PDFStream getDataStream() throws IOException { + if(isPS) { + return getPSDataStream(); + } else { + // delegate the stream work to PDFStream + PDFStream imgStream = new PDFStream(0); + + imgStream.setData(fopImage.getBitmaps()); + + /* + * Added by Eric Dalquist + * If the DCT filter hasn't been added to the object we add it here + */ + if (pdfFilter != null) { + imgStream.addFilter(pdfFilter); + } + + imgStream.addDefaultFilters(); + return imgStream; + } + } + + protected PDFStream getPSDataStream() throws IOException { + int length = 0; + int i = 0; + EPSImage epsImage = (EPSImage) fopImage; + int[] bbox = epsImage.getBBox(); + int bboxw = bbox[2] - bbox[0]; + int bboxh = bbox[3] - bbox[1]; + + // delegate the stream work to PDFStream + PDFStream imgStream = new PDFStream(0); + + StringBuffer preamble = new StringBuffer(); + preamble.append("%%BeginDocument: " + epsImage.getDocName() + "\n"); + + preamble.append("userdict begin % Push userdict on dict stack\n"); + preamble.append("/PreEPS_state save def\n"); + preamble.append("/dict_stack countdictstack def\n"); + preamble.append("/ops_count count 1 sub def\n"); + preamble.append("/showpage {} def\n"); + + + preamble.append((double)(1f / (double) bboxw) + " " + + (double)(1f / (double) bboxh) + " scale\n"); + preamble.append(-bbox[0] + " " + (-bbox[1]) + " translate\n"); + preamble.append(bbox[0] + " " + bbox[1] + " " + bboxw + " " + + bboxh + " rectclip\n"); + preamble.append("newpath\n"); + + StringBuffer post = new StringBuffer(); + post.append("%%EndDocument\n"); + post.append("count ops_count sub {pop} repeat\n"); + post.append("countdictstack dict_stack sub {end} repeat\n"); + post.append("PreEPS_state restore\n"); + post.append("end % userdict\n"); + + byte[] preBytes = preamble.toString().getBytes(); + byte[] postBytes = post.toString().getBytes(); + byte[] imgData = new byte[preBytes.length + postBytes.length + + fopImage.getBitmaps().length]; + + System.arraycopy (preBytes, 0, imgData, 0, preBytes.length); + System.arraycopy (fopImage.getBitmaps(), 0, imgData, + preBytes.length, fopImage.getBitmaps().length); + System.arraycopy (postBytes, 0, imgData, + preBytes.length + fopImage.getBitmaps().length, + postBytes.length); + + + imgStream.setData(imgData); + imgStream.addDefaultFilters(); + + return imgStream; + } + + public PDFICCStream getICCStream() { + return pdfICCStream; + } + + protected PDFColorSpace toPDFColorSpace(ColorSpace cs) { + if(cs == null) return null; + + PDFColorSpace pdfCS = new PDFColorSpace(0); + switch(cs.getType()) { + case ColorSpace.TYPE_CMYK: + pdfCS.setColorSpace(PDFColorSpace.DEVICE_CMYK); + break; + case ColorSpace.TYPE_RGB: + pdfCS.setColorSpace(PDFColorSpace.DEVICE_RGB); + break; + case ColorSpace.TYPE_GRAY: + pdfCS.setColorSpace(PDFColorSpace.DEVICE_GRAY); + break; + } + return pdfCS; + } +} + diff --git a/src/org/apache/fop/render/pdf/PDFRenderer.java b/src/org/apache/fop/render/pdf/PDFRenderer.java index 26691e61d..69ed8770d 100644 --- a/src/org/apache/fop/render/pdf/PDFRenderer.java +++ b/src/org/apache/fop/render/pdf/PDFRenderer.java @@ -460,7 +460,7 @@ public class PDFRenderer extends PrintRenderer { this.currentFontName = name; this.currentFontSize = size; - pdf = pdf.append("/" + name + " " + (size / 1000) + " Tf\n"); + pdf = pdf.append("/" + name + " " + ((float)size / 1000f) + " Tf\n"); } } @@ -497,19 +497,22 @@ public class PDFRenderer extends PrintRenderer { if(!fopimage.load(FopImage.ORIGINAL_DATA, userAgent)) { return; } - int xobj = pdfDoc.addImage(fopimage); + FopPDFImage pdfimage = new FopPDFImage(fopimage); + int xobj = pdfDoc.addImage(pdfimage).getXNumber(); fact.releaseImage(url, userAgent); } else if("image/jpg".equals(mime)) { if(!fopimage.load(FopImage.ORIGINAL_DATA, userAgent)) { return; } - int xobj = pdfDoc.addImage(fopimage); + FopPDFImage pdfimage = new FopPDFImage(fopimage); + int xobj = pdfDoc.addImage(pdfimage).getXNumber(); fact.releaseImage(url, userAgent); } else { if(!fopimage.load(FopImage.BITMAP, userAgent)) { return; } - int xobj = pdfDoc.addImage(fopimage); + FopPDFImage pdfimage = new FopPDFImage(fopimage); + int xobj = pdfDoc.addImage(pdfimage).getXNumber(); fact.releaseImage(url, userAgent); closeText(); diff --git a/src/org/apache/fop/render/ps/PSGraphics2D.java b/src/org/apache/fop/render/ps/PSGraphics2D.java index e2fe42180..cd04f21db 100644 --- a/src/org/apache/fop/render/ps/PSGraphics2D.java +++ b/src/org/apache/fop/render/ps/PSGraphics2D.java @@ -12,7 +12,6 @@ import org.apache.fop.layout.*; import org.apache.fop.fonts.*; import org.apache.fop.render.pdf.*; import org.apache.fop.image.*; -import org.apache.fop.datatypes.ColorSpace; import org.apache.fop.fo.FOUserAgent; import org.apache.batik.ext.awt.g2d.*; @@ -201,7 +200,7 @@ public class PSGraphics2D extends AbstractGraphics2D { break; } - try { + /*try { FopImage fopimg = new TempImage(width, height, result, mask); AffineTransform at = getTransform(); double[] matrix = new double[6]; @@ -216,7 +215,7 @@ public class PSGraphics2D extends AbstractGraphics2D { psRenderer.write("grestore"); } catch (Exception e) { e.printStackTrace(); - } + }*/ return true; } @@ -225,11 +224,11 @@ public class PSGraphics2D extends AbstractGraphics2D { BufferedImage.TYPE_INT_ARGB); } - class TempImage implements FopImage { + /*class TempImage implements FopImage { int m_height; int m_width; int m_bitsPerPixel; - ColorSpace m_colorSpace; + PDFColorSpace m_colorSpace; int m_bitmapSiye; byte[] m_bitmaps; byte[] m_mask; @@ -240,7 +239,7 @@ public class PSGraphics2D extends AbstractGraphics2D { this.m_height = height; this.m_width = width; this.m_bitsPerPixel = 8; - this.m_colorSpace = new ColorSpace(ColorSpace.DEVICE_RGB); + this.m_colorSpace = new PDFColorSpace(PDFColorSpace.DEVICE_RGB); // this.m_isTransparent = false; // this.m_bitmapsSize = this.m_width * this.m_height * 3; this.m_bitmaps = result; @@ -269,7 +268,7 @@ public class PSGraphics2D extends AbstractGraphics2D { } // DeviceGray, DeviceRGB, or DeviceCMYK - public ColorSpace getColorSpace() { + public PDFColorSpace getColorSpace() { return m_colorSpace; } @@ -287,7 +286,11 @@ public class PSGraphics2D extends AbstractGraphics2D { return transparent; } - public byte[] getMask() { + public boolean hasSoftMask() { + return m_mask != null; + } + + public byte[] getSoftMask() { return m_mask; } @@ -322,7 +325,7 @@ public class PSGraphics2D extends AbstractGraphics2D { // release memory public void close() {} - } + }*/ /** @@ -559,7 +562,7 @@ public class PSGraphics2D extends AbstractGraphics2D { c2.getBlue()); someColors.add(color2); - ColorSpace aColorSpace = new ColorSpace(ColorSpace.DEVICE_RGB); + PDFColorSpace aColorSpace = new PDFColorSpace(PDFColorSpace.DEVICE_RGB); } else if (paint instanceof TexturePaint) {} } diff --git a/src/org/apache/fop/svg/PDFGraphics2D.java b/src/org/apache/fop/svg/PDFGraphics2D.java index 4295656d0..91c7389e6 100644 --- a/src/org/apache/fop/svg/PDFGraphics2D.java +++ b/src/org/apache/fop/svg/PDFGraphics2D.java @@ -12,14 +12,20 @@ import org.apache.fop.layout.*; import org.apache.fop.fonts.*; import org.apache.fop.render.pdf.*; import org.apache.fop.image.*; -import org.apache.fop.datatypes.ColorSpace; import org.apache.fop.render.pdf.CIDFont; import org.apache.fop.render.pdf.fonts.LazyFont; +import org.apache.fop.render.pdf.FopPDFImage; import org.apache.fop.fo.FOUserAgent; import org.apache.batik.ext.awt.g2d.*; import org.apache.batik.ext.awt.image.GraphicsUtil; +import org.apache.batik.ext.awt.MultipleGradientPaint; +import org.apache.batik.ext.awt.RadialGradientPaint; +import org.apache.batik.ext.awt.LinearGradientPaint; +import org.apache.batik.gvt.PatternPaint; +import org.apache.batik.gvt.GraphicsNode; + import java.text.AttributedCharacterIterator; import java.text.CharacterIterator; import java.awt.*; @@ -28,6 +34,7 @@ import java.awt.Image; import java.awt.image.*; import java.awt.font.*; import java.awt.geom.*; +import java.awt.color.ColorSpace; import java.awt.image.renderable.*; import java.io.*; @@ -74,7 +81,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { /** * the current font size in millipoints */ - protected int currentFontSize; + protected float currentFontSize; /** * the current vertical position in millipoints from bottom @@ -106,7 +113,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { * existing document. */ public PDFGraphics2D(boolean textAsShapes, FontState fs, PDFDocument doc, - PDFPage page, String font, int size, int xpos, int ypos) { + PDFPage page, String font, float size, int xpos, int ypos) { super(textAsShapes); pdfDoc = doc; currentPage = page; @@ -176,7 +183,8 @@ public class PDFGraphics2D extends AbstractGraphics2D { } public void addJpegImage(JpegImage jpeg, float x, float y, float width, float height) { - int xObjectNum = this.pdfDoc.addImage(jpeg); + FopPDFImage fopimage = new FopPDFImage(jpeg); + int xObjectNum = this.pdfDoc.addImage(fopimage).getXNumber(); AffineTransform at = getTransform(); double[] matrix = new double[6]; @@ -254,8 +262,10 @@ public class PDFGraphics2D extends AbstractGraphics2D { g.dispose(); final byte[] result = new byte[buf.getWidth() * buf.getHeight() * 3]; - final byte[] mask = new byte[buf.getWidth() * buf.getHeight()]; - + byte[] mask = new byte[buf.getWidth() * buf.getHeight()]; + boolean hasMask = false; + boolean binaryMask = true; + Raster raster = buf.getData(); DataBuffer bd = raster.getDataBuffer(); @@ -271,8 +281,11 @@ public class PDFGraphics2D extends AbstractGraphics2D { for (j = 0; j < iarray.length; j++) { val = iarray[j]; alpha = val >>> 24; - // mask[maskpos++] = (byte)((idata[i][j] >> 24) & 0xFF); + mask[maskpos++] = (byte)(alpha & 0xFF); if (alpha != 255) { + hasMask = true; + if(alpha != 0) binaryMask = false; + // System.out.println("Alpha: " + alpha); // Composite with opaque white... add = (255 - alpha); @@ -298,14 +311,21 @@ public class PDFGraphics2D extends AbstractGraphics2D { // error break; } - - try { - FopImage fopimg = new TempImage("TempImage:" + img.toString(), buf.getWidth(), buf.getHeight(), result, mask); - imageInfo.xObjectNum = this.pdfDoc.addImage(fopimg); - imageInfos.put(img, imageInfo); - } catch (Exception e) { - e.printStackTrace(); + String ref = null; + if(hasMask) { + // if the mask is binary then we could convert it into a bitmask + BitmapImage fopimg = new BitmapImage("TempImageMask:" + img.toString(), buf.getWidth(), buf.getHeight(), mask, null); + fopimg.setColorSpace(new PDFColorSpace(PDFColorSpace.DEVICE_GRAY)); + PDFXObject xobj = pdfDoc.addImage(fopimg); + ref = xobj.referencePDF(); + } else { + mask = null; } + + BitmapImage fopimg = new BitmapImage("TempImage:" + img.toString(), buf.getWidth(), buf.getHeight(), result, ref); + fopimg.setTransparent(new PDFColor(255, 255, 255)); + imageInfo.xObjectNum = pdfDoc.addImage(fopimg).getXNumber(); + imageInfos.put(img, imageInfo); } // now do any transformation required and add the actual image @@ -330,108 +350,6 @@ public class PDFGraphics2D extends AbstractGraphics2D { BufferedImage.TYPE_INT_ARGB); } - class TempImage implements FopImage { - int m_height; - int m_width; - int m_bitsPerPixel; - ColorSpace m_colorSpace; - int m_bitmapSiye; - byte[] m_bitmaps; - byte[] m_mask; - PDFColor transparent = new PDFColor(255, 255, 255); - String url; - - TempImage(String url, int width, int height, byte[] result, - byte[] mask) { - this.url = url; - this.m_height = height; - this.m_width = width; - this.m_bitsPerPixel = 8; - this.m_colorSpace = new ColorSpace(ColorSpace.DEVICE_RGB); - // this.m_isTransparent = false; - // this.m_bitmapsSize = this.m_width * this.m_height * 3; - this.m_bitmaps = result; - this.m_mask = mask; - } - - public boolean load(int type, FOUserAgent ua) { - return true; - } - - public String getMimeType() { - return ""; - } - - public String getURL() { - return url; - } - - // image size - public int getWidth() { - return m_width; - } - - public int getHeight() { - return m_height; - } - - // DeviceGray, DeviceRGB, or DeviceCMYK - public ColorSpace getColorSpace() { - return m_colorSpace; - } - - // bits per pixel - public int getBitsPerPixel() { - return m_bitsPerPixel; - } - - // For transparent images - public boolean isTransparent() { - return transparent != null; - } - - public PDFColor getTransparentColor() { - return transparent; - } - - public byte[] getMask() { - return m_mask; - } - - // get the image bytes, and bytes properties - - // get uncompressed image bytes - public byte[] getBitmaps() { - return m_bitmaps; - } - - // width * (bitsPerPixel / 8) * height, no ? - public int getBitmapsSize() { - return m_width * m_height * 3; - } - - // get compressed image bytes - // I don't know if we really need it, nor if it - // should be changed... - public byte[] getRessourceBytes() { - return null; - } - - public int getRessourceBytesSize() { - return 0; - } - - // return null if no corresponding PDFFilter - public PDFFilter getPDFFilter() { - return null; - } - - // release memory - public void close() {} - - } - - /** * Draws as much of the specified image as has already been scaled * to fit inside the specified rectangle. @@ -656,12 +574,12 @@ public class PDFGraphics2D extends AbstractGraphics2D { protected void applyColor(Color col, boolean fill) { Color c = col; if (c.getColorSpace().getType() - == java.awt.color.ColorSpace.TYPE_RGB) { + == ColorSpace.TYPE_RGB) { PDFColor currentColour = new PDFColor(c.getRed(), c.getGreen(), c.getBlue()); currentStream.write(currentColour.getColorSpaceOut(fill)); } else if (c.getColorSpace().getType() - == java.awt.color.ColorSpace.TYPE_CMYK) { + == ColorSpace.TYPE_CMYK) { float[] cComps = c.getColorComponents(new float[3]); double[] cmyk = new double[3]; for (int i = 0; i < 3; i++) { @@ -671,7 +589,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { PDFColor currentColour = new PDFColor(cmyk[0], cmyk[1], cmyk[2], cmyk[3]); currentStream.write(currentColour.getColorSpaceOut(fill)); } else if (c.getColorSpace().getType() - == java.awt.color.ColorSpace.TYPE_2CLR) { + == ColorSpace.TYPE_2CLR) { // used for black/magenta float[] cComps = c.getColorComponents(new float[1]); double[] blackMagenta = new double[1]; @@ -686,13 +604,14 @@ public class PDFGraphics2D extends AbstractGraphics2D { } protected void applyPaint(Paint paint, boolean fill) { - if (paint instanceof GradientPaint) { - GradientPaint gp = (GradientPaint)paint; - Color c1 = gp.getColor1(); - Color c2 = gp.getColor2(); - Point2D p1 = gp.getPoint1(); - Point2D p2 = gp.getPoint2(); - boolean cyclic = gp.isCyclic(); + + if (paint instanceof LinearGradientPaint) { + LinearGradientPaint gp = (LinearGradientPaint)paint; + Color[] cols = gp.getColors(); + Point2D p1 = gp.getStartPoint(); + Point2D p2 = gp.getEndPoint(); + MultipleGradientPaint.CycleMethodEnum cycenum = gp.getCycleMethod(); + boolean cyclic = cycenum == MultipleGradientPaint.REPEAT; ArrayList theCoords = new ArrayList(); theCoords.add(new Double(p1.getX())); @@ -722,6 +641,9 @@ public class PDFGraphics2D extends AbstractGraphics2D { ArrayList someColors = new ArrayList(); + Color c1 = cols[0]; + Color c2 = cols[1]; + PDFColor color1 = new PDFColor(c1.getRed(), c1.getGreen(), c1.getBlue()); someColors.add(color1); @@ -732,12 +654,84 @@ public class PDFGraphics2D extends AbstractGraphics2D { PDFFunction myfunc = this.pdfDoc.makeFunction(2, theDomain, null, color1.getVector(), color2.getVector(), 1.0); - ColorSpace aColorSpace = new ColorSpace(ColorSpace.DEVICE_RGB); + PDFColorSpace aColorSpace = new PDFColorSpace(PDFColorSpace.DEVICE_RGB); PDFPattern myPat = this.pdfDoc.createGradient(false, aColorSpace, someColors, null, theCoords); currentStream.write(myPat.getColorSpaceOut(fill)); - } else if (paint instanceof TexturePaint) {} + } else if (paint instanceof RadialGradientPaint) { + System.err.println("Radial gradient paint not supported"); + + RadialGradientPaint rgp = (RadialGradientPaint)paint; +/* + ArrayList theCoords = new ArrayList(); + theCoords.add( new Double(currentXPosition / 1000f + acx)); + theCoords.add( new Double(currentYPosition / 1000f - acy)); + theCoords.add(new Double(0)); + theCoords.add( new Double(currentXPosition / 1000f + afx)); // Fx + theCoords.add(new Double(currentYPosition / 1000f - afy)); // Fy + theCoords.add(new Double(ar)); + + float lastoffset = 0; + PDFColor color = new PDFColor(0, 0, 0); + color = new PDFColor(red, green, blue); + + float offset = stop.getOffset().getBaseVal(); +// create bounds from last to offset + lastoffset = offset; + someColors.add(color); + } + PDFPattern myPat = pdfDoc.createGradient(true, aColorSpace, + someColors, theBounds, theCoords); + + currentStream.write(myPat.getColorSpaceOut(fill)); +*/ + } else if (paint instanceof PatternPaint) { + PatternPaint pp = (PatternPaint)paint; + Rectangle2D rect = pp.getPatternRect(); + + PDFGraphics2D pattGraphic = new PDFGraphics2D(textAsShapes, fontState, + pdfDoc, currentPage, + currentFontName, currentFontSize, + currentYPosition, currentXPosition); + pattGraphic.gc = (GraphicContext)this.gc.clone(); + pattGraphic.gc.validateTransformStack(); + + GraphicsNode gn = pp.getGraphicsNode(); + gn.paint(pattGraphic); + + StringWriter pattStream = new StringWriter(); + pattStream.write("q\n"); + + // this makes the pattern the right way up, since + // it is outside the original transform around the + // whole svg document + pattStream.write("1 0 0 -1 0 " + rect.getHeight() + " cm\n"); + + pattStream.write(pattGraphic.getString()); + pattStream.write("Q"); + + ArrayList bbox = new ArrayList(); + bbox.add(new Double(0)); + bbox.add(new Double(0)); + bbox.add(new Double(rect.getWidth())); + bbox.add(new Double(rect.getHeight())); + ArrayList translate = new ArrayList(); + // TODO combine with pattern transform + translate.add(new Double(1)); + translate.add(new Double(0)); + translate.add(new Double(0)); + translate.add(new Double(1)); + translate.add(new Double(rect.getX())); + translate.add(new Double(rect.getY())); + // TODO handle PDFResources + PDFPattern myPat = pdfDoc.makePattern(1, null, 1, 1, bbox, + rect.getWidth(), rect.getHeight(), + translate, null, pattStream.getBuffer()); + + currentStream.write(myPat.getColorSpaceOut(fill)); + + } } protected void applyStroke(Stroke stroke) { @@ -900,9 +894,9 @@ public class PDFGraphics2D extends AbstractGraphics2D { ovFontState = null; } String name; - int size; + float size; name = fontState.getFontName(); - size = fontState.getFontSize() / 1000; + size = (float)fontState.getFontSize() / 1000f; if ((!name.equals(this.currentFontName)) || (size != this.currentFontSize)) { @@ -918,8 +912,17 @@ public class PDFGraphics2D extends AbstractGraphics2D { writeClip(imclip); Color c = getColor(); applyColor(c, true); + int salpha = c.getAlpha(); + c = getBackground(); applyColor(c, false); + if(salpha != 255 || c.getAlpha() != 255) { + PDFGState gstate = pdfDoc.makeGState(); + gstate.setAlpha(salpha / 255f, true); + //gstate.setAlpha(c.getAlpha() / 255f, false); + currentPage.addGState(gstate); + currentStream.write("/" + gstate.getName() + " gs\n"); + } currentStream.write("BT\n"); diff --git a/src/org/apache/fop/svg/PDFTextElementBridge.java b/src/org/apache/fop/svg/PDFTextElementBridge.java index bb88865db..933165b97 100644 --- a/src/org/apache/fop/svg/PDFTextElementBridge.java +++ b/src/org/apache/fop/svg/PDFTextElementBridge.java @@ -60,9 +60,9 @@ public class PDFTextElementBridge extends SVGTextElementBridge { private boolean isSimple(BridgeContext ctx, Element element, GraphicsNode node) { // Font size, in user space units. float fs = TextUtilities.convertFontSize(element).floatValue(); - if(((int)fs) != fs) { + /*if(((int)fs) != fs) { return false; - } + }*/ if(fs > 36) { return false; } |