You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by je...@apache.org on 2008/01/11 20:51:11 UTC

svn commit: r611278 [4/5] - in /xmlgraphics/fop/trunk: ./ examples/mathml/resources/META-INF/services/ examples/mathml/src/org/apache/fop/mathml/ examples/plan/resources/META-INF/services/ examples/plan/src/org/apache/fop/plan/ lib/ src/java/META-INF/s...

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSRenderer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSRenderer.java?rev=611278&r1=611277&r2=611278&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSRenderer.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSRenderer.java Fri Jan 11 11:50:53 2008
@@ -24,6 +24,7 @@
 import java.awt.geom.Rectangle2D;
 import java.awt.image.RenderedImage;
 import java.io.File;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.LineNumberReader;
@@ -35,14 +36,28 @@
 
 import javax.xml.transform.Source;
 
-import org.w3c.dom.Document;
-
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
+import org.apache.xmlgraphics.image.loader.ImageException;
+import org.apache.xmlgraphics.image.loader.ImageFlavor;
+import org.apache.xmlgraphics.image.loader.ImageInfo;
+import org.apache.xmlgraphics.image.loader.ImageManager;
+import org.apache.xmlgraphics.image.loader.ImageSessionContext;
+import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D;
+import org.apache.xmlgraphics.image.loader.impl.ImageRawCCITTFax;
+import org.apache.xmlgraphics.image.loader.impl.ImageRawEPS;
+import org.apache.xmlgraphics.image.loader.impl.ImageRawJPEG;
+import org.apache.xmlgraphics.image.loader.impl.ImageRawStream;
+import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
+import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM;
+import org.apache.xmlgraphics.image.loader.pipeline.ImageProviderPipeline;
+import org.apache.xmlgraphics.image.loader.util.ImageUtil;
 import org.apache.xmlgraphics.ps.DSCConstants;
+import org.apache.xmlgraphics.ps.ImageEncoder;
 import org.apache.xmlgraphics.ps.PSGenerator;
+import org.apache.xmlgraphics.ps.PSImageUtils;
 import org.apache.xmlgraphics.ps.PSProcSets;
 import org.apache.xmlgraphics.ps.PSResource;
 import org.apache.xmlgraphics.ps.PSState;
@@ -69,15 +84,12 @@
 import org.apache.fop.area.inline.SpaceArea;
 import org.apache.fop.area.inline.TextArea;
 import org.apache.fop.area.inline.WordArea;
+import org.apache.fop.datatypes.URISpecification;
 import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.extensions.ExtensionAttachment;
 import org.apache.fop.fonts.Font;
 import org.apache.fop.fonts.LazyFont;
 import org.apache.fop.fonts.Typeface;
-import org.apache.fop.image.EPSImage;
-import org.apache.fop.image.FopImage;
-import org.apache.fop.image.ImageFactory;
-import org.apache.fop.image.XMLImage;
 import org.apache.fop.render.AbstractPathOrientedRenderer;
 import org.apache.fop.render.Graphics2DAdapter;
 import org.apache.fop.render.ImageAdapter;
@@ -108,7 +120,8 @@
  * @author <a href="mailto:fop-dev@xmlgraphics.apache.org">Apache FOP Development Team</a>
  * @version $Id$
  */
-public class PSRenderer extends AbstractPathOrientedRenderer implements ImageAdapter {
+public class PSRenderer extends AbstractPathOrientedRenderer
+            implements ImageAdapter, PSSupportedFlavors {
 
     /** logging instance */
     private static Log log = LogFactory.getLog(PSRenderer.class);
@@ -377,58 +390,183 @@
         }
     }
 
+    /**
+     * Indicates whether an image should be inlined or added as a PostScript form.
+     * @param uri the URI of the image
+     * @return true if the image should be inlined rather than added as a form
+     */
+    protected boolean isImageInlined(String uri) {
+        return !isOptimizeResources() || uri == null || "".equals(uri);
+    }
+    
+    /**
+     * Indicates whether an image should be inlined or added as a PostScript form.
+     * @param info the ImageInfo object of the image
+     * @return true if the image should be inlined rather than added as a form
+     */
+    protected boolean isImageInlined(ImageInfo info) {
+        if (isImageInlined(info.getOriginalURI())) {
+            return true;
+        }
+        
+        if (!isOptimizeResources()) {
+            throw new IllegalStateException("Must not get here if form support is enabled");
+        }
+
+        //Investigate choice for inline mode
+        ImageFlavor[] inlineFlavors = getInlineFlavors();
+        ImageManager manager = getUserAgent().getFactory().getImageManager();
+        ImageProviderPipeline[] inlineCandidates
+            = manager.getPipelineFactory().determineCandidatePipelines(
+                    info, inlineFlavors);
+        ImageProviderPipeline inlineChoice = manager.choosePipeline(inlineCandidates);
+        ImageFlavor inlineFlavor = (inlineChoice != null ? inlineChoice.getTargetFlavor() : null);
+        
+        //Investigate choice for form mode
+        ImageFlavor[] formFlavors = getFormFlavors();
+        ImageProviderPipeline[] formCandidates
+            = manager.getPipelineFactory().determineCandidatePipelines(
+                    info, formFlavors);
+        ImageProviderPipeline formChoice = manager.choosePipeline(formCandidates);
+        ImageFlavor formFlavor = (formChoice != null ? formChoice.getTargetFlavor() : null);
+        
+        //Inline if form is not supported or if a better choice is available with inline mode
+        return formFlavor == null || !formFlavor.equals(inlineFlavor);
+    }
+    
     /** {@inheritDoc} */
     protected void drawImage(String uri, Rectangle2D pos, Map foreignAttributes) {
         endTextObject();
-        uri = ImageFactory.getURL(uri);
-        ImageFactory fact = userAgent.getFactory().getImageFactory();
-        FopImage fopimage = fact.getImage(uri, userAgent);
-        if (fopimage == null) {
-            return;
-        }
-        if (!fopimage.load(FopImage.DIMENSIONS)) {
-            return;
-        }
-        float x = (float)pos.getX() / 1000f;
-        x += currentIPPosition / 1000f;
-        float y = (float)pos.getY() / 1000f;
-        y += currentBPPosition / 1000f;
-        float w = (float)pos.getWidth() / 1000f;
-        float h = (float)pos.getHeight() / 1000f;
+        int x = currentIPPosition + (int)Math.round(pos.getX());
+        int y = currentBPPosition + (int)Math.round(pos.getY());
+        uri = URISpecification.getURL(uri);
+        if (log.isDebugEnabled()) {
+            log.debug("Handling image: " + uri);
+        }
+        
+        ImageManager manager = getUserAgent().getFactory().getImageManager();
+        ImageInfo info = null;
         try {
-            String mime = fopimage.getMimeType();
-            if ("text/xml".equals(mime)) {
-                if (!fopimage.load(FopImage.ORIGINAL_DATA)) {
-                    return;
+            ImageSessionContext sessionContext = getUserAgent().getImageSessionContext();
+            info = manager.getImageInfo(uri, sessionContext);
+            int width = (int)pos.getWidth();
+            int height = (int)pos.getHeight();
+            
+            //millipoints --> points for PostScript
+            float ptx = x / 1000f;
+            float pty = y / 1000f;
+            float ptw = width / 1000f;
+            float pth = height / 1000f;
+
+            if (isImageInlined(info)) {
+                if (log.isDebugEnabled()) {
+                    log.debug("Image " + info + " is inlined");
                 }
-                Document doc = ((XMLImage) fopimage).getDocument();
-                String ns = ((XMLImage) fopimage).getNameSpace();
-
-                renderDocument(doc, ns, pos, foreignAttributes);
-            } else if ("image/svg+xml".equals(mime)) {
-                if (!fopimage.load(FopImage.ORIGINAL_DATA)) {
-                    return;
+                //Only now fully load/prepare the image
+                Map hints = ImageUtil.getDefaultHints(sessionContext);
+                org.apache.xmlgraphics.image.loader.Image img = manager.getImage(
+                        info, getInlineFlavors(), hints, sessionContext);
+                
+                //...and embed as inline image
+                if (img instanceof ImageGraphics2D) {
+                    ImageGraphics2D imageG2D = (ImageGraphics2D)img;
+                    RendererContext context = createRendererContext(
+                            x, y, width, height, foreignAttributes);
+                    getGraphics2DAdapter().paintImage(imageG2D.getGraphics2DImagePainter(),
+                            context, x, y, width, height);
+                } else if (img instanceof ImageRendered) {
+                    ImageRendered imgRend = (ImageRendered)img;
+                    RenderedImage ri = imgRend.getRenderedImage();
+                    PSImageUtils.renderBitmapImage(ri, ptx, pty, ptw, pth, gen);
+                } else if (img instanceof ImageXMLDOM) {
+                    ImageXMLDOM imgXML = (ImageXMLDOM)img;
+                    renderDocument(imgXML.getDocument(), imgXML.getRootNamespace(),
+                            pos, foreignAttributes);
+                } else if (img instanceof ImageRawStream) {
+                    final ImageRawStream raw = (ImageRawStream)img;
+                    if (raw instanceof ImageRawEPS) {
+                        ImageRawEPS eps = (ImageRawEPS)raw;
+                        Rectangle2D bbox = eps.getBoundingBox(); 
+                        InputStream in = raw.createInputStream();
+                        try {
+                            PSImageUtils.renderEPS(in, uri,
+                                    new Rectangle2D.Float(ptx, pty, ptw, pth),
+                                    bbox,
+                                    gen);
+                        } finally {
+                            IOUtils.closeQuietly(in);
+                        }
+                    } else if (raw instanceof ImageRawCCITTFax) {
+                        final ImageRawCCITTFax ccitt = (ImageRawCCITTFax)raw;
+                        ImageEncoder encoder = new ImageEncoderCCITTFax(ccitt);
+                        Rectangle2D targetRect = new Rectangle2D.Float(
+                                ptx, pty, ptw, pth);
+                        PSImageUtils.writeImage(encoder, info.getSize().getDimensionPx(),
+                                uri, targetRect,
+                                ccitt.getColorSpace(), 1, false, gen);
+                    } else if (raw instanceof ImageRawJPEG) {
+                        ImageRawJPEG jpeg = (ImageRawJPEG)raw;
+                        ImageEncoder encoder = new ImageEncoderJPEG(jpeg);
+                        Rectangle2D targetRect = new Rectangle2D.Float(
+                                ptx, pty, ptw, pth);
+                        PSImageUtils.writeImage(encoder, info.getSize().getDimensionPx(),
+                                uri, targetRect,
+                                jpeg.getColorSpace(), 8, jpeg.isInverted(), gen);
+                    } else {
+                        throw new UnsupportedOperationException("Unsupported raw image: " + info);
+                    }
+                } else {
+                    throw new UnsupportedOperationException("Unsupported image type: " + img);
                 }
-                Document doc = ((XMLImage) fopimage).getDocument();
-                String ns = ((XMLImage) fopimage).getNameSpace();
-
-                renderDocument(doc, ns, pos, foreignAttributes);
-            } else if (fopimage instanceof EPSImage) {
-                PSImageUtils.renderEPS((EPSImage)fopimage, x, y, w, h, gen);
             } else {
-                if (isImageInlined(uri, fopimage)) {
-                    PSImageUtils.renderBitmapImage(fopimage, x, y, w, h, gen);
-                } else {
-                    PSResource form = getFormForImage(uri, fopimage);
-                    PSImageUtils.renderForm(fopimage, form, x, y, w, h, gen);
+                if (log.isDebugEnabled()) {
+                    log.debug("Image " + info + " is embedded as a form later");
                 }
+                //Don't load image at this time, just put a form placeholder in the stream
+                PSResource form = getFormForImage(uri);   
+                Rectangle2D targetRect = new Rectangle2D.Double(ptx, pty, ptw, pth);
+                PSImageUtils.paintForm(form, info.getSize().getDimensionPt(), targetRect, gen);   
             }
+
+        } catch (ImageException ie) {
+            log.error("Error while processing image: "
+                    + (info != null ? info.toString() : uri), ie);
+        } catch (FileNotFoundException fe) {
+            log.error(fe.getMessage());
         } catch (IOException ioe) {
             handleIOTrouble(ioe);
         }
     }
 
-    protected PSResource getFormForImage(String uri, FopImage fopimage) {
+    private ImageFlavor[] getInlineFlavors() {
+        ImageFlavor[] flavors;
+        if (gen.getPSLevel() >= 3) {
+            flavors = LEVEL_3_FLAVORS_INLINE;
+        } else {
+            flavors = LEVEL_2_FLAVORS_INLINE;
+        }
+        return flavors;
+    }
+
+    private ImageFlavor[] getFormFlavors() {
+        ImageFlavor[] flavors;
+        if (gen.getPSLevel() >= 3) {
+            flavors = LEVEL_3_FLAVORS_FORM;
+        } else {
+            flavors = LEVEL_2_FLAVORS_FORM;
+        }
+        return flavors;
+    }
+
+    /**
+     * Returns a PSResource instance representing a image as a PostScript form.
+     * @param uri the image URI
+     * @return a PSResource instance
+     */
+    protected PSResource getFormForImage(String uri) {
+        if (uri == null || "".equals(uri)) {
+            throw new IllegalArgumentException("uri must not be empty or null");
+        }
         if (this.formResources == null) {
             this.formResources = new java.util.HashMap();
         }
@@ -439,11 +577,7 @@
         }
         return form;
     }
-    
-    protected boolean isImageInlined(String uri, FopImage image) {
-        return !isOptimizeResources();
-    }
-    
+
     /** {@inheritDoc} */
     public void paintImage(RenderedImage image, RendererContext context, 
             int x, int y, int width, int height) throws IOException {

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/ResourceHandler.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/ResourceHandler.java?rev=611278&r1=611277&r2=611278&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/ResourceHandler.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/ResourceHandler.java Fri Jan 11 11:50:53 2008
@@ -19,6 +19,8 @@
 
 package org.apache.fop.render.ps;
 
+import java.awt.geom.Dimension2D;
+import java.awt.image.RenderedImage;
 import java.awt.geom.Rectangle2D;
 import java.io.IOException;
 import java.io.InputStream;
@@ -27,8 +29,25 @@
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.xmlgraphics.image.loader.ImageException;
+import org.apache.xmlgraphics.image.loader.ImageFlavor;
+import org.apache.xmlgraphics.image.loader.ImageInfo;
+import org.apache.xmlgraphics.image.loader.ImageManager;
+import org.apache.xmlgraphics.image.loader.ImageSessionContext;
+import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D;
+import org.apache.xmlgraphics.image.loader.impl.ImageRawCCITTFax;
+import org.apache.xmlgraphics.image.loader.impl.ImageRawEPS;
+import org.apache.xmlgraphics.image.loader.impl.ImageRawJPEG;
+import org.apache.xmlgraphics.image.loader.impl.ImageRawStream;
+import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
+import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM;
+import org.apache.xmlgraphics.image.loader.util.ImageUtil;
 import org.apache.xmlgraphics.ps.DSCConstants;
+import org.apache.xmlgraphics.ps.FormGenerator;
+import org.apache.xmlgraphics.ps.ImageEncoder;
+import org.apache.xmlgraphics.ps.ImageFormGenerator;
 import org.apache.xmlgraphics.ps.PSGenerator;
+import org.apache.xmlgraphics.ps.PSProcSets;
 import org.apache.xmlgraphics.ps.dsc.DSCException;
 import org.apache.xmlgraphics.ps.dsc.DSCFilter;
 import org.apache.xmlgraphics.ps.dsc.DSCParser;
@@ -50,8 +69,6 @@
 
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.fonts.FontInfo;
-import org.apache.fop.image.FopImage;
-import org.apache.fop.image.ImageFactory;
 
 /**
  * This class is used when two-pass production is used to generate the PostScript file (setting
@@ -59,7 +76,7 @@
  * temporary file generated by the PSRenderer and adds all used fonts and images as resources
  * to the PostScript file.
  */
-public class ResourceHandler implements DSCParserConstants {
+public class ResourceHandler implements DSCParserConstants, PSSupportedFlavors {
 
     /**
      * Rewrites the temporary PostScript file generated by PSRenderer adding all needed resources
@@ -208,13 +225,129 @@
         Iterator iter = formResources.values().iterator();
         while (iter.hasNext()) {
             PSImageFormResource form = (PSImageFormResource)iter.next();
-            ImageFactory fact = userAgent.getFactory().getImageFactory();
-            FopImage image = fact.getImage(form.getImageURI(), userAgent);
-            if (image == null) {
-                throw new NullPointerException("Image not found: " + form.getImageURI());
+            final String uri = form.getImageURI();
+            
+            ImageManager manager = userAgent.getFactory().getImageManager();
+            ImageInfo info = null;
+            try {
+                ImageSessionContext sessionContext = userAgent.getImageSessionContext();
+                info = manager.getImageInfo(uri, sessionContext);
+                
+                ImageFlavor[] flavors;
+                if (gen.getPSLevel() >= 3) {
+                    flavors = LEVEL_3_FLAVORS_FORM;
+                } else {
+                    flavors = LEVEL_2_FLAVORS_FORM;
+                }
+                Map hints = ImageUtil.getDefaultHints(sessionContext);
+                org.apache.xmlgraphics.image.loader.Image img = manager.getImage(
+                        info, flavors, hints, sessionContext);
+                
+                String imageDescription = info.getMimeType() + " " + info.getOriginalURI();
+                final Dimension2D dimensionsPt = info.getSize().getDimensionPt();
+                final Dimension2D dimensionsMpt = info.getSize().getDimensionMpt();
+
+                if (img instanceof ImageGraphics2D) {
+                    final ImageGraphics2D imageG2D = (ImageGraphics2D)img;
+                    FormGenerator formGen = new FormGenerator(
+                            form.getName(), imageDescription, dimensionsPt) {
+
+                        protected void generatePaintProc(PSGenerator gen)
+                                throws IOException {
+                            gen.getResourceTracker().notifyResourceUsageOnPage(
+                                    PSProcSets.EPS_PROCSET);
+                            gen.writeln("BeginEPSF");
+                            PSGraphics2DAdapter adapter = new PSGraphics2DAdapter(gen, false);
+                            adapter.paintImage(imageG2D.getGraphics2DImagePainter(),
+                                    null,
+                                    0, 0, 
+                                    (int)Math.round(dimensionsMpt.getWidth()),
+                                    (int)Math.round(dimensionsMpt.getHeight()));
+                            gen.writeln("EndEPSF");
+                        }
+                        
+                    };
+                    formGen.generate(gen);
+                } else if (img instanceof ImageRendered) {
+                    ImageRendered imgRend = (ImageRendered)img;
+                    RenderedImage ri = imgRend.getRenderedImage();
+                    FormGenerator formGen = new ImageFormGenerator(
+                            form.getName(), imageDescription,
+                            info.getSize().getDimensionPt(),
+                            ri, false);
+                    formGen.generate(gen);
+                } else if (img instanceof ImageXMLDOM) {
+                    throw new UnsupportedOperationException(
+                            "Embedding an ImageXMLDOM as a form isn't supported, yet");
+                } else if (img instanceof ImageRawStream) {
+                    final ImageRawStream raw = (ImageRawStream)img;
+                    if (raw instanceof ImageRawEPS) {
+                        final ImageRawEPS eps = (ImageRawEPS)raw;
+                        throw new UnsupportedOperationException(
+                                "Embedding EPS as forms isn't supported, yet");
+                        /*
+                        InputStream in = eps.createInputStream();
+                        try {
+                            FormGenerator formGen = new EPSFormGenerator(form.getName(),
+                                    imageDescription, dimensions, in);
+                            formGen.generate(gen);
+                        } finally {
+                            IOUtils.closeQuietly(in);
+                        }*/
+                    } else if (raw instanceof ImageRawCCITTFax) {
+                        ImageRawCCITTFax jpeg = (ImageRawCCITTFax)raw;
+                        ImageEncoder encoder = new ImageEncoderCCITTFax(jpeg);
+                        FormGenerator formGen = new ImageFormGenerator(
+                                form.getName(), imageDescription,
+                                info.getSize().getDimensionPt(),
+                                info.getSize().getDimensionPx(),
+                                encoder,
+                                jpeg.getColorSpace(), 1, false);
+                        formGen.generate(gen);
+                    } else if (raw instanceof ImageRawJPEG) {
+                        ImageRawJPEG jpeg = (ImageRawJPEG)raw;
+                        ImageEncoder encoder = new ImageEncoderJPEG(jpeg);
+                        FormGenerator formGen = new ImageFormGenerator(
+                                form.getName(), imageDescription,
+                                info.getSize().getDimensionPt(),
+                                info.getSize().getDimensionPx(),
+                                encoder,
+                                jpeg.getColorSpace(), jpeg.isInverted());
+                        formGen.generate(gen);
+                    } else {
+                        throw new UnsupportedOperationException("Unsupported raw image: " + info);
+                    }
+                } else {
+                    throw new UnsupportedOperationException("Unsupported image type: " + img);
+                }
+            } catch (ImageException ie) {
+                throw new IOException("Error while generating form for image: " + ie.getMessage());
             }
-            PSImageUtils.generateFormResourceForImage(image, form, gen);
         }
     }
 
+    private static FormGenerator createMissingForm(String formName, final Dimension2D dimensions) {
+        FormGenerator formGen = new FormGenerator(formName, null, dimensions) {
+
+            protected void generatePaintProc(PSGenerator gen) throws IOException {
+                gen.writeln("0 setgray");
+                gen.writeln("0 setlinewidth");
+                String w = gen.formatDouble(dimensions.getWidth());
+                String h = gen.formatDouble(dimensions.getHeight());
+                gen.writeln(w + " " + h  + " scale");
+                gen.writeln("0 0 1 1 rectstroke");
+                gen.writeln("newpath");
+                gen.writeln("0 0 moveto");
+                gen.writeln("1 1 lineto");
+                gen.writeln("stroke");
+                gen.writeln("newpath");
+                gen.writeln("0 1 moveto");
+                gen.writeln("1 0 lineto");
+                gen.writeln("stroke");
+            }
+            
+        };
+        return formGen;
+    }
+    
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/RTFHandler.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/RTFHandler.java?rev=611278&r1=611277&r2=611278&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/RTFHandler.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/RTFHandler.java Fri Jan 11 11:50:53 2008
@@ -20,26 +20,33 @@
 package org.apache.fop.render.rtf;
 
 // Java
-import java.awt.color.ColorSpace;
 import java.awt.geom.Point2D;
-import java.awt.image.BufferedImage;
-import java.awt.image.ColorModel;
-import java.awt.image.ComponentColorModel;
-import java.awt.image.DataBuffer;
-import java.awt.image.DataBufferByte;
-import java.awt.image.PixelInterleavedSampleModel;
-import java.awt.image.Raster;
-import java.awt.image.SampleModel;
-import java.awt.image.WritableRaster;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.util.Iterator;
+import java.util.Map;
 
-import org.apache.batik.dom.svg.SVGDOMImplementation;
-import org.apache.commons.io.output.ByteArrayOutputStream;
+import org.w3c.dom.Document;
+
+import org.xml.sax.SAXException;
+
+import org.apache.commons.io.IOUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+
+import org.apache.xmlgraphics.image.loader.Image;
+import org.apache.xmlgraphics.image.loader.ImageException;
+import org.apache.xmlgraphics.image.loader.ImageFlavor;
+import org.apache.xmlgraphics.image.loader.ImageInfo;
+import org.apache.xmlgraphics.image.loader.ImageManager;
+import org.apache.xmlgraphics.image.loader.ImageSessionContext;
+import org.apache.xmlgraphics.image.loader.ImageSize;
+import org.apache.xmlgraphics.image.loader.impl.ImageRawStream;
+import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM;
+import org.apache.xmlgraphics.image.loader.util.ImageUtil;
+
 import org.apache.fop.apps.FOPException;
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.datatypes.LengthBase;
@@ -79,9 +86,6 @@
 import org.apache.fop.fo.pagination.StaticContent;
 import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
 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.IRtfAfterContainer;
 import org.apache.fop.render.rtf.rtflib.rtfdoc.IRtfBeforeContainer;
@@ -108,10 +112,6 @@
 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.xmlgraphics.image.writer.ImageWriter;
-import org.apache.xmlgraphics.image.writer.ImageWriterRegistry;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
 
 /**
  * RTF Handler: generates RTF output using the structure events from
@@ -1104,24 +1104,18 @@
         }
 
         try {
-            String url = eg.getURL();
+            String uri = eg.getURL();
 
             //set image data
             FOUserAgent userAgent = eg.getUserAgent();
-            ImageFactory fact = userAgent.getFactory().getImageFactory();
-            FopImage fopimage = fact.getImage(url, userAgent);
-            if (fopimage == null) {
-                log.error("Image could not be found: " + url);
+            ImageManager manager = userAgent.getFactory().getImageManager();
+            ImageInfo info = manager.getImageInfo(uri, userAgent.getImageSessionContext());
+            if (info == null) {
+                log.error("Image could not be found: " + uri);
                 return;
             }
-            if ("image/gif".equals(fopimage.getMimeType())) {
-                //GIF is not directly supported by RTF, so it must be converted to PNG
-                fopimage.load(FopImage.BITMAP);
-            } else {
-                fopimage.load(FopImage.ORIGINAL_DATA);
-            }
             
-            putGraphic(eg, fopimage);
+            putGraphic(eg, info);
         } catch (Exception e) {
             log.error("Error while handling an external-graphic: " + e.getMessage(), e);
         }
@@ -1140,85 +1134,83 @@
             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);
+            ImageInfo info = new ImageInfo(null, null);
+            // Set the resolution to that of the FOUserAgent
+            FOUserAgent ua = ifo.getUserAgent();
+            ImageSize size = new ImageSize();
+            size.setResolution(ua.getSourceResolution());
+            
+            // Set the image size to the size of the svg.
+            Point2D csize = new Point2D.Float(-1, -1);
+            Point2D intrinsicDimensions = child.getDimension(csize);
+            size.setSizeInMillipoints(
+                    (int)Math.round(intrinsicDimensions.getX() * 1000),
+                    (int)Math.round(intrinsicDimensions.getY() * 1000));
+            size.calcPixelsFromSize();
+            info.setSize(size);
 
-                putGraphic(ifo, fopImage);
-            } else {
-                log.warn("The namespace " + ns
-                        + " for instream-foreign-objects is not supported.");
-            }
+            ImageXMLDOM image = new ImageXMLDOM(info, doc, ns);
             
+            FOUserAgent userAgent = ifo.getUserAgent();
+            ImageManager manager = userAgent.getFactory().getImageManager();
+            Image converted = manager.convertImage(image, FLAVORS);
+            putGraphic(ifo, converted);
             
         } catch (Exception e) {
             log.error("Error while handling an instream-foreign-object: " + e.getMessage(), e);
         }
     }
 
-    private BufferedImage createBufferedImageFromBitmaps(FopImage image) {
-        // TODO Hardcoded color and sample models, FIX ME!
-        ColorModel cm = new ComponentColorModel(
-                ColorSpace.getInstance(ColorSpace.CS_sRGB), 
-                new int[] {8, 8, 8},
-                false, false,
-                ColorModel.OPAQUE, DataBuffer.TYPE_BYTE);
-        SampleModel sampleModel = new PixelInterleavedSampleModel(
-                DataBuffer.TYPE_BYTE, image.getWidth(), image.getHeight(), 3, image.getWidth() * 3, 
-                new int[] {0, 1, 2});
-        DataBuffer dbuf = new DataBufferByte(image.getBitmaps(), 
-                image.getWidth() * image.getHeight() * 3);
-
-        WritableRaster raster = Raster.createWritableRaster(sampleModel,
-                dbuf, null);
-
-        // Combine the color model and raster into a buffered image
-        return new BufferedImage(cm, raster, false, null);
+    private static final ImageFlavor[] FLAVORS = new ImageFlavor[] {
+        ImageFlavor.RAW_EMF, ImageFlavor.RAW_PNG, ImageFlavor.RAW_JPEG
+    };
+    
+    /**
+     * Puts a graphic/image into the generated RTF file.
+     * @param abstractGraphic the graphic (external-graphic or instream-foreign-object)
+     * @param info the image info object
+     * @throws IOException In case of an I/O error
+     */
+    private void putGraphic(AbstractGraphics abstractGraphic, ImageInfo info) 
+            throws IOException {
+        try {
+            FOUserAgent userAgent = abstractGraphic.getUserAgent();
+            ImageManager manager = userAgent.getFactory().getImageManager();
+            ImageSessionContext sessionContext = userAgent.getImageSessionContext();
+            Map hints = ImageUtil.getDefaultHints(sessionContext);
+            Image image = manager.getImage(info, FLAVORS, hints, sessionContext);
+
+            putGraphic(abstractGraphic, image);
+        } catch (ImageException ie) {
+            log.error("Error while loading/processing image: " + info.getOriginalURI(), ie);
+        }
     }
     
     /**
      * Puts a graphic/image into the generated RTF file.
      * @param abstractGraphic the graphic (external-graphic or instream-foreign-object)
-     * @param fopImage the image
+     * @param image the image
      * @throws IOException In case of an I/O error
      */
-    private void putGraphic(AbstractGraphics abstractGraphic, FopImage fopImage) 
+    private void putGraphic(AbstractGraphics abstractGraphic, Image image) 
             throws IOException {
-        byte[] rawData;
-        if ("image/svg+xml".equals(fopImage.getMimeType())) {
-            rawData = SVGConverter.convertToJPEG((XMLImage) fopImage);
-        } else if (fopImage.getRessourceBytes() != null) {
-            rawData = fopImage.getRessourceBytes();
-        } else {
-            //TODO Revisit after the image library redesign!!!
-            //Convert the decoded bitmaps to a BufferedImage
-            BufferedImage bufImage = createBufferedImageFromBitmaps(fopImage);
-            ImageWriter writer = ImageWriterRegistry.getInstance().getWriterFor("image/png");
-            ByteArrayOutputStream baout = new ByteArrayOutputStream();
-            writer.writeImage(bufImage, baout);
-            rawData = baout.toByteArray();
+        byte[] rawData = null;
+        
+        ImageInfo info = image.getInfo();
+
+        if (image instanceof ImageRawStream) {
+            ImageRawStream rawImage = (ImageRawStream)image;
+            InputStream in = rawImage.createInputStream();
+            try {
+                rawData = IOUtils.toByteArray(in);
+            } finally {
+                IOUtils.closeQuietly(in);
+            }
         }
+
         if (rawData == null) {
             log.warn(FONode.decorateWithContextInfo("Image could not be embedded: "
-                    + fopImage.getOriginalURI(), abstractGraphic));
+                    + image, abstractGraphic));
             return;
         }
 
@@ -1229,7 +1221,9 @@
         final RtfExternalGraphic rtfGraphic = c.getTextrun().newImage();
    
         //set URL
-        rtfGraphic.setURL(fopImage.getOriginalURI());
+        if (info.getOriginalURI() != null) {
+            rtfGraphic.setURL(info.getOriginalURI());
+        }
         rtfGraphic.setImageData(rawData);
 
         //set scaling
@@ -1240,7 +1234,7 @@
         //get width
         int width = 0;
         if (abstractGraphic.getWidth().getEnum() == Constants.EN_AUTO) {
-            width = fopImage.getIntrinsicWidth();
+            width = info.getSize().getWidthMpt();
         } else {
             width = abstractGraphic.getWidth().getValue();
         }
@@ -1248,7 +1242,7 @@
         //get height
         int height = 0;
         if (abstractGraphic.getWidth().getEnum() == Constants.EN_AUTO) {
-            height = fopImage.getIntrinsicHeight();
+            height = info.getSize().getHeightMpt();
         } else {
             height = abstractGraphic.getHeight().getValue();
         }
@@ -1257,7 +1251,7 @@
         int contentwidth = 0;
         if (abstractGraphic.getContentWidth().getEnum()
                 == Constants.EN_AUTO) {
-            contentwidth = fopImage.getIntrinsicWidth();
+            contentwidth = info.getSize().getWidthMpt();
         } else if (abstractGraphic.getContentWidth().getEnum()
                 == Constants.EN_SCALE_TO_FIT) {
             contentwidth = width;
@@ -1271,7 +1265,7 @@
         if (abstractGraphic.getContentHeight().getEnum()
                 == Constants.EN_AUTO) {
 
-            contentheight = fopImage.getIntrinsicHeight();
+            contentheight = info.getSize().getHeightMpt();
 
         } else if (abstractGraphic.getContentHeight().getEnum()
                 == Constants.EN_SCALE_TO_FIT) {

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfExternalGraphic.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfExternalGraphic.java?rev=611278&r1=611277&r2=611278&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfExternalGraphic.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfExternalGraphic.java Fri Jan 11 11:50:53 2008
@@ -26,19 +26,17 @@
  * the FOP project.
  */
 
-import org.apache.commons.io.IOUtils;
-import org.apache.fop.render.rtf.rtflib.tools.ImageConstants;
-import org.apache.fop.render.rtf.rtflib.tools.ImageUtil;
-//import org.apache.fop.render.rtf.rtflib.tools.jpeg.Encoder;
-//import org.apache.fop.render.rtf.rtflib.tools.jpeg.JPEGException;
-
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.Writer;
-
-import java.io.File;
-import java.net.URL;
 import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.apache.commons.io.IOUtils;
+
+import org.apache.fop.render.rtf.rtflib.tools.ImageConstants;
+import org.apache.fop.render.rtf.rtflib.tools.ImageUtil;
 
 /**
  * Creates an RTF image from an external graphic file.
@@ -342,13 +340,13 @@
         }
 
 
-        if (url == null) {
-            throw new ExternalGraphicException("The attribute 'url' of "
-                    + "<fo:external-graphic> is null.");
+        if (url == null && imagedata == null) {
+            throw new ExternalGraphicException(
+                    "No image data is available (neither URL, nor in-memory)");
         }
 
         String linkToRoot = System.getProperty("jfor_link_to_root");
-        if (linkToRoot != null) {
+        if (url != null && linkToRoot != null) {
             writer.write("{\\field {\\* \\fldinst { INCLUDEPICTURE \"");
             writer.write(linkToRoot);
             File urlFile = new File(url.getFile());
@@ -380,7 +378,7 @@
         }
 
         // Determine image file format
-        String file = url.getFile ();
+        String file = (url != null ? url.getFile() : "<unknown>");
         imageformat = FormatBase.determineFormat(imagedata);
         if (imageformat != null) {
             imageformat = imageformat.convert(imageformat, imagedata);

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFBridgeContext.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFBridgeContext.java?rev=611278&r1=611277&r2=611278&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFBridgeContext.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFBridgeContext.java Fri Jan 11 11:50:53 2008
@@ -26,6 +26,10 @@
 import org.apache.batik.bridge.BridgeContext;
 import org.apache.batik.bridge.DocumentLoader;
 import org.apache.batik.bridge.UserAgent;
+
+import org.apache.xmlgraphics.image.loader.ImageManager;
+import org.apache.xmlgraphics.image.loader.ImageSessionContext;
+
 import org.apache.fop.fonts.FontInfo;
 
 /**
@@ -36,6 +40,9 @@
     /** The font list. */
     private final FontInfo fontInfo;
 
+    private final ImageManager imageManager;
+    private final ImageSessionContext imageSessionContext;
+
     private AffineTransform linkTransform;
     
     /**
@@ -50,9 +57,13 @@
     public PDFBridgeContext(UserAgent userAgent,
                             DocumentLoader loader,
                             FontInfo fontInfo,
+                            ImageManager imageManager,
+                            ImageSessionContext imageSessionContext,
                             AffineTransform linkTransform) {
         super(userAgent, loader);
         this.fontInfo = fontInfo;
+        this.imageManager = imageManager;
+        this.imageSessionContext = imageSessionContext;
         this.linkTransform = linkTransform;
     }
 
@@ -66,9 +77,13 @@
      */
     public PDFBridgeContext(UserAgent userAgent, 
                             FontInfo fontInfo, 
+                            ImageManager imageManager,
+                            ImageSessionContext imageSessionContext,
                             AffineTransform linkTransform) {
         super(userAgent);
         this.fontInfo = fontInfo;
+        this.imageManager = imageManager;
+        this.imageSessionContext = imageSessionContext;
         this.linkTransform = linkTransform;
     }
 
@@ -78,10 +93,29 @@
      * @param fontInfo the font list for the text painter, may be null
      *                 in which case text is painted as shapes
      */
-    public PDFBridgeContext(UserAgent userAgent, FontInfo fontInfo) {
-        this(userAgent, fontInfo, null);
+    public PDFBridgeContext(UserAgent userAgent,
+                            FontInfo fontInfo,
+                            ImageManager imageManager,
+                            ImageSessionContext imageSessionContext) {
+        this(userAgent, fontInfo, imageManager, imageSessionContext, null);
     }
 
+    /**
+     * Returns the ImageManager to be used by the ImageElementBridge.
+     * @return the image manager
+     */
+    public ImageManager getImageManager() {
+        return this.imageManager;
+    }
+
+    /**
+     * Returns the ImageSessionContext to be used by the ImageElementBridge.
+     * @return the image session context
+     */
+    public ImageSessionContext getImageSessionContext() {
+        return this.imageSessionContext;
+    }
+    
     private void putPDFElementBridgeConditional(String className, String testFor) {
         try {
             Class.forName(testFor);
@@ -136,7 +170,10 @@
     //TODO There's no matching method in the super-class here
     public BridgeContext createBridgeContext() {
         return new PDFBridgeContext(getUserAgent(), getDocumentLoader(),
-                                    fontInfo, linkTransform);
+                                    fontInfo,
+                                    getImageManager(),
+                                    getImageSessionContext(),
+                                    linkTransform);
     }
-    
+
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFGraphics2D.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFGraphics2D.java?rev=611278&r1=611277&r2=611278&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFGraphics2D.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFGraphics2D.java Fri Jan 11 11:50:53 2008
@@ -62,13 +62,17 @@
 import org.apache.batik.ext.awt.RenderingHintsKeyExt;
 import org.apache.batik.gvt.GraphicsNode;
 import org.apache.batik.gvt.PatternPaint;
+
+import org.apache.xmlgraphics.image.loader.impl.ImageRawJPEG;
+import org.apache.xmlgraphics.java2d.AbstractGraphics2D;
+import org.apache.xmlgraphics.java2d.GraphicContext;
+
 import org.apache.fop.fonts.CIDFont;
 import org.apache.fop.fonts.Font;
 import org.apache.fop.fonts.FontInfo;
 import org.apache.fop.fonts.FontSetup;
 import org.apache.fop.fonts.FontTriplet;
 import org.apache.fop.fonts.LazyFont;
-import org.apache.fop.image.JpegImage;
 import org.apache.fop.pdf.BitmapImage;
 import org.apache.fop.pdf.PDFAnnotList;
 import org.apache.fop.pdf.PDFColor;
@@ -76,6 +80,7 @@
 import org.apache.fop.pdf.PDFDeviceColorSpace;
 import org.apache.fop.pdf.PDFDocument;
 import org.apache.fop.pdf.PDFGState;
+import org.apache.fop.pdf.PDFImage;
 import org.apache.fop.pdf.PDFImageXObject;
 import org.apache.fop.pdf.PDFLink;
 import org.apache.fop.pdf.PDFName;
@@ -86,10 +91,8 @@
 import org.apache.fop.pdf.PDFState;
 import org.apache.fop.pdf.PDFText;
 import org.apache.fop.pdf.PDFXObject;
-import org.apache.fop.render.pdf.FopPDFImage;
+import org.apache.fop.render.pdf.ImageRawJPEGAdapter;
 import org.apache.fop.util.ColorExt;
-import org.apache.xmlgraphics.java2d.AbstractGraphics2D;
-import org.apache.xmlgraphics.java2d.GraphicContext;
 
 /**
  * PDF Graphics 2D.
@@ -397,7 +400,7 @@
      * @param width the width to draw the image
      * @param height the height to draw the image
      */
-    public void addJpegImage(JpegImage jpeg, float x, float y, 
+    public void addJpegImage(ImageRawJPEG jpeg, float x, float y, 
                              float width, float height) {
         preparePainting();
         // Need to include hash code as when invoked from FO you
@@ -405,9 +408,9 @@
         // count is not enough.
         String key = "__AddJPEG_" + hashCode() + "_" + jpegCount[0];
         jpegCount[0]++;
-        FopPDFImage fopimage = new FopPDFImage(jpeg, key);
+        PDFImage pdfimage = new ImageRawJPEGAdapter(jpeg, key);
         PDFName imageName = this.pdfDoc.addImage(resourceContext, 
-                                              fopimage).getName();
+                                              pdfimage).getName();
         AffineTransform at = getTransform();
         double[] matrix = new double[6];
         at.getMatrix(matrix);

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFImageElementBridge.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFImageElementBridge.java?rev=611278&r1=611277&r2=611278&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFImageElementBridge.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFImageElementBridge.java Fri Jan 11 11:50:53 2008
@@ -19,24 +19,28 @@
  
 package org.apache.fop.svg;
 
-import org.apache.batik.bridge.SVGImageElementBridge;
-
-import java.awt.Shape;
 import java.awt.Graphics2D;
+import java.awt.Shape;
 import java.awt.geom.Rectangle2D;
-import java.io.BufferedInputStream;
-import java.io.InputStream;
 
 import org.w3c.dom.Element;
+import org.w3c.dom.svg.SVGDocument;
 
 import org.apache.batik.bridge.BridgeContext;
+import org.apache.batik.bridge.SVGImageElementBridge;
 import org.apache.batik.gvt.AbstractGraphicsNode;
 import org.apache.batik.gvt.GraphicsNode;
 import org.apache.batik.util.ParsedURL;
 
-import org.apache.fop.image.JpegImage;
-import org.apache.fop.image.FopImage;
-import org.apache.fop.image.analyser.ImageReaderFactory;
+import org.apache.xmlgraphics.image.loader.Image;
+import org.apache.xmlgraphics.image.loader.ImageException;
+import org.apache.xmlgraphics.image.loader.ImageFlavor;
+import org.apache.xmlgraphics.image.loader.ImageInfo;
+import org.apache.xmlgraphics.image.loader.ImageManager;
+import org.apache.xmlgraphics.image.loader.ImageSessionContext;
+import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D;
+import org.apache.xmlgraphics.image.loader.impl.ImageRawJPEG;
+import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM;
 
 /**
  * Bridge class for the &lt;image> element when jpeg images.
@@ -50,6 +54,10 @@
      */
     public PDFImageElementBridge() { }
 
+    private final ImageFlavor[] supportedFlavors = new ImageFlavor[]
+                                               {ImageFlavor.RAW_JPEG,
+                                                ImageFlavor.GRAPHICS2D,
+                                                ImageFlavor.XML_DOM};
     /**
      * Create the raster image node.
      * THis checks if it is a jpeg file and creates a jpeg node
@@ -60,51 +68,68 @@
      * @return a new graphics node
      */
     protected GraphicsNode createImageGraphicsNode
-        (BridgeContext ctx, Element imageElement, ParsedURL purl) {
+                (BridgeContext ctx, Element imageElement, ParsedURL purl) {
+        PDFBridgeContext pdfCtx = (PDFBridgeContext)ctx;
+        
+        ImageManager manager = pdfCtx.getImageManager();
+        ImageSessionContext sessionContext = pdfCtx.getImageSessionContext();
         try {
-            InputStream is = purl.openStream();
-            if (!is.markSupported()) {
-                is = new BufferedInputStream(is, 1024);
-            }
+            ImageInfo info = manager.getImageInfo(purl.toString(), sessionContext);
+            Image image = manager.getImage(info, supportedFlavors, sessionContext);
             
-            is.mark(3);
-            byte [] data = new byte[3];
-            is.read(data);
-            is.reset();
-            if ((data[0] == (byte)0xFF) 
-                    && (data[1] == (byte)0xD8) 
-                    && (data[2] == (byte)0xFF)) {
-                FopImage.ImageInfo ii = ImageReaderFactory.make
-                        (purl.toString(), is, null);
-                JpegImage jpeg = new JpegImage(ii);
-                jpeg.load(FopImage.ORIGINAL_DATA);
-                PDFJpegNode node = new PDFJpegNode(jpeg, ctx, imageElement, purl);
-    
-                Rectangle2D imgBounds = getImageBounds(ctx, imageElement);
-                Rectangle2D bounds = node.getPrimitiveBounds();
-                float [] vb = new float[4];
-                vb[0] = 0; // x
-                vb[1] = 0; // y
-                vb[2] = (float) bounds.getWidth(); // width
-                vb[3] = (float) bounds.getHeight(); // height
-    
-                // handles the 'preserveAspectRatio', 'overflow' and 'clip' 
-                // and sets the appropriate AffineTransform to the image node
-                initializeViewport(ctx, imageElement, node, vb, imgBounds);
-                return node;
+            AbstractGraphicsNode specializedNode = null;
+            if (image instanceof ImageXMLDOM) {
+                ImageXMLDOM xmlImage = (ImageXMLDOM)image;
+                if (xmlImage.getDocument() instanceof SVGDocument) {
+                    return createSVGImageNode(ctx, imageElement,
+                            (SVGDocument)xmlImage.getDocument());
+                } else {
+                    //Convert image to Graphics2D
+                    image = manager.convertImage(xmlImage,
+                            new ImageFlavor[] {ImageFlavor.GRAPHICS2D});
+                }
+            }
+            if (image instanceof ImageRawJPEG) {
+                ImageRawJPEG jpegImage = (ImageRawJPEG)image;
+                specializedNode = new PDFJpegNode(jpegImage, ctx, imageElement, purl);
+                
+            } else if (image instanceof ImageGraphics2D) {
+                ImageGraphics2D g2dImage = (ImageGraphics2D)image;
+                specializedNode = new Graphics2DNode(g2dImage);
+            } else {
+                ctx.getUserAgent().displayError(
+                        new ImageException("Cannot convert an image to a usable format: " + purl));
             }
-        } catch (Exception ex) {
-            //TODO Handle this exception
+            
+            Rectangle2D imgBounds = getImageBounds(ctx, imageElement);
+            Rectangle2D bounds = specializedNode.getPrimitiveBounds();
+            float [] vb = new float[4];
+            vb[0] = 0; // x
+            vb[1] = 0; // y
+            vb[2] = (float) bounds.getWidth(); // width
+            vb[3] = (float) bounds.getHeight(); // height
+
+            // handles the 'preserveAspectRatio', 'overflow' and 'clip' 
+            // and sets the appropriate AffineTransform to the image node
+            initializeViewport(ctx, imageElement, specializedNode, vb, imgBounds);
+            return specializedNode;
+        } catch (Exception e) {
+            ctx.getUserAgent().displayError(e);
         }
-
+        
         return superCreateGraphicsNode(ctx, imageElement, purl);
     }
 
     /**
+     * Calls the superclass' createImageGraphicNode() method to create the normal GraphicsNode.
+     * @param ctx the bridge context
+     * @param imageElement the image element
+     * @param purl the parsed URL
+     * @return the newly created graphics node
      * @see org.apache.batik.bridge.SVGImageElementBridge#createGraphicsNode(BridgeContext, Element)
      */
     protected GraphicsNode superCreateGraphicsNode
-        (BridgeContext ctx, Element imageElement, ParsedURL purl) {
+            (BridgeContext ctx, Element imageElement, ParsedURL purl) {
         return super.createImageGraphicsNode(ctx, imageElement, purl);
     }
 
@@ -116,21 +141,21 @@
      */
     public class PDFJpegNode extends AbstractGraphicsNode {
         
-        private JpegImage jpeg;
+        private ImageRawJPEG jpeg;
         private BridgeContext ctx;
         private Element imageElement;
         private ParsedURL purl;
         private GraphicsNode origGraphicsNode = null;
         
         /**
-         * Create a new pdf jpeg node for drawing jpeg images
+         * Create a new PDF JPEG node for drawing JPEG images
          * into pdf graphics.
-         * @param j the jpeg image
+         * @param j the JPEG image
          * @param ctx the bridge context
          * @param imageElement the SVG image element
          * @param purl the URL to the image
          */
-        public PDFJpegNode(JpegImage j, BridgeContext ctx, 
+        public PDFJpegNode(ImageRawJPEG j, BridgeContext ctx, 
                            Element imageElement, ParsedURL purl) {
             this.jpeg = j;
             this.ctx  = ctx;
@@ -138,32 +163,23 @@
             this.purl = purl;
         }
 
-        /**
-         * Get the outline of this image.
-         * @return the outline shape which is the primitive bounds
-         */
+        /** {@inheritDoc} */
         public Shape getOutline() {
             return getPrimitiveBounds();
         }
 
-        /**
-         * Paint this jpeg image.
-         * As this is used for inserting jpeg into pdf
-         * it adds the jpeg image to the PDFGraphics2D.
-         * @param g2d the graphics to draw the image on
-         */
+        /** {@inheritDoc} */
         public void primitivePaint(Graphics2D g2d) {
             if (g2d instanceof PDFGraphics2D) {
                 PDFGraphics2D pdfg = (PDFGraphics2D) g2d;
                 float x = 0;
                 float y = 0;
                 try {
-                    float width = jpeg.getWidth();
-                    float height = jpeg.getHeight();
+                    float width = jpeg.getSize().getWidthPx();
+                    float height = jpeg.getSize().getHeightPx();
                     pdfg.addJpegImage(jpeg, x, y, width, height);
                 } catch (Exception e) {
-                    //TODO Handle this exception properly
-                    e.printStackTrace();
+                    ctx.getUserAgent().displayError(e);
                 }
             } else {
                 // Not going directly into PDF so use
@@ -179,40 +195,71 @@
             }
         }
 
-        /**
-         * Get the geometrix bounds of the image.
-         * @return the primitive bounds
-         */
+        /** {@inheritDoc} */
         public Rectangle2D getGeometryBounds() {
             return getPrimitiveBounds();
         }
 
-        /**
-         * Get the primitive bounds of this bridge element.
-         * @return the bounds of the jpeg image
-         */
+        /** {@inheritDoc} */
         public Rectangle2D getPrimitiveBounds() {
-            try {
-                return new Rectangle2D.Double(0, 0, jpeg.getWidth(),
-                                              jpeg.getHeight());
-            } catch (Exception e) {
-                //TODO Handle this exception properly
-                e.printStackTrace();
-            }
-            return null;
+            return new Rectangle2D.Double(0, 0,
+                       jpeg.getSize().getWidthPx(),
+                       jpeg.getSize().getHeightPx());
         }
 
+        /** {@inheritDoc} */
+        public Rectangle2D getSensitiveBounds() {
+            //No interactive features, just return primitive bounds
+            return getPrimitiveBounds();
+        }
+
+    }
+
+    /**
+     * A node that holds a Graphics2D image.
+     */
+    public class Graphics2DNode extends AbstractGraphicsNode {
+        
+        private ImageGraphics2D image;
+        
         /**
-         * Returns the bounds of the sensitive area covered by this node,
-         * This includes the stroked area but does not include the effects
-         * of clipping, masking or filtering.
-         * @return the bounds of the sensitive area
+         * Create a new Graphics2D node.
+         * @param g2d the Graphics2D image
          */
+        public Graphics2DNode(ImageGraphics2D g2d) {
+            this.image = g2d;
+        }
+
+        /** {@inheritDoc} */
+        public Shape getOutline() {
+            return getPrimitiveBounds();
+        }
+
+        /** {@inheritDoc} */
+        public void primitivePaint(Graphics2D g2d) {
+            int width = image.getSize().getWidthPx();
+            int height = image.getSize().getHeightPx();
+            Rectangle2D area = new Rectangle2D.Double(0, 0, width, height);
+            image.getGraphics2DImagePainter().paint(g2d, area);
+        }
+
+        /** {@inheritDoc} */
+        public Rectangle2D getGeometryBounds() {
+            return getPrimitiveBounds();
+        }
+
+        /** {@inheritDoc} */
+        public Rectangle2D getPrimitiveBounds() {
+            return new Rectangle2D.Double(0, 0,
+                    image.getSize().getWidthPx(),
+                    image.getSize().getHeightPx());
+        }
+
+        /** {@inheritDoc} */
         public Rectangle2D getSensitiveBounds() {
             //No interactive features, just return primitive bounds
             return getPrimitiveBounds();
         }
 
     }
-
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFTranscoder.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFTranscoder.java?rev=611278&r1=611277&r2=611278&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFTranscoder.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFTranscoder.java Fri Jan 11 11:50:53 2008
@@ -23,6 +23,10 @@
 import java.io.BufferedOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.io.InputStream;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.svg.SVGLength;
@@ -41,6 +45,12 @@
 import org.apache.batik.transcoder.image.ImageTranscoder;
 import org.apache.batik.transcoder.keys.BooleanKey;
 import org.apache.batik.transcoder.keys.FloatKey;
+import org.apache.batik.util.ParsedURL;
+
+import org.apache.xmlgraphics.image.loader.ImageContext;
+import org.apache.xmlgraphics.image.loader.ImageManager;
+import org.apache.xmlgraphics.image.loader.ImageSessionContext;
+import org.apache.xmlgraphics.image.loader.impl.AbstractImageSessionContext;
 
 import org.apache.fop.Version;
 import org.apache.fop.fonts.FontInfo;
@@ -99,6 +109,9 @@
     /** Graphics2D instance that is used to paint to */
     protected PDFDocumentGraphics2D graphics = null;
 
+    private ImageManager imageManager;
+    private ImageSessionContext imageSessionContext;
+    
     /**
      * Constructs a new <tt>PDFTranscoder</tt>.
      */
@@ -141,6 +154,11 @@
         graphics.getPDFDocument().getInfo().setProducer("Apache FOP Version " 
                 + Version.getVersion() 
                 + ": PDF Transcoder for Batik");
+        if (hints.containsKey(KEY_DEVICE_RESOLUTION)) {
+            graphics.setDeviceDPI(((Float)hints.get(KEY_DEVICE_RESOLUTION)).floatValue());
+        }
+        
+        setupImageInfrastructure(uri);
         
         try {
             Configuration effCfg = this.cfg; 
@@ -196,9 +214,6 @@
         //int h = (int)(height + 0.5);
 
         try {
-            if (hints.containsKey(KEY_DEVICE_RESOLUTION)) {
-                graphics.setDeviceDPI(((Float)hints.get(KEY_DEVICE_RESOLUTION)).floatValue());
-            }
             OutputStream out = output.getOutputStream();
             if (!(out instanceof BufferedOutputStream)) {
                 out = new BufferedOutputStream(out);
@@ -227,6 +242,39 @@
         }
     }
 
+    private void setupImageInfrastructure(final String baseURI) {
+        final ImageContext imageContext = new ImageContext() {
+            public float getSourceResolution() {
+                return 25.4f / userAgent.getPixelUnitToMillimeter();
+            }
+        };
+        this.imageManager = new ImageManager(imageContext);
+        this.imageSessionContext = new AbstractImageSessionContext() {
+
+            public ImageContext getParentContext() {
+                return imageContext;
+            }
+
+            public float getTargetResolution() {
+                return graphics.getDeviceDPI();
+            }
+
+            public Source resolveURI(String uri) {
+                System.out.println("resolve " + uri);
+                try {
+                    ParsedURL url = new ParsedURL(baseURI, uri);
+                    InputStream in = url.openStream();
+                    StreamSource source = new StreamSource(in, url.toString());
+                    return source;
+                } catch (IOException ioe) {
+                    userAgent.displayError(ioe);
+                    return null;
+                }
+            }
+            
+        };
+    }
+
     /** {@inheritDoc} */
     protected BridgeContext createBridgeContext() {
         //For compatibility with Batik 1.6
@@ -239,7 +287,8 @@
         if (isTextStroked()) {
             fontInfo = null;
         }
-        BridgeContext ctx = new PDFBridgeContext(userAgent, fontInfo);
+        BridgeContext ctx = new PDFBridgeContext(userAgent, fontInfo,
+                this.imageManager, this.imageSessionContext);
         return ctx;
     }
     

Modified: xmlgraphics/fop/trunk/status.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/status.xml?rev=611278&r1=611277&r2=611278&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/status.xml (original)
+++ xmlgraphics/fop/trunk/status.xml Fri Jan 11 11:50:53 2008
@@ -28,6 +28,10 @@
 
   <changes>
     <release version="FOP Trunk">
+      <action context="Code" dev="JM" importance="high" type="fix">
+        A new image loading framework has been introduced to fix various problems with external
+        graphics and improve performance.
+      </action>
       <action context="Code" dev="JM" type="fix">
         Fixed generation of named destinations so it works when the PDF document is encrypted.
       </action>
@@ -46,13 +50,17 @@
         will make up an entire page. See the documentation for details.
       </action>
       <action context="Code" dev="JM" type="add">
+        Added minimal support for the .minimum/.maximum components of block/inline-progression-dimension 
+        on fo:external-graphic and fo:instream-foreign-object.
+      </action>
+      <action context="Code" dev="JM" type="add">
         Added support for scale-down-to-fit and scale-up-to-fit (introduced in XSL 1.1).
       </action>
       <action context="Code" dev="VH" type="fix" fixes-bug="43633">
         Bugfix: content of a row with zero height overriding the previous row
       </action>
       <action context="Code" dev="AC" importance="high" type="add">
-	Added SVG support for AFP (GOCA).
+        Added SVG support for AFP (GOCA).
       </action>
       <action context="Code" dev="JM" type="fix" fixes-bug="37993">
         Bugfix: allow multiple bookmarks to point at the same destination.

Modified: xmlgraphics/fop/trunk/test/java/org/apache/fop/memory/MemoryEater.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/java/org/apache/fop/memory/MemoryEater.java?rev=611278&r1=611277&r2=611278&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/test/java/org/apache/fop/memory/MemoryEater.java (original)
+++ xmlgraphics/fop/trunk/test/java/org/apache/fop/memory/MemoryEater.java Fri Jan 11 11:50:53 2008
@@ -36,6 +36,7 @@
 
 import org.apache.commons.io.output.NullOutputStream;
 
+import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.apps.Fop;
 import org.apache.fop.apps.FopFactory;
 import org.apache.fop.apps.MimeConstants;
@@ -63,7 +64,9 @@
         transformer.setParameter("repeats", new Integer(replicatorRepeats));
         
         OutputStream out = new NullOutputStream(); //write to /dev/nul
-        Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out);
+        FOUserAgent userAgent = fopFactory.newFOUserAgent();
+        userAgent.setBaseURL(foFile.getParentFile().toURL().toExternalForm());
+        Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, userAgent, out);
         Result res = new SAXResult(fop.getDefaultHandler());
         
         transformer.transform(src, res);

Modified: xmlgraphics/fop/trunk/test/java/org/apache/fop/render/pdf/PDFAConformanceTestCase.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/java/org/apache/fop/render/pdf/PDFAConformanceTestCase.java?rev=611278&r1=611277&r2=611278&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/test/java/org/apache/fop/render/pdf/PDFAConformanceTestCase.java (original)
+++ xmlgraphics/fop/trunk/test/java/org/apache/fop/render/pdf/PDFAConformanceTestCase.java Fri Jan 11 11:50:53 2008
@@ -89,20 +89,6 @@
     }
     
     /**
-     * Test exception when PDF/A-1 is enabled and an EPS is used.
-     * @throws Exception if the test fails
-     */
-    public void testEPSUsage() throws Exception {
-        File foFile = new File(foBaseDir, "with-eps.fo");
-        try {
-            convertFO(foFile, getUserAgent(), dumpPDF);
-            fail("Expected PDFConformanceException. PDF/A-1 does not allow PostScript XObjects.");
-        } catch (PDFConformanceException e) {
-            //Good!
-        }
-    }
-    
-    /**
      * Test exception when PDF/A-1 is enabled and images.
      * @throws Exception if the test fails
      */

Modified: xmlgraphics/fop/trunk/test/java/org/apache/fop/threading/FOPTestbed.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/java/org/apache/fop/threading/FOPTestbed.java?rev=611278&r1=611277&r2=611278&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/test/java/org/apache/fop/threading/FOPTestbed.java (original)
+++ xmlgraphics/fop/trunk/test/java/org/apache/fop/threading/FOPTestbed.java Fri Jan 11 11:50:53 2008
@@ -19,12 +19,12 @@
 
 package org.apache.fop.threading;
 
-import java.util.List;
-import java.util.Iterator;
 import java.io.File;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.text.DecimalFormat;
+import java.util.Iterator;
+import java.util.List;
 
 import javax.xml.transform.Source;
 import javax.xml.transform.Templates;
@@ -40,35 +40,45 @@
 import org.apache.avalon.framework.configuration.ConfigurationException;
 import org.apache.avalon.framework.container.ContainerUtil;
 import org.apache.avalon.framework.logger.AbstractLogEnabled;
-import org.apache.avalon.framework.logger.Logger;
 import org.apache.commons.io.IOUtils;
 
+/**
+ * Testbed for multi-threading tests. The class can run a configurable set of task a number of
+ * times in a configurable number of threads to easily reproduce multi-threading issues.
+ */
 public class FOPTestbed extends AbstractLogEnabled 
             implements Configurable, Initializable {
 
     private int repeat;
-    private List tasks = new java.util.ArrayList();
+    private List taskList = new java.util.ArrayList();
     private int threads;
     private File outputDir;
     private Configuration fopCfg;
+    private FOProcessor foprocessor;
 
     private int counter = 0;
     
+    /** {@inheritDoc} */
     public void configure(Configuration configuration) throws ConfigurationException {
         this.threads = configuration.getChild("threads").getValueAsInteger(10);
         this.outputDir = new File(configuration.getChild("output-dir").getValue());
         Configuration tasks = configuration.getChild("tasks");
         this.repeat = tasks.getAttributeAsInteger("repeat", 1);
         Configuration[] entries = tasks.getChildren("task");
-        for (int i=0; i<entries.length; i++) {
-            this.tasks.add(new TaskDef(entries[i]));
+        for (int i = 0; i < entries.length; i++) {
+            this.taskList.add(new TaskDef(entries[i]));
         }
         this.fopCfg = configuration.getChild("foprocessor");
     }
 
+    /** {@inheritDoc} */
     public void initialize() throws Exception {
+        this.foprocessor = createFOProcessor();
     }
 
+    /**
+     * Starts the stress test.
+     */
     public void doStressTest() {
         getLogger().info("Starting stress test...");
         long start = System.currentTimeMillis();
@@ -99,6 +109,7 @@
             try {
                 Thread.sleep(100);
             } catch (InterruptedException ie) {
+                //ignore
             }
         }
         getLogger().info("Stress test duration: " + (System.currentTimeMillis() - start) + "ms");
@@ -109,10 +120,10 @@
         public void run() {
             try {
                 for (int r = 0; r < repeat; r++) {
-                    Iterator i = tasks.iterator();
+                    Iterator i = taskList.iterator();
                     while (i.hasNext()) {
                         TaskDef def = (TaskDef)i.next();
-                        final Task task = new Task(def, counter++);
+                        final Task task = new Task(def, counter++, foprocessor);
                         ContainerUtil.enableLogging(task, getLogger());
                         task.execute();
                     }
@@ -124,7 +135,10 @@
 
     }
     
-    
+    /**
+     * Creates a new FOProcessor.
+     * @return the newly created instance
+     */
     public FOProcessor createFOProcessor() {
         try {
             Class clazz = Class.forName(this.fopCfg.getAttribute("class", 
@@ -197,18 +211,19 @@
 
         private TaskDef def;
         private int num;
+        private FOProcessor fop;
 
-        public Task(TaskDef def, int num) {
+        public Task(TaskDef def, int num, FOProcessor fop) {
             this.def = def;
             this.num = num;
+            this.fop = fop;
         }
 
 
         public void execute() throws Exception {
             getLogger().info("Processing: " + def);
-            FOProcessor fop = (FOProcessor)createFOProcessor();
             DecimalFormat df = new DecimalFormat("00000");
-            File outfile = new File(outputDir, df.format(num) + ".pdf");
+            File outfile = new File(outputDir, df.format(num) + fop.getTargetFileExtension());
             OutputStream out = new java.io.FileOutputStream(outfile);
             try {
                 InputStream in;

Modified: xmlgraphics/fop/trunk/test/java/org/apache/fop/threading/FOProcessor.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/java/org/apache/fop/threading/FOProcessor.java?rev=611278&r1=611277&r2=611278&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/test/java/org/apache/fop/threading/FOProcessor.java (original)
+++ xmlgraphics/fop/trunk/test/java/org/apache/fop/threading/FOProcessor.java Fri Jan 11 11:50:53 2008
@@ -24,11 +24,24 @@
 
 import javax.xml.transform.Templates;
 
+/**
+ * Represents an FO processor.
+ */
 public interface FOProcessor {
 
-    String ROLE = FOProcessor.class.getName();
-
+    /**
+     * Process a file.
+     * @param in the InputStream for the FO or XML file
+     * @param templates a JAXP Templates object for an XSLT transformation or null
+     * @param out the OutputStream for the target file
+     * @throws Exception if an error occurs
+     */
     void process(InputStream in, Templates templates, OutputStream out)
-            throws org.apache.fop.apps.FOPException, java.io.IOException;
+            throws Exception;
 
+    /**
+     * Returns the target file extension for the configured output format.
+     * @return the target file extension (for example ".pdf")
+     */
+    String getTargetFileExtension();
 }

Modified: xmlgraphics/fop/trunk/test/java/org/apache/fop/threading/FOProcessorImpl.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/java/org/apache/fop/threading/FOProcessorImpl.java?rev=611278&r1=611277&r2=611278&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/test/java/org/apache/fop/threading/FOProcessorImpl.java (original)
+++ xmlgraphics/fop/trunk/test/java/org/apache/fop/threading/FOProcessorImpl.java Fri Jan 11 11:50:53 2008
@@ -28,69 +28,53 @@
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerException;
 import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.stream.StreamSource;
 import javax.xml.transform.sax.SAXResult;
+import javax.xml.transform.stream.StreamSource;
 
-import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.activity.Initializable;
 import org.apache.avalon.framework.configuration.Configurable;
 import org.apache.avalon.framework.configuration.Configuration;
 import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
 
+import org.apache.fop.apps.FOPException;
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.apps.Fop;
-import org.apache.fop.apps.FOPException;
 import org.apache.fop.apps.FopFactory;
 import org.apache.fop.apps.MimeConstants;
-import org.apache.avalon.framework.activity.Initializable;
 
+/**
+ * Default implementation of the FOProcessor interface using FOP.
+ */
 public class FOProcessorImpl extends AbstractLogEnabled
             implements FOProcessor, Configurable, Initializable {
 
     private FopFactory fopFactory = FopFactory.newInstance();
     private TransformerFactory factory = TransformerFactory.newInstance();
-    private String baseDir;
-    private String fontBaseDir;
     private String userconfig;
-    private boolean strokeSVGText;
+    private String mime;
+    private String fileExtension;
 
+    /** {@inheritDoc} */
     public void configure(Configuration configuration) throws ConfigurationException {
-        this.baseDir = configuration.getChild("basedir").getValue(null);
-        this.fontBaseDir = configuration.getChild("fontbasedir").getValue(null);
         this.userconfig = configuration.getChild("userconfig").getValue(null);
-        this.strokeSVGText = configuration.getChild("strokesvgtext").getValueAsBoolean(true);
+        this.mime = configuration.getChild("mime").getValue(MimeConstants.MIME_PDF);
+        this.fileExtension = configuration.getChild("extension").getValue(".pdf");
     }
 
-
+    /** {@inheritDoc} */
     public void initialize() throws Exception {
-        /*
-        org.apache.fop.messaging.MessageHandler.setScreenLogger(getLogger());
-        if (userconfig != null) {
-            getLogger().info("Using user config: "+userconfig);
-            InputStream in = org.apache.fop.tools.URLBuilder.buildURL(userconfig).openStream();
-            try {
-                new org.apache.fop.apps.Options(in);
-            } finally {
-                in.close();
-            }
-        }
-        if (this.baseDir != null) {
-            getLogger().info("Setting base dir: "+baseDir);
-            org.apache.fop.configuration.Configuration.put("baseDir", this.baseDir);
-        }
-        if (this.fontBaseDir != null) {
-            getLogger().info("Setting font base dir: "+fontBaseDir);
-            org.apache.fop.configuration.Configuration.put("fontBaseDir", this.fontBaseDir);
+        if (this.userconfig != null) {
+            getLogger().debug("Setting user config: " + userconfig);
+            fopFactory.setUserConfig(this.userconfig);
         }
-        String value = (this.strokeSVGText?"true":"false");
-        org.apache.fop.configuration.Configuration.put("strokeSVGText", value);
-        */
     }
 
-
+    /** {@inheritDoc} */
     public void process(InputStream in, Templates templates, OutputStream out) 
                 throws org.apache.fop.apps.FOPException, java.io.IOException {
         FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
-        Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);
+        Fop fop = fopFactory.newFop(this.mime, foUserAgent, out);
 
         try {
             Transformer transformer;
@@ -105,6 +89,11 @@
         } catch (TransformerException e) {
             throw new FOPException(e);
         }
+    }
+
+    /** {@inheritDoc} */
+    public String getTargetFileExtension() {
+        return this.fileExtension;
     }
 
 }

Modified: xmlgraphics/fop/trunk/test/java/org/apache/fop/threading/Main.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/java/org/apache/fop/threading/Main.java?rev=611278&r1=611277&r2=611278&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/test/java/org/apache/fop/threading/Main.java (original)
+++ xmlgraphics/fop/trunk/test/java/org/apache/fop/threading/Main.java Fri Jan 11 11:50:53 2008
@@ -19,7 +19,9 @@
 
 package org.apache.fop.threading;
 
+import java.io.BufferedReader;
 import java.io.File;
+import java.io.IOException;
 
 import org.apache.avalon.framework.ExceptionUtil;
 import org.apache.avalon.framework.configuration.Configuration;
@@ -27,14 +29,32 @@
 import org.apache.avalon.framework.container.ContainerUtil;
 import org.apache.avalon.framework.logger.ConsoleLogger;
 
+/**
+ * Starter class for the multi-threading testbed.
+ */
 public class Main {
 
+    private static void prompt() throws IOException {
+        BufferedReader in = new BufferedReader(new java.io.InputStreamReader(System.in));
+        System.out.print("Press return to continue...");
+        in.readLine();
+    }
+    
+    /**
+     * Main method.
+     * @param args the command-line arguments
+     */
     public static void main(String[] args) {
         try {
             //Read configuration
             File cfgFile = new File(args[0]);
             DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
             Configuration cfg = builder.buildFromFile(cfgFile);
+            
+            boolean doPrompt = cfg.getAttributeAsBoolean("prompt", false);
+            if (doPrompt) {
+                prompt();
+            }
             
             //Setup testbed
             FOPTestbed testbed = new FOPTestbed();

Modified: xmlgraphics/fop/trunk/test/java/org/apache/fop/threading/sample.cfg.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/java/org/apache/fop/threading/sample.cfg.xml?rev=611278&r1=611277&r2=611278&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/test/java/org/apache/fop/threading/sample.cfg.xml (original)
+++ xmlgraphics/fop/trunk/test/java/org/apache/fop/threading/sample.cfg.xml Fri Jan 11 11:50:53 2008
@@ -1,12 +1,13 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<config>
+<config prompt="false">
   <threads>2</threads>
   <output-dir>C:/Dev/FOP/temp/out</output-dir>
-  <foprocessor>
-    <!--basedir>C:/Dev/FOP/temp</basedir>
-    <fontbasedir>C:/Dev/FOP/temp/fonts</fontbasedir>
+  <foprocessor class="org.apache.fop.threading.FOProcessorImpl">
+    <!--
     <userconfig>C:/Dev/FOP/temp/userconfig.xml</userconfig>
-    <strokesvgtext>true</strokesvgtext-->
+    -->
+    <mime>application/pdf</mime>
+    <extension>.pdf</extension>
   </foprocessor>
   <tasks repeat="2">
     <task fo="C:/Dev/FOP/temp/helloworld.fo"/>

Modified: xmlgraphics/fop/trunk/test/java/org/apache/fop/visual/BatchDiffer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/java/org/apache/fop/visual/BatchDiffer.java?rev=611278&r1=611277&r2=611278&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/test/java/org/apache/fop/visual/BatchDiffer.java (original)
+++ xmlgraphics/fop/trunk/test/java/org/apache/fop/visual/BatchDiffer.java Fri Jan 11 11:50:53 2008
@@ -20,31 +20,28 @@
 package org.apache.fop.visual;
 
 import java.awt.image.BufferedImage;
-import java.awt.image.RenderedImage;
 import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.OutputStream;
 import java.util.Collection;
 import java.util.Iterator;
 
 import javax.xml.transform.TransformerConfigurationException;
 import javax.xml.transform.stream.StreamSource;
 
+import org.xml.sax.SAXException;
+
 import org.apache.avalon.framework.configuration.Configuration;
 import org.apache.avalon.framework.configuration.ConfigurationException;
 import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
 import org.apache.avalon.framework.container.ContainerUtil;
 import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
 import org.apache.commons.io.filefilter.IOFileFilter;
 import org.apache.commons.io.filefilter.SuffixFileFilter;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.xmlgraphics.image.writer.ImageWriterUtil;
+
 import org.apache.fop.layoutengine.LayoutEngineTestSuite;
-import org.apache.xmlgraphics.image.writer.ImageWriter;
-import org.apache.xmlgraphics.image.writer.ImageWriterRegistry;
-import org.xml.sax.SAXException;
 
 /**
  * This class is used to visually diff bitmap images created through various sources.
@@ -110,22 +107,6 @@
     }
 
     /**
-     * Saves a BufferedImage as a PNG file.
-     * @param bitmap the bitmap to encode
-     * @param outputFile the target file
-     * @throws IOException in case of an I/O problem
-     */
-    public static void saveAsPNG(RenderedImage bitmap, File outputFile) throws IOException {
-        OutputStream out = new FileOutputStream(outputFile);
-        try {
-            ImageWriter writer = ImageWriterRegistry.getInstance().getWriterFor("image/png");
-            writer.writeImage(bitmap, out);
-        } finally {
-            IOUtils.closeQuietly(out);
-        }
-    }
-    
-    /**
      * Runs the batch.
      * @param cfgFile configuration file to use
      * @throws ConfigurationException In case of a problem with the configuration
@@ -216,14 +197,14 @@
                     
                     //Save combined bitmap as PNG file
                     File outputFile = new File(targetDir, f.getName() + "._combined.png");
-                    saveAsPNG(combined, outputFile);
+                    ImageWriterUtil.saveAsPNG(combined, outputFile);
 
                     if (createDiffs) {
                         for (int k = 1; k < bitmaps.length; k++) {
                             BufferedImage diff = BitmapComparator.buildDiffImage(
                                     bitmaps[0], bitmaps[k]);
                             outputFile = new File(targetDir, f.getName() + "._diff" + k + ".png");
-                            saveAsPNG(diff, outputFile);
+                            ImageWriterUtil.saveAsPNG(diff, outputFile);
                         }
                     }
                     //Release memory as soon as possible. These images are huge!

Modified: xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/external-graphic_bmp.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/external-graphic_bmp.xml?rev=611278&r1=611277&r2=611278&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/external-graphic_bmp.xml (original)
+++ xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/external-graphic_bmp.xml Fri Jan 11 11:50:53 2008
@@ -45,13 +45,13 @@
     </fo:root>
   </fo>
   <checks>
-    <eval expected="46091" xpath="//flow/block[2]/lineArea/viewport/@ipd"/>
-    <eval expected="46091" xpath="//flow/block[2]/lineArea/viewport/@ipda"/>
-    <eval expected="46091" xpath="//flow/block[2]/lineArea/viewport/@bpd"/>
-    <eval expected="46091" xpath="//flow/block[2]/lineArea/viewport/@bpda"/>
-    <eval expected="192043" xpath="//flow/block[4]/lineArea/viewport/@ipd"/>
-    <eval expected="192043" xpath="//flow/block[4]/lineArea/viewport/@ipda"/>
-    <eval expected="192043" xpath="//flow/block[4]/lineArea/viewport/@bpd"/>
-    <eval expected="192043" xpath="//flow/block[4]/lineArea/viewport/@bpda"/>
+    <eval expected="46091" tolerance="5" xpath="//flow/block[2]/lineArea/viewport/@ipd"/>
+    <eval expected="46091" tolerance="5" xpath="//flow/block[2]/lineArea/viewport/@ipda"/>
+    <eval expected="46091" tolerance="5" xpath="//flow/block[2]/lineArea/viewport/@bpd"/>
+    <eval expected="46091" tolerance="5" xpath="//flow/block[2]/lineArea/viewport/@bpda"/>
+    <eval expected="192043" tolerance="5" xpath="//flow/block[4]/lineArea/viewport/@ipd"/>
+    <eval expected="192043" tolerance="5" xpath="//flow/block[4]/lineArea/viewport/@ipda"/>
+    <eval expected="192043" tolerance="5" xpath="//flow/block[4]/lineArea/viewport/@bpd"/>
+    <eval expected="192043" tolerance="5" xpath="//flow/block[4]/lineArea/viewport/@bpda"/>
   </checks>
 </testcase>

Modified: xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/external-graphic_emf.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/external-graphic_emf.xml?rev=611278&r1=611277&r2=611278&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/external-graphic_emf.xml (original)
+++ xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/external-graphic_emf.xml Fri Jan 11 11:50:53 2008
@@ -41,9 +41,9 @@
     </fo:root>
   </fo>
   <checks>
-    <eval expected="56692" xpath="//flow/block[2]/lineArea/viewport/@ipd"/>
-    <eval expected="56692" xpath="//flow/block[2]/lineArea/viewport/@ipda"/>
-    <eval expected="56692" xpath="//flow/block[2]/lineArea/viewport/@bpd"/>
-    <eval expected="56692" xpath="//flow/block[2]/lineArea/viewport/@bpda"/>
+    <eval expected="56692" tolerance="40" xpath="//flow/block[2]/lineArea/viewport/@ipd"/>
+    <eval expected="56692" tolerance="40" xpath="//flow/block[2]/lineArea/viewport/@ipda"/>
+    <eval expected="56692" tolerance="40" xpath="//flow/block[2]/lineArea/viewport/@bpd"/>
+    <eval expected="56692" tolerance="40" xpath="//flow/block[2]/lineArea/viewport/@bpda"/>
   </checks>
 </testcase>

Modified: xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/external-graphic_eps.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/external-graphic_eps.xml?rev=611278&r1=611277&r2=611278&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/external-graphic_eps.xml (original)
+++ xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/external-graphic_eps.xml Fri Jan 11 11:50:53 2008
@@ -41,9 +41,9 @@
     </fo:root>
   </fo>
   <checks>
-    <eval expected="136000" xpath="//flow/block[2]/lineArea/viewport/@ipd"/>
-    <eval expected="136000" xpath="//flow/block[2]/lineArea/viewport/@ipda"/>
-    <eval expected="43000" xpath="//flow/block[2]/lineArea/viewport/@bpd"/>
-    <eval expected="43000" xpath="//flow/block[2]/lineArea/viewport/@bpda"/>
+    <eval expected="135655" xpath="//flow/block[2]/lineArea/viewport/@ipd"/>
+    <eval expected="135655" xpath="//flow/block[2]/lineArea/viewport/@ipda"/>
+    <eval expected="42525" xpath="//flow/block[2]/lineArea/viewport/@bpd"/>
+    <eval expected="42525" xpath="//flow/block[2]/lineArea/viewport/@bpda"/>
   </checks>
 </testcase>



---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org