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 2005/08/21 15:37:19 UTC

svn commit: r234201 [1/2] - in /xmlgraphics/fop/trunk/src/java/org/apache/fop/render: ./ pdf/ ps/

Author: jeremias
Date: Sun Aug 21 06:36:53 2005
New Revision: 234201

URL: http://svn.apache.org/viewcvs?rev=234201&view=rev
Log:
A big step towards a usable PostScript renderer.
Some code that can be used by both PS and PDF renderers factored out into a common base class (AbstractPathOrientedRenderer).
Coordinate system of PS renderer and PSGraphics2D changed to be based on points rather than millipoints to be the same as the PDFRenderer. This improves the chance to reuse code.
PSGenerator set to PostScript level 2 now, should later be configurable. There may still be some PS commands which should be changed from Level 2 to Level 1, just to be able to support Level 1 later should anyone ask for it.
Bitmap, EPS and SVG support should be mostly restored now.
PSState was extended to provide the same break-out mechanism for fixed b-cs. And it has better support for tracking the graphics state.
Added some FOP-specific comments to certain constructs for people who want to post-process the PS output.
BatchDiffer shows very few visual differences now on the layout engine test cases between PDF and PS.

Added:
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java   (with props)
Modified:
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/PrintRenderer.java   (contents, props changed)
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderer.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/AbstractPSDocumentGraphics2D.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSGenerator.java   (contents, props changed)
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSGraphics2D.java   (contents, props changed)
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSImageUtils.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSRenderer.java   (contents, props changed)
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSState.java   (contents, props changed)
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSXMLHandler.java   (contents, props changed)

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java?rev=234201&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java Sun Aug 21 06:36:53 2005
@@ -0,0 +1,628 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render;
+
+import java.awt.Color;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.fop.area.Area;
+import org.apache.fop.area.Block;
+import org.apache.fop.area.BlockViewport;
+import org.apache.fop.area.CTM;
+import org.apache.fop.area.RegionViewport;
+import org.apache.fop.area.Trait;
+import org.apache.fop.area.inline.Viewport;
+import org.apache.fop.datatypes.ColorType;
+import org.apache.fop.image.FopImage;
+import org.apache.fop.pdf.PDFState;
+import org.apache.fop.render.pdf.CTMHelper;
+import org.apache.fop.traits.BorderProps;
+
+/**
+ * Abstract base class for renderers like PDF and PostScript where many painting operations
+ * follow similar patterns which makes it possible to share some code.
+ */
+public abstract class AbstractPathOrientedRenderer extends PrintRenderer {
+
+    /**
+     * Converts a ColorType to a java.awt.Color (sRGB).
+     * @param col the color
+     * @return the converted color
+     */
+    protected Color toColor(ColorType col) {
+        return new Color(col.getRed(), col.getGreen(), col.getBlue());
+    }
+    
+    /**
+     * Handle block traits.
+     * The block could be any sort of block with any positioning
+     * so this should render the traits such as border and background
+     * in its position.
+     *
+     * @param block the block to render the traits
+     */
+    protected void handleBlockTraits(Block block) {
+        int borderPaddingStart = block.getBorderAndPaddingWidthStart();
+        int borderPaddingBefore = block.getBorderAndPaddingWidthBefore();
+        
+        float startx = currentIPPosition / 1000f;
+        float starty = currentBPPosition / 1000f;
+        float width = block.getIPD() / 1000f;
+        float height = block.getBPD() / 1000f;
+
+        /* using start-indent now
+        Integer spaceStart = (Integer) block.getTrait(Trait.SPACE_START);
+        if (spaceStart != null) {
+            startx += spaceStart.floatValue() / 1000f;
+        }*/
+        startx += block.getStartIndent() / 1000f;
+        startx -= block.getBorderAndPaddingWidthStart() / 1000f;
+
+        width += borderPaddingStart / 1000f;
+        width += block.getBorderAndPaddingWidthEnd() / 1000f;
+        height += borderPaddingBefore / 1000f;
+        height += block.getBorderAndPaddingWidthAfter() / 1000f;
+
+        drawBackAndBorders(block, startx, starty,
+            width, height);
+    }
+
+    /**
+     * Handle the traits for a region
+     * This is used to draw the traits for the given page region.
+     * (See Sect. 6.4.1.2 of XSL-FO spec.)
+     * @param region the RegionViewport whose region is to be drawn
+     */
+    protected void handleRegionTraits(RegionViewport region) {
+        Rectangle2D viewArea = region.getViewArea();
+        float startx = (float)(viewArea.getX() / 1000f);
+        float starty = (float)(viewArea.getY() / 1000f);
+        float width = (float)(viewArea.getWidth() / 1000f);
+        float height = (float)(viewArea.getHeight() / 1000f);
+
+        if (region.getRegionReference().getRegionClass() == FO_REGION_BODY) {
+            currentBPPosition = region.getBorderAndPaddingWidthBefore();
+            currentIPPosition = region.getBorderAndPaddingWidthStart();
+        }
+        drawBackAndBorders(region, startx, starty, width, height);
+    }
+
+    
+    /**
+     * Draw the background and borders.
+     * This draws the background and border traits for an area given
+     * the position.
+     *
+     * @param area the area to get the traits from
+     * @param startx the start x position
+     * @param starty the start y position
+     * @param width the width of the area
+     * @param height the height of the area
+     */
+    protected void drawBackAndBorders(Area area,
+                    float startx, float starty,
+                    float width, float height) {
+        // draw background then border
+
+        BorderProps bpsBefore = (BorderProps)area.getTrait(Trait.BORDER_BEFORE);
+        BorderProps bpsAfter = (BorderProps)area.getTrait(Trait.BORDER_AFTER);
+        BorderProps bpsStart = (BorderProps)area.getTrait(Trait.BORDER_START);
+        BorderProps bpsEnd = (BorderProps)area.getTrait(Trait.BORDER_END);
+
+        Trait.Background back;
+        back = (Trait.Background)area.getTrait(Trait.BACKGROUND);
+        if (back != null) {
+            endTextObject();
+
+            //Calculate padding rectangle
+            float sx = startx;
+            float sy = starty;
+            float paddRectWidth = width;
+            float paddRectHeight = height;
+            if (bpsStart != null) {
+                sx += bpsStart.width / 1000f;
+                paddRectWidth -= bpsStart.width / 1000f;
+            }
+            if (bpsBefore != null) {
+                sy += bpsBefore.width / 1000f;
+                paddRectHeight -= bpsBefore.width / 1000f;
+            }
+            if (bpsEnd != null) {
+                paddRectWidth -= bpsEnd.width / 1000f;
+            }
+            if (bpsAfter != null) {
+                paddRectHeight -= bpsAfter.width / 1000f;
+            }
+
+            if (back.getColor() != null) {
+                updateColor(back.getColor(), true);
+                fillRect(sx, sy, paddRectWidth, paddRectHeight);
+            }
+            if (back.getFopImage() != null) {
+                FopImage fopimage = back.getFopImage();
+                if (fopimage != null && fopimage.load(FopImage.DIMENSIONS)) {
+                    saveGraphicsState();
+                    clipRect(sx, sy, paddRectWidth, paddRectHeight);
+                    int horzCount = (int)((paddRectWidth 
+                            * 1000 / fopimage.getIntrinsicWidth()) + 1.0f); 
+                    int vertCount = (int)((paddRectHeight 
+                            * 1000 / fopimage.getIntrinsicHeight()) + 1.0f); 
+                    if (back.getRepeat() == EN_NOREPEAT) {
+                        horzCount = 1;
+                        vertCount = 1;
+                    } else if (back.getRepeat() == EN_REPEATX) {
+                        vertCount = 1;
+                    } else if (back.getRepeat() == EN_REPEATY) {
+                        horzCount = 1;
+                    }
+                    //change from points to millipoints
+                    sx *= 1000;
+                    sy *= 1000;
+                    if (horzCount == 1) {
+                        sx += back.getHoriz();
+                    }
+                    if (vertCount == 1) {
+                        sy += back.getVertical();
+                    }
+                    for (int x = 0; x < horzCount; x++) {
+                        for (int y = 0; y < vertCount; y++) {
+                            // place once
+                            Rectangle2D pos;
+                            pos = new Rectangle2D.Float(sx + (x * fopimage.getIntrinsicWidth()),
+                                                        sy + (y * fopimage.getIntrinsicHeight()),
+                                                        fopimage.getIntrinsicWidth(),
+                                                        fopimage.getIntrinsicHeight());
+                            drawImage(back.getURL(), pos);
+                        }
+                    }
+                    
+                    restoreGraphicsState();
+                } else {
+                    log.warn("Can't find background image: " + back.getURL());
+                }
+            }
+        }
+
+        boolean[] b = new boolean[] {
+            (bpsBefore != null), (bpsEnd != null), 
+            (bpsAfter != null), (bpsStart != null)};
+        if (!b[0] && !b[1] && !b[2] && !b[3]) {
+            return;
+        }
+        float[] bw = new float[] {
+            (b[0] ? bpsBefore.width / 1000f : 0.0f),
+            (b[1] ? bpsEnd.width / 1000f : 0.0f),
+            (b[2] ? bpsAfter.width / 1000f : 0.0f),
+            (b[3] ? bpsStart.width / 1000f : 0.0f)};
+        float[] clipw = new float[] {
+            BorderProps.getClippedWidth(bpsBefore) / 1000f,    
+            BorderProps.getClippedWidth(bpsEnd) / 1000f,    
+            BorderProps.getClippedWidth(bpsAfter) / 1000f,    
+            BorderProps.getClippedWidth(bpsStart) / 1000f};
+        starty += clipw[0];
+        height -= clipw[0];
+        height -= clipw[2];
+        startx += clipw[3];
+        width -= clipw[3];
+        width -= clipw[1];
+        
+        boolean[] slant = new boolean[] {
+            (b[3] && b[0]), (b[0] && b[1]), (b[1] && b[2]), (b[2] && b[3])};
+        if (bpsBefore != null) {
+            endTextObject();
+
+            float sx1 = startx;
+            float sx2 = (slant[0] ? sx1 + bw[3] - clipw[3] : sx1);
+            float ex1 = startx + width;
+            float ex2 = (slant[1] ? ex1 - bw[1] + clipw[1] : ex1);
+            float outery = starty - clipw[0];
+            float clipy = outery + clipw[0];
+            float innery = outery + bw[0];
+
+            saveGraphicsState();
+            moveTo(sx1, clipy);
+            float sx1a = sx1;
+            float ex1a = ex1;
+            if (bpsBefore.mode == BorderProps.COLLAPSE_OUTER) {
+                if (bpsStart != null && bpsStart.mode == BorderProps.COLLAPSE_OUTER) {
+                    sx1a -= clipw[3];
+                }
+                if (bpsEnd != null && bpsEnd.mode == BorderProps.COLLAPSE_OUTER) {
+                    ex1a += clipw[1];
+                }
+                lineTo(sx1a, outery);
+                lineTo(ex1a, outery);
+            }
+            lineTo(ex1, clipy);
+            lineTo(ex2, innery);
+            lineTo(sx2, innery);
+            closePath();
+            clip();
+            drawBorderLine(sx1a, outery, ex1a, innery, true, true, 
+                    bpsBefore.style, bpsBefore.color);
+            restoreGraphicsState();
+        }
+        if (bpsEnd != null) {
+            endTextObject();
+
+            float sy1 = starty;
+            float sy2 = (slant[1] ? sy1 + bw[0] - clipw[0] : sy1);
+            float ey1 = starty + height;
+            float ey2 = (slant[2] ? ey1 - bw[2] + clipw[2] : ey1);
+            float outerx = startx + width + clipw[1];
+            float clipx = outerx - clipw[1];
+            float innerx = outerx - bw[1];
+            
+            saveGraphicsState();
+            moveTo(clipx, sy1);
+            float sy1a = sy1;
+            float ey1a = ey1;
+            if (bpsEnd.mode == BorderProps.COLLAPSE_OUTER) {
+                if (bpsBefore != null && bpsBefore.mode == BorderProps.COLLAPSE_OUTER) {
+                    sy1a -= clipw[0];
+                }
+                if (bpsAfter != null && bpsAfter.mode == BorderProps.COLLAPSE_OUTER) {
+                    ey1a += clipw[2];
+                }
+                lineTo(outerx, sy1a);
+                lineTo(outerx, ey1a);
+            }
+            lineTo(clipx, ey1);
+            lineTo(innerx, ey2);
+            lineTo(innerx, sy2);
+            closePath();
+            clip();
+            drawBorderLine(innerx, sy1a, outerx, ey1a, false, false, bpsEnd.style, bpsEnd.color);
+            restoreGraphicsState();
+        }
+        if (bpsAfter != null) {
+            endTextObject();
+
+            float sx1 = startx;
+            float sx2 = (slant[3] ? sx1 + bw[3] - clipw[3] : sx1);
+            float ex1 = startx + width;
+            float ex2 = (slant[2] ? ex1 - bw[1] + clipw[1] : ex1);
+            float outery = starty + height + clipw[2];
+            float clipy = outery - clipw[2];
+            float innery = outery - bw[2];
+
+            saveGraphicsState();
+            moveTo(ex1, clipy);
+            float sx1a = sx1;
+            float ex1a = ex1;
+            if (bpsAfter.mode == BorderProps.COLLAPSE_OUTER) {
+                if (bpsStart != null && bpsStart.mode == BorderProps.COLLAPSE_OUTER) {
+                    sx1a -= clipw[3];
+                }
+                if (bpsEnd != null && bpsEnd.mode == BorderProps.COLLAPSE_OUTER) {
+                    ex1a += clipw[1];
+                }
+                lineTo(ex1a, outery);
+                lineTo(sx1a, outery);
+            }
+            lineTo(sx1, clipy);
+            lineTo(sx2, innery);
+            lineTo(ex2, innery);
+            closePath();
+            clip();
+            drawBorderLine(sx1a, innery, ex1a, outery, true, false, bpsAfter.style, bpsAfter.color);
+            restoreGraphicsState();
+        }
+        if (bpsStart != null) {
+            endTextObject();
+
+            float sy1 = starty;
+            float sy2 = (slant[0] ? sy1 + bw[0] - clipw[0] : sy1);
+            float ey1 = sy1 + height;
+            float ey2 = (slant[3] ? ey1 - bw[2] + clipw[2] : ey1);
+            float outerx = startx - clipw[3];
+            float clipx = outerx + clipw[3];
+            float innerx = outerx + bw[3];
+
+            saveGraphicsState();
+            moveTo(clipx, ey1);
+            float sy1a = sy1;
+            float ey1a = ey1;
+            if (bpsStart.mode == BorderProps.COLLAPSE_OUTER) {
+                if (bpsBefore != null && bpsBefore.mode == BorderProps.COLLAPSE_OUTER) {
+                    sy1a -= clipw[0];
+                }
+                if (bpsAfter != null && bpsAfter.mode == BorderProps.COLLAPSE_OUTER) {
+                    ey1a += clipw[2];
+                }
+                lineTo(outerx, ey1a);
+                lineTo(outerx, sy1a);
+            }
+            lineTo(clipx, sy1);
+            lineTo(innerx, sy2);
+            lineTo(innerx, ey2);
+            closePath();
+            clip();
+            drawBorderLine(outerx, sy1a, innerx, ey1a, false, true, bpsStart.style, bpsStart.color);
+            restoreGraphicsState();
+        }
+    }
+    
+    /**
+     * @see org.apache.fop.render.AbstractRenderer#renderBlockViewport(BlockViewport, List)
+     */
+    protected void renderBlockViewport(BlockViewport bv, List children) {
+        // clip and position viewport if necessary
+
+        // 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;
+
+        if (bv.getPositioning() == Block.ABSOLUTE
+                || bv.getPositioning() == Block.FIXED) {
+
+            //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);
+
+            //This is the content-rect
+            float width = (float)bv.getIPD() / 1000f;
+            float height = (float)bv.getBPD() / 1000f;
+            
+            //Adjust for spaces (from margin or indirectly by start-indent etc.
+            Integer spaceStart = (Integer) bv.getTrait(Trait.SPACE_START);
+            if (spaceStart != null) {
+                x += spaceStart.floatValue() / 1000;
+            }
+            Integer spaceBefore = (Integer) bv.getTrait(Trait.SPACE_BEFORE);
+            if (spaceBefore != null) {
+                y += spaceBefore.floatValue() / 1000;
+            }
+
+            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
+            x += borderPaddingStart / 1000f;
+            y += borderPaddingBefore / 1000f;
+            
+            if (bv.getClip()) {
+                saveGraphicsState();
+                clipRect(x, y, width, height);
+            }
+
+            startVParea(ctm);
+
+            currentIPPosition = 0;
+            currentBPPosition = 0;
+
+            renderBlocks(bv, children);
+            endVParea();
+
+            if (bv.getClip()) {
+                restoreGraphicsState();
+            }
+
+            // clip if necessary
+
+            if (breakOutList != null) {
+                restoreStateStackAfterBreakOut(breakOutList);
+            }
+            
+            currentIPPosition = saveIP;
+            currentBPPosition = saveBP;
+        } else {
+
+            Integer spaceBefore = (Integer)bv.getTrait(Trait.SPACE_BEFORE);
+            if (spaceBefore != null) {
+                currentBPPosition += spaceBefore.intValue();
+            }
+
+            //borders and background in the old coordinate system
+            handleBlockTraits(bv);
+
+            CTM tempctm = new CTM(containingIPPosition, currentBPPosition);
+            ctm = tempctm.multiply(ctm);
+            
+            //Now adjust for border/padding
+            x += borderPaddingStart / 1000f;
+            y += borderPaddingBefore / 1000f;
+
+            // clip if necessary
+            if (bv.getClip()) {
+                saveGraphicsState();
+                float width = (float)bv.getIPD() / 1000f;
+                float height = (float)bv.getBPD() / 1000f;
+                clipRect(x, y, width, height);
+            }
+
+            if (ctm != null) {
+                startVParea(ctm);
+                currentIPPosition = 0;
+                currentBPPosition = 0;
+            }
+            renderBlocks(bv, children);
+            if (ctm != null) {
+                endVParea();
+            }
+
+            if (bv.getClip()) {
+                restoreGraphicsState();
+            }
+
+            currentIPPosition = saveIP;
+            currentBPPosition = saveBP;
+            
+            //Adjust BP position (alloc BPD + spaces)
+            if (spaceBefore != null) {
+                currentBPPosition += spaceBefore.intValue();
+            }
+            currentBPPosition += (int)(bv.getAllocBPD());
+            Integer spaceAfter = (Integer)bv.getTrait(Trait.SPACE_AFTER);
+            if (spaceAfter != null) {
+                currentBPPosition += spaceAfter.intValue();
+            }
+        }
+        //currentFontName = saveFontName;
+    }
+
+    /**
+     * Render an inline viewport.
+     * This renders an inline viewport by clipping if necessary.
+     * @param viewport the viewport to handle
+     */
+    public void renderViewport(Viewport viewport) {
+
+        float x = currentIPPosition / 1000f;
+        float y = (currentBPPosition + viewport.getOffset()) / 1000f;
+        float width = viewport.getIPD() / 1000f;
+        float height = viewport.getBPD() / 1000f;
+        // TODO: Calculate the border rect correctly. 
+        float borderPaddingStart = viewport.getBorderAndPaddingWidthStart() / 1000f;
+        float borderPaddingBefore = viewport.getBorderAndPaddingWidthBefore() / 1000f;
+        float bpwidth = borderPaddingStart 
+                + (viewport.getBorderAndPaddingWidthEnd() / 1000f);
+        float bpheight = borderPaddingBefore
+                + (viewport.getBorderAndPaddingWidthAfter() / 1000f);
+
+        drawBackAndBorders(viewport, x, y, width + bpwidth, height + bpheight);
+
+        if (viewport.getClip()) {
+            saveGraphicsState();
+
+            clipRect(x + borderPaddingStart, y + borderPaddingBefore, width, height);
+        }
+        super.renderViewport(viewport);
+
+        if (viewport.getClip()) {
+            restoreGraphicsState();
+        }
+    }
+
+    /**
+     * Restores the state stack after a break out.
+     * @param breakOutList the state stack to restore.
+     */
+    protected abstract void restoreStateStackAfterBreakOut(List breakOutList);
+    
+    /**
+     * Breaks out of the state stack to handle fixed block-containers.
+     * @return the saved state stack to recreate later
+     */
+    protected abstract List breakOutOfStateStack();
+
+    /** Saves the graphics state of the rendering engine. */
+    protected abstract void saveGraphicsState();
+    
+    /** Restores the last graphics state of the rendering engine. */
+    protected abstract void restoreGraphicsState();
+
+    /** Indicates the beginning of a text object. */
+    protected abstract void beginTextObject();
+    
+    /** Indicates the end of a text object. */
+    protected abstract void endTextObject();
+    
+    /** Clip using the current path. */
+    protected abstract void clip();
+        
+    /**
+     * Clip using a rectangular area.
+     * @param x the x coordinate
+     * @param y the y coordinate
+     * @param width the width of the rectangle
+     * @param height the height of the rectangle
+     */
+    protected abstract void clipRect(float x, float y, float width, float height);
+    
+    /**
+     * Moves the current point to (x, y), omitting any connecting line segment. 
+     * @param x x coordinate
+     * @param y y coordinate
+     */
+    protected abstract void moveTo(float x, float y);
+    
+    /**
+     * Appends a straight line segment from the current point to (x, y). The 
+     * new current point is (x, y). 
+     * @param x x coordinate
+     * @param y y coordinate
+     */
+    protected abstract void lineTo(float x, float y);
+    
+    /**
+     * Closes the current subpath by appending a straight line segment from 
+     * the current point to the starting point of the subpath.
+     */
+    protected abstract void closePath();
+    
+    /**
+     * Fill a rectangular area.
+     * @param x the x coordinate
+     * @param y the y coordinate
+     * @param width the width of the rectangle
+     * @param height the height of the rectangle
+     */
+    protected abstract void fillRect(float x, float y, float width, float height);
+
+    /**
+     * Establishes a new foreground or fill color.
+     * @param col the color to apply (null skips this operation)
+     * @param fill true to set the fill color, false for the foreground color
+     */
+    protected abstract void updateColor(ColorType col, boolean fill);
+    
+    /**
+     * Draw an image at the indicated location.
+     * @param url the URI/URL of the image
+     * @param pos the position of the image
+     */
+    protected abstract void drawImage(String url, Rectangle2D pos);
+    
+    /**
+     * Draw a border segment of an XSL-FO style border.
+     * @param x1 starting x coordinate
+     * @param y1 starting y coordinate
+     * @param x2 ending x coordinate
+     * @param y2 ending y coordinate
+     * @param horz true for horizontal border segments, false for vertical border segments
+     * @param startOrBefore true for border segments on the start or before edge, 
+     *                      false for end or after.
+     * @param style the border style (one of Constants.EN_DASHED etc.)
+     * @param col the color for the border segment
+     */
+    protected abstract void drawBorderLine(float x1, float y1, float x2, float y2, 
+            boolean horz, boolean startOrBefore, int style, ColorType col);
+    
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/PrintRenderer.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/PrintRenderer.java?rev=234201&r1=234200&r2=234201&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/PrintRenderer.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/PrintRenderer.java Sun Aug 21 06:36:53 2005
@@ -19,10 +19,16 @@
 package org.apache.fop.render;
 
 // FOP
+import org.apache.fop.area.Area;
+import org.apache.fop.area.Trait;
 import org.apache.fop.fonts.FontInfo;
 import org.apache.fop.fonts.FontSetup;
+import org.apache.fop.image.FopImage;
+import org.apache.fop.traits.BorderProps;
 
 // Java
+import java.awt.Color;
+import java.awt.geom.Rectangle2D;
 import java.util.List;
 
 /** Abstract base class of "Print" type renderers.  */
@@ -42,6 +48,27 @@
     public void setupFontInfo(FontInfo inFontInfo) {
         this.fontInfo = inFontInfo;
         FontSetup.setup(fontInfo, fontList);
+    }
+
+    /**
+     * Lightens up a color for groove, ridge, inset and outset border effects.
+     * @param col the color to lighten up
+     * @param factor factor by which to lighten up (negative values darken the color)
+     * @return the modified color
+     */
+    protected Color lightenColor(Color col, float factor) {
+        float[] cols = new float[3];
+        cols = col.getColorComponents(cols);
+        if (factor > 0) {
+            cols[0] += (1.0 - cols[0]) * factor;
+            cols[1] += (1.0 - cols[1]) * factor;
+            cols[2] += (1.0 - cols[2]) * factor;
+        } else {
+            cols[0] -= cols[0] * -factor;
+            cols[1] -= cols[1] * -factor;
+            cols[2] -= cols[2] * -factor;
+        }
+        return new Color(cols[0], cols[1], cols[2]);
     }
 
 }

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/PrintRenderer.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderer.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderer.java?rev=234201&r1=234200&r2=234201&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderer.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderer.java Sun Aug 21 06:36:53 2005
@@ -81,6 +81,7 @@
 import org.apache.fop.pdf.PDFStream;
 import org.apache.fop.pdf.PDFText;
 import org.apache.fop.pdf.PDFXObject;
+import org.apache.fop.render.AbstractPathOrientedRenderer;
 import org.apache.fop.render.PrintRenderer;
 import org.apache.fop.render.RendererContext;
 import org.apache.fop.traits.BorderProps;
@@ -103,7 +104,7 @@
  * Renderer that renders areas to PDF
  *
  */
-public class PDFRenderer extends PrintRenderer {
+public class PDFRenderer extends AbstractPathOrientedRenderer {
     
     /**
      * The mime type for pdf
@@ -514,326 +515,11 @@
      */
     protected void handleRegionTraits(RegionViewport region) {
         currentFontName = "";
-        Rectangle2D viewArea = region.getViewArea();
-        float startx = (float)(viewArea.getX() / 1000f);
-        float starty = (float)(viewArea.getY() / 1000f);
-        float width = (float)(viewArea.getWidth() / 1000f);
-        float height = (float)(viewArea.getHeight() / 1000f);
-
-        if (region.getRegionReference().getRegionClass() == FO_REGION_BODY) {
-            currentBPPosition = region.getBorderAndPaddingWidthBefore();
-            currentIPPosition = region.getBorderAndPaddingWidthStart();
-        }
-        drawBackAndBorders(region, startx, starty, width, height);
-    }
-
-    /**
-     * Handle block traits.
-     * The block could be any sort of block with any positioning
-     * so this should render the traits such as border and background
-     * in its position.
-     *
-     * @param block the block to render the traits
-     */
-    protected void handleBlockTraits(Block block) {
-        int borderPaddingStart = block.getBorderAndPaddingWidthStart();
-        int borderPaddingBefore = block.getBorderAndPaddingWidthBefore();
-        
-        float startx = currentIPPosition / 1000f;
-        float starty = currentBPPosition / 1000f;
-        float width = block.getIPD() / 1000f;
-        float height = block.getBPD() / 1000f;
-
-        /* using start-indent now
-        Integer spaceStart = (Integer) block.getTrait(Trait.SPACE_START);
-        if (spaceStart != null) {
-            startx += spaceStart.floatValue() / 1000f;
-        }*/
-        startx += block.getStartIndent() / 1000f;
-        startx -= block.getBorderAndPaddingWidthStart() / 1000f;
-
-        width += borderPaddingStart / 1000f;
-        width += block.getBorderAndPaddingWidthEnd() / 1000f;
-        height += borderPaddingBefore / 1000f;
-        height += block.getBorderAndPaddingWidthAfter() / 1000f;
-
-        drawBackAndBorders(block, startx, starty,
-            width, height);
+        super.handleRegionTraits(region);
     }
 
-    /**
-     * Draw the background and borders.
-     * This draws the background and border traits for an area given
-     * the position.
-     *
-     * @param area the area to get the traits from
-     * @param startx the start x position
-     * @param starty the start y position
-     * @param width the width of the area
-     * @param height the height of the area
-     */
-    protected void drawBackAndBorders(Area area,
-                    float startx, float starty,
-                    float width, float height) {
-        // draw background then border
-
-        BorderProps bpsBefore = (BorderProps)area.getTrait(Trait.BORDER_BEFORE);
-        BorderProps bpsAfter = (BorderProps)area.getTrait(Trait.BORDER_AFTER);
-        BorderProps bpsStart = (BorderProps)area.getTrait(Trait.BORDER_START);
-        BorderProps bpsEnd = (BorderProps)area.getTrait(Trait.BORDER_END);
-
-        Trait.Background back;
-        back = (Trait.Background)area.getTrait(Trait.BACKGROUND);
-        if (back != null) {
-            endTextObject();
-
-            //Calculate padding rectangle
-            float sx = startx;
-            float sy = starty;
-            float paddRectWidth = width;
-            float paddRectHeight = height;
-            if (bpsStart != null) {
-                sx += bpsStart.width / 1000f;
-                paddRectWidth -= bpsStart.width / 1000f;
-            }
-            if (bpsBefore != null) {
-                sy += bpsBefore.width / 1000f;
-                paddRectHeight -= bpsBefore.width / 1000f;
-            }
-            if (bpsEnd != null) {
-                paddRectWidth -= bpsEnd.width / 1000f;
-            }
-            if (bpsAfter != null) {
-                paddRectHeight -= bpsAfter.width / 1000f;
-            }
-
-            if (back.getColor() != null) {
-                updateColor(back.getColor(), true, null);
-                currentStream.add(sx + " " + sy + " "
-                                  + paddRectWidth + " " + paddRectHeight + " re\n");
-                currentStream.add("f\n");
-            }
-            if (back.getFopImage() != null) {
-                FopImage fopimage = back.getFopImage();
-                if (fopimage != null && fopimage.load(FopImage.DIMENSIONS)) {
-                    saveGraphicsState();
-                    clip(sx, sy, paddRectWidth, paddRectHeight);
-                    int horzCount = (int)((paddRectWidth 
-                            * 1000 / fopimage.getIntrinsicWidth()) + 1.0f); 
-                    int vertCount = (int)((paddRectHeight 
-                            * 1000 / fopimage.getIntrinsicHeight()) + 1.0f); 
-                    if (back.getRepeat() == EN_NOREPEAT) {
-                        horzCount = 1;
-                        vertCount = 1;
-                    } else if (back.getRepeat() == EN_REPEATX) {
-                        vertCount = 1;
-                    } else if (back.getRepeat() == EN_REPEATY) {
-                        horzCount = 1;
-                    }
-                    //change from points to millipoints
-                    sx *= 1000;
-                    sy *= 1000;
-                    if (horzCount == 1) {
-                        sx += back.getHoriz();
-                    }
-                    if (vertCount == 1) {
-                        sy += back.getVertical();
-                    }
-                    for (int x = 0; x < horzCount; x++) {
-                        for (int y = 0; y < vertCount; y++) {
-                            // place once
-                            Rectangle2D pos;
-                            pos = new Rectangle2D.Float(sx + (x * fopimage.getIntrinsicWidth()),
-                                                        sy + (y * fopimage.getIntrinsicHeight()),
-                                                        fopimage.getIntrinsicWidth(),
-                                                        fopimage.getIntrinsicHeight());
-                            putImage(back.getURL(), pos);
-                        }
-                    }
-                    
-                    restoreGraphicsState();
-                } else {
-                    log.warn("Can't find background image: " + back.getURL());
-                }
-            }
-        }
-
-        boolean[] b = new boolean[] {
-            (bpsBefore != null), (bpsEnd != null), 
-            (bpsAfter != null), (bpsStart != null)};
-        if (!b[0] && !b[1] && !b[2] && !b[3]) {
-            return;
-        }
-        float[] bw = new float[] {
-            (b[0] ? bpsBefore.width / 1000f : 0.0f),
-            (b[1] ? bpsEnd.width / 1000f : 0.0f),
-            (b[2] ? bpsAfter.width / 1000f : 0.0f),
-            (b[3] ? bpsStart.width / 1000f : 0.0f)};
-        float[] clipw = new float[] {
-            BorderProps.getClippedWidth(bpsBefore) / 1000f,    
-            BorderProps.getClippedWidth(bpsEnd) / 1000f,    
-            BorderProps.getClippedWidth(bpsAfter) / 1000f,    
-            BorderProps.getClippedWidth(bpsStart) / 1000f};
-        starty += clipw[0];
-        height -= clipw[0];
-        height -= clipw[2];
-        startx += clipw[3];
-        width -= clipw[3];
-        width -= clipw[1];
-        
-        boolean[] slant = new boolean[] {
-            (b[3] && b[0]), (b[0] && b[1]), (b[1] && b[2]), (b[2] && b[3])};
-        if (bpsBefore != null) {
-            endTextObject();
-
-            float sx1 = startx;
-            float sx2 = (slant[0] ? sx1 + bw[3] - clipw[3] : sx1);
-            float ex1 = startx + width;
-            float ex2 = (slant[1] ? ex1 - bw[1] + clipw[1] : ex1);
-            float outery = starty - clipw[0];
-            float clipy = outery + clipw[0];
-            float innery = outery + bw[0];
-
-            saveGraphicsState();
-            moveTo(sx1, clipy);
-            float sx1a = sx1;
-            float ex1a = ex1;
-            if (bpsBefore.mode == BorderProps.COLLAPSE_OUTER) {
-                if (bpsStart != null && bpsStart.mode == BorderProps.COLLAPSE_OUTER) {
-                    sx1a -= clipw[3];
-                }
-                if (bpsEnd != null && bpsEnd.mode == BorderProps.COLLAPSE_OUTER) {
-                    ex1a += clipw[1];
-                }
-                lineTo(sx1a, outery);
-                lineTo(ex1a, outery);
-            }
-            lineTo(ex1, clipy);
-            lineTo(ex2, innery);
-            lineTo(sx2, innery);
-            closePath();
-            clip();
-            drawBorderLine(sx1a, outery, ex1a, innery, true, true, 
-                    bpsBefore.style, bpsBefore.color);
-            restoreGraphicsState();
-        }
-        if (bpsEnd != null) {
-            endTextObject();
-
-            float sy1 = starty;
-            float sy2 = (slant[1] ? sy1 + bw[0] - clipw[0] : sy1);
-            float ey1 = starty + height;
-            float ey2 = (slant[2] ? ey1 - bw[2] + clipw[2] : ey1);
-            float outerx = startx + width + clipw[1];
-            float clipx = outerx - clipw[1];
-            float innerx = outerx - bw[1];
-            
-            saveGraphicsState();
-            moveTo(clipx, sy1);
-            float sy1a = sy1;
-            float ey1a = ey1;
-            if (bpsEnd.mode == BorderProps.COLLAPSE_OUTER) {
-                if (bpsBefore != null && bpsBefore.mode == BorderProps.COLLAPSE_OUTER) {
-                    sy1a -= clipw[0];
-                }
-                if (bpsAfter != null && bpsAfter.mode == BorderProps.COLLAPSE_OUTER) {
-                    ey1a += clipw[2];
-                }
-                lineTo(outerx, sy1a);
-                lineTo(outerx, ey1a);
-            }
-            lineTo(clipx, ey1);
-            lineTo(innerx, ey2);
-            lineTo(innerx, sy2);
-            closePath();
-            clip();
-            drawBorderLine(innerx, sy1a, outerx, ey1a, false, false, bpsEnd.style, bpsEnd.color);
-            restoreGraphicsState();
-        }
-        if (bpsAfter != null) {
-            endTextObject();
-
-            float sx1 = startx;
-            float sx2 = (slant[3] ? sx1 + bw[3] - clipw[3] : sx1);
-            float ex1 = startx + width;
-            float ex2 = (slant[2] ? ex1 - bw[1] + clipw[1] : ex1);
-            float outery = starty + height + clipw[2];
-            float clipy = outery - clipw[2];
-            float innery = outery - bw[2];
-
-            saveGraphicsState();
-            moveTo(ex1, clipy);
-            float sx1a = sx1;
-            float ex1a = ex1;
-            if (bpsAfter.mode == BorderProps.COLLAPSE_OUTER) {
-                if (bpsStart != null && bpsStart.mode == BorderProps.COLLAPSE_OUTER) {
-                    sx1a -= clipw[3];
-                }
-                if (bpsEnd != null && bpsEnd.mode == BorderProps.COLLAPSE_OUTER) {
-                    ex1a += clipw[1];
-                }
-                lineTo(ex1a, outery);
-                lineTo(sx1a, outery);
-            }
-            lineTo(sx1, clipy);
-            lineTo(sx2, innery);
-            lineTo(ex2, innery);
-            closePath();
-            clip();
-            drawBorderLine(sx1a, innery, ex1a, outery, true, false, bpsAfter.style, bpsAfter.color);
-            restoreGraphicsState();
-        }
-        if (bpsStart != null) {
-            endTextObject();
-
-            float sy1 = starty;
-            float sy2 = (slant[0] ? sy1 + bw[0] - clipw[0] : sy1);
-            float ey1 = sy1 + height;
-            float ey2 = (slant[3] ? ey1 - bw[2] + clipw[2] : ey1);
-            float outerx = startx - clipw[3];
-            float clipx = outerx + clipw[3];
-            float innerx = outerx + bw[3];
-
-            saveGraphicsState();
-            moveTo(clipx, ey1);
-            float sy1a = sy1;
-            float ey1a = ey1;
-            if (bpsStart.mode == BorderProps.COLLAPSE_OUTER) {
-                if (bpsBefore != null && bpsBefore.mode == BorderProps.COLLAPSE_OUTER) {
-                    sy1a -= clipw[0];
-                }
-                if (bpsAfter != null && bpsAfter.mode == BorderProps.COLLAPSE_OUTER) {
-                    ey1a += clipw[2];
-                }
-                lineTo(outerx, ey1a);
-                lineTo(outerx, sy1a);
-            }
-            lineTo(clipx, sy1);
-            lineTo(innerx, sy2);
-            lineTo(innerx, ey2);
-            closePath();
-            clip();
-            drawBorderLine(outerx, sy1a, innerx, ey1a, false, true, bpsStart.style, bpsStart.color);
-            restoreGraphicsState();
-        }
-    }
-    
-    private Color lightenColor(Color col, float factor) {
-        float[] cols = new float[3];
-        cols = col.getColorComponents(cols);
-        if (factor > 0) {
-            cols[0] += (1.0 - cols[0]) * factor;
-            cols[1] += (1.0 - cols[1]) * factor;
-            cols[2] += (1.0 - cols[2]) * factor;
-        } else {
-            cols[0] -= cols[0] * -factor;
-            cols[1] -= cols[1] * -factor;
-            cols[2] -= cols[2] * -factor;
-        }
-        return new Color(cols[0], cols[1], cols[2]);
-    }
-
-    private void drawBorderLine(float x1, float y1, float x2, float y2, 
+    /** @see org.apache.fop.render.AbstractPathOrientedRenderer */
+    protected void drawBorderLine(float x1, float y1, float x2, float y2, 
             boolean horz, boolean startOrBefore, int style, ColorType col) {
         float w = x2 - x1;
         float h = y2 - y1;
@@ -1012,11 +698,33 @@
     }
 
     /**
+     * Clip a rectangular area.
+     * write a clipping operation given coordinates in the current
+     * transform.
+     * @param x the x coordinate
+     * @param y the y coordinate
+     * @param width the width of the area
+     * @param height the height of the area
+     */
+    protected void clipRect(float x, float y, float width, float height) {
+        currentStream.add(x + " " + y + " " + width + " " + height + " re ");
+        clip();
+    }
+
+    /**
+     * Clip an area.
+     */
+    protected void clip() {
+        currentStream.add("W\n");
+        currentStream.add("n\n");
+    }
+
+    /**
      * Moves the current point to (x, y), omitting any connecting line segment. 
      * @param x x coordinate
      * @param y y coordinate
      */
-    private void moveTo(float x, float y) {
+    protected void moveTo(float x, float y) {
         currentStream.add(x + " " + y + " m ");
     }
     
@@ -1026,7 +734,7 @@
      * @param x x coordinate
      * @param y y coordinate
      */
-    private void lineTo(float x, float y) {
+    protected void lineTo(float x, float y) {
         currentStream.add(x + " " + y + " l ");
     }
     
@@ -1034,9 +742,16 @@
      * Closes the current subpath by appending a straight line segment from 
      * the current point to the starting point of the subpath.
      */
-    private void closePath() {
+    protected void closePath() {
         currentStream.add("h ");
     }
+
+    /** 
+     * @see org.apache.fop.render.AbstractPathOrientedRenderer#fillRect(float, float, float, float)
+     */
+    protected void fillRect(float x, float y, float w, float h) {
+        currentStream.add(x + " " + y + " " + w + " " + h + " re f\n");
+    }
     
     /**
      * Draw a line.
@@ -1053,7 +768,7 @@
 
     /**
      * @see org.apache.fop.render.AbstractRenderer#renderBlockViewport(BlockViewport, List)
-     */
+     *//*
     protected void renderBlockViewport(BlockViewport bv, List children) {
         // clip and position viewport if necessary
 
@@ -1077,21 +792,7 @@
             //after the block-container has been painted. See below.
             List breakOutList = null;
             if (bv.getPositioning() == Block.FIXED) {
-                //break out
-                breakOutList = new java.util.ArrayList();
-                PDFState.Data data;
-                while (true) {
-                    data = currentState.getData();
-                    if (currentState.pop() == null) {
-                        break;
-                    }
-                    if (breakOutList.size() == 0) {
-                        comment("------ break out!");
-                    }
-                    breakOutList.add(0, data); //Insert because of stack-popping
-                    //getLogger().debug("Adding to break out list: " + data);
-                    restoreGraphicsState();
-                }
+                breakOutList = breakOutOfStateStack();
             }
             
             CTM tempctm = new CTM(containingIPPosition, containingBPPosition);
@@ -1122,7 +823,7 @@
             
             if (bv.getClip()) {
                 saveGraphicsState();
-                clip(x, y, width, height);
+                clipRect(x, y, width, height);
             }
 
             startVParea(ctm);
@@ -1140,31 +841,7 @@
             // clip if necessary
 
             if (breakOutList != null) {
-                comment("------ restoring context after break-out...");
-                PDFState.Data data;
-                Iterator i = breakOutList.iterator();
-                while (i.hasNext()) {
-                    data = (PDFState.Data)i.next();
-                    //getLogger().debug("Restoring: " + data);
-                    currentState.push();
-                    saveGraphicsState();
-                    if (data.concatenations != null) {
-                        Iterator tr = data.concatenations.iterator();
-                        while (tr.hasNext()) {
-                            AffineTransform at = (AffineTransform)tr.next();
-                            currentState.setTransform(at);
-                            double[] matrix = new double[6];
-                            at.getMatrix(matrix);
-                            tempctm = new CTM(matrix[0], matrix[1], matrix[2], matrix[3], 
-                                    matrix[4] * 1000, matrix[5] * 1000);
-                            currentStream.add(CTMHelper.toPDFString(tempctm) + " cm\n");
-                        }
-                    }
-                    //TODO Break-out: Also restore items such as line width and color
-                    //Left out for now because all this painting stuff is very
-                    //inconsistent. Some values go over PDFState, some don't.
-                }
-                comment("------ done.");
+                restoreStateStackAfterBreakOut(breakOutList);
             }
             
             currentIPPosition = saveIP;
@@ -1191,7 +868,7 @@
                 saveGraphicsState();
                 float width = (float)bv.getIPD() / 1000f;
                 float height = (float)bv.getBPD() / 1000f;
-                clip(x, y, width, height);
+                clipRect(x, y, width, height);
             }
 
             if (ctm != null) {
@@ -1222,28 +899,59 @@
             }
         }
         currentFontName = saveFontName;
-    }
-
+    }*/
+   
     /**
-     * Clip an area.
-     * write a clipping operation given coordinates in the current
-     * transform.
-     * @param x the x coordinate
-     * @param y the y coordinate
-     * @param width the width of the area
-     * @param height the height of the area
+     * Breaks out of the state stack to handle fixed block-containers.
+     * @return the saved state stack to recreate later
      */
-    protected void clip(float x, float y, float width, float height) {
-        currentStream.add(x + " " + y + " " + width + " " + height + " re ");
-        clip();
+    protected List breakOutOfStateStack() {
+        List breakOutList = new java.util.ArrayList();
+        PDFState.Data data;
+        while (true) {
+            data = currentState.getData();
+            if (currentState.pop() == null) {
+                break;
+            }
+            if (breakOutList.size() == 0) {
+                comment("------ break out!");
+            }
+            breakOutList.add(0, data); //Insert because of stack-popping
+            restoreGraphicsState();
+        }
+        return breakOutList;
     }
 
     /**
-     * Clip an area.
+     * Restores the state stack after a break out.
+     * @param breakOutList the state stack to restore.
      */
-    protected void clip() {
-        currentStream.add("W\n");
-        currentStream.add("n\n");
+    protected void restoreStateStackAfterBreakOut(List breakOutList) {
+        CTM tempctm;
+        comment("------ restoring context after break-out...");
+        PDFState.Data data;
+        Iterator i = breakOutList.iterator();
+        while (i.hasNext()) {
+            data = (PDFState.Data)i.next();
+            currentState.push();
+            saveGraphicsState();
+            if (data.concatenations != null) {
+                Iterator tr = data.concatenations.iterator();
+                while (tr.hasNext()) {
+                    AffineTransform at = (AffineTransform)tr.next();
+                    currentState.setTransform(at);
+                    double[] matrix = new double[6];
+                    at.getMatrix(matrix);
+                    tempctm = new CTM(matrix[0], matrix[1], matrix[2], matrix[3], 
+                            matrix[4] * 1000, matrix[5] * 1000);
+                    currentStream.add(CTMHelper.toPDFString(tempctm) + " cm\n");
+                }
+            }
+            //TODO Break-out: Also restore items such as line width and color
+            //Left out for now because all this painting stuff is very
+            //inconsistent. Some values go over PDFState, some don't.
+        }
+        comment("------ done.");
     }
 
     /**
@@ -1593,15 +1301,6 @@
     }
     
     /**
-     * Converts a ColorType to a java.awt.Color (sRGB).
-     * @param col the color
-     * @return the converted color
-     */
-    private Color toColor(ColorType col) {
-        return new Color(col.getRed(), col.getGreen(), col.getBlue());
-    }
-    
-    /**
      * Establishes a new foreground or fill color.
      * @param col the color to apply (null skips this operation)
      * @param fill true to set the fill color, false for the foreground color
@@ -1625,6 +1324,11 @@
         }
     }
 
+    /** @see org.apache.fop.render.AbstractPathOrientedRenderer */
+    protected  void updateColor(ColorType col, boolean fill) {
+        updateColor(col, fill, null);
+    }
+    
     private void updateFont(String name, int size, StringBuffer pdf) {
         if ((!name.equals(this.currentFontName))
                 || (size != this.currentFontSize)) {
@@ -1646,6 +1350,12 @@
         putImage(url, pos);
     }
 
+    /** @see org.apache.fop.render.AbstractPathOrientedRenderer */
+    protected void drawImage(String url, Rectangle2D pos) {
+        endTextObject();
+        putImage(url, pos);
+    }
+    
     /**
      * Adds a PDF XObject (a bitmap) to the PDF that will later be referenced.
      * @param url URL of the bitmap
@@ -1789,32 +1499,6 @@
                             new Integer((int) pos.getHeight()));
         renderXML(context, doc, ns);
 
-    }
-
-    /**
-     * Render an inline viewport.
-     * This renders an inline viewport by clipping if necessary.
-     * @param viewport the viewport to handle
-     */
-    public void renderViewport(Viewport viewport) {
-
-        float x = currentIPPosition / 1000f;
-        float y = (currentBPPosition + viewport.getOffset()) / 1000f;
-        float width = viewport.getIPD() / 1000f;
-        float height = viewport.getBPD() / 1000f;
-        // TODO: Calculate the border rect correctly. 
-        drawBackAndBorders(viewport, x, y, width, height);
-
-        if (viewport.getClip()) {
-            saveGraphicsState();
-
-            clip(x, y, width, height);
-        }
-        super.renderViewport(viewport);
-
-        if (viewport.getClip()) {
-            restoreGraphicsState();
-        }
     }
 
     /**

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/AbstractPSDocumentGraphics2D.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/AbstractPSDocumentGraphics2D.java?rev=234201&r1=234200&r2=234201&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/AbstractPSDocumentGraphics2D.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/AbstractPSDocumentGraphics2D.java Sun Aug 21 06:36:53 2005
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,7 +35,6 @@
  * <tt>PSGraphics2D</tt>.
  *
  * @author <a href="mailto:keiron@aftexsw.com">Keiron Liddle</a>
- * @author <a href="mailto:jeremias@apache.org">Jeremias Maerki</a>
  * @version $Id$
  * @see org.apache.fop.render.ps.PSGraphics2D
  */
@@ -218,15 +217,14 @@
         }
           
         writePageHeader();
-        gen.writeln("0.001 0.001 scale");
         if ((this.viewportWidth != this.width 
                 || this.viewportHeight != this.height)
                 && (this.viewportWidth > 0) && (this.viewportHeight > 0)){
             gen.concatMatrix(this.width / this.viewportWidth, 0, 
                        0, -1 * (this.height / this.viewportHeight), 
-                       0, this.height * 1000);
+                       0, this.height);
         } else {
-            gen.concatMatrix(1, 0, 0, -1, 0, this.height * 1000);
+            gen.concatMatrix(1, 0, 0, -1, 0, this.height);
         }
         gen.writeDSCComment(DSCConstants.END_PAGE_SETUP);
         this.pagePending = true;

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSGenerator.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSGenerator.java?rev=234201&r1=234200&r2=234201&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSGenerator.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSGenerator.java Sun Aug 21 06:36:53 2005
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
  
 package org.apache.fop.render.ps;
 
+import java.awt.Color;
 import java.awt.geom.AffineTransform;
 import java.io.OutputStream;
 import java.io.IOException;
@@ -32,8 +33,7 @@
  * This class is used to output PostScript code to an OutputStream.
  *
  * @author <a href="mailto:fop-dev@xml.apache.org">Apache XML FOP Development Team</a>
- * @author <a href="mailto:jeremias@apache.org">Jeremias Maerki</a>
- * @version $Id: PSGenerator.java,v 1.3 2003/03/07 09:46:30 jeremias Exp $
+ * @version $Id$
  */
 public class PSGenerator {
 
@@ -49,8 +49,8 @@
     
     private Stack graphicsStateStack = new Stack();
     private PSState currentState;
-    private DecimalFormat df3 = new DecimalFormat("0.000", new DecimalFormatSymbols(Locale.US));
-    private DecimalFormat df1 = new DecimalFormat("0.#", new DecimalFormatSymbols(Locale.US));
+    //private DecimalFormat df3 = new DecimalFormat("0.000", new DecimalFormatSymbols(Locale.US));
+    private DecimalFormat df3 = new DecimalFormat("0.###", new DecimalFormatSymbols(Locale.US));
     private DecimalFormat df5 = new DecimalFormat("0.#####", new DecimalFormatSymbols(Locale.US));
 
     private StringBuffer tempBuffer = new StringBuffer(256);
@@ -59,7 +59,7 @@
     public PSGenerator(OutputStream out) {
         this.out = out;
         this.currentState = new PSState();
-        this.graphicsStateStack.push(this.currentState);
+        //this.graphicsStateStack.push(this.currentState);
     }
     
     /**
@@ -72,13 +72,13 @@
 
     /**
      * Returns the selected PostScript level. 
-     * (Hardcoded to level 3 for the moment.)
+     * (Hardcoded to level 2 for the moment.)
      * @return the PostScript level
      */
     public int getPSLevel() {
-        return 3; 
+        return 2; 
     }
-
+    
     /**
      * Writes a newline character to the OutputStream.
      * 
@@ -95,7 +95,7 @@
      * @return the formatted value
      */
     public String formatDouble(double value) {
-        return df1.format(value);
+        return df3.format(value);
     }
 
     /**
@@ -327,20 +327,35 @@
     public void saveGraphicsState() throws IOException {
         writeln("gsave");
         
-        PSState state = (PSState)this.currentState.clone();
+        PSState state = new PSState(this.currentState, false);
         this.graphicsStateStack.push(this.currentState);
         this.currentState = state;
     }
     
     /** 
      * Restores the last graphics state of the rendering engine.
+     * @return true if the state was restored, false if there's a stack underflow.
      * @exception IOException In case of an I/O problem
      */
-    public void restoreGraphicsState() throws IOException {
-        writeln("grestore");
-        this.currentState = (PSState)this.graphicsStateStack.pop();
+    public boolean restoreGraphicsState() throws IOException {
+        if (this.graphicsStateStack.size() > 0) {
+            writeln("grestore");
+            this.currentState = (PSState)this.graphicsStateStack.pop();
+            return true;
+        } else {
+            return false;
+        }
     }
     
+    
+    /**
+     * Returns the current graphics state.
+     * @return the current graphics state
+     */
+    public PSState getCurrentState() {
+        return this.currentState;
+    }
+
     /**
      * Concats the transformation matrix.
      * @param a A part
@@ -352,14 +367,11 @@
      * @exception IOException In case of an I/O problem
      */
     public void concatMatrix(double a, double b,
-                                double c, double d, 
-                                double e, double f) throws IOException {
-        writeln("[" + formatDouble5(a) + " "
-                    + formatDouble5(b) + " "
-                    + formatDouble5(c) + " "
-                    + formatDouble5(d) + " "
-                    + formatDouble5(e) + " "
-                    + formatDouble5(f) + "] concat");
+            double c, double d, 
+            double e, double f) throws IOException {
+        AffineTransform at = new AffineTransform(a, b, c, d, e, f);
+        concatMatrix(at);
+        
     }
     
     /**
@@ -381,7 +393,13 @@
     public void concatMatrix(AffineTransform at) throws IOException {
         double[] matrix = new double[6];
         at.getMatrix(matrix);
-        concatMatrix(matrix);                   
+        getCurrentState().concatMatrix(at);
+        writeln("[" + formatDouble5(matrix[0]) + " "
+                + formatDouble5(matrix[1]) + " "
+                + formatDouble5(matrix[2]) + " "
+                + formatDouble5(matrix[3]) + " "
+                + formatDouble5(matrix[4]) + " "
+                + formatDouble5(matrix[5]) + "] concat");
     }
                
     /**
@@ -400,18 +418,76 @@
             + " " + formatDouble(h) 
             + " re");
     }
+    
+    /**
+     * Establishes the specified line cap style.
+     * @param linecap the line cap style (0, 1 or 2) as defined by the setlinecap command.
+     * @exception IOException In case of an I/O problem
+     */
+    public void useLineCap(int linecap) throws IOException {
+        if (getCurrentState().useLineCap(linecap)) {
+            writeln(linecap + " setlinecap");
+        }
+    }
                                 
     /**
-     * Returns the current graphics state.
-     * @return the current graphics state
+     * Establishes the specified line width.
+     * @param width the line width as defined by the setlinewidth command.
+     * @exception IOException In case of an I/O problem
      */
-    public PSState getCurrentState() {
-        return this.currentState;
+    public void useLineWidth(double width) throws IOException {
+        if (getCurrentState().useLineWidth(width)) {
+            writeln(formatDouble(width) + " setlinewidth");
+        }
+    }
+                                
+    /**
+     * Establishes the specified dash pattern.
+     * @param pattern the dash pattern as defined by the setdash command.
+     * @exception IOException In case of an I/O problem
+     */
+    public void useDash(String pattern) throws IOException {
+        if (pattern == null) {
+            pattern = PSState.DEFAULT_DASH;
+        }
+        if (getCurrentState().useDash(pattern)) {
+            writeln(pattern + " setdash");
+        }
+    }
+                                
+    /**
+     * Establishes the specified color (RGB).
+     * @param col the color as defined by the setrgbcolor command.
+     * @exception IOException In case of an I/O problem
+     */
+    public void useRGBColor(Color col) throws IOException {
+        if (col == null) {
+            col = PSState.DEFAULT_RGB_COLOR;
+        }
+        if (getCurrentState().useColor(col)) {
+            float[] comps = col.getColorComponents(null);
+            writeln(formatDouble(comps[0])
+                    + " " + formatDouble(comps[1])
+                    + " " + formatDouble(comps[2])
+                    + " setrgbcolor");
+        }
     }
-
     
+    /**
+     * Establishes the specified font and size.
+     * @param name name of the font for the "F" command (see FOP Std Proc Set)
+     * @param size size of the font
+     * @exception IOException In case of an I/O problem
+     */
+    public void useFont(String name, float size) throws IOException {
+        if (getCurrentState().useFont(name, size)) {
+            writeln(name + " " + formatDouble(size) + " F");
+        }
+    }
+
     /** Used for the ATEND constant. See there. */
     private static interface AtendIndicator {
     }
+
 
 }

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSGenerator.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSGraphics2D.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSGraphics2D.java?rev=234201&r1=234200&r2=234201&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSGraphics2D.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSGraphics2D.java Sun Aug 21 06:36:53 2005
@@ -73,18 +73,20 @@
  * implementing a <tt>Graphic2D</tt> piece-meal.
  *
  * @author <a href="mailto:keiron@aftexsw.com">Keiron Liddle</a>
- * @version $Id: PSGraphics2D.java,v 1.11 2003/03/11 08:42:24 jeremias Exp $
+ * @version $Id$
  * @see org.apache.batik.ext.awt.g2d.AbstractGraphics2D
  */
 public class PSGraphics2D extends AbstractGraphics2D {
 
+    private static final AffineTransform IDENTITY_TRANSFORM = new AffineTransform();
+    
     /** the logger for this class */
     protected Log log = LogFactory.getLog(PSTextPainter.class);
 
     /** the PostScript generator being created */
     protected PSGenerator gen;
 
-    private boolean clippingDisabled = true;
+    private boolean clippingDisabled = false;
 
     /** Currently valid FontState */
     protected Font font;
@@ -279,8 +281,8 @@
             Shape imclip = getClip();
             writeClip(imclip);
             gen.concatMatrix(at);
-            PSImageUtils.renderFopImage(fopimg, 
-                1000 * x, 1000 * y, 1000 * width, 1000 * height, gen);
+            PSImageUtils.renderBitmapImage(fopimg, 
+                x, y, width, height, gen);
             gen.restoreGraphicsState();
         } catch (IOException ioe) {
             handleIOException(ioe);
@@ -396,12 +398,12 @@
 
         /** @see org.apache.fop.image.FopImage#getIntrinsicWidth() */
         public int getIntrinsicWidth() {
-            return (int)(getWidth() * 72000 / getHorizontalResolution());
+            return (int)(getWidth() * 72 / getHorizontalResolution());
         }
 
         /** @see org.apache.fop.image.FopImage#getIntrinsicHeight() */
         public int getIntrinsicHeight() {
-            return (int)(getHeight() * 72000 / getVerticalResolution());
+            return (int)(getHeight() * 72 / getVerticalResolution());
         }
 
         /** @see org.apache.fop.image.FopImage#getHorizontalResolution() */
@@ -503,29 +505,29 @@
             int type = iter.currentSegment(vals);
             switch (type) {
             case PathIterator.SEG_CUBICTO:
-                gen.writeln(gen.formatDouble(1000 * vals[0]) + " "
-                                 + gen.formatDouble(1000 * vals[1]) + " "
-                                 + gen.formatDouble(1000 * vals[2]) + " "
-                                 + gen.formatDouble(1000 * vals[3]) + " "
-                                 + gen.formatDouble(1000 * vals[4]) + " "
-                                 + gen.formatDouble(1000 * vals[5])
+                gen.writeln(gen.formatDouble(vals[0]) + " "
+                                 + gen.formatDouble(vals[1]) + " "
+                                 + gen.formatDouble(vals[2]) + " "
+                                 + gen.formatDouble(vals[3]) + " "
+                                 + gen.formatDouble(vals[4]) + " "
+                                 + gen.formatDouble(vals[5])
                                  + " curveto");
                 break;
             case PathIterator.SEG_LINETO:
-                gen.writeln(gen.formatDouble(1000 * vals[0]) + " "
-                                 + gen.formatDouble(1000 * vals[1])
+                gen.writeln(gen.formatDouble(vals[0]) + " "
+                                 + gen.formatDouble(vals[1])
                                  + " lineto");
                 break;
             case PathIterator.SEG_MOVETO:
-                gen.writeln(gen.formatDouble(1000 * vals[0]) + " "
-                                 + gen.formatDouble(1000 * vals[1])
+                gen.writeln(gen.formatDouble(vals[0]) + " "
+                                 + gen.formatDouble(vals[1])
                                  + " M");
                 break;
             case PathIterator.SEG_QUADTO:
-                gen.writeln(gen.formatDouble(1000 * vals[0]) + " " 
-                          + gen.formatDouble(1000 * vals[1]) + " " 
-                          + gen.formatDouble(1000 * vals[2]) + " " 
-                          + gen.formatDouble(1000 * vals[3]) + " QUADTO ");
+                gen.writeln(gen.formatDouble(vals[0]) + " " 
+                          + gen.formatDouble(vals[1]) + " " 
+                          + gen.formatDouble(vals[2]) + " " 
+                          + gen.formatDouble(vals[3]) + " QUADTO ");
                 break;
             case PathIterator.SEG_CLOSE:
                 gen.writeln("closepath");
@@ -557,15 +559,23 @@
         preparePainting();
         try {
             gen.saveGraphicsState();
+            
+            AffineTransform trans = getTransform();
+            boolean newTransform = gen.getCurrentState().checkTransform(trans)
+                    && !trans.isIdentity();
+
             Shape imclip = getClip();
             writeClip(imclip);
+            if (newTransform) {
+                gen.concatMatrix(trans);
+            }
             establishColor(getColor());
 
             applyPaint(getPaint(), false);
             applyStroke(getStroke());
 
             gen.writeln("newpath");
-            PathIterator iter = s.getPathIterator(getTransform());
+            PathIterator iter = s.getPathIterator(IDENTITY_TRANSFORM);
             processPathIterator(iter);
             doDrawing(false, true, false);
             gen.restoreGraphicsState();
@@ -589,7 +599,7 @@
                 PathIterator iter = s.getPathIterator(getTransform());
                 processPathIterator(iter);
                 // clip area
-                gen.writeln("clippath");
+                gen.writeln("clip");
             } catch (IOException ioe) {
                 handleIOException(ioe);
             }
@@ -624,14 +634,14 @@
                 if (da != null) {
                     gen.write("[");
                     for (int count = 0; count < da.length; count++) {
-                        gen.write("" + (1000 * (int)da[count]));
+                        gen.write("" + ((int)da[count]));
                         if (count < da.length - 1) {
                             gen.write(" ");
                         }
                     }
                     gen.write("] ");
                     float offset = bs.getDashPhase();
-                    gen.writeln((1000 * (int)offset) + " setdash");
+                    gen.writeln(((int)offset) + " setdash");
                 }
                 int ec = bs.getEndCap();
                 switch (ec) {
@@ -661,10 +671,10 @@
                 default: log.warn("Unsupported line join: " + lj);
                 }
                 float lw = bs.getLineWidth();
-                gen.writeln(gen.formatDouble(1000 * lw) + " setlinewidth");
+                gen.writeln(gen.formatDouble(lw) + " setlinewidth");
 
                 float ml = bs.getMiterLimit();
-                gen.writeln(gen.formatDouble(1000 * ml) + " setmiterlimit");
+                gen.writeln(gen.formatDouble(ml) + " setmiterlimit");
             }
         } catch (IOException ioe) {
             handleIOException(ioe);
@@ -857,9 +867,9 @@
 
             //Prepare correct transformation
             AffineTransform trans = getTransform();
-            gen.writeln("[" + toArray(trans) + "] concat"); 
-            gen.writeln(gen.formatDouble(1000 * x) + " "
-                      + gen.formatDouble(1000 * y) + " moveto ");
+            gen.concatMatrix(trans);
+            gen.writeln(gen.formatDouble(x) + " "
+                      + gen.formatDouble(y) + " moveto ");
             gen.writeln("1 -1 scale");
       
             StringBuffer sb = new StringBuffer("(");
@@ -872,22 +882,6 @@
         } catch (IOException ioe) {
             handleIOException(ioe);
         }
-    }
-
-    /**
-     * Converts an AffineTransform to a value array.
-     * @param at AffineTransform to convert
-     * @return a String (array of six space-separated values)
-     */
-    protected String toArray(AffineTransform at) {
-        final double[] vals = new double[6];
-        at.getMatrix(vals);
-        return gen.formatDouble5(vals[0]) + " " 
-                + gen.formatDouble5(vals[1]) + " " 
-                + gen.formatDouble5(vals[2]) + " "   
-                + gen.formatDouble5(vals[3]) + " "   
-                + gen.formatDouble(1000 * vals[4]) + " "   
-                + gen.formatDouble(1000 * vals[5]); 
     }
 
     private void escapeText(final String text, StringBuffer target) {

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSGraphics2D.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSImageUtils.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSImageUtils.java?rev=234201&r1=234200&r2=234201&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSImageUtils.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSImageUtils.java Sun Aug 21 06:36:53 2005
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004 The Apache Software Foundation.
+ * Copyright 2004-2005 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,20 +22,29 @@
 import java.io.IOException;
 import java.io.OutputStream;
 
+import org.apache.commons.io.output.CountingOutputStream;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.fop.image.EPSImage;
 import org.apache.fop.image.FopImage;
 import org.apache.fop.image.JpegImage;
+import org.apache.fop.image.XMLImage;
 import org.apache.fop.util.ASCII85OutputStream;
 import org.apache.fop.util.Finalizable;
 import org.apache.fop.util.FlateEncodeOutputStream;
 import org.apache.fop.util.RunLengthEncodeOutputStream;
+import org.w3c.dom.Document;
 
 /**
  * Utility code for rendering images in PostScript. 
  */
 public class PSImageUtils {
 
+    /** logging instance */
+    protected static Log log = LogFactory.getLog(PSImageUtils.class);
+
     /**
-     * Renders an image to PostScript.
+     * Renders a bitmap image to PostScript.
      * @param img image to render
      * @param x x position
      * @param y y position
@@ -44,12 +53,26 @@
      * @param gen PS generator
      * @throws IOException In case of an I/O problem while rendering the image
      */
-    public static void renderFopImage(FopImage img, int x, int y, int w, int h, PSGenerator gen) throws IOException {
+    public static void renderBitmapImage(FopImage img, 
+                float x, float y, float w, float h, PSGenerator gen)
+                    throws IOException {
+        if (img instanceof JpegImage) {
+            if (!img.load(FopImage.ORIGINAL_DATA)) {
+                gen.commentln("%JPEG image could not be processed: " + img);
+                return;
+            }
+        } else {
+            if (!img.load(FopImage.BITMAP)) {
+                gen.commentln("%Bitmap image could not be processed: " + img);
+                return;
+            }
+        }
         boolean iscolor = img.getColorSpace().getType()
                           != ColorSpace.CS_GRAY;
         byte[] imgmap = img.getBitmaps();
 
         gen.saveGraphicsState();
+        gen.commentln("%FOPBeginBitmap: " + img.getMimeType());
         if (img.getColorSpace().getType() == ColorSpace.TYPE_CMYK) {
             gen.writeln("/DeviceCMYK setcolorspace");
         } else if (img.getColorSpace().getType() == ColorSpace.CS_GRAY) {
@@ -108,22 +131,6 @@
         gen.writeln("  RawData flushfile");
         gen.writeln("} exec");
 
-        /*
-         * for (int y=0; y<img.getHeight(); y++) {
-         * int indx = y * img.getWidth();
-         * if (iscolor) indx*= 3;
-         * for (int x=0; x<img.getWidth(); x++) {
-         * if (iscolor) {
-         * writeASCIIHex(imgmap[indx++] & 0xFF);
-         * writeASCIIHex(imgmap[indx++] & 0xFF);
-         * writeASCIIHex(imgmap[indx++] & 0xFF);
-         * } else {
-         * writeASCIIHex(imgmap[indx++] & 0xFF);
-         * }
-         * }
-         * }
-         */
-
         OutputStream out = gen.getOutputStream();
         out = new ASCII85OutputStream(out);
         if (img instanceof JpegImage) {
@@ -143,8 +150,70 @@
         }
 
         gen.writeln("");
+        gen.commentln("%FOPEndBitmap");
         gen.restoreGraphicsState();
     }
 
+    public static void renderEPS(EPSImage img, 
+            float x, float y, float w, float h,
+            PSGenerator gen) {
+        try {
+            if (!img.load(FopImage.ORIGINAL_DATA)) {
+                gen.commentln("%EPS image could not be processed: " + img);
+                return;
+            }
+            int[] bbox = img.getBBox();
+            int bboxw = bbox[2] - bbox[0];
+            int bboxh = bbox[3] - bbox[1];
+            renderEPS(img.getEPSImage(), img.getDocName(),
+                x, y, w, h,
+                bbox[0], bbox[1], bboxw, bboxh, gen);
+
+        } catch (Exception e) {
+            log.error("PSRenderer.renderImageArea(): Error rendering bitmap ("
+                                   + e.getMessage() + ")", e);
+        }
+    }
+
+    /**
+     * Places an EPS file in the PostScript stream.
+     * @param rawEPS byte array containing the raw EPS data
+     * @param name name for the EPS document
+     * @param x x-coordinate of viewport in millipoints
+     * @param y y-coordinate of viewport in millipoints
+     * @param w width of viewport in millipoints
+     * @param h height of viewport in millipoints
+     * @param bboxx x-coordinate of EPS bounding box in points
+     * @param bboxy y-coordinate of EPS bounding box in points
+     * @param bboxw width of EPS bounding box in points
+     * @param bboxh height of EPS bounding box in points
+     * @throws IOException in case an I/O error happens during output
+     */
+    public static void renderEPS(byte[] rawEPS, String name,
+                    float x, float y, float w, float h,
+                    int bboxx, int bboxy, int bboxw, int bboxh,
+                    PSGenerator gen) throws IOException {
+        gen.writeln("BeginEPSF");
+        gen.writeln("%%BeginDocument: " + name);
+
+        gen.writeln(gen.formatDouble(x) + " " + gen.formatDouble(y) + " translate");
+        gen.writeln("0 " + gen.formatDouble(h) + " translate");
+        gen.writeln("1 -1 scale");
+        float sx = w / bboxw;
+        float sy = h / bboxh;
+        if (sx != 1 || sy != 1) {
+            gen.writeln(gen.formatDouble(sx) + " " + gen.formatDouble(sy) + " scale");
+        }
+        if (bboxx != 0 || bboxy != 0) {
+            gen.writeln(gen.formatDouble(-bboxx) + " " + gen.formatDouble(-bboxy) + " translate");
+        }
+        gen.writeln(gen.formatDouble(bboxy) + " " + gen.formatDouble(bboxy) 
+                + " " + gen.formatDouble(bboxw) + " " + gen.formatDouble(bboxh) + " re clip");
+        gen.writeln("newpath");
+        gen.writeByteArr(rawEPS);
+        gen.writeln("%%EndDocument");
+        gen.writeln("EndEPSF");
+        gen.writeln("");
+    }
 
 }



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