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 ac...@apache.org on 2008/03/27 17:16:38 UTC

svn commit: r641873 [2/5] - in /xmlgraphics/fop/branches/Temp_AFPGOCAResources/src/java/org/apache/fop: image/ render/afp/ render/afp/extensions/ render/afp/modca/ render/afp/modca/triplets/ render/pdf/ render/ps/extensions/

Modified: xmlgraphics/fop/branches/Temp_AFPGOCAResources/src/java/org/apache/fop/render/afp/AFPRenderer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AFPGOCAResources/src/java/org/apache/fop/render/afp/AFPRenderer.java?rev=641873&r1=641872&r2=641873&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_AFPGOCAResources/src/java/org/apache/fop/render/afp/AFPRenderer.java (original)
+++ xmlgraphics/fop/branches/Temp_AFPGOCAResources/src/java/org/apache/fop/render/afp/AFPRenderer.java Thu Mar 27 09:16:30 2008
@@ -23,6 +23,7 @@
 import java.awt.Point;
 import java.awt.Rectangle;
 import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
 import java.awt.geom.Rectangle2D;
 import java.awt.image.RenderedImage;
 import java.io.FileNotFoundException;
@@ -30,8 +31,6 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -39,7 +38,6 @@
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.io.output.ByteArrayOutputStream;
 
-import org.apache.xmlgraphics.image.codec.tiff.TIFFImage;
 import org.apache.xmlgraphics.image.loader.ImageException;
 import org.apache.xmlgraphics.image.loader.ImageFlavor;
 import org.apache.xmlgraphics.image.loader.ImageInfo;
@@ -58,6 +56,7 @@
 import org.apache.fop.area.BlockViewport;
 import org.apache.fop.area.BodyRegion;
 import org.apache.fop.area.CTM;
+import org.apache.fop.area.LineArea;
 import org.apache.fop.area.OffDocumentItem;
 import org.apache.fop.area.PageViewport;
 import org.apache.fop.area.RegionReference;
@@ -89,6 +88,7 @@
 import org.apache.fop.render.afp.modca.AFPConstants;
 import org.apache.fop.render.afp.modca.AFPDataStream;
 import org.apache.fop.render.afp.modca.ImageObject;
+import org.apache.fop.render.afp.modca.IncludeObject;
 import org.apache.fop.render.afp.modca.PageObject;
 
 /**
@@ -139,28 +139,23 @@
  * handle all types of inline area, text, image etc and draws various lines and
  * rectangles.
  * </p>
- * 
- * Note: There are specific extensions that have been added to the FO. They are
- * specific to their location within the FO and have to be processed accordingly
- * (ie. at the start or end of the page).
- * 
+ *
+ * Note: There are specific extensions that have been added to the
+ * FO. They are specific to their location within the FO and have to be
+ * processed accordingly (ie. at the start or end of the page).
+ *
  */
 public class AFPRenderer extends AbstractPathOrientedRenderer {
 
     /**
-     * 2400 dpi renderer resolution
+     * The default afp renderer output resolution
      */
-    protected static final int DPI_240_RESOLUTION = 240;
-
-    /**
-     * 14400 dpi renderer resolution
-     */
-    protected static final int DPI_1440_RESOLUTION = 1440;
+    public static final int DPI_240_RESOLUTION = 240;
 
     /**
      * The afp factor for calculating resolutions (e.g. 72000/240 = 300)
      */
-    protected static final int DPI_CONVERSION_FACTOR = 72000;
+    private static final int DPI_CONVERSION_FACTOR = 72000;
 
     /**
      * The afp data stream object responsible for generating afp data
@@ -168,11 +163,46 @@
     private AFPDataStream afpDataStream = null;
 
     /**
+     * The map of afp root extensions
+     */
+    // UNUSED
+    // private HashMap rootExtensionMap = null;
+    /**
      * The map of page segments
      */
     private Map pageSegmentsMap = null;
 
     /**
+     * The fonts on the current page
+     */
+    private Map currentPageFonts = null;
+
+    /**
+     * The current color object
+     */
+    private Color currentColor = null;
+
+    /**
+     * The page font number counter, used to determine the next font reference
+     */
+    private int pageFontCounter = 0;
+
+    /**
+     * The current font family
+     */
+    // UNUSED
+    // private String currentFontFamily = "";
+    /**
+     * The current font size
+     */
+    private int currentFontSize = 0;
+
+    /**
+     * The Options to be set on the AFPRenderer
+     */
+    // UNUSED
+    // private Map afpOptions = null;
+    /**
      * The page width
      */
     private int pageWidth = 0;
@@ -183,6 +213,11 @@
     private int pageHeight = 0;
 
     /**
+     * The current page sequence id
+     */
+    // UNUSED
+    // private String pageSequenceId = null;
+    /**
      * The portrait rotation
      */
     private int portraitRotation = 0;
@@ -193,6 +228,21 @@
     private int landscapeRotation = 270;
 
     /**
+     * The line cache, avoids drawing duplicate lines in tables.
+     */
+    // UNUSED
+    // private HashSet lineCache = null;
+    /**
+     * The current x position for line drawing
+     */
+    // UNUSED
+    // private float x;
+    /**
+     * The current y position for line drawing
+     */
+    // UNUSED
+    // private float y;
+    /**
      * The map of saved incomplete pages
      */
     private Map pages = null;
@@ -213,7 +263,7 @@
     private int resolution = DPI_240_RESOLUTION;
 
     /** drawing state */
-    protected AFPState currentState = null;
+    private AFPState currentState = null;
 
     /**
      * Constructor for AFPRenderer.
@@ -224,22 +274,20 @@
 
     /**
      * Set up the font info
-     * 
-     * @param inFontInfo
-     *            font info to set up
+     *
+     * @param inFontInfo  font info to set up
      */
     public void setupFontInfo(FontInfo inFontInfo) {
         this.fontInfo = inFontInfo;
         int num = 1;
         if (this.fontList != null && this.fontList.size() > 0) {
             for (Iterator it = this.fontList.iterator(); it.hasNext();) {
-                AFPFontInfo afi = (AFPFontInfo) it.next();
-                AFPFont bf = (AFPFont) afi.getAFPFont();
-                for (Iterator it2 = afi.getFontTriplets().iterator(); it2
-                        .hasNext();) {
-                    FontTriplet ft = (FontTriplet) it2.next();
-                    this.fontInfo.addFontProperties("F" + num, ft.getName(), ft
-                            .getStyle(), ft.getWeight());
+                AFPFontInfo afi = (AFPFontInfo)it.next();
+                AFPFont bf = (AFPFont)afi.getAFPFont();
+                for (Iterator it2 = afi.getFontTriplets().iterator(); it2.hasNext();) {
+                    FontTriplet ft = (FontTriplet)it2.next();
+                    this.fontInfo.addFontProperties("F" + num, ft.getName()
+                                                    , ft.getStyle(), ft.getWeight());
                     this.fontInfo.addMetrics("F" + num, bf);
                     num++;
                 }
@@ -248,36 +296,33 @@
             log.warn("No AFP fonts configured - using default setup");
         }
         if (this.fontInfo.fontLookup("sans-serif", "normal", 400) == null) {
-            CharacterSet cs = new FopCharacterSet("T1V10500", "Cp500",
-                    "CZH200  ", 1, new Helvetica());
+            CharacterSet cs  = new FopCharacterSet("T1V10500", "Cp500", "CZH200  ",
+                    1, new Helvetica());
             AFPFont bf = new OutlineFont("Helvetica", cs);
-            this.fontInfo.addFontProperties("F" + num, "sans-serif", "normal",
-                    400);
+            this.fontInfo.addFontProperties("F" + num, "sans-serif", "normal", 400);
             this.fontInfo.addMetrics("F" + num, bf);
             num++;
         }
         if (this.fontInfo.fontLookup("serif", "normal", 400) == null) {
-            CharacterSet cs = new FopCharacterSet("T1V10500", "Cp500",
-                    "CZN200  ", 1, new TimesRoman());
+            CharacterSet cs  = new FopCharacterSet("T1V10500", "Cp500", "CZN200  ",
+                    1, new TimesRoman());
             AFPFont bf = new OutlineFont("Helvetica", cs);
             this.fontInfo.addFontProperties("F" + num, "serif", "normal", 400);
             this.fontInfo.addMetrics("F" + num, bf);
             num++;
         }
         if (this.fontInfo.fontLookup("monospace", "normal", 400) == null) {
-            CharacterSet cs = new FopCharacterSet("T1V10500", "Cp500",
-                    "CZ4200  ", 1, new Courier());
+            CharacterSet cs  = new FopCharacterSet("T1V10500", "Cp500", "CZ4200  ",
+                    1, new Courier());
             AFPFont bf = new OutlineFont("Helvetica", cs);
-            this.fontInfo.addFontProperties("F" + num, "monospace", "normal",
-                    400);
+            this.fontInfo.addFontProperties("F" + num, "monospace", "normal", 400);
             this.fontInfo.addMetrics("F" + num, bf);
             num++;
         }
         if (this.fontInfo.fontLookup("any", "normal", 400) == null) {
-            FontTriplet ft = this.fontInfo.fontLookup("sans-serif", "normal",
-                    400);
-            this.fontInfo.addFontProperties(this.fontInfo
-                    .getInternalFontKey(ft), "any", "normal", 400);
+            FontTriplet ft = this.fontInfo.fontLookup("sans-serif", "normal", 400);
+            this.fontInfo.addFontProperties(
+                    this.fontInfo.getInternalFontKey(ft), "any", "normal", 400);
         }
     }
 
@@ -292,54 +337,62 @@
      * {@inheritDoc}
      */
     public void startRenderer(OutputStream outputStream) throws IOException {
-        this.currentState = new AFPState();
-        this.afpDataStream = new AFPDataStream();
-        this.afpDataStream.setPortraitRotation(portraitRotation);
-        this.afpDataStream.setLandscapeRotation(landscapeRotation);
-        this.afpDataStream.startDocument(outputStream);
+        currentPageFonts = new java.util.HashMap();
+        currentColor = new Color(255, 255, 255);
+        afpDataStream = new AFPDataStream();
+        afpDataStream.setPortraitRotation(portraitRotation);
+        afpDataStream.setLandscapeRotation(landscapeRotation);
+        afpDataStream.setOutputStream(outputStream);
     }
 
     /**
      * {@inheritDoc}
      */
     public void stopRenderer() throws IOException {
-        this.afpDataStream.endDocument();
+        afpDataStream.write();
     }
 
     /**
      * {@inheritDoc}
      */
     public boolean supportsOutOfOrder() {
-        // return false;
+        //return false;
         return true;
     }
 
     /**
-     * Prepare a page for rendering. This is called if the renderer supports out
-     * of order rendering. The renderer should prepare the page so that a page
-     * further on in the set of pages can be rendered. The body of the page
-     * should not be rendered. The page will be rendered at a later time by the
-     * call to render page.
-     * 
+     * Prepare a page for rendering. This is called if the renderer supports
+     * out of order rendering. The renderer should prepare the page so that a
+     * page further on in the set of pages can be rendered. The body of the
+     * page should not be rendered. The page will be rendered at a later time
+     * by the call to render page.
+     *
      * {@inheritDoc}
      */
     public void preparePage(PageViewport page) {
+        // initializeRootExtensions(page);
 
-        this.currentState.reset();
+        // this.currentFontFamily = "";
+        this.currentFontSize = 0;
+        this.pageFontCounter = 0;
+        this.currentPageFonts.clear();
+        // this.lineCache = new HashSet();
 
         Rectangle2D bounds = page.getViewArea();
 
         this.pageWidth = mpts2units(bounds.getWidth());
         this.pageHeight = mpts2units(bounds.getHeight());
 
+        // renderPageGroupExtensions(page);
+
         final int pageRotation = 0;
         this.afpDataStream.startPage(pageWidth, pageHeight, pageRotation,
-                this.resolution, this.resolution);
+                getResolution(), getResolution());
 
         renderPageObjectExtensions(page);
 
         if (this.pages == null) {
-            this.pages = new HashMap();
+            this.pages = new java.util.HashMap();
         }
         this.pages.put(page, afpDataStream.savePage());
 
@@ -372,15 +425,12 @@
     }
 
     /**
-     * Renders a region viewport.
-     * <p>
-     * 
-     * The region may clip the area and it establishes a position from where the
-     * region is placed.
-     * </p>
-     * 
-     * @param port
-     *            The region viewport to be rendered
+     * Renders a region viewport. <p>
+     *
+     * The region may clip the area and it establishes a position from where
+     * the region is placed.</p>
+     *
+     * @param port  The region viewport to be rendered
      */
     public void renderRegionViewport(RegionViewport port) {
         if (port != null) {
@@ -395,9 +445,11 @@
             handleRegionTraits(port);
 
             /*
-             * _afpDataStream.startOverlay(mpts2units(view.getX()) ,
-             * mpts2units(view.getY()) , mpts2units(view.getWidth()) ,
-             * mpts2units(view.getHeight()) , rotation);
+            _afpDataStream.startOverlay(mpts2units(view.getX())
+                , mpts2units(view.getY())
+                , mpts2units(view.getWidth())
+                , mpts2units(view.getHeight())
+                , rotation);
              */
 
             pushViewPortPos(new ViewPortPos(view, regionReference.getCTM()));
@@ -408,7 +460,7 @@
                 renderRegion(regionReference);
             }
             /*
-             * _afpDataStream.endOverlay();
+            _afpDataStream.endOverlay();
              */
             popViewPortPos();
         }
@@ -423,65 +475,77 @@
         // save positions
         int saveIP = currentIPPosition;
         int saveBP = currentBPPosition;
-        // String saveFontName = currentFontName;
 
         CTM ctm = bv.getCTM();
         int borderPaddingStart = bv.getBorderAndPaddingWidthStart();
         int borderPaddingBefore = bv.getBorderAndPaddingWidthBefore();
-        float x, y;
-        x = (float) (bv.getXOffset() + containingIPPosition) / 1000f;
-        y = (float) (bv.getYOffset() + containingBPPosition) / 1000f;
-        // This is the content-rect
-        float width = (float) bv.getIPD() / 1000f;
-        float height = (float) bv.getBPD() / 1000f;
+        //This is the content-rect
+        float width = (float)bv.getIPD() / 1000f;
+        float height = (float)bv.getBPD() / 1000f;
 
         if (bv.getPositioning() == Block.ABSOLUTE
                 || bv.getPositioning() == Block.FIXED) {
 
-            currentIPPosition = bv.getXOffset();
-            currentBPPosition = bv.getYOffset();
-
-            // For FIXED, we need to break out of the current viewports to the
-            // one established by the page. We save the state stack for
-            // restoration
-            // after the block-container has been painted. See below.
+            //For FIXED, we need to break out of the current viewports to the
+            //one established by the page. We save the state stack for restoration
+            //after the block-container has been painted. See below.
             List breakOutList = null;
             if (bv.getPositioning() == Block.FIXED) {
                 breakOutList = breakOutOfStateStack();
             }
 
-            CTM tempctm = new CTM(containingIPPosition, containingBPPosition);
-            ctm = tempctm.multiply(ctm);
-
-            // Adjust for spaces (from margin or indirectly by start-indent etc.
-            x += bv.getSpaceStart() / 1000f;
-            currentIPPosition += bv.getSpaceStart();
-
-            y += bv.getSpaceBefore() / 1000f;
-            currentBPPosition += bv.getSpaceBefore();
-
-            float bpwidth = (borderPaddingStart + bv
-                    .getBorderAndPaddingWidthEnd()) / 1000f;
-            float bpheight = (borderPaddingBefore + bv
-                    .getBorderAndPaddingWidthAfter()) / 1000f;
-
-            drawBackAndBorders(bv, x, y, width + bpwidth, height + bpheight);
-
-            // Now adjust for border/padding
-            currentIPPosition += borderPaddingStart;
-            currentBPPosition += borderPaddingBefore;
+            AffineTransform positionTransform = new AffineTransform();
+            positionTransform.translate(bv.getXOffset(), bv.getYOffset());
+            
+            //"left/"top" (bv.getX/YOffset()) specify the position of the content rectangle
+            positionTransform.translate(-borderPaddingStart, -borderPaddingBefore);
 
-            Rectangle2D clippingRect = null;
-            clippingRect = new Rectangle(currentIPPosition, currentBPPosition,
-                    bv.getIPD(), bv.getBPD());
+            //skipping fox:transform here
 
-            // startVParea(ctm, clippingRect);
-            pushViewPortPos(new ViewPortPos(clippingRect, ctm));
+            //saveGraphicsState();
+            //Viewport position
+            //concatenateTransformationMatrix(mptToPt(positionTransform));
+            
+            //Background and borders
+            float bpwidth = (borderPaddingStart + bv.getBorderAndPaddingWidthEnd()) / 1000f;
+            float bpheight = (borderPaddingBefore + bv.getBorderAndPaddingWidthAfter()) / 1000f;
+            Point2D ptSrc = new Point(0, 0);
+            Point2D ptDst = positionTransform.transform(ptSrc, null);
+            Rectangle2D borderRect = new Rectangle2D.Double(ptDst.getX(), ptDst.getY(),
+                    1000 * (width + bpwidth), 1000 * (height + bpheight));
+            pushViewPortPos(new ViewPortPos(borderRect, new CTM(positionTransform)));
+            drawBackAndBorders(bv, 0, 0, width + bpwidth, height + bpheight);
+
+            //Shift to content rectangle after border painting
+            AffineTransform contentRectTransform = new AffineTransform();
+            contentRectTransform.translate(borderPaddingStart, borderPaddingBefore);
+            //concatenateTransformationMatrix(mptToPt(contentRectTransform));
+            ptSrc = new Point(0, 0);
+            ptDst = contentRectTransform.transform(ptSrc, null);
+            Rectangle2D contentRect = new Rectangle2D.Double(ptDst.getX(), ptDst.getY(),
+                    1000 * width, 1000 * height);
+            pushViewPortPos(new ViewPortPos(contentRect, new CTM(contentRectTransform)));
+
+            //Clipping is not supported, yet
+            //Rectangle2D clippingRect = null;
+            //clippingRect = new Rectangle(0, 0, bv.getIPD(), bv.getBPD());
+
+            //saveGraphicsState();
+            //Set up coordinate system for content rectangle
+            AffineTransform contentTransform = ctm.toAffineTransform();
+            //concatenateTransformationMatrix(mptToPt(contentTransform));
+            contentRect = new Rectangle2D.Double(0, 0, 1000 * width, 1000 * height);
+            pushViewPortPos(new ViewPortPos(contentRect, new CTM(contentTransform)));
+            
             currentIPPosition = 0;
             currentBPPosition = 0;
             renderBlocks(bv, children);
-            // endVParea();
+
             popViewPortPos();
+            popViewPortPos();
+            //restoreGraphicsState();
+            popViewPortPos();
+            //restoreGraphicsState();
 
             if (breakOutList != null) {
                 restoreStateStackAfterBreakOut(breakOutList);
@@ -493,37 +557,36 @@
 
             currentBPPosition += bv.getSpaceBefore();
 
-            // borders and background in the old coordinate system
+            //borders and background in the old coordinate system
             handleBlockTraits(bv);
 
-            // Advance to start of content area
+            //Advance to start of content area
             currentIPPosition += bv.getStartIndent();
 
             CTM tempctm = new CTM(containingIPPosition, currentBPPosition);
             ctm = tempctm.multiply(ctm);
 
-            // Now adjust for border/padding
+            //Now adjust for border/padding
             currentBPPosition += borderPaddingBefore;
 
             Rectangle2D clippingRect = null;
             clippingRect = new Rectangle(currentIPPosition, currentBPPosition,
                     bv.getIPD(), bv.getBPD());
 
-            // startVParea(ctm, clippingRect);
+            //startVParea(ctm, clippingRect);
             pushViewPortPos(new ViewPortPos(clippingRect, ctm));
 
             currentIPPosition = 0;
             currentBPPosition = 0;
             renderBlocks(bv, children);
-            // endVParea();
+            //endVParea();
             popViewPortPos();
 
             currentIPPosition = saveIP;
             currentBPPosition = saveBP;
 
-            currentBPPosition += (int) (bv.getAllocBPD());
+            currentBPPosition += (int)(bv.getAllocBPD());
         }
-        // currentFontName = saveFontName;
     }
 
     /** {@inheritDoc} */
@@ -537,7 +600,13 @@
      */
     public void renderPage(PageViewport pageViewport) {
 
-        currentState.reset();
+        // initializeRootExtensions(page);
+
+        // this.currentFontFamily = "";
+        this.currentFontSize = 0;
+        this.pageFontCounter = 0;
+        this.currentPageFonts.clear();
+        // this.lineCache = new HashSet();
 
         Rectangle2D bounds = pageViewport.getViewArea();
 
@@ -546,14 +615,14 @@
 
         if (pages != null && pages.containsKey(pageViewport)) {
 
-            this.afpDataStream.restorePage((PageObject) pages
-                    .remove(pageViewport));
+            this.afpDataStream.restorePage((PageObject) pages.remove(pageViewport));
 
         } else {
+            // renderPageGroupExtensions(page);
 
             final int pageRotation = 0;
             this.afpDataStream.startPage(pageWidth, pageHeight, pageRotation,
-                    this.resolution, this.resolution);
+                    getResolution(), getResolution());
 
             renderPageObjectExtensions(pageViewport);
 
@@ -563,16 +632,20 @@
 
         renderPageAreas(pageViewport.getPage());
 
-        this.afpDataStream.addFontsToCurrentPage(currentState.getPageFonts());
+        Iterator i = currentPageFonts.values().iterator();
+        while (i.hasNext()) {
+            AFPFontAttributes afpFontAttributes = (AFPFontAttributes) i.next();
+
+            afpDataStream.createFont(
+                (byte)afpFontAttributes.getFontReference(),
+                afpFontAttributes.getFont(),
+                afpFontAttributes.getPointSize());
 
-        try {
-            afpDataStream.endPage();
-        } catch (IOException ioex) {
-            // TODO What shall we do?
         }
 
+        afpDataStream.endPage();
+        
         popViewPortPos();
-
     }
 
     /**
@@ -615,12 +688,22 @@
      */
     public void fillRect(float x, float y, float width, float height) {
         /*
-         * afpDataStream.createShading( pts2units(x), pts2units(y),
-         * pts2units(width), pts2units(height), currentColor.getRed(),
-         * currentColor.getGreen(), currentColor.getBlue());
+        afpDataStream.createShading(
+            pts2units(x),
+            pts2units(y),
+            pts2units(width),
+            pts2units(height),
+            currentColor.getRed(),
+            currentColor.getGreen(),
+            currentColor.getBlue());
          */
-        afpDataStream.createLine(pts2units(x), pts2units(y), pts2units(x
-                + width), pts2units(y), pts2units(height), currentState.getColor());
+        afpDataStream.createLine(
+            pts2units(x),
+            pts2units(y),
+            pts2units(x + width),
+            pts2units(y),
+            pts2units(height),
+            currentColor);
     }
 
     /**
@@ -635,112 +718,193 @@
             return;
         }
         switch (style) {
-        case Constants.EN_DOUBLE:
-            if (horz) {
-                float h3 = h / 3;
-                float ym1 = y1;
-                float ym2 = ym1 + h3 + h3;
-                afpDataStream.createLine(pts2units(x1), pts2units(ym1),
-                        pts2units(x2), pts2units(ym1), pts2units(h3), col);
-                afpDataStream.createLine(pts2units(x1), pts2units(ym2),
-                        pts2units(x2), pts2units(ym2), pts2units(h3), col);
-            } else {
-                float w3 = w / 3;
-                float xm1 = x1;
-                float xm2 = xm1 + w3 + w3;
-                afpDataStream.createLine(pts2units(xm1), pts2units(y1),
-                        pts2units(xm1), pts2units(y2), pts2units(w3), col);
-                afpDataStream.createLine(pts2units(xm2), pts2units(y1),
-                        pts2units(xm2), pts2units(y2), pts2units(w3), col);
-            }
-            break;
-        case Constants.EN_DASHED:
-            if (horz) {
-                float w2 = 2 * h;
-                while (x1 + w2 < x2) {
-                    afpDataStream.createLine(pts2units(x1), pts2units(y1),
-                            pts2units(x1 + w2), pts2units(y1), pts2units(h),
-                            col);
-                    x1 += 2 * w2;
+            case Constants.EN_DOUBLE:
+                if (horz) {
+                    float h3 = h / 3;
+                    float ym1 = y1;
+                    float ym2 = ym1 + h3 + h3;
+                    afpDataStream.createLine(
+                        pts2units(x1),
+                        pts2units(ym1),
+                        pts2units(x2),
+                        pts2units(ym1),
+                        pts2units(h3),
+                        col
+                    );
+                    afpDataStream.createLine(
+                        pts2units(x1),
+                        pts2units(ym2),
+                        pts2units(x2),
+                        pts2units(ym2),
+                        pts2units(h3),
+                        col
+                    );
+                } else {
+                    float w3 = w / 3;
+                    float xm1 = x1;
+                    float xm2 = xm1 + w3 + w3;
+                    afpDataStream.createLine(
+                        pts2units(xm1),
+                        pts2units(y1),
+                        pts2units(xm1),
+                        pts2units(y2),
+                        pts2units(w3),
+                        col
+                    );
+                    afpDataStream.createLine(
+                        pts2units(xm2),
+                        pts2units(y1),
+                        pts2units(xm2),
+                        pts2units(y2),
+                        pts2units(w3),
+                        col
+                    );
                 }
-            } else {
-                float h2 = 2 * w;
-                while (y1 + h2 < y2) {
-                    afpDataStream.createLine(pts2units(x1), pts2units(y1),
-                            pts2units(x1), pts2units(y1 + h2), pts2units(w),
-                            col);
-                    y1 += 2 * h2;
+                break;
+            case Constants.EN_DASHED:
+                if (horz) {
+                    float w2 = 2 * h;
+                    while (x1 + w2 < x2) {
+                        afpDataStream.createLine(
+                            pts2units(x1),
+                            pts2units(y1),
+                            pts2units(x1 + w2),
+                            pts2units(y1),
+                            pts2units(h),
+                            col
+                        );
+                        x1 += 2 * w2;
+                    }
+                } else {
+                    float h2 = 2 * w;
+                    while (y1 + h2 < y2) {
+                        afpDataStream.createLine(
+                            pts2units(x1),
+                            pts2units(y1),
+                            pts2units(x1),
+                            pts2units(y1 + h2),
+                            pts2units(w),
+                            col
+                        );
+                        y1 += 2 * h2;
+                    }
                 }
-            }
-            break;
-        case Constants.EN_DOTTED:
-            if (horz) {
-                while (x1 + h < x2) {
-                    afpDataStream
-                            .createLine(pts2units(x1), pts2units(y1),
-                                    pts2units(x1 + h), pts2units(y1),
-                                    pts2units(h), col);
-                    x1 += 2 * h;
+                break;
+            case Constants.EN_DOTTED:
+                if (horz) {
+                    while (x1 + h < x2) {
+                        afpDataStream.createLine(
+                            pts2units(x1),
+                            pts2units(y1),
+                            pts2units(x1 + h),
+                            pts2units(y1),
+                            pts2units(h),
+                            col
+                        );
+                        x1 += 2 * h;
+                    }
+                } else {
+                    while (y1 + w < y2) {
+                        afpDataStream.createLine(
+                            pts2units(x1),
+                            pts2units(y1),
+                            pts2units(x1),
+                            pts2units(y1 + w),
+                            pts2units(w),
+                            col
+                        );
+                        y1 += 2 * w;
+                    }
                 }
-            } else {
-                while (y1 + w < y2) {
-                    afpDataStream
-                            .createLine(pts2units(x1), pts2units(y1),
-                                    pts2units(x1), pts2units(y1 + w),
-                                    pts2units(w), col);
-                    y1 += 2 * w;
+                break;
+            case Constants.EN_GROOVE:
+            case Constants.EN_RIDGE:
+            {
+                float colFactor = (style == EN_GROOVE ? 0.4f : -0.4f);
+                if (horz) {
+                    Color uppercol = lightenColor(col, -colFactor);
+                    Color lowercol = lightenColor(col, colFactor);
+                    float h3 = h / 3;
+                    float ym1 = y1;
+                    afpDataStream.createLine(
+                        pts2units(x1),
+                        pts2units(ym1),
+                        pts2units(x2),
+                        pts2units(ym1),
+                        pts2units(h3),
+                        uppercol
+                    );
+                    afpDataStream.createLine(
+                        pts2units(x1),
+                        pts2units(ym1 + h3),
+                        pts2units(x2),
+                        pts2units(ym1 + h3),
+                        pts2units(h3),
+                        col
+                    );
+                    afpDataStream.createLine(
+                        pts2units(x1),
+                        pts2units(ym1 + h3 + h3),
+                        pts2units(x2),
+                        pts2units(ym1 + h3 + h3),
+                        pts2units(h3),
+                        lowercol
+                    );
+                } else {
+                    Color leftcol = lightenColor(col, -colFactor);
+                    Color rightcol = lightenColor(col, colFactor);
+                    float w3 = w / 3;
+                    float xm1 = x1 + (w3 / 2);
+                    afpDataStream.createLine(
+                        pts2units(xm1),
+                        pts2units(y1),
+                        pts2units(xm1),
+                        pts2units(y2),
+                        pts2units(w3),
+                        leftcol
+                    );
+                    afpDataStream.createLine(
+                        pts2units(xm1 + w3),
+                        pts2units(y1),
+                        pts2units(xm1 + w3),
+                        pts2units(y2),
+                        pts2units(w3),
+                        col
+                    );
+                    afpDataStream.createLine(
+                        pts2units(xm1 + w3 + w3),
+                        pts2units(y1),
+                        pts2units(xm1 + w3 + w3),
+                        pts2units(y2),
+                        pts2units(w3),
+                        rightcol
+                    );
                 }
+                break;
             }
-            break;
-        case Constants.EN_GROOVE:
-        case Constants.EN_RIDGE: {
-            float colFactor = (style == EN_GROOVE ? 0.4f : -0.4f);
-            if (horz) {
-                Color uppercol = lightenColor(col, -colFactor);
-                Color lowercol = lightenColor(col, colFactor);
-                float h3 = h / 3;
-                float ym1 = y1;
-                afpDataStream.createLine(pts2units(x1), pts2units(ym1),
-                        pts2units(x2), pts2units(ym1), pts2units(h3), uppercol);
-                afpDataStream.createLine(pts2units(x1), pts2units(ym1 + h3),
-                        pts2units(x2), pts2units(ym1 + h3), pts2units(h3), col);
-                afpDataStream.createLine(pts2units(x1),
-                        pts2units(ym1 + h3 + h3), pts2units(x2), pts2units(ym1
-                                + h3 + h3), pts2units(h3), lowercol);
-            } else {
-                Color leftcol = lightenColor(col, -colFactor);
-                Color rightcol = lightenColor(col, colFactor);
-                float w3 = w / 3;
-                float xm1 = x1 + (w3 / 2);
-                afpDataStream.createLine(pts2units(xm1), pts2units(y1),
-                        pts2units(xm1), pts2units(y2), pts2units(w3), leftcol);
-                afpDataStream.createLine(pts2units(xm1 + w3), pts2units(y1),
-                        pts2units(xm1 + w3), pts2units(y2), pts2units(w3), col);
-                afpDataStream.createLine(pts2units(xm1 + w3 + w3),
-                        pts2units(y1), pts2units(xm1 + w3 + w3), pts2units(y2),
-                        pts2units(w3), rightcol);
-            }
-            break;
-        }
-        case Constants.EN_HIDDEN:
-            break;
-        case Constants.EN_INSET:
-        case Constants.EN_OUTSET:
-        default:
-            afpDataStream.createLine(pts2units(x1), pts2units(y1),
-                    pts2units(horz ? x2 : x1), pts2units(horz ? y1 : y2),
-                    pts2units(Math.abs(horz ? (y2 - y1) : (x2 - x1))), col);
+            case Constants.EN_HIDDEN:
+                break;
+            case Constants.EN_INSET:
+            case Constants.EN_OUTSET:
+            default:
+                afpDataStream.createLine(
+                    pts2units(x1),
+                    pts2units(y1),
+                    pts2units(horz ? x2 : x1),
+                    pts2units(horz ? y1 : y2),
+                    pts2units(Math.abs(horz ? (y2 - y1) : (x2 - x1))),
+                    col
+                );
         }
     }
 
     /**
      * {@inheritDoc}
      */
-    protected RendererContext createRendererContext(int x, int y, int width,
-            int height, Map foreignAttributes) {
+    protected RendererContext createRendererContext(int x, int y, int width, int height,
+            Map foreignAttributes) {
         RendererContext context;
-        context = super.createRendererContext(x, y, width, height,
-                foreignAttributes);
+        context = super.createRendererContext(x, y, width, height, foreignAttributes);
         context.setProperty(AFPRendererContextConstants.AFP_GRAYSCALE,
                 new Boolean(!this.colorImages));
         context.setProperty(AFPRendererContextConstants.AFP_FONT_INFO,
@@ -750,9 +914,9 @@
         context.setProperty(AFPRendererContextConstants.AFP_BITS_PER_PIXEL,
                 new Integer(this.bitsPerPixel));
         context.setProperty(AFPRendererContextConstants.AFP_DATASTREAM,
-                this.afpDataStream);
+                getAFPDataStream());
         context.setProperty(AFPRendererContextConstants.AFP_STATE,
-                this.currentState);
+                getState());
         return context;
     }
 
@@ -763,6 +927,7 @@
                                                       ImageFlavor.RENDERED_IMAGE,
                                                       ImageFlavor.XML_DOM};
 
+        
     /** {@inheritDoc} */
     public void drawImage(String uri, Rectangle2D pos, Map foreignAttributes) {
         uri = URISpecification.getURL(uri);
@@ -784,6 +949,7 @@
         } else {
             ImageManager manager = getUserAgent().getFactory().getImageManager();
             ImageInfo info = null;
+            InputStream in = null;
             try {
                 ImageSessionContext sessionContext = getUserAgent().getImageSessionContext();
                 info = manager.getImageInfo(uri, sessionContext);
@@ -806,48 +972,62 @@
                 } else if (img instanceof ImageRendered) {
                     ImageRendered imgRend = (ImageRendered)img;
                     RenderedImage ri = imgRend.getRenderedImage();
-                    
-                    drawBufferedImage(ri, getResolution(),
+                    drawBufferedImage(uri, ri, getResolution(),
                             posInt.x + currentIPPosition,
                             posInt.y + currentBPPosition,
                             posInt.width,
-                            posInt.height);
+                            posInt.height, foreignAttributes);
                 } else if (img instanceof ImageRawCCITTFax) {
                     ImageRawCCITTFax ccitt = (ImageRawCCITTFax)img;
+                    in = ccitt.createInputStream();
+                    byte[] buf = IOUtils.toByteArray(in);
                     int afpx = mpts2units(posInt.x + currentIPPosition);
                     int afpy = mpts2units(posInt.y + currentBPPosition);
                     int afpw = mpts2units(posInt.getWidth());
                     int afph = mpts2units(posInt.getHeight());
                     int afpres = getResolution();
-                    ImageObject io = afpDataStream.getImageObject(afpx, afpy, afpw, afph,
-                            afpres, afpres);
-                    io.setImageParameters(
-                            (int) (ccitt.getSize().getDpiHorizontal() * 10),
-                            (int) (ccitt.getSize().getDpiVertical() * 10),
+                    ImageObjectParameters params = new ImageObjectParameters(
+                            uri, afpx, afpy, afpw, afph, afpres, afpres,
+                            buf,
                             ccitt.getSize().getWidthPx(),
-                            ccitt.getSize().getHeightPx());
-                    int compression = ccitt.getCompression();
-                    switch (compression) {
-                    case TIFFImage.COMP_FAX_G3_1D :
-                        io.setImageEncoding((byte) 0x80);
-                        break;
-                    case TIFFImage.COMP_FAX_G3_2D :
-                        io.setImageEncoding((byte) 0x81);
-                        break;
-                    case TIFFImage.COMP_FAX_G4_2D :
-                        io.setImageEncoding((byte) 0x82);
-                        break;
-                    default:
-                        throw new IllegalStateException(
-                                "Invalid compression scheme: " + compression);
-                    }
-                    InputStream in = ccitt.createInputStream();
-                    try {
-                        byte[] buf = IOUtils.toByteArray(in);
-                        io.setImageData(buf);
-                    } finally {
-                        IOUtils.closeQuietly(in);
-                    }
+                            ccitt.getSize().getHeightPx(),
+                            colorImages, bitsPerPixel
+                    );
+                    params.setCompression(ccitt.getCompression());
+                    params.setResourceLevelFromForeignAttributes(foreignAttributes);
+//                    params.setData(buf);
+                    afpDataStream.createImageObject(params);
+
+                            
+//                    ImageObject io = afpDataStream.getImageObject(afpx, afpy, afpw, afph,
+//                            afpres, afpres);
+//                    io.setImageParameters(
+//                            (int) (ccitt.getSize().getDpiHorizontal() * 10),
+//                            (int) (ccitt.getSize().getDpiVertical() * 10),
+//                            ccitt.getSize().getWidthPx(),
+//                            ccitt.getSize().getHeightPx());
+//                    int compression = ccitt.getCompression();
+//                    switch (compression) {
+//                    case TIFFImage.COMP_FAX_G3_1D :
+//                        io.setImageEncoding((byte) 0x80);
+//                        break;
+//                    case TIFFImage.COMP_FAX_G3_2D :
+//                        io.setImageEncoding((byte) 0x81);
+//                        break;
+//                    case TIFFImage.COMP_FAX_G4_2D :
+//                        io.setImageEncoding((byte) 0x82);
+//                        break;
+//                    default:
+//                        throw new IllegalStateException(
+//                                "Invalid compression scheme: " + compression);
+//                    }
+//                    InputStream in = ccitt.createInputStream();
+//                    try {
+//                        byte[] buf = IOUtils.toByteArray(in);
+//                        io.setImageData(buf);
+//                    } finally {
+//                        IOUtils.closeQuietly(in);
+//                    }
                 } else if (img instanceof ImageXMLDOM) {
                     ImageXMLDOM imgXML = (ImageXMLDOM)img;
                     renderDocument(imgXML.getDocument(), imgXML.getRootNamespace(),
@@ -864,6 +1044,10 @@
             } catch (IOException ioe) {
                 log.error("I/O error while processing image: "
                         + (info != null ? info.toString() : uri), ioe);
+            } finally {
+                if (in != null) {
+                    IOUtils.closeQuietly(in);
+                }
             }
             
             /*
@@ -906,46 +1090,47 @@
                  * io.setImageData(fopimage.getRessourceBytes());
                  *//*
             } else if (MimeConstants.MIME_TIFF.equals(mime)
-                    && fopimage instanceof TIFFImage) {
+                        && fopimage instanceof TIFFImage) {
                 TIFFImage tiffImage = (TIFFImage) fopimage;
                 int x = mpts2units(pos.getX() + currentIPPosition);
                 int y = mpts2units(pos.getY() + currentBPPosition);
                 int w = mpts2units(pos.getWidth());
                 int h = mpts2units(pos.getHeight());
-                int res = getResolution();
-                ImageObject io = afpDataStream.getImageObject(x, y, w, h, res,
-                        res);
+                ImageObject io = afpDataStream.getImageObject(x, y, w, h,
+                        getResolution(), getResolution());
                 io.setImageParameters(
-                        (int) (fopimage.getHorizontalResolution() * 10),
-                        (int) (fopimage.getVerticalResolution() * 10), fopimage
-                                .getWidth(), fopimage.getHeight());
+                    (int)(fopimage.getHorizontalResolution() * 10),
+                    (int)(fopimage.getVerticalResolution() * 10),
+                    fopimage.getWidth(),
+                    fopimage.getHeight()
+                );
                 if (tiffImage.getStripCount() == 1) {
                     int comp = tiffImage.getCompression();
                     if (comp == 3) {
                         if (!fopimage.load(FopImage.ORIGINAL_DATA)) {
                             return;
                         }
-                        io.setImageEncoding((byte) 0x81);
+                        io.setImageEncoding((byte)0x81);
                         io.setImageData(fopimage.getRessourceBytes());
                     } else if (comp == 4) {
                         if (!fopimage.load(FopImage.ORIGINAL_DATA)) {
                             return;
                         }
-                        io.setImageEncoding((byte) 0x82);
+                        io.setImageEncoding((byte)0x82);
                         io.setImageData(fopimage.getRessourceBytes());
                     } else {
                         if (!fopimage.load(FopImage.BITMAP)) {
                             return;
                         }
-                        convertToGrayScaleImage(io, fopimage.getBitmaps(),
-                                fopimage.getWidth(), fopimage.getHeight(), this.bitsPerPixel);
+                        convertToGrayScaleImage(io, fopimage.getBitmaps(), 
+                                fopimage.getWidth(), fopimage.getHeight());
                     }
                 } else {
                     if (!fopimage.load(FopImage.BITMAP)) {
                         return;
                     }
-                    convertToGrayScaleImage(io, fopimage.getBitmaps(), fopimage
-                            .getWidth(), fopimage.getHeight(), this.bitsPerPixel);
+                    convertToGrayScaleImage(io, fopimage.getBitmaps(),
+                            fopimage.getWidth(), fopimage.getHeight());
                 }
             } else {
                 if (!fopimage.load(FopImage.BITMAP)) {
@@ -957,19 +1142,20 @@
                 int y = mpts2units(pos.getY() + currentBPPosition);
                 int w = mpts2units(pos.getWidth());
                 int h = mpts2units(pos.getHeight());
-                int res = getResolution();
-                ImageObject io = afpDataStream.getImageObject(x, y, w, h, res,
-                        res);
+                ImageObject io = afpDataStream.getImageObject(x, y, w, h,
+                        getResolution(), getResolution());
                 io.setImageParameters(
-                        (int) (fopimage.getHorizontalResolution() * 10),
-                        (int) (fopimage.getVerticalResolution() * 10), fopimage
-                                .getWidth(), fopimage.getHeight());
+                    (int)(fopimage.getHorizontalResolution() * 10),
+                    (int)(fopimage.getVerticalResolution() * 10),
+                    fopimage.getWidth(),
+                    fopimage.getHeight()
+                );
                 if (colorImages) {
-                    io.setImageIDESize((byte) 24);
+                    io.setImageIDESize((byte)24);
                     io.setImageData(fopimage.getBitmaps());
                 } else {
-                    convertToGrayScaleImage(io, fopimage.getBitmaps(), fopimage
-                            .getWidth(), fopimage.getHeight(), this.bitsPerPixel);
+                    convertToGrayScaleImage(io, fopimage.getBitmaps(),
+                            fopimage.getWidth(), fopimage.getHeight());
                 }
             }*/
         }
@@ -983,7 +1169,9 @@
      * @param out
      *            the OutputStream
      * @throws IOException
-     *             In case of an I/O error.
+     *            In case of an I/O error.
+     * @deprecated
+     *            use ImageEncodingHelper.encodeRenderedImageAsRGB(image, out) directly instead
      */
     public static void writeImage(RenderedImage image, OutputStream out)
             throws IOException {
@@ -993,9 +1181,11 @@
     /**
      * Draws a BufferedImage to AFP.
      * 
+     * @param uri
+     *            the uri of the image
      * @param image
      *            the RenderedImage
-     * @param imageResolution
+     * @param imageRes
      *            the resolution of the BufferedImage
      * @param x
      *            the x coordinate (in mpt)
@@ -1006,55 +1196,67 @@
      * @param h
      *            the height of the viewport (in mpt)
      */
-    public void drawBufferedImage(RenderedImage image, int imageResolution, int x,
-            int y, int w, int h) {
-        int afpx = mpts2units(x);
-        int afpy = mpts2units(y);
-        int afpw = mpts2units(w);
-        int afph = mpts2units(h);
-        int afpres = getResolution();
+    public void drawBufferedImage(String uri, RenderedImage image, int imageRes, int x,
+            int y, int w, int h, Map foreignAttributes) {
+//        int afpx = mpts2units(x);
+//        int afpy = mpts2units(y);
+//        int afpw = mpts2units(w);
+//        int afph = mpts2units(h);
         ByteArrayOutputStream baout = new ByteArrayOutputStream();
         try {
             // Serialize image
             //TODO Eventually, this should be changed not to buffer as this increases the
             //memory consumption (see PostScript output)
-            writeImage(image, baout);
-            byte[] buf = baout.toByteArray();
-
-            // Generate image
-            ImageObject io = afpDataStream.getImageObject(afpx, afpy, afpw,
-                    afph, afpres, afpres);
-            io.setImageParameters(imageResolution, imageResolution,
-                    image.getWidth(), image.getHeight());
-            if (colorImages) {
-                io.setImageIDESize((byte)24);
-                io.setImageData(buf);
-            } else {
-                // TODO Teach it how to handle grayscale BufferedImages directly
-                // because this is pretty inefficient
-                convertToGrayScaleImage(io, buf,
-                        image.getWidth(), image.getHeight(), this.bitsPerPixel);
-            }
+            ImageEncodingHelper.encodeRenderedImageAsRGB(image, baout);
         } catch (IOException ioe) {
-            log.error("Error while serializing bitmap: " + ioe.getMessage(),
-                    ioe);
+            log.error("Error while serializing bitmap: " + ioe.getMessage(), ioe);
+            return;
         }
+        //int res = getResolution();
+//        String uri = null;// = image.getProperty(name);
+//        String uri = image.getProperty(name);
+        // Generate image
+        ImageObjectParameters params = new ImageObjectParameters(
+                uri,
+                mpts2units(x), mpts2units(y),
+                mpts2units(w), mpts2units(h),
+                imageRes, imageRes,
+                baout.toByteArray(),
+                image.getWidth(),
+                image.getHeight(),
+                colorImages,
+                bitsPerPixel);
+
+        params.setResourceLevelFromForeignAttributes(foreignAttributes);
+        IncludeObject io = afpDataStream.createImageObject(params);
+//            ImageObject io = afpDataStream.getImageObject(afpx, afpy, afpw,
+//                    afph, afpres, afpres);
+//            io.setImageParameters(imageResolution, imageResolution,
+//                    image.getWidth(), image.getHeight());
+//            if (colorImages) {
+//                io.setImageIDESize((byte)24);
+//                io.setImageData(buf);
+//            } else {
+//                // TODO Teach it how to handle grayscale BufferedImages directly
+//                // because this is pretty inefficient
+//                convertToGrayScaleImage(io, buf,
+//                        image.getWidth(), image.getHeight(), this.bitsPerPixel);
+//            }
     }
 
     /**
-     * Establishes a new foreground or fill color. {@inheritDoc}
+     * Establishes a new foreground or fill color.
+     * {@inheritDoc}
      */
     public void updateColor(Color col, boolean fill) {
         if (fill) {
-            currentState.setColor(col);
+            currentColor = col;
         }
     }
 
     /**
      * Restores the state stack after a break out.
-     * 
-     * @param breakOutList
-     *            the state stack to restore.
+     * @param breakOutList the state stack to restore.
      */
     public void restoreStateStackAfterBreakOut(List breakOutList) {
 
@@ -1062,7 +1264,6 @@
 
     /**
      * Breaks out of the state stack to handle fixed block-containers.
-     * 
      * @return the saved state stack to recreate later
      */
     public List breakOutOfStateStack() {
@@ -1093,8 +1294,7 @@
      * {@inheritDoc}
      */
     public void renderImage(Image image, Rectangle2D pos) {
-        String url = image.getURL();
-        drawImage(url, pos);
+        drawImage(image.getURL(), pos, image.getForeignAttributes());
     }
 
     /**
@@ -1103,58 +1303,76 @@
     public void renderText(TextArea text) {
         renderInlineAreaBackAndBorders(text);
 
-        String internalFontName = getInternalFontNameForArea(text);
-        this.currentState.setFontName(internalFontName);
-        int currentFontSize = ((Integer) text.getTrait(Trait.FONT_SIZE)).intValue();
-        this.currentState.setFontSize(currentFontSize); 
-        AFPFont font = (AFPFont) fontInfo.getFonts().get(internalFontName);
+        String name = getInternalFontNameForArea(text);
+        currentFontSize = ((Integer) text.getTrait(Trait.FONT_SIZE)).intValue();
+        AFPFont tf = (AFPFont) fontInfo.getFonts().get(name);
 
         Color col = (Color) text.getTrait(Trait.COLOR);
 
-        int vsci = mpts2units(font.getWidth(' ', currentFontSize) / 1000
-                + text.getTextWordSpaceAdjust()
-                + text.getTextLetterSpaceAdjust());
+        int vsci = mpts2units(tf.getWidth(' ', currentFontSize) / 1000
+                                + text.getTextWordSpaceAdjust()
+                                + text.getTextLetterSpaceAdjust());
 
         // word.getOffset() = only height of text itself
         // currentBlockIPPosition: 0 for beginning of line; nonzero
-        // where previous line area failed to take up entire allocated space
+        //  where previous line area failed to take up entire allocated space
         int rx = currentIPPosition + text.getBorderAndPaddingWidthStart();
-        int bl = currentBPPosition + text.getOffset()
-                + text.getBaselineOffset();
+        int bl = currentBPPosition + text.getOffset() + text.getBaselineOffset();
 
         // Set letterSpacing
-        // float ls = fs.getLetterSpacing() / this.currentFontSize;
+        //float ls = fs.getLetterSpacing() / this.currentFontSize;
 
         String worddata = text.getText();
 
-        AFPPageFonts pageFonts = this.currentState.getPageFonts();
-        AFPFontAttributes afpFontAttributes = pageFonts.registerFont(
-                internalFontName, font, currentFontSize);
+        // Create an AFPFontAttributes object from the current font details
+        AFPFontAttributes afpFontAttributes = new AFPFontAttributes(name, tf, currentFontSize);
+
+        if (!currentPageFonts.containsKey(afpFontAttributes.getFontKey())) {
+            // Font not found on current page, so add the new one
+            pageFontCounter++;
+            afpFontAttributes.setFontReference(pageFontCounter);
+            currentPageFonts.put(
+               afpFontAttributes.getFontKey(),
+               afpFontAttributes);
+
+        } else {
+            // Use the previously stored font attributes
+            afpFontAttributes = (AFPFontAttributes) currentPageFonts.get(
+                    afpFontAttributes.getFontKey());
+        }
 
         // Try and get the encoding to use for the font
         String encoding = null;
 
         try {
-            encoding = font.getCharacterSet(currentFontSize).getEncoding();
+            encoding = tf.getCharacterSet(currentFontSize).getEncoding();
         } catch (Throwable ex) {
             encoding = AFPConstants.EBCIDIC_ENCODING;
-            log.warn("renderText():: Error getting encoding for font "
-                    + " - using default encoding " + encoding);
+            log.warn(
+                "renderText():: Error getting encoding for font "
+                + " - using default encoding "
+                + encoding);
         }
 
         try {
-            afpDataStream.createText(afpFontAttributes.getFontReference(),
-                    mpts2units(rx), pts2units(bl), col, vsci, mpts2units(text
-                            .getTextLetterSpaceAdjust()), worddata
-                            .getBytes(encoding));
+            afpDataStream.createText(
+                afpFontAttributes.getFontReference(),
+                mpts2units(rx),
+                mpts2units(bl),
+                col,
+                vsci,
+                mpts2units(text.getTextLetterSpaceAdjust()),
+                worddata.getBytes(encoding));
         } catch (UnsupportedEncodingException usee) {
-            log.error("renderText:: Font " + afpFontAttributes.getFontKey()
-                    + " caused UnsupportedEncodingException");
+            log.error(
+                "renderText:: Font "
+                + afpFontAttributes.getFontKey()
+                + " caused UnsupportedEncodingException");
         }
 
         super.renderText(text);
 
-        renderTextDecoration(font, currentFontSize, text, bl, rx);
+        renderTextDecoration(tf, currentFontSize, text, bl, rx);
     }
 
     /**
@@ -1192,41 +1410,88 @@
     }
 
     /**
-     * Render leader area. This renders a leader area which is an area with a
-     * rule.
-     * 
-     * @param area
-     *            the leader area to render
+     * Render leader area.
+     * This renders a leader area which is an area with a rule.
+     * @param area the leader area to render
      */
     public void renderLeader(Leader area) {
         renderInlineAreaBackAndBorders(area);
 
         int style = area.getRuleStyle();
-        float startx = (currentIPPosition + area
-                .getBorderAndPaddingWidthStart()) / 1000f;
+        float startx = (currentIPPosition + area.getBorderAndPaddingWidthStart()) / 1000f;
         float starty = (currentBPPosition + area.getOffset()) / 1000f;
-        float endx = (currentIPPosition + area.getBorderAndPaddingWidthStart() + area
-                .getIPD()) / 1000f;
+        float endx = (currentIPPosition + area.getBorderAndPaddingWidthStart()
+                        + area.getIPD()) / 1000f;
         float ruleThickness = area.getRuleThickness() / 1000f;
-        Color col = (Color) area.getTrait(Trait.COLOR);
+        Color col = (Color)area.getTrait(Trait.COLOR);
 
         switch (style) {
-        case EN_SOLID:
-        case EN_DASHED:
-        case EN_DOUBLE:
-        case EN_DOTTED:
-        case EN_GROOVE:
-        case EN_RIDGE:
-            drawBorderLine(startx, starty, endx, starty + ruleThickness, true,
-                    true, style, col);
-            break;
-        default:
-            throw new UnsupportedOperationException("rule style not supported");
+            case EN_SOLID:
+            case EN_DASHED:
+            case EN_DOUBLE:
+            case EN_DOTTED:
+            case EN_GROOVE:
+            case EN_RIDGE:
+                drawBorderLine(startx, starty, endx, starty + ruleThickness,
+                        true, true, style, col);
+                break;
+            default:
+                throw new UnsupportedOperationException("rule style not supported");
         }
         super.renderLeader(area);
     }
 
     /**
+     * Sets the AFPRenderer options
+     * @param options   the <code>Map</code> containing the options
+     */
+// UNUSED
+//     public void setOptions(Map options) {
+//    
+//         this.afpOptions = options;
+//    
+//     }
+    /**
+     * Determines the orientation from the string representation, this method
+     * guarantees to return a value of either 0, 90, 180 or 270.
+     *
+     * @return the orientation
+     */
+// UNUSED
+//     private int getOrientation(String orientationString) {
+//
+//        int orientation = 0;
+//        if (orientationString != null && orientationString.length() > 0) {
+//            try {
+//                orientation = Integer.parseInt(orientationString);
+//            } catch (NumberFormatException nfe) {
+//                log.error("Cannot use orientation of " + orientation
+//                        + " defaulting to zero.");
+//                orientation = 0;
+//            }
+//        } else {
+//            orientation = 0;
+//        }
+//        switch (orientation) {
+//        case 0:
+//            break;
+//        case 90:
+//            break;
+//        case 180:
+//            break;
+//        case 270:
+//            break;
+//        default:
+//            log.error("Cannot use orientation of " + orientation
+//                    + " defaulting to zero.");
+//            orientation = 0;
+//            break;
+//        }
+//
+//        return orientation;
+//
+//    }
+    /**
      * Sets the rotation to be used for portrait pages, valid values are 0
      * (default), 90, 180, 270.
      * 
@@ -1235,13 +1500,14 @@
      */
     public void setPortraitRotation(int rotation) {
 
-        if (rotation == 0 || rotation == 90 || rotation == 180
-                || rotation == 270) {
+        if (rotation == 0
+            || rotation == 90
+            || rotation == 180
+            || rotation == 270) {
             portraitRotation = rotation;
         } else {
-            throw new IllegalArgumentException(
-                    "The portrait rotation must be one"
-                            + " of the values 0, 90, 180, 270");
+            throw new IllegalArgumentException("The portrait rotation must be one"
+                + " of the values 0, 90, 180, 270");
 
         }
 
@@ -1250,19 +1516,20 @@
     /**
      * Sets the rotation to be used for landsacpe pages, valid values are 0, 90,
      * 180, 270 (default).
-     * 
+     *  
      * @param rotation
      *            The rotation in degrees.
      */
     public void setLandscapeRotation(int rotation) {
 
-        if (rotation == 0 || rotation == 90 || rotation == 180
-                || rotation == 270) {
+        if (rotation == 0
+            || rotation == 90
+            || rotation == 180
+            || rotation == 270) {
             landscapeRotation = rotation;
         } else {
-            throw new IllegalArgumentException(
-                    "The landscape rotation must be one"
-                            + " of the values 0, 90, 180, 270");
+            throw new IllegalArgumentException("The landscape rotation must be one"
+                + " of the values 0, 90, 180, 270");
         }
 
     }
@@ -1270,7 +1537,7 @@
     /**
      * Get the MIME type of the renderer.
      * 
-     * @return The MIME type of the renderer
+     * @return   The MIME type of the renderer
      */
     public String getMimeType() {
         return MimeConstants.MIME_AFP;
@@ -1280,8 +1547,7 @@
      * Method to render the page extension.
      * <p>
      * 
-     * @param pageViewport
-     *            the page object
+     * @param pageViewport the page object
      */
     private void renderPageObjectExtensions(PageViewport pageViewport) {
 
@@ -1292,7 +1558,7 @@
             // the s-p-m
             Iterator i = pageViewport.getExtensionAttachments().iterator();
             while (i.hasNext()) {
-                ExtensionAttachment attachment = (ExtensionAttachment) i.next();
+                ExtensionAttachment attachment = (ExtensionAttachment)i.next();
                 if (AFPPageSetup.CATEGORY.equals(attachment.getCategory())) {
                     AFPPageSetup aps = (AFPPageSetup) attachment;
                     String element = aps.getElementName();
@@ -1306,7 +1572,7 @@
                         String name = aps.getName();
                         String source = aps.getValue();
                         if (pageSegmentsMap == null) {
-                            pageSegmentsMap = new HashMap();
+                            pageSegmentsMap = new java.util.HashMap();
                         }
                         pageSegmentsMap.put(source, name);
                     } else if (AFPElementMapping.TAG_LOGICAL_ELEMENT
@@ -1314,7 +1580,7 @@
                         String name = aps.getName();
                         String value = aps.getValue();
                         if (pageSegmentsMap == null) {
-                            pageSegmentsMap = new HashMap();
+                            pageSegmentsMap = new java.util.HashMap();
                         }
                         afpDataStream.createTagLogicalElement(name, value);
                     } else if (AFPElementMapping.NO_OPERATION.equals(element)) {
@@ -1322,6 +1588,8 @@
                         if (content != null) {
                             afpDataStream.createNoOperation(content);
                         }
+                    } else if (AFPElementMapping.RESOURCE.equals(element)) {
+                        System.out.println("resource: " + attachment);
                     }
                 }
             }
@@ -1331,9 +1599,7 @@
 
     /**
      * Converts FOP mpt measurement to afp measurement units
-     * 
-     * @param mpt
-     *            the millipoints value
+     * @param mpt the millipoints value
      */
     private int mpts2units(int mpt) {
         return mpts2units((double) mpt);
@@ -1341,9 +1607,7 @@
 
     /**
      * Converts FOP pt measurement to afp measurement units
-     * 
-     * @param mpt
-     *            the millipoints value
+     * @param mpt the millipoints value
      */
     private int pts2units(float mpt) {
         return mpts2units(mpt * 1000d);
@@ -1357,8 +1621,7 @@
      * @return afp measurement unit value
      */
     private int mpts2units(double mpt) {
-        return (int) Math
-                .round(mpt / (DPI_CONVERSION_FACTOR / getResolution()));
+        return (int)Math.round(mpt / (DPI_CONVERSION_FACTOR / getResolution()));
     }
 
     /**
@@ -1422,7 +1685,7 @@
         io.setImageIDESize((byte) bitsPerPixel);
         io.setImageData(bw);
     }
-
+    
     private final class ViewPortPos {
         private int x = 0;
 
@@ -1521,7 +1784,7 @@
 
     }
 
-    private List viewPortPositions = new ArrayList();
+    private List viewPortPositions = new java.util.ArrayList();
 
     private void pushViewPortPos(ViewPortPos vpp) {
         viewPortPositions.add(vpp);
@@ -1531,8 +1794,7 @@
     private void popViewPortPos() {
         viewPortPositions.remove(viewPortPositions.size() - 1);
         if (viewPortPositions.size() > 0) {
-            ViewPortPos vpp = (ViewPortPos) viewPortPositions
-                    .get(viewPortPositions.size() - 1);
+            ViewPortPos vpp = (ViewPortPos)viewPortPositions.get(viewPortPositions.size() - 1);
             afpDataStream.setOffsets(vpp.x, vpp.y, vpp.rot);
         }
     }
@@ -1546,9 +1808,9 @@
     public void setBitsPerPixel(int bitsPerPixel) {
         this.bitsPerPixel = bitsPerPixel;
         switch (bitsPerPixel) {
-        case 1:
-        case 4:
-        case 8:
+            case 1:
+            case 4:
+            case 8:
             break;
         default:
             log.warn("Invalid bits_per_pixel value, must be 1, 4 or 8.");
@@ -1573,6 +1835,9 @@
      * @return the AFPDataStream
      */
     public AFPDataStream getAFPDataStream() {
+        if (afpDataStream == null) {
+            this.afpDataStream = new AFPDataStream();
+        }
         return afpDataStream;
     }
 
@@ -1583,24 +1848,46 @@
      *            the output resolution (dpi)
      */
     public void setResolution(int resolution) {
-        if (resolution == DPI_240_RESOLUTION
-                || resolution == DPI_1440_RESOLUTION) {
-            this.resolution = resolution;
-            if (log.isDebugEnabled()) {
-                log.debug("renderer-resolution set to: " + resolution + " dpi");
-            }
-        } else {
-            log.error("invalid resolution, can only be " + DPI_240_RESOLUTION
-                    + " or " + DPI_1440_RESOLUTION + " dpi");
+        if (log.isDebugEnabled()) {
+            log.debug("renderer-resolution set to: " + resolution + "dpi");
         }
+        this.resolution = resolution;
     }
-
+    
     /**
      * Returns the output/device resolution.
-     * 
      * @return the resolution in dpi
      */
     public int getResolution() {
         return this.resolution;
+    }
+    
+    private AFPState getState() {
+        if (currentState == null) {
+            currentState = new AFPState();
+        }
+        return currentState;
+    }
+
+    private boolean gocaEnabled = false;
+
+    /**
+     * @param enabled true if AFP GOCA is enabled for SVG support
+     */
+    protected void setGOCAEnabled(boolean enabled) {
+        this.gocaEnabled = enabled;
+    }
+
+    /**
+     * @return true of AFP GOCA is enabled for SVG support
+     */
+    protected boolean isGOCAEnabled() {
+        return this.gocaEnabled;
+    }
+    
+    /** {@inheritDoc} */
+    public void startPageSequence(LineArea seqTitle) {
+        afpDataStream.endPageGroup();
+        afpDataStream.startPageGroup();
     }
 }

Modified: xmlgraphics/fop/branches/Temp_AFPGOCAResources/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AFPGOCAResources/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java?rev=641873&r1=641872&r2=641873&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_AFPGOCAResources/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java (original)
+++ xmlgraphics/fop/branches/Temp_AFPGOCAResources/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java Thu Mar 27 09:16:30 2008
@@ -140,18 +140,14 @@
             return new AFPFontInfo(font, tripleList);
 
         } else if ("outline".equalsIgnoreCase(type)) {
-
             String characterset = afpFontCfg.getAttribute("characterset");
             if (characterset == null) {
                 log.error("Mandatory afp-font configuration attribute 'characterset=' is missing");
                 return null;
             }
             String name = afpFontCfg.getAttribute("name", characterset);
-
             CharacterSet characterSet = null;
-
             String base14 = afpFontCfg.getAttribute("base14-font", null);
-
             if (base14 != null) {
                 try {
                     Class clazz = Class.forName("org.apache.fop.fonts.base14."
@@ -205,7 +201,6 @@
                                   + triplet.getWeight());
                     }
                 }
-
                 fontList.add(afi);
             }
         }
@@ -242,6 +237,31 @@
                 afpRenderer.setResolution(rendererResolutionCfg.getValueAsInteger(
                         AFPRenderer.DPI_240_RESOLUTION));
             }
+
+            Configuration gocaSupportCfg = cfg.getChild("goca-enabled", false);
+            if (gocaSupportCfg != null) {
+                afpRenderer.setGOCAEnabled(true);
+            }
+
+//            Configuration resourceGroupsCfg = cfg.getChild("resource-groups", false);
+//            if (resourceGroupsCfg != null) {
+//                resourceGroupsCfg.getValue("print-file-level");
+//            }
+//            if (externalCfg != null) {
+//                Configuration[] resourceGroups = externalCfg.getChildren("resource-groups");
+//                for (int i = 0; i < resourceGroups.length; i++) {
+//                    String resourceresourceGroups[i].getAttribute("url", null);
+//                    Configuration resourceGroup = externalCfg.getChild("resource-group", false);
+//                }
+//            }
+//            Configuration externalResourceGroupCfg = cfg.getChild("external-resource-group", false);
+//            if (externalResourceGroupCfg != null) {
+////                afpRenderer.setExternalResources(true);
+//                String resourceLibraryUrl = externalResourceGroupCfg.getAttribute("url", null);
+//                if (resourceLibraryUrl != null) {
+//                    afpRenderer.setExternalResourceLibraryUrl(resourceLibraryUrl);
+//                }
+//            }
         }
     }
 }

Modified: xmlgraphics/fop/branches/Temp_AFPGOCAResources/src/java/org/apache/fop/render/afp/AFPSVGHandler.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AFPGOCAResources/src/java/org/apache/fop/render/afp/AFPSVGHandler.java?rev=641873&r1=641872&r2=641873&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_AFPGOCAResources/src/java/org/apache/fop/render/afp/AFPSVGHandler.java (original)
+++ xmlgraphics/fop/branches/Temp_AFPGOCAResources/src/java/org/apache/fop/render/afp/AFPSVGHandler.java Thu Mar 27 09:16:30 2008
@@ -22,10 +22,12 @@
 // FOP
 import java.awt.geom.AffineTransform;
 import java.io.IOException;
+import java.util.Map;
 
 import org.apache.avalon.framework.configuration.Configuration;
 import org.apache.batik.bridge.BridgeContext;
 import org.apache.batik.bridge.GVTBuilder;
+import org.apache.batik.dom.AbstractDocument;
 import org.apache.batik.dom.svg.SVGDOMImplementation;
 import org.apache.batik.gvt.GraphicsNode;
 import org.apache.commons.logging.Log;
@@ -33,7 +35,10 @@
 import org.apache.fop.render.AbstractGenericSVGHandler;
 import org.apache.fop.render.Renderer;
 import org.apache.fop.render.RendererContext;
+import org.apache.fop.render.RendererContextConstants;
 import org.apache.fop.render.afp.modca.AFPDataStream;
+import org.apache.fop.render.afp.modca.GraphicsObject;
+import org.apache.fop.render.afp.modca.IncludeObject;
 import org.apache.fop.svg.SVGUserAgent;
 import org.w3c.dom.Document;
 
@@ -65,28 +70,29 @@
      */
     public static AFPInfo getAFPInfo(RendererContext context) {
         AFPInfo afpi = new AFPInfo();
-        afpi.width = ((Integer)context.getProperty(WIDTH)).intValue();
-        afpi.height = ((Integer)context.getProperty(HEIGHT)).intValue();
-        afpi.currentXPosition = ((Integer)context.getProperty(XPOS)).intValue();
-        afpi.currentYPosition = ((Integer)context.getProperty(YPOS)).intValue();
-        afpi.cfg = (Configuration)context.getProperty(HANDLER_CONFIGURATION);
-        afpi.fontInfo = (org.apache.fop.fonts.FontInfo)context.getProperty(
-                AFPRendererContextConstants.AFP_FONT_INFO);
-        afpi.resolution = ((Integer)context.getProperty(
-                AFPRendererContextConstants.AFP_RESOLUTION)).intValue();
-        afpi.afpState = (AFPState)context.getProperty(
-                AFPRendererContextConstants.AFP_STATE);
-        afpi.afpDataStream = (AFPDataStream)context.getProperty(
-                AFPRendererContextConstants.AFP_DATASTREAM);
-        afpi.grayscale = ((Boolean)context.getProperty(
-                AFPRendererContextConstants.AFP_GRAYSCALE)).booleanValue();
-        afpi.bitsPerPixel = ((Integer)context.getProperty(
-                AFPRendererContextConstants.AFP_BITS_PER_PIXEL)).intValue();
+        afpi.setWidth(((Integer)context.getProperty(WIDTH)).intValue());
+        afpi.setHeight(((Integer)context.getProperty(HEIGHT)).intValue());
+        afpi.setX(((Integer)context.getProperty(XPOS)).intValue());
+        afpi.setY(((Integer)context.getProperty(YPOS)).intValue());
+        afpi.setHandlerConfiguration((Configuration)context.getProperty(HANDLER_CONFIGURATION));
+        afpi.setFontInfo((org.apache.fop.fonts.FontInfo)context.getProperty(
+                AFPRendererContextConstants.AFP_FONT_INFO));
+        afpi.setResolution(((Integer)context.getProperty(
+                AFPRendererContextConstants.AFP_RESOLUTION)).intValue());
+        afpi.setState((AFPState)context.getProperty(
+                AFPRendererContextConstants.AFP_STATE));
+        afpi.setAFPDataStream((AFPDataStream)context.getProperty(
+                AFPRendererContextConstants.AFP_DATASTREAM));
+        afpi.setColor(!((Boolean)context.getProperty(
+                AFPRendererContextConstants.AFP_GRAYSCALE)).booleanValue());
+        afpi.setBitsPerPixel(((Integer)context.getProperty(
+                AFPRendererContextConstants.AFP_BITS_PER_PIXEL)).intValue());
         return afpi;
     }
 
     /**
      * Render the SVG document.
+     * 
      * @param context the renderer context
      * @param doc the SVG document
      * @param afpInfo the AFPInfo renderer parameters
@@ -100,14 +106,16 @@
         graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());
         graphics.setAFPInfo(afpInfo);
         
+        String uri = ((AbstractDocument)doc).getDocumentURI();
+        graphics.setDocumentURI(uri);
+        
         GVTBuilder builder = new GVTBuilder();
 
         boolean strokeText = false;
-        Configuration cfg = afpInfo.cfg;
+        Configuration cfg = afpInfo.getHandlerConfiguration();
         if (cfg != null) {
             strokeText = cfg.getChild("stroke-text", true).getValueAsBoolean(strokeText);
         }
-        
         final float uaResolution = context.getUserAgent().getSourceResolution();
         SVGUserAgent svgUserAgent = new SVGUserAgent(25.4f / uaResolution, new AffineTransform());
 
@@ -122,7 +130,7 @@
             AFPTextElementBridge tBridge = new AFPTextElementBridge(textPainter);
             ctx.putBridge(tBridge);
         }
-
+        
         GraphicsNode root;
         try {
             root = builder.build(ctx, doc);
@@ -132,33 +140,59 @@
             return;
         }
         log.debug("Generating SVG at " 
-                + afpInfo.resolution + "dpi.");
+                + afpInfo.getResolution() + "dpi.");
 
-        int res = afpInfo.resolution;
-        
+        int res = afpInfo.getResolution();
         double w = ctx.getDocumentSize().getWidth() * 1000f;
         double h = ctx.getDocumentSize().getHeight() * 1000f;
         
         // convert to afp inches
-        double sx = ((afpInfo.width / w) * res) / 72f;
-        double sy = ((afpInfo.height / h) * res) / 72f;
-        double xOffset = (afpInfo.currentXPosition * res) / 72000f;
-        double yOffset = ((afpInfo.height - afpInfo.currentYPosition) * res) / 72000f;
+        double sx = ((afpInfo.getWidth() / w) * res) / 72f;
+        double sy = ((afpInfo.getHeight() / h) * res) / 72f;
+        double xOffset = (afpInfo.getX() * res) / 72000f;
+        double yOffset = ((afpInfo.getHeight() - afpInfo.getY()) * res) / 72000f;
 
         // Transformation matrix that establishes the local coordinate system for the SVG graphic
         // in relation to the current coordinate system (note: y axis is inverted)
         AffineTransform trans = new AffineTransform(sx, 0, 0, -sy, xOffset, yOffset);
         graphics.setTransform(trans);
+        
+        int x = (int)Math.round((afpInfo.getX() * 25.4f) / 1000);
+        int y = (int)Math.round((afpInfo.getY() * 25.4f) / 1000);
+        int width = (int)Math.round((afpInfo.getWidth() * res) / 72000f);
+        int height = (int)Math.round((afpInfo.getHeight() * res) / 72000f);
+        
+        DataObjectParameters params = new DataObjectParameters(
+                uri, x, y, width, height, res, res);
+        
+        Map/*<QName, String>*/ foreignAttributes
+            = (Map/*<QName, String>*/)context.getProperty(
+                RendererContextConstants.FOREIGN_ATTRIBUTES);
+
+        if (foreignAttributes != null) {
+            params.setResourceLevelFromForeignAttributes(foreignAttributes);
+        }
+
+        IncludeObject includeObj = afpInfo.getAFPDataStream().createGraphicsObject(params);
+        GraphicsObject graphicsObj = (GraphicsObject)includeObj.getReferencedObject();
+        graphics.setGraphicsObject(graphicsObj);
+        
         try {
             root.paint(graphics);
         } catch (Exception e) {
             log.error("SVG graphic could not be rendered: " + e.getMessage(), e);
         }
+        
+        graphics.dispose();
     }
     
     /** {@inheritDoc} */
     public boolean supportsRenderer(Renderer renderer) {
-        return (renderer instanceof AFPRenderer);
+        if (renderer instanceof AFPRenderer) {
+            AFPRenderer afpRenderer = (AFPRenderer)renderer;
+            return afpRenderer.isGOCAEnabled();
+        }
+        return false;
     }
     
     /** {@inheritDoc} */
@@ -166,4 +200,3 @@
         return SVGDOMImplementation.SVG_NAMESPACE_URI;
     }
 }
-

Modified: xmlgraphics/fop/branches/Temp_AFPGOCAResources/src/java/org/apache/fop/render/afp/AFPState.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AFPGOCAResources/src/java/org/apache/fop/render/afp/AFPState.java?rev=641873&r1=641872&r2=641873&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_AFPGOCAResources/src/java/org/apache/fop/render/afp/AFPState.java (original)
+++ xmlgraphics/fop/branches/Temp_AFPGOCAResources/src/java/org/apache/fop/render/afp/AFPState.java Thu Mar 27 09:16:30 2008
@@ -20,51 +20,18 @@
 package org.apache.fop.render.afp;
 
 import java.awt.Color;
+import java.awt.geom.AffineTransform;
+import java.io.Serializable;
 import java.util.Arrays;
+import java.util.List;
 
 /**
  * This keeps information about the current state when writing to pdf.
  */
 public class AFPState {
-    /**
-     * The current color
-     */
-    private Color color = null;
-
-    /**
-     * The current background color
-     */
-    private Color backColor = null;
-
-    /**
-     * The current font name
-     */
-    private String fontName = null;
-
-    /**
-     * The current font size
-     */
-    private int fontSize = 0;
-
-    /**
-     * The current line width
-     */
-    private float lineWidth = 0;
-
-    /**
-     * The dash array for the current basic stroke (line type)
-     */
-    private float[] dashArray = null;
-
-    /**
-     * The current fill status
-     */
-    private boolean filled = false;
+    private Data data = new Data();
     
-    /**
-     * The fonts on the current page
-     */
-    private AFPPageFonts pageFonts = null;
+    private List stateStack = new java.util.ArrayList();
 
     /**
      * Set the current color.
@@ -74,8 +41,8 @@
      * @return true if the color has changed
      */
     protected boolean setColor(Color col) {
-        if (!col.equals(this.color)) {
-            this.color = col;
+        if (!col.equals(getData().color)) {
+            getData().color = col;
             return true;
         }
         return false;
@@ -87,8 +54,8 @@
      * @return true if the fill value has changed
      */
     protected boolean setFill(boolean fill) {
-        if (fill != this.filled) {
-            this.filled = fill;
+        if (fill != getData().filled) {
+            getData().filled = fill;
             return true;
         }
         return false;
@@ -99,10 +66,10 @@
      * @return the color
      */
     protected Color getColor() {
-        if (this.color == null) {
-            this.color = Color.black;
+        if (getData().color == null) {
+            getData().color = Color.black;
         }
-        return this.color;
+        return getData().color;
     }
 
     /**
@@ -111,8 +78,8 @@
      * @return true if the line width has changed
      */
     protected boolean setLineWidth(float width) {
-        if (this.lineWidth != width) {
-            this.lineWidth = width;
+        if (getData().lineWidth != width) {
+            getData().lineWidth = width;
             return true;
         }
         return false;
@@ -124,8 +91,8 @@
      * @return true if the dash array has changed
      */
     public boolean setDashArray(float[] dash) {
-        if (!Arrays.equals(dash, this.dashArray)) {
-            this.dashArray = dash;
+        if (!Arrays.equals(dash, getData().dashArray)) {
+            getData().dashArray = dash;
             return true;
         }
         return false;
@@ -136,7 +103,7 @@
      * @return the current line width
      */
     protected float getLineWidth() {
-        return lineWidth;
+        return getData().lineWidth;
     }
 
     /**
@@ -144,10 +111,10 @@
      * @return the background color
      */
     protected Color getBackColor() {
-        if (this.backColor == null) {
-            this.backColor = Color.white;
+        if (getData().backColor == null) {
+            getData().backColor = Color.white;
         }
-        return backColor;
+        return getData().backColor;
     }
 
     /**
@@ -158,8 +125,8 @@
      * @return true if the color has changed
      */
     protected boolean setBackColor(Color col) {
-        if (!col.equals(this.backColor)) {
-            this.backColor = col;
+        if (!col.equals(getData().backColor)) {
+            getData().backColor = col;
             return true;
         }
         return false;
@@ -171,8 +138,8 @@
      * @return true if the font name has changed
      */
     protected boolean setFontName(String internalFontName) {
-        if (!internalFontName.equals(this.fontName)) {
-            this.fontName = internalFontName;
+        if (!internalFontName.equals(getData().fontName)) {
+            getData().fontName = internalFontName;
             return true;
         }
         return false;
@@ -183,7 +150,7 @@
      * @return the current font name
      */
     protected String getFontName() {
-        return this.fontName;
+        return getData().fontName;
     }
     
     /**
@@ -191,7 +158,7 @@
      * @return the current font size
      */
     protected int getFontSize() {
-        return this.fontSize;
+        return getData().fontSize;
     }
 
     /**
@@ -202,8 +169,8 @@
      * @return true if the font size has changed
      */
     protected boolean setFontSize(int size) {
-        if (size != this.fontSize) {
-            this.fontSize = size;
+        if (size != getData().fontSize) {
+            getData().fontSize = size;
             return true;
         }
         return false;
@@ -214,25 +181,98 @@
      * @return the current page fonts
      */
     protected AFPPageFonts getPageFonts() {
-        if (this.pageFonts == null) {
-            this.pageFonts = new AFPPageFonts();
+        if (getData().pageFonts == null) {
+            getData().pageFonts = new AFPPageFonts();
         }
-        return this.pageFonts;
+        return getData().pageFonts;
     }
 
     /**
-     * Resets the current state
-     */    
-    protected void reset() {
-        this.color = null;
-        this.backColor = null;
-        this.fontName = null;         
-        this.fontSize = 0;         
-        this.lineWidth = 0;
-        this.dashArray = null;
-        this.filled = false;
-        if (this.pageFonts != null) {
-            this.pageFonts.clear();
+     * Push the current state onto the stack.
+     * This call should be used when the q operator is used
+     * so that the state is known when popped.
+     */
+    public void push() {
+        Data copy;
+        try {
+            copy = (Data)getData().clone();
+        } catch (CloneNotSupportedException e) {
+            throw new RuntimeException(e.getMessage());
+        }
+        stateStack.add(copy);
+    }
+
+    /**
+     * Get the current stack level.
+     *
+     * @return the current stack level
+     */
+    public int getStackLevel() {
+        return stateStack.size();
+    }
+
+    /**
+     * Pop the state from the stack and set current values to popped state.
+     * This should be called when a Q operator is used so
+     * the state is restored to the correct values.
+     * @return the restored state, null if the stack is empty
+     */
+    public Data pop() {
+        if (getStackLevel() > 0) {
+            Data popped = (Data)stateStack.remove(stateStack.size() - 1);
+            data = popped;
+            return popped;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * @return the currently valid state
+     */
+    public Data getData() {
+        return data;
+    }
+    
+    public class Data implements Cloneable, Serializable {
+        private static final long serialVersionUID = -1789481244175275686L;
+
+        /** The current color */
+        private Color color = null;
+
+        /** The current background color */
+        private Color backColor = null;
+
+        /** The current font name */
+        private String fontName = null;
+
+        /** The current font size */
+        private int fontSize = 0;
+
+        /** The current line width */
+        private float lineWidth = 0;
+
+        /** The dash array for the current basic stroke (line type) */
+        private float[] dashArray = null;
+
+        /** The current fill status */
+        private boolean filled = false;
+        
+        /** The fonts on the current page */
+        private AFPPageFonts pageFonts = null;
+
+        /** {@inheritDoc} */
+        public Object clone() throws CloneNotSupportedException {
+            Data obj = new Data();
+            obj.color = this.color;
+            obj.backColor = this.backColor;
+            obj.fontName = this.fontName;
+            obj.fontSize = this.fontSize;
+            obj.lineWidth = this.lineWidth;
+            obj.dashArray = this.dashArray;
+            obj.filled = this.filled;
+            obj.pageFonts = this.pageFonts;
+            return obj;
         }
     }
 }



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