]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Use FOP's wrapper classes to load images. Support 'auto' in fo:external-grapic@height...
authorPeter Herweg <pherweg@apache.org>
Sun, 30 Oct 2005 16:55:47 +0000 (16:55 +0000)
committerPeter Herweg <pherweg@apache.org>
Sun, 30 Oct 2005 16:55:47 +0000 (16:55 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@329590 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/fop/image/EmfImage.java [new file with mode: 0644]
src/java/org/apache/fop/image/ImageFactory.java
src/java/org/apache/fop/image/analyser/EMFReader.java [new file with mode: 0644]
src/java/org/apache/fop/image/analyser/ImageReaderFactory.java
src/java/org/apache/fop/render/rtf/RTFHandler.java
src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfExternalGraphic.java

diff --git a/src/java/org/apache/fop/image/EmfImage.java b/src/java/org/apache/fop/image/EmfImage.java
new file mode 100644 (file)
index 0000000..bbe3794
--- /dev/null
@@ -0,0 +1,72 @@
+/*\r
+ * Copyright 1999-2005 The Apache Software Foundation.\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * \r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+\r
+package org.apache.fop.image;\r
+\r
+// Java\r
+import java.io.ByteArrayOutputStream;\r
+\r
+import org.apache.commons.io.IOUtils;\r
+\r
+/**\r
+ * Enhanced metafile image.\r
+ * This supports loading a emf image.\r
+ *\r
+ * @author Peter Herweg\r
+ * @see AbstractFopImage\r
+ * @see FopImage\r
+ */\r
+public class EmfImage extends AbstractFopImage {\r
+    /**\r
+     * Create a bitmap image with the image data.\r
+     *\r
+     * @param imgInfo the image information\r
+     */\r
+    public EmfImage(FopImage.ImageInfo imgInfo) {\r
+        super(imgInfo);\r
+    }\r
+\r
+    /**\r
+     * Load the original jpeg data.\r
+     * This loads the original jpeg data and reads the color space,\r
+     * and icc profile if any.\r
+     *\r
+     * @return true if loaded false for any error\r
+     */\r
+    protected boolean loadOriginalData() {\r
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();\r
+\r
+        try {\r
+            byte[] readBuf = new byte[4096];\r
+            int bytesRead;\r
+            while ((bytesRead = inputStream.read(readBuf)) != -1) {\r
+                baos.write(readBuf, 0, bytesRead);\r
+            }\r
+        } catch (java.io.IOException ex) {\r
+            log.error("Error while loading image (Emf): " + ex.getMessage(), ex);\r
+            return false;\r
+        } finally {\r
+            IOUtils.closeQuietly(inputStream);\r
+            inputStream = null;\r
+        }\r
+\r
+        this.raw = baos.toByteArray();\r
+        \r
+        return true;\r
+    }\r
+}\r
+\r
index 8379cda856e5869cdd4bbfdc59aa71c4c1dfbee1..d7b73c37227c51a48a9ef2509db2357fe99dc3d1 100644 (file)
@@ -71,6 +71,7 @@ public final class ImageFactory {
         ImageProvider pngImage = new ImageProvider("PNGImage", "org.apache.fop.image.PNGImage");
         ImageProvider tiffImage = new ImageProvider("TIFFImage", "org.apache.fop.image.TIFFImage");
         ImageProvider xmlImage = new ImageProvider("XMLImage", "org.apache.fop.image.XMLImage");
+        ImageProvider emfImage = new ImageProvider("EMFImage", "org.apache.fop.image.EmfImage");
         
         ImageMimeType imt = new ImageMimeType("image/gif");
         imageMimeTypes.put(imt.getMimeType(), imt);
@@ -113,7 +114,10 @@ public final class ImageFactory {
         imt = new ImageMimeType("text/xml");
         imageMimeTypes.put(imt.getMimeType(), imt);
         imt.addProvider(xmlImage);
-
+        
+        imt = new ImageMimeType("image/emf");
+        imageMimeTypes.put(imt.getMimeType(), imt);
+        imt.addProvider(emfImage);
     }
 
     /**
diff --git a/src/java/org/apache/fop/image/analyser/EMFReader.java b/src/java/org/apache/fop/image/analyser/EMFReader.java
new file mode 100644 (file)
index 0000000..a5c0184
--- /dev/null
@@ -0,0 +1,159 @@
+/*\r
+ * Copyright 1999-2005 The Apache Software Foundation.\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * \r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.apache.fop.image.analyser;\r
+\r
+// Java\r
+import java.io.InputStream;\r
+import java.io.IOException;\r
+\r
+// FOP\r
+import org.apache.fop.image.FopImage;\r
+import org.apache.fop.apps.FOUserAgent;\r
+\r
+/**\r
+ * ImageReader object for EMF image type.\r
+ *\r
+ * @author    Peter Herweg\r
+ */\r
+public class EMFReader implements ImageReader {\r
+\r
+    /** Length of the EMF header */\r
+    protected static final int EMF_SIG_LENGTH = 88;\r
+    \r
+    /** offset to signature */\r
+    private static final int SIGNATURE_OFFSET = 40;\r
+    /** offset to width */\r
+    private static final int WIDTH_OFFSET = 32;\r
+    /** offset to height */\r
+    private static final int HEIGHT_OFFSET = 36;\r
+    /** offset to horizontal resolution in pixel */\r
+    private static final int HRES_PIXEL_OFFSET = 72;\r
+    /** offset to vertical resolution in pixel */\r
+    private static final int VRES_PIXEL_OFFSET = 76;\r
+    /** offset to horizontal resolution in mm */\r
+    private static final int HRES_MM_OFFSET = 80;\r
+    /** offset to vertical resolution in mm */\r
+    private static final int VRES_MM_OFFSET = 84;\r
+\r
+    /** @see org.apache.fop.image.analyser.ImageReader */\r
+    public FopImage.ImageInfo verifySignature(String uri, InputStream bis,\r
+                FOUserAgent ua) throws IOException {\r
+        byte[] header = getDefaultHeader(bis);\r
+        boolean supported = \r
+                 ( (header[SIGNATURE_OFFSET + 0] == (byte) 0x20)\r
+                && (header[SIGNATURE_OFFSET + 1] == (byte) 0x45)\r
+                && (header[SIGNATURE_OFFSET + 2] == (byte) 0x4D)\r
+                && (header[SIGNATURE_OFFSET + 3] == (byte) 0x46) );\r
+        \r
+        if (supported) {\r
+            FopImage.ImageInfo info = getDimension(header);\r
+            info.originalURI = uri;\r
+            info.mimeType = getMimeType();\r
+            info.inputStream = bis;\r
+            return info;\r
+        } else {\r
+            return null;\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Returns the MIME type supported by this implementation.\r
+     *\r
+     * @return   The MIME type\r
+     */\r
+    public String getMimeType() {\r
+        return "image/emf";\r
+    }\r
+\r
+    private FopImage.ImageInfo getDimension(byte[] header) {\r
+        FopImage.ImageInfo info = new FopImage.ImageInfo();\r
+        long value = 0;\r
+        int byte1;\r
+        int byte2;\r
+        int byte3;\r
+        int byte4;\r
+        \r
+        // little endian notation\r
+\r
+        //resolution        \r
+        byte1 = header[HRES_MM_OFFSET] & 0xff;\r
+        byte2 = header[HRES_MM_OFFSET + 1] & 0xff;\r
+        byte3 = header[HRES_MM_OFFSET + 2] & 0xff;\r
+        byte4 = header[HRES_MM_OFFSET + 3] & 0xff;\r
+        long hresMM = (long) ((byte4 << 24) | (byte3 << 16) | (byte2 << 8) | byte1);\r
+        \r
+        byte1 = header[VRES_MM_OFFSET] & 0xff;\r
+        byte2 = header[VRES_MM_OFFSET + 1] & 0xff;\r
+        byte3 = header[VRES_MM_OFFSET + 2] & 0xff;\r
+        byte4 = header[VRES_MM_OFFSET + 3] & 0xff;\r
+        long vresMM = (long) ((byte4 << 24) | (byte3 << 16) | (byte2 << 8) | byte1);\r
+        \r
+        byte1 = header[HRES_PIXEL_OFFSET] & 0xff;\r
+        byte2 = header[HRES_PIXEL_OFFSET + 1] & 0xff;\r
+        byte3 = header[HRES_PIXEL_OFFSET + 2] & 0xff;\r
+        byte4 = header[HRES_PIXEL_OFFSET + 3] & 0xff;\r
+        long hresPixel = (long) ((byte4 << 24) | (byte3 << 16) | (byte2 << 8) | byte1);\r
+        \r
+        byte1 = header[VRES_PIXEL_OFFSET] & 0xff;\r
+        byte2 = header[VRES_PIXEL_OFFSET + 1] & 0xff;\r
+        byte3 = header[VRES_PIXEL_OFFSET + 2] & 0xff;\r
+        byte4 = header[VRES_PIXEL_OFFSET + 3] & 0xff;\r
+        long vresPixel = (long) ((byte4 << 24) | (byte3 << 16) | (byte2 << 8) | byte1);\r
+        \r
+        info.dpiHorizontal = hresPixel / (hresMM/25.4);\r
+        info.dpiVertical   = vresPixel / (vresMM/25.4);;\r
+        \r
+        //width\r
+        byte1 = header[WIDTH_OFFSET] & 0xff;\r
+        byte2 = header[WIDTH_OFFSET + 1] & 0xff;\r
+        byte3 = header[WIDTH_OFFSET + 2] & 0xff;\r
+        byte4 = header[WIDTH_OFFSET + 3] & 0xff;\r
+        value = (long) ((byte4 << 24) | (byte3 << 16)\r
+                | (byte2 << 8) | byte1);\r
+        value = (long) (value / 100f / 25.4 * info.dpiHorizontal);\r
+        info.width = (int) (value & 0xffffffff);\r
+\r
+        //height\r
+        byte1 = header[HEIGHT_OFFSET] & 0xff;\r
+        byte2 = header[HEIGHT_OFFSET + 1] & 0xff;\r
+        byte3 = header[HEIGHT_OFFSET + 2] & 0xff;\r
+        byte4 = header[HEIGHT_OFFSET + 3] & 0xff;\r
+        value = (long) ((byte4 << 24) | (byte3 << 16) | (byte2 << 8) | byte1);\r
+        value = (long) (value / 100f / 25.4 * info.dpiVertical);\r
+        info.height = (int) (value & 0xffffffff);\r
+\r
+        return info;\r
+    }\r
+\r
+    private byte[] getDefaultHeader(InputStream imageStream)\r
+                throws IOException {\r
+        byte[] header = new byte[EMF_SIG_LENGTH];\r
+        try {\r
+            imageStream.mark(EMF_SIG_LENGTH + 1);\r
+            imageStream.read(header);\r
+            imageStream.reset();\r
+        } catch (IOException ex) {\r
+            try {\r
+                imageStream.reset();\r
+            } catch (IOException exbis) {\r
+                // throw the original exception, not this one\r
+            }\r
+            throw ex;\r
+        }\r
+        return header;\r
+    }\r
+}\r
index 826f4b60f08402f741fb5fec5bf5f80b44f95fa3..853508761a4ad870f837f0047f00da8e12e7d333 100644 (file)
@@ -50,6 +50,7 @@ public class ImageReaderFactory {
         registerFormat(new PNGReader());
         registerFormat(new TIFFReader());
         registerFormat(new EPSReader());
+        registerFormat(new EMFReader());
         // the xml parser through batik closes the stream when finished
         // so there is a workaround in the SVGReader
         registerFormat(new SVGReader());
index 4c08d80e79ddce9121d2e8ae5235a4ce4fe60fa4..6487b53940ec078ac9334331badd716317cf5622 100644 (file)
@@ -23,6 +23,7 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.util.Iterator;
+import org.apache.fop.*;
 
 // Libs
 import org.apache.commons.logging.Log;
@@ -86,6 +87,8 @@ import org.apache.fop.render.rtf.rtflib.rtfdoc.IRtfTableContainer;
 import org.apache.fop.render.rtf.rtflib.tools.BuilderContext;
 import org.apache.fop.render.rtf.rtflib.tools.TableContext;
 import org.apache.fop.fonts.FontSetup;
+import org.apache.fop.image.FopImage;
+import org.apache.fop.image.ImageFactory;
 
 /**
  * RTF Handler: generates RTF output using the structure events from
@@ -938,21 +941,72 @@ public class RTFHandler extends FOEventHandler {
             
             final RtfExternalGraphic newGraphic = c.getTextrun().newImage();
        
-            //Property p = null; 
-               
-            //get source file
-            newGraphic.setURL(eg.getSrc());
+            //set URL
+            String url = eg.getURL();
+            newGraphic.setURL(url);
+                       
+            //set image data
+            ImageFactory fact = ImageFactory.getInstance();
+            FopImage fopimage = fact.getImage(url, eg.getUserAgent());
+            fopimage.load(fopimage.ORIGINAL_DATA);
             
-            //get scaling
+            newGraphic.setImageData(fopimage.getRessourceBytes());
+            
+            //set scaling
             if (eg.getScaling() == Constants.EN_UNIFORM) {
                 newGraphic.setScaling ("uniform");
             }
             
             //get width
-            newGraphic.setWidth(eg.getWidth().getValue() / 1000f + "pt");
+            int width = 0;
+            if (eg.getWidth().getEnum() == Constants.EN_AUTO) {
+                width = fopimage.getIntrinsicWidth();
+            } else {
+                width = eg.getWidth().getValue();
+            }
             
             //get height
-            newGraphic.setHeight(eg.getHeight().getValue() / 1000f + "pt");
+            int height = 0;
+            if (eg.getWidth().getEnum() == Constants.EN_AUTO) {
+                height = fopimage.getIntrinsicHeight();
+            } else {
+                height = eg.getHeight().getValue();
+            }
+            
+            //get content-width
+            int contentwidth = 0;
+            if (eg.getContentWidth().getEnum() 
+                    == Constants.EN_AUTO) {
+                contentwidth = fopimage.getIntrinsicWidth();
+            } else if(eg.getContentWidth().getEnum() 
+                    == Constants.EN_SCALE_TO_FIT) {
+                contentwidth = width;
+            } else {
+                //TODO: check, if the value is a percent value
+                contentwidth = eg.getContentWidth().getValue();                    
+            }
+            
+            //get content-width
+            int contentheight = 0;
+            if (eg.getContentHeight().getEnum() 
+                    == Constants.EN_AUTO) {
+                
+                contentheight = fopimage.getIntrinsicHeight();
+                
+            } else if(eg.getContentHeight().getEnum() 
+                    == Constants.EN_SCALE_TO_FIT) {
+                
+                contentheight = height;
+            } else {
+                //TODO: check, if the value is a percent value
+                contentheight = eg.getContentHeight().getValue();                    
+            }
+                        
+            //set width in rtf
+            newGraphic.setWidth((long) (contentwidth / 1000f) + "pt");
+            
+            //set height in rtf
+            newGraphic.setHeight((long) (contentheight / 1000f) + "pt");
 
             //TODO: make this configurable:
             //      int compression = m_context.m_options.getRtfExternalGraphicCompressionRate ();
index c34f19b5f24e44cb1d7be747439a75d9065d5820..5f0bb1e3d09c6ee0ec93b29f6f714ae934943835 100644 (file)
@@ -105,7 +105,6 @@ public class RtfExternalGraphic extends RtfElement {
          */
 
         public static FormatBase determineFormat(byte[] data) {
-            int type = ImageConstants.I_NOT_SUPPORTED;
 
             if (FormatPNG.isFormat(data)) {
                 return new FormatPNG();
@@ -361,18 +360,19 @@ public class RtfExternalGraphic extends RtfElement {
 //        getRtfFile ().getLog ().logInfo ("Writing image '" + url + "'.");
 
 
-        imagedata = null;
-        try {
-            final InputStream in = url.openStream();
+        if (imagedata == null) {
             try {
-                imagedata = IOUtils.toByteArray(url.openStream());
-            } finally {
-                IOUtils.closeQuietly(in);
-            }
-        } catch (Exception e) {
-            throw new ExternalGraphicException("The attribute 'src' of "
-                    + "<fo:external-graphic> has a invalid value: '"
-                    + url + "' (" + e + ")");
+                final InputStream in = url.openStream();
+                try {
+                    imagedata = IOUtils.toByteArray(url.openStream());
+                } finally {
+                    IOUtils.closeQuietly(in);
+                }
+            } catch (Exception e) {
+                throw new ExternalGraphicException("The attribute 'src' of "
+                        + "<fo:external-graphic> has a invalid value: '"
+                        + url + "' (" + e + ")");
+            }            
         }
 
         if (imagedata == null) {
@@ -463,8 +463,18 @@ public class RtfExternalGraphic extends RtfElement {
                 height = ImageUtil.getIntFromByteArray(imagedata, basis, 2, true);
             }
         } else if (imageformat.getType() == ImageConstants.I_EMF) {
-            width = ImageUtil.getIntFromByteArray(imagedata, 151, 4, false);
-            height = ImageUtil.getIntFromByteArray(imagedata, 155, 4, false);
+            int i = 0;
+            
+            i = ImageUtil.getIntFromByteArray(imagedata, 151, 4, false);
+            if (i != 0 ) {
+                width = i; 
+            }
+            
+            i = ImageUtil.getIntFromByteArray(imagedata, 155, 4, false);
+            if (i != 0 ) {
+                height = i;
+            }
+            
         }
     }
 
@@ -546,6 +556,16 @@ public class RtfExternalGraphic extends RtfElement {
             this.scaleUniform = true;
         }
     }
+    
+    /**
+     * Sets the binary imagedata of the image.
+     *
+     * @param imagedata Binary imagedata as read from file.
+     * @throws IOException On error
+     */
+    public void setImageData(byte[] imagedata) throws IOException {
+        this.imagedata = imagedata;
+    }
 
     /**
      * Sets the url of the image.