]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Bugzilla #40849:
authorJeremias Maerki <jeremias@apache.org>
Sun, 12 Nov 2006 15:28:15 +0000 (15:28 +0000)
committerJeremias Maerki <jeremias@apache.org>
Sun, 12 Nov 2006 15:28:15 +0000 (15:28 +0000)
Support for fo:instream-foreign-object (SVG only) for RTF output.
Submitted by: Dominic Brügger <bruegger.at.puzzle.ch>

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@473975 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/fop/fo/flow/InstreamForeignObject.java
src/java/org/apache/fop/render/rtf/RTFHandler.java
src/java/org/apache/fop/render/rtf/rtflib/tools/BuilderContext.java
status.xml

index c79b290907ef56147ed7611f30967726b6d141da..790785a6b05763aad23bb8ff28711fc99142ef43 100644 (file)
@@ -65,6 +65,7 @@ public class InstreamForeignObject extends AbstractGraphics {
         if (childNodes == null || childNodes.size() != 1) {
             missingChildElementError("one (1) non-XSL namespace child");
         }
+        getFOEventHandler().foreignObject(this);
     }
 
     /**
index c751a424e2cc2655dc0a0ce5cfe0df8f8a159fc0..d17e3285c7e049cb6fd05b611aa6d21de8efa689 100644 (file)
 package org.apache.fop.render.rtf;
 
 // Java
+import java.awt.geom.Point2D;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.util.Iterator;
 
-// Libs
+import org.apache.batik.dom.svg.SVGDOMImplementation;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.xml.sax.SAXException;
-
-// FOP
 import org.apache.fop.apps.FOPException;
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.datatypes.LengthBase;
 import org.apache.fop.datatypes.SimplePercentBaseContext;
+import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.FOEventHandler;
 import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.FOText;
+import org.apache.fop.fo.XMLObj;
+import org.apache.fop.fo.flow.AbstractGraphics;
 import org.apache.fop.fo.flow.BasicLink;
 import org.apache.fop.fo.flow.Block;
 import org.apache.fop.fo.flow.BlockContainer;
@@ -53,9 +55,9 @@ import org.apache.fop.fo.flow.ListItemBody;
 import org.apache.fop.fo.flow.ListItemLabel;
 import org.apache.fop.fo.flow.PageNumber;
 import org.apache.fop.fo.flow.Table;
-import org.apache.fop.fo.flow.TableColumn;
 import org.apache.fop.fo.flow.TableBody;
 import org.apache.fop.fo.flow.TableCell;
+import org.apache.fop.fo.flow.TableColumn;
 import org.apache.fop.fo.flow.TableHeader;
 import org.apache.fop.fo.flow.TableRow;
 import org.apache.fop.fo.pagination.Flow;
@@ -65,14 +67,17 @@ import org.apache.fop.fo.pagination.Region;
 import org.apache.fop.fo.pagination.SimplePageMaster;
 import org.apache.fop.fo.pagination.StaticContent;
 import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
-import org.apache.fop.fo.Constants;
-import org.apache.fop.fo.FOText;
+import org.apache.fop.fonts.FontSetup;
+import org.apache.fop.image.FopImage;
+import org.apache.fop.image.ImageFactory;
+import org.apache.fop.image.XMLImage;
 import org.apache.fop.render.DefaultFontResolver;
-import org.apache.fop.render.rtf.rtflib.rtfdoc.ITableAttributes;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.IRtfAfterContainer;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.IRtfBeforeContainer;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.IRtfListContainer;
+import org.apache.fop.render.rtf.rtflib.rtfdoc.IRtfTableContainer;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.IRtfTextrunContainer;
+import org.apache.fop.render.rtf.rtflib.rtfdoc.ITableAttributes;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfAfter;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfAttributes;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfBefore;
@@ -84,19 +89,16 @@ import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfFootnote;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfHyperLink;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfList;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfListItem;
-import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfListItem.RtfListItemLabel;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection;
-import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTextrun;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTable;
-import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableRow;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableCell;
-import org.apache.fop.render.rtf.rtflib.rtfdoc.IRtfTableContainer;
+import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableRow;
+import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTextrun;
+import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfListItem.RtfListItemLabel;
 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;
-import org.apache.fop.image.XMLImage;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
 
 /**
  * RTF Handler: generates RTF output using the structure events from
@@ -971,9 +973,6 @@ public class RTFHandler extends FOEventHandler {
         } catch (IOException ioe) {
             log.error("startList: " + ioe.getMessage());
             throw new RuntimeException(ioe.getMessage());
-        } catch (FOPException fe) {
-            log.error("startList: " + fe.getMessage());
-            throw new RuntimeException(fe.getMessage());
         } catch (Exception e) {
             log.error("startList: " + e.getMessage());
             throw new RuntimeException(e.getMessage());
@@ -1130,114 +1129,166 @@ public class RTFHandler extends FOEventHandler {
                 return;
             }
             fopimage.load(FopImage.ORIGINAL_DATA);
+            
+            putGraphic(eg, fopimage);
+        } catch (Exception e) {
+            log.error("Error while handling an external-graphic: " + e.getMessage(), e);
+        }
+    }
 
-            byte[] rawData;
-            if ("image/svg+xml".equals(fopimage.getMimeType())) {
-                rawData = SVGConverter.convertToJPEG((XMLImage)fopimage);
+    /**
+     * @see org.apache.fop.fo.FOEventHandler#foreignObject(InstreamForeignObject)
+     * @param ifo InstreamForeignObject that is starting
+     */
+    public void foreignObject(InstreamForeignObject ifo) {
+        if (bDefer) {
+            return;
+        }
+        
+        try {
+            XMLObj child = (XMLObj) ifo.getChildXMLObj();
+            Document doc = child.getDOMDocument();
+            String ns = child.getNamespaceURI();
+            
+            if (SVGDOMImplementation.SVG_NAMESPACE_URI.equals(ns)) {
+                // Build the image info.
+                FopImage.ImageInfo info = new FopImage.ImageInfo();
+                info.mimeType = "image/svg+xml";
+                info.str = SVGDOMImplementation.SVG_NAMESPACE_URI;
+                info.originalURI = "";
+                info.data = doc;
+
+                // Set the resolution to that of the FOUserAgent
+                FOUserAgent ua = ifo.getUserAgent();
+                info.dpiHorizontal = 25.4f / ua.getSourcePixelUnitToMillimeter();
+                info.dpiVertical = info.dpiHorizontal;
+                
+                // Set the image size to the size of the svg.
+                Point2D csize = new Point2D.Float(-1, -1);
+                Point2D intrinsicDimensions = child.getDimension(csize);
+                info.width = (int) intrinsicDimensions.getX();
+                info.height = (int) intrinsicDimensions.getY();
+                
+                FopImage fopImage = new XMLImage(info);
+                fopImage.load(FopImage.ORIGINAL_DATA);
+
+                putGraphic(ifo, fopImage);
             } else {
-                rawData = fopimage.getRessourceBytes();
-            }
-            if (rawData == null) {
-                log.warn(FONode.decorateWithContextInfo(
-                        "Image could not be embedded: " + url, eg));
-                return;
+                log.warn("The namespace " + ns
+                        + " for instream-foreign-objects is not supported.");
             }
+            
+            
+        } catch (Exception e) {
+            log.error("Error while handling an instream-foreign-object: " + e.getMessage(), e);
+        }
+    }
 
-            final IRtfTextrunContainer c
-                = (IRtfTextrunContainer)builderContext.getContainer(
-                    IRtfTextrunContainer.class, true, this);
+    /**
+     * Puts a graphic/image into the generated RTF file.
+     * @param abstractGraphic the graphic (external-graphic or instream-foreign-object)
+     * @param fopImage the image
+     * @throws IOException In case of an I/O error
+     */
+    private void putGraphic(AbstractGraphics abstractGraphic, FopImage fopImage) 
+            throws IOException {
+        byte[] rawData;
+        if ("image/svg+xml".equals(fopImage.getMimeType())) {
+            rawData = SVGConverter.convertToJPEG((XMLImage) fopImage);
+        } else {
+            rawData = fopImage.getRessourceBytes();
+        }
+        if (rawData == null) {
+            log.warn(FONode.decorateWithContextInfo("Image could not be embedded: "
+                    + fopImage.getOriginalURI(), abstractGraphic));
+            return;
+        }
 
-            final RtfExternalGraphic newGraphic = c.getTextrun().newImage();
-    
-            //set URL
-            newGraphic.setURL(url);
-            newGraphic.setImageData(rawData);
+        final IRtfTextrunContainer c
+            = (IRtfTextrunContainer)builderContext.getContainer(
+                IRtfTextrunContainer.class, true, this);
 
-            //set scaling
-            if (eg.getScaling() == Constants.EN_UNIFORM) {
-                newGraphic.setScaling ("uniform");
-            }
+        final RtfExternalGraphic rtfGraphic = c.getTextrun().newImage();
+   
+        //set URL
+        rtfGraphic.setURL(fopImage.getOriginalURI());
+        rtfGraphic.setImageData(rawData);
 
-            //get width
-            int width = 0;
-            if (eg.getWidth().getEnum() == Constants.EN_AUTO) {
-                width = fopimage.getIntrinsicWidth();
-            } else {
-                width = eg.getWidth().getValue();
-            }
+        //set scaling
+        if (abstractGraphic.getScaling() == Constants.EN_UNIFORM) {
+            rtfGraphic.setScaling ("uniform");
+        }
 
-            //get height
-            int height = 0;
-            if (eg.getWidth().getEnum() == Constants.EN_AUTO) {
-                height = fopimage.getIntrinsicHeight();
-            } else {
-                height = eg.getHeight().getValue();
-            }
+        //get width
+        int width = 0;
+        if (abstractGraphic.getWidth().getEnum() == Constants.EN_AUTO) {
+            width = fopImage.getIntrinsicWidth();
+        } else {
+            width = abstractGraphic.getWidth().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 height
+        int height = 0;
+        if (abstractGraphic.getWidth().getEnum() == Constants.EN_AUTO) {
+            height = fopImage.getIntrinsicHeight();
+        } else {
+            height = abstractGraphic.getHeight().getValue();
+        }
 
-            //get content-width
-            int contentheight = 0;
-            if (eg.getContentHeight().getEnum()
-                    == Constants.EN_AUTO) {
+        //get content-width
+        int contentwidth = 0;
+        if (abstractGraphic.getContentWidth().getEnum()
+                == Constants.EN_AUTO) {
+            contentwidth = fopImage.getIntrinsicWidth();
+        } else if (abstractGraphic.getContentWidth().getEnum()
+                == Constants.EN_SCALE_TO_FIT) {
+            contentwidth = width;
+        } else {
+            //TODO: check, if the value is a percent value
+            contentwidth = abstractGraphic.getContentWidth().getValue();
+        }
 
-                contentheight = fopimage.getIntrinsicHeight();
+        //get content-width
+        int contentheight = 0;
+        if (abstractGraphic.getContentHeight().getEnum()
+                == Constants.EN_AUTO) {
 
-            } else if (eg.getContentHeight().getEnum()
-                    == Constants.EN_SCALE_TO_FIT) {
+            contentheight = fopImage.getIntrinsicHeight();
 
-                contentheight = height;
-            } else {
-                //TODO: check, if the value is a percent value
-                contentheight = eg.getContentHeight().getValue();
-            }
+        } else if (abstractGraphic.getContentHeight().getEnum()
+                == Constants.EN_SCALE_TO_FIT) {
 
-            //set width in rtf
-            //newGraphic.setWidth((long) (contentwidth / 1000f) + "pt");
-            newGraphic.setWidth((long) (contentwidth / 50f) + "twips");
-
-            //set height in rtf
-            //newGraphic.setHeight((long) (contentheight / 1000f) + "pt");
-            newGraphic.setHeight((long) (contentheight / 50f) + "twips");
-
-            //TODO: make this configurable:
-            //      int compression = m_context.m_options.getRtfExternalGraphicCompressionRate ();
-            int compression = 0;
-            if (compression != 0) {
-                if (!newGraphic.setCompressionRate(compression)) {
-                    log.warn("The compression rate " + compression
-                        + " is invalid. The value has to be between 1 and 100 %.");
-                }
+            contentheight = height;
+        } else {
+            //TODO: check, if the value is a percent value
+            contentheight = abstractGraphic.getContentHeight().getValue();
+        }
+
+        //set width in rtf
+        //newGraphic.setWidth((long) (contentwidth / 1000f) + "pt");
+        rtfGraphic.setWidth((long) (contentwidth / 50f) + "twips");
+
+        //set height in rtf
+        //newGraphic.setHeight((long) (contentheight / 1000f) + "pt");
+        rtfGraphic.setHeight((long) (contentheight / 50f) + "twips");
+
+        //TODO: make this configurable:
+        //      int compression = m_context.m_options.getRtfExternalGraphicCompressionRate ();
+        int compression = 0;
+        if (compression != 0) {
+            if (!rtfGraphic.setCompressionRate(compression)) {
+                log.warn("The compression rate " + compression
+                    + " is invalid. The value has to be between 1 and 100 %.");
             }
-        } catch (Exception e) {
-            log.error("Error while handling an external-graphic: " + e.getMessage(), e);
         }
     }
-
+    
     /**
      * @see org.apache.fop.fo.FOEventHandler#pageRef()
      */
     public void pageRef() {
     }
 
-    /**
-     * @see org.apache.fop.fo.FOEventHandler#foreignObject(InstreamForeignObject)
-     * @param ifo InstreamForeignObject that is starting
-     */
-    public void foreignObject(InstreamForeignObject ifo) {
-    }
-
     /**
      * @see org.apache.fop.fo.FOEventHandler#startFootnote(Footnote)
      * @param footnote Footnote that is starting
@@ -1440,6 +1491,10 @@ public class RTFHandler extends FOEventHandler {
             if (bStart) {
                 image( (ExternalGraphic) foNode );
             }
+        } else if (foNode instanceof InstreamForeignObject) {
+            if (bStart) {
+                foreignObject( (InstreamForeignObject) foNode );
+            }
         } else if (foNode instanceof Block) {
             if (bStart) {
                 startBlock( (Block) foNode);
index 8684e91efd1959125856ebde62d6db27c1e13819..7e9b59c20b38bc494d90ae8bd5892547cd5ddba7 100644 (file)
@@ -21,6 +21,7 @@ package org.apache.fop.render.rtf.rtflib.tools;
 
 import java.util.Stack;
 
+import org.apache.fop.render.rtf.rtflib.exceptions.RtfException;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.IRtfOptions;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfContainer;
 
@@ -86,14 +87,14 @@ public class BuilderContext {
      *  @param forWhichBuilder used in error message if container not found
      */
     public RtfContainer getContainer(Class containerClass, boolean required,
-                              Object /*IBuilder*/ forWhichBuilder) throws Exception {
+                              Object /*IBuilder*/ forWhichBuilder) throws RtfException {
         // TODO what to do if the desired container is not at the top of the stack?
         // close top-of-stack container?
         final RtfContainer result = (RtfContainer)getObjectFromStack(containers,
                 containerClass);
 
         if (result == null && required) {
-            throw new Exception(
+            throw new RtfException(
                 "No RtfContainer of class '" + containerClass.getName()
                 + "' available for '" + forWhichBuilder.getClass().getName() + "' builder"
                );
index 419dae43ab4fc3d91c38c432ab8cd85950596ad7..7224186e094cf7b7c3abb836e81e090c054ab12d 100644 (file)
@@ -28,6 +28,9 @@
 
   <changes>
     <release version="FOP Trunk">
+      <action context="Code" dev="JM" type="add" fixes-bug="40849" due-to="Dominic Brügger">
+        Added support for SVG in fo:instream-foreign objects for RTF output.
+      </action>
       <action context="Code" dev="JM" type="fix">
         Bugfix: Fixed bug when the sum of column widths of a table is larger than the
         specified widths. The table width was not adjusted.