]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Initial implementation for border painting for the new IF (including support for...
authorJeremias Maerki <jeremias@apache.org>
Thu, 14 Aug 2008 09:13:09 +0000 (09:13 +0000)
committerJeremias Maerki <jeremias@apache.org>
Thu, 14 Aug 2008 09:13:09 +0000 (09:13 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign@685827 13f79535-47bb-0310-9956-ffa450edef68

13 files changed:
src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java
src/java/org/apache/fop/render/intermediate/BorderPainter.java [new file with mode: 0644]
src/java/org/apache/fop/render/intermediate/IFConstants.java
src/java/org/apache/fop/render/intermediate/IFPainter.java
src/java/org/apache/fop/render/intermediate/IFParser.java
src/java/org/apache/fop/render/intermediate/IFRenderer.java
src/java/org/apache/fop/render/intermediate/IFSerializer.java
src/java/org/apache/fop/render/pdf/PDFBorderPainter.java [new file with mode: 0644]
src/java/org/apache/fop/render/pdf/PDFContentGenerator.java
src/java/org/apache/fop/render/pdf/PDFPainter.java
src/java/org/apache/fop/render/pdf/PDFRenderer.java
src/sandbox/org/apache/fop/render/svg/AbstractSVGPainter.java
test/test.xconf

index 5f904858faf81290a309c14c767e4362a23978c0..90876b18c9b125b64f31bf71e43efa820b3f3db3 100644 (file)
@@ -60,6 +60,8 @@ public abstract class AbstractIFPainter implements IFPainter {
 
     /** Image handler registry */
     protected ImageHandlerRegistry imageHandlerRegistry = new ImageHandlerRegistry();
+    //TODO Move reference to FOPFactory to the user has a chance to add his own implementations
+    //and so the lookup process isn't redone for each painter instance.
 
     /**
      * Default constructor.
diff --git a/src/java/org/apache/fop/render/intermediate/BorderPainter.java b/src/java/org/apache/fop/render/intermediate/BorderPainter.java
new file mode 100644 (file)
index 0000000..fdde321
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.intermediate;
+
+import java.awt.Color;
+import java.awt.Rectangle;
+
+import org.apache.fop.traits.BorderProps;
+
+/**
+ * This is an abstract base class for handling border painting.
+ */
+public abstract class BorderPainter {
+
+    /**
+     * Draws borders.
+     * @param borderRect the border rectangle
+     * @param bpsBefore the border specification on the before side
+     * @param bpsAfter the border specification on the after side
+     * @param bpsStart the border specification on the start side
+     * @param bpsEnd the border specification on the end side
+     */
+    public void drawBorders(Rectangle borderRect,
+            BorderProps bpsBefore, BorderProps bpsAfter,
+            BorderProps bpsStart, BorderProps bpsEnd) {
+        int startx = borderRect.x;
+        int starty = borderRect.y;
+        int width = borderRect.width;
+        int height = borderRect.height;
+        boolean[] b = new boolean[] {
+            (bpsBefore != null), (bpsEnd != null),
+            (bpsAfter != null), (bpsStart != null)};
+        if (!b[0] && !b[1] && !b[2] && !b[3]) {
+            return;
+        }
+        int[] bw = new int[] {
+            (b[0] ? bpsBefore.width : 0),
+            (b[1] ? bpsEnd.width : 0),
+            (b[2] ? bpsAfter.width : 0),
+            (b[3] ? bpsStart.width : 0)};
+        int[] clipw = new int[] {
+            BorderProps.getClippedWidth(bpsBefore),
+            BorderProps.getClippedWidth(bpsEnd),
+            BorderProps.getClippedWidth(bpsAfter),
+            BorderProps.getClippedWidth(bpsStart)};
+        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) {
+            int sx1 = startx;
+            int sx2 = (slant[0] ? sx1 + bw[3] - clipw[3] : sx1);
+            int ex1 = startx + width;
+            int ex2 = (slant[1] ? ex1 - bw[1] + clipw[1] : ex1);
+            int outery = starty - clipw[0];
+            int clipy = outery + clipw[0];
+            int innery = outery + bw[0];
+
+            saveGraphicsState();
+            moveTo(sx1, clipy);
+            int sx1a = sx1;
+            int 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) {
+            int sy1 = starty;
+            int sy2 = (slant[1] ? sy1 + bw[0] - clipw[0] : sy1);
+            int ey1 = starty + height;
+            int ey2 = (slant[2] ? ey1 - bw[2] + clipw[2] : ey1);
+            int outerx = startx + width + clipw[1];
+            int clipx = outerx - clipw[1];
+            int innerx = outerx - bw[1];
+
+            saveGraphicsState();
+            moveTo(clipx, sy1);
+            int sy1a = sy1;
+            int 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) {
+            int sx1 = startx;
+            int sx2 = (slant[3] ? sx1 + bw[3] - clipw[3] : sx1);
+            int ex1 = startx + width;
+            int ex2 = (slant[2] ? ex1 - bw[1] + clipw[1] : ex1);
+            int outery = starty + height + clipw[2];
+            int clipy = outery - clipw[2];
+            int innery = outery - bw[2];
+
+            saveGraphicsState();
+            moveTo(ex1, clipy);
+            int sx1a = sx1;
+            int 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) {
+            int sy1 = starty;
+            int sy2 = (slant[0] ? sy1 + bw[0] - clipw[0] : sy1);
+            int ey1 = sy1 + height;
+            int ey2 = (slant[3] ? ey1 - bw[2] + clipw[2] : ey1);
+            int outerx = startx - clipw[3];
+            int clipx = outerx + clipw[3];
+            int innerx = outerx + bw[3];
+
+            saveGraphicsState();
+            moveTo(clipx, ey1);
+            int sy1a = sy1;
+            int 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();
+        }
+    }
+
+
+    protected abstract void drawBorderLine(int x1, int y1, int x2, int y2,
+            boolean horz, boolean startOrBefore, int style, Color col);
+
+    protected abstract void moveTo(int x, int y);
+
+    protected abstract void lineTo(int x, int y);
+
+    protected abstract void closePath();
+
+    protected abstract void clip();
+
+    protected abstract void saveGraphicsState();
+    protected abstract void restoreGraphicsState();
+
+}
index 2ea97a2310e077e91e96c61029f727ae4533ef5f..8fe09460488482d6740c30a1e4d6cebf1f7590a4 100644 (file)
@@ -44,4 +44,8 @@ public interface IFConstants extends XMLConstants {
     String EL_VIEWPORT = "viewport";
     String EL_GROUP = "g";
     String EL_IMAGE = "image";
+    String EL_RECT = "rect";
+    String EL_BORDER_RECT = "border-rect";
+    String EL_FONT = "font";
+    String EL_TEXT = "text";
 }
index 026f43a8e8b3449b4e06e6e31c8f625ad07747ed..6042ed816367f4543020f6c3f2b0a05e4d86055f 100644 (file)
@@ -32,6 +32,7 @@ import org.w3c.dom.Document;
 
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.traits.BorderProps;
 
 /**
  * Interface used to paint whole documents layouted by Apache FOP.
@@ -276,6 +277,20 @@ public interface IFPainter {
      */
     void drawRect(Rectangle rect, Paint fill, Color stroke) throws IFException;
 
+    /**
+     * Draws a border rectangle. The border segments are specified through {@code BorderProps}
+     * instances.
+     * @param rect the rectangle's coordinates and extent
+     * @param before the border segment on the before-side (top)
+     * @param after the border segment on the after-side (bottom)
+     * @param start the border segment on the start-side (left)
+     * @param end the border segment on the end-side (right)
+     * @throws IFException if an error occurs while handling this event
+     */
+    void drawBorderRect(Rectangle rect,
+            BorderProps before, BorderProps after,
+            BorderProps start, BorderProps end) throws IFException;
+
     /**
      * Draws an image identified by a URI inside a given rectangle. This is the equivalent to
      * an fo:external-graphic in XSL-FO.
index 9c615427f9ab2a5331fa4fd1f50554e92e7e09b8..e365bb5196fb6495c73100c6a2c9152996a4f52d 100644 (file)
@@ -49,6 +49,7 @@ import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.fo.ElementMapping;
 import org.apache.fop.fo.ElementMappingRegistry;
 import org.apache.fop.fo.expr.PropertyException;
+import org.apache.fop.traits.BorderProps;
 import org.apache.fop.util.ColorUtil;
 import org.apache.fop.util.ContentHandlerFactory;
 import org.apache.fop.util.ContentHandlerFactoryRegistry;
@@ -133,9 +134,10 @@ public class IFParser implements IFConstants {
             //Page content
             elementHandlers.put(EL_VIEWPORT, new ViewportHandler());
             elementHandlers.put(EL_GROUP, new GroupHandler());
-            elementHandlers.put("font", new FontHandler());
-            elementHandlers.put("text", new TextHandler());
-            elementHandlers.put("rect", new RectHandler());
+            elementHandlers.put(EL_FONT, new FontHandler());
+            elementHandlers.put(EL_TEXT, new TextHandler());
+            elementHandlers.put(EL_RECT, new RectHandler());
+            elementHandlers.put(EL_BORDER_RECT, new BorderRectHandler());
             elementHandlers.put(EL_IMAGE, new ImageHandler());
         }
 
@@ -442,10 +444,10 @@ public class IFParser implements IFConstants {
         private class RectHandler extends AbstractElementHandler {
 
             public void startElement(Attributes attributes) throws IFException {
-                int x = Integer.parseInt(lastAttributes.getValue("x"));
-                int y = Integer.parseInt(lastAttributes.getValue("y"));
-                int width = Integer.parseInt(lastAttributes.getValue("width"));
-                int height = Integer.parseInt(lastAttributes.getValue("height"));
+                int x = Integer.parseInt(attributes.getValue("x"));
+                int y = Integer.parseInt(attributes.getValue("y"));
+                int width = Integer.parseInt(attributes.getValue("width"));
+                int height = Integer.parseInt(attributes.getValue("height"));
                 Color fillColor;
                 try {
                     fillColor = getAttributeAsColor(attributes, "fill");
@@ -463,6 +465,29 @@ public class IFParser implements IFConstants {
 
         }
 
+        private static final String[] SIDES = new String[] {"before", "after", "start", "end"};
+
+        private class BorderRectHandler extends AbstractElementHandler {
+
+            public void startElement(Attributes attributes) throws IFException {
+                int x = Integer.parseInt(attributes.getValue("x"));
+                int y = Integer.parseInt(attributes.getValue("y"));
+                int width = Integer.parseInt(attributes.getValue("width"));
+                int height = Integer.parseInt(attributes.getValue("height"));
+                BorderProps[] borders = new BorderProps[4];
+                for (int i = 0; i < 4; i++) {
+                    String b = attributes.getValue(SIDES[i]);
+                    if (b != null) {
+                        borders[i] = BorderProps.valueOf(userAgent, b);
+                    }
+                }
+
+                painter.drawBorderRect(new Rectangle(x, y, width, height),
+                        borders[0], borders[1], borders[2], borders[3]);
+            }
+
+        }
+
         private class ImageHandler extends AbstractElementHandler {
 
             public void startElement(Attributes attributes) throws IFException {
index e5dcccf620f111d0e7aa1adc93188385786c6241..529aee4d0e2d676cddbb462ad55f9f445e5a1808 100644 (file)
@@ -85,6 +85,7 @@ import org.apache.fop.render.intermediate.extensions.BookmarkTree;
 import org.apache.fop.render.intermediate.extensions.GoToXYAction;
 import org.apache.fop.render.intermediate.extensions.NamedDestination;
 import org.apache.fop.render.pdf.PDFEventProducer;
+import org.apache.fop.traits.BorderProps;
 
 /**
  * This renderer implementation is an adapter to the {@code IFPainter} interface. It is used
@@ -92,6 +93,11 @@ import org.apache.fop.render.pdf.PDFEventProducer;
  */
 public class IFRenderer extends AbstractPathOrientedRenderer {
 
+    //TODO Many parts of the Renderer infrastructure are using floats (coordinates in points)
+    //instead of ints (in millipoints). A lot of conversion to and from is performed.
+    //When the new IF is established, the Renderer infrastructure should be revisited so check
+    //if optimizations can be done to avoid int->float->int conversions.
+
     /** logging instance */
     protected static Log log = LogFactory.getLog(IFRenderer.class);
 
@@ -963,18 +969,37 @@ public class IFRenderer extends AbstractPathOrientedRenderer {
         log.warn("closePath() NYI");
     }
 
+    /** {@inheritDoc} */
+    protected void drawBorders(float startx, float starty,
+            float width, float height,
+            BorderProps bpsBefore, BorderProps bpsAfter,
+            BorderProps bpsStart, BorderProps bpsEnd) {
+        Rectangle rect = toMillipointRectangle(startx, starty, width, height);
+        try {
+            painter.drawBorderRect(rect, bpsBefore, bpsAfter, bpsStart, bpsEnd);
+        } catch (IFException ife) {
+            handleIFException(ife);
+        }
+    }
+
     /** {@inheritDoc} */
     protected void drawBorderLine(float x1, float y1, float x2, float y2, boolean horz,
             boolean startOrBefore, int style, Color col) {
-        // TODO Auto-generated method stub
-        //log.warn("drawBorderLine() NYI");
+        log.warn("drawBorderLine() not properly implemented, yet");
         updateColor(col, true);
         fillRect(x1, y1, x2 - x1, y2 - y1);
     }
 
+    private int toMillipoints(float coordinate) {
+        return (int)(coordinate * 1000);
+    }
+
     private Rectangle toMillipointRectangle(float x, float y, float width, float height) {
         return new Rectangle(
-                (int)(x * 1000), (int)(y * 1000), (int)(width * 1000), (int)(height * 1000));
+                toMillipoints(x),
+                toMillipoints(y),
+                toMillipoints(width),
+                toMillipoints(height));
     }
 
     /** {@inheritDoc} */
index 9ca242fb9cb44757f189b1053f73c16ac6d81303..40cd9a25bfde93bfbc630297cde50577febdf678 100644 (file)
@@ -36,6 +36,7 @@ import org.apache.xmlgraphics.util.QName;
 import org.apache.xmlgraphics.util.XMLizable;
 
 import org.apache.fop.render.RenderingContext;
+import org.apache.fop.traits.BorderProps;
 import org.apache.fop.util.ColorUtil;
 import org.apache.fop.util.DOM2SAX;
 import org.apache.fop.util.XMLUtil;
@@ -242,7 +243,7 @@ public class IFSerializer extends AbstractXMLWritingIFPainter implements IFConst
         try {
             AttributesImpl atts = new AttributesImpl();
             if (transform != null && transform.length() > 0) {
-                addAttribute(atts,"transform", transform);
+                addAttribute(atts, "transform", transform);
             }
             addAttribute(atts, "width", Integer.toString(size.width));
             addAttribute(atts, "height", Integer.toString(size.height));
@@ -363,14 +364,44 @@ public class IFSerializer extends AbstractXMLWritingIFPainter implements IFConst
                 addAttribute(atts, "fill", toString(fill));
             }
             if (stroke != null) {
-                addAttribute(atts, "sroke", toString(stroke));
+                addAttribute(atts, "stroke", toString(stroke));
             }
-            element("rect", atts);
+            element(EL_RECT, atts);
         } catch (SAXException e) {
             throw new IFException("SAX error in drawRect()", e);
         }
     }
 
+    /** {@inheritDoc} */
+    public void drawBorderRect(Rectangle rect, BorderProps before, BorderProps after,
+            BorderProps start, BorderProps end) throws IFException {
+        if (before == null && after == null && start == null && end == null) {
+            return;
+        }
+        try {
+            AttributesImpl atts = new AttributesImpl();
+            addAttribute(atts, "x", Integer.toString(rect.x));
+            addAttribute(atts, "y", Integer.toString(rect.y));
+            addAttribute(atts, "width", Integer.toString(rect.width));
+            addAttribute(atts, "height", Integer.toString(rect.height));
+            if (before != null) {
+                addAttribute(atts, "before", before.toString());
+            }
+            if (after != null) {
+                addAttribute(atts, "after", after.toString());
+            }
+            if (start != null) {
+                addAttribute(atts, "start", start.toString());
+            }
+            if (end != null) {
+                addAttribute(atts, "end", end.toString());
+            }
+            element(EL_BORDER_RECT, atts);
+        } catch (SAXException e) {
+            throw new IFException("SAX error in drawBorderRect()", e);
+        }
+    }
+
     /** {@inheritDoc} */
     public void drawText(int x, int y, int[] dx, int[] dy, String text) throws IFException {
         try {
@@ -383,10 +414,10 @@ public class IFSerializer extends AbstractXMLWritingIFPainter implements IFConst
             if (dy != null) {
                 addAttribute(atts, "dy", toString(dy));
             }
-            startElement("text", atts);
+            startElement(EL_TEXT, atts);
             char[] chars = text.toCharArray();
             handler.characters(chars, 0, chars.length);
-            endElement("text");
+            endElement(EL_TEXT);
         } catch (SAXException e) {
             throw new IFException("SAX error in setFont()", e);
         }
@@ -415,7 +446,7 @@ public class IFSerializer extends AbstractXMLWritingIFPainter implements IFConst
             if (color != null) {
                 addAttribute(atts, "color", toString(color));
             }
-            element("font", atts);
+            element(EL_FONT, atts);
         } catch (SAXException e) {
             throw new IFException("SAX error in setFont()", e);
         }
diff --git a/src/java/org/apache/fop/render/pdf/PDFBorderPainter.java b/src/java/org/apache/fop/render/pdf/PDFBorderPainter.java
new file mode 100644 (file)
index 0000000..ab34e36
--- /dev/null
@@ -0,0 +1,263 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.pdf;
+
+import java.awt.Color;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.fo.Constants;
+import org.apache.fop.render.PrintRenderer;
+import org.apache.fop.render.intermediate.BorderPainter;
+
+/**
+ * PDF-specific implementation of the {@code BorderPainter}.
+ */
+public class PDFBorderPainter extends BorderPainter {
+
+    /** logging instance */
+    private static Log log = LogFactory.getLog(PDFBorderPainter.class);
+
+    private PDFContentGenerator generator;
+
+    public PDFBorderPainter(PDFContentGenerator generator) {
+        this.generator = generator;
+    }
+
+    /** {@inheritDoc} */
+    protected void drawBorderLine(int x1, int y1, int x2, int y2, boolean horz,
+            boolean startOrBefore, int style, Color col) {
+       drawBorderLine(generator, x1 / 1000f, y1 / 1000f, x2 / 1000f, y2 / 1000f,
+               horz, startOrBefore, style, col);
+    }
+
+    /** {@inheritDoc} */
+    public static void drawBorderLine(PDFContentGenerator generator,
+            float x1, float y1, float x2, float y2, boolean horz,
+            boolean startOrBefore, int style, Color col) {
+        float w = x2 - x1;
+        float h = y2 - y1;
+        if ((w < 0) || (h < 0)) {
+            log.error("Negative extent received (w=" + w + ", h=" + h
+                    + "). Border won't be painted.");
+            return;
+        }
+        switch (style) {
+            case Constants.EN_DASHED:
+                generator.setColor(col, false);
+                if (horz) {
+                    float unit = Math.abs(2 * h);
+                    int rep = (int)(w / unit);
+                    if (rep % 2 == 0) {
+                        rep++;
+                    }
+                    unit = w / rep;
+                    generator.add("[" + format(unit) + "] 0 d ");
+                    generator.add(format(h) + " w\n");
+                    float ym = y1 + (h / 2);
+                    generator.add(format(x1) + " " + format(ym) + " m "
+                            + format(x2) + " " + format(ym) + " l S\n");
+                } else {
+                    float unit = Math.abs(2 * w);
+                    int rep = (int)(h / unit);
+                    if (rep % 2 == 0) {
+                        rep++;
+                    }
+                    unit = h / rep;
+                    generator.add("[" + format(unit) + "] 0 d ");
+                    generator.add(format(w) + " w\n");
+                    float xm = x1 + (w / 2);
+                    generator.add(format(xm) + " " + format(y1) + " m "
+                            + format(xm) + " " + format(y2) + " l S\n");
+                }
+                break;
+            case Constants.EN_DOTTED:
+                generator.setColor(col, false);
+                generator.add("1 J ");
+                if (horz) {
+                    float unit = Math.abs(2 * h);
+                    int rep = (int)(w / unit);
+                    if (rep % 2 == 0) {
+                        rep++;
+                    }
+                    unit = w / rep;
+                    generator.add("[0 " + format(unit) + "] 0 d ");
+                    generator.add(format(h) + " w\n");
+                    float ym = y1 + (h / 2);
+                    generator.add(format(x1) + " " + format(ym) + " m "
+                            + format(x2) + " " + format(ym) + " l S\n");
+                } else {
+                    float unit = Math.abs(2 * w);
+                    int rep = (int)(h / unit);
+                    if (rep % 2 == 0) {
+                        rep++;
+                    }
+                    unit = h / rep;
+                    generator.add("[0 " + format(unit) + " ] 0 d ");
+                    generator.add(format(w) + " w\n");
+                    float xm = x1 + (w / 2);
+                    generator.add(format(xm) + " " + format(y1) + " m "
+                            + format(xm) + " " + format(y2) + " l S\n");
+                }
+                break;
+            case Constants.EN_DOUBLE:
+                generator.setColor(col, false);
+                generator.add("[] 0 d ");
+                if (horz) {
+                    float h3 = h / 3;
+                    generator.add(format(h3) + " w\n");
+                    float ym1 = y1 + (h3 / 2);
+                    float ym2 = ym1 + h3 + h3;
+                    generator.add(format(x1) + " " + format(ym1) + " m "
+                            + format(x2) + " " + format(ym1) + " l S\n");
+                    generator.add(format(x1) + " " + format(ym2) + " m "
+                            + format(x2) + " " + format(ym2) + " l S\n");
+                } else {
+                    float w3 = w / 3;
+                    generator.add(format(w3) + " w\n");
+                    float xm1 = x1 + (w3 / 2);
+                    float xm2 = xm1 + w3 + w3;
+                    generator.add(format(xm1) + " " + format(y1) + " m "
+                            + format(xm1) + " " + format(y2) + " l S\n");
+                    generator.add(format(xm2) + " " + format(y1) + " m "
+                            + format(xm2) + " " + format(y2) + " l S\n");
+                }
+                break;
+            case Constants.EN_GROOVE:
+            case Constants.EN_RIDGE:
+            {
+                float colFactor = (style == Constants.EN_GROOVE ? 0.4f : -0.4f);
+                generator.add("[] 0 d ");
+                if (horz) {
+                    Color uppercol = PrintRenderer.lightenColor(col, -colFactor);
+                    Color lowercol = PrintRenderer.lightenColor(col, colFactor);
+                    float h3 = h / 3;
+                    generator.add(format(h3) + " w\n");
+                    float ym1 = y1 + (h3 / 2);
+                    generator.setColor(uppercol, false);
+                    generator.add(format(x1) + " " + format(ym1) + " m "
+                            + format(x2) + " " + format(ym1) + " l S\n");
+                    generator.setColor(col, false);
+                    generator.add(format(x1) + " " + format(ym1 + h3) + " m "
+                                        + format(x2) + " " + format(ym1 + h3) + " l S\n");
+                    generator.setColor(lowercol, false);
+                    generator.add(format(x1) + " " + format(ym1 + h3 + h3) + " m "
+                                        + format(x2) + " " + format(ym1 + h3 + h3) + " l S\n");
+                } else {
+                    Color leftcol = PrintRenderer.lightenColor(col, -colFactor);
+                    Color rightcol = PrintRenderer.lightenColor(col, colFactor);
+                    float w3 = w / 3;
+                    generator.add(format(w3) + " w\n");
+                    float xm1 = x1 + (w3 / 2);
+                    generator.setColor(leftcol, false);
+                    generator.add(format(xm1) + " " + format(y1) + " m "
+                            + format(xm1) + " " + format(y2) + " l S\n");
+                    generator.setColor(col, false);
+                    generator.add(format(xm1 + w3) + " " + format(y1) + " m "
+                                        + format(xm1 + w3) + " " + format(y2) + " l S\n");
+                    generator.setColor(rightcol, false);
+                    generator.add(format(xm1 + w3 + w3) + " " + format(y1) + " m "
+                                        + format(xm1 + w3 + w3) + " " + format(y2) + " l S\n");
+                }
+                break;
+            }
+            case Constants.EN_INSET:
+            case Constants.EN_OUTSET:
+            {
+                float colFactor = (style == Constants.EN_OUTSET ? 0.4f : -0.4f);
+                generator.add("[] 0 d ");
+                Color c = col;
+                if (horz) {
+                    c = PrintRenderer.lightenColor(c, (startOrBefore ? 1 : -1) * colFactor);
+                    generator.add(format(h) + " w\n");
+                    float ym1 = y1 + (h / 2);
+                    generator.setColor(c, false);
+                    generator.add(format(x1) + " " + format(ym1) + " m "
+                            + format(x2) + " " + format(ym1) + " l S\n");
+                } else {
+                    c = PrintRenderer.lightenColor(c, (startOrBefore ? 1 : -1) * colFactor);
+                    generator.add(format(w) + " w\n");
+                    float xm1 = x1 + (w / 2);
+                    generator.setColor(c, false);
+                    generator.add(format(xm1) + " " + format(y1) + " m "
+                            + format(xm1) + " " + format(y2) + " l S\n");
+                }
+                break;
+            }
+            case Constants.EN_HIDDEN:
+                break;
+            default:
+                generator.setColor(col, false);
+                generator.add("[] 0 d ");
+                if (horz) {
+                    generator.add(format(h) + " w\n");
+                    float ym = y1 + (h / 2);
+                    generator.add(format(x1) + " " + format(ym) + " m "
+                            + format(x2) + " " + format(ym) + " l S\n");
+                } else {
+                    generator.add(format(w) + " w\n");
+                    float xm = x1 + (w / 2);
+                    generator.add(format(xm) + " " + format(y1) + " m "
+                            + format(xm) + " " + format(y2) + " l S\n");
+                }
+        }
+    }
+
+
+    static final String format(int coordinate) {
+        return format(coordinate / 1000f);
+    }
+
+    static final String format(float coordinate) {
+        return PDFContentGenerator.format(coordinate);
+    }
+
+    /** {@inheritDoc} */
+    protected void moveTo(int x, int y) {
+        generator.add(format(x) + " " + format(y) + " m ");
+    }
+
+    /** {@inheritDoc} */
+    protected void lineTo(int x, int y) {
+        generator.add(format(x) + " " + format(y) + " l ");
+    }
+
+    /** {@inheritDoc} */
+    protected void closePath() {
+        generator.add("h ");
+    }
+
+    /** {@inheritDoc} */
+    protected void clip() {
+        generator.add("W\n" + "n\n");
+    }
+
+    /** {@inheritDoc} */
+    protected void saveGraphicsState() {
+        generator.add("q\n");
+    }
+
+    /** {@inheritDoc} */
+    protected void restoreGraphicsState() {
+        generator.add("Q\n");
+    }
+
+}
index 8d5b4ccb0ea74938f9d34c06c7a5b540b7c72f16..da1bf728e92736573427c252f27c3e714581f063 100644 (file)
@@ -222,7 +222,7 @@ public class PDFContentGenerator {
      * @param value the value
      * @return the formatted value
      */
-    protected static String format(float value) {
+    public static final String format(float value) {
         return PDFNumber.doubleOut(value);
     }
 
index 5e57946fb95e7768d42031d2c55ba6298afd8932..cfbc21d35727cc86cb41239664a98daad07691dc 100644 (file)
@@ -64,6 +64,7 @@ import org.apache.fop.render.intermediate.extensions.Bookmark;
 import org.apache.fop.render.intermediate.extensions.BookmarkTree;
 import org.apache.fop.render.intermediate.extensions.GoToXYAction;
 import org.apache.fop.render.intermediate.extensions.NamedDestination;
+import org.apache.fop.traits.BorderProps;
 import org.apache.fop.util.CharUtilities;
 
 /**
@@ -92,6 +93,8 @@ public class PDFPainter extends AbstractBinaryWritingIFPainter {
     /** The current content generator */
     protected PDFContentGenerator generator;
 
+    private PDFBorderPainter borderPainter;
+
     /** the current annotation list to add annotations to */
     protected PDFResourceContext currentContext;
 
@@ -201,6 +204,8 @@ public class PDFPainter extends AbstractBinaryWritingIFPainter {
         AffineTransform basicPageTransform = new AffineTransform(1, 0, 0, -1, 0,
                 size.height / 1000f);
         generator.concatenate(basicPageTransform);
+
+        this.borderPainter = new PDFBorderPainter(this.generator);
     }
 
     /** {@inheritDoc} */
@@ -357,6 +362,13 @@ public class PDFPainter extends AbstractBinaryWritingIFPainter {
         }
     }
 
+    /** {@inheritDoc} */
+    public void drawBorderRect(Rectangle rect, BorderProps before, BorderProps after,
+            BorderProps start, BorderProps end) throws IFException {
+        this.borderPainter.drawBorders(rect, before, after, start, end);
+
+    }
+
     private Typeface getTypeface(String fontName) {
         if (fontName == null) {
             throw new NullPointerException("fontName must not be null");
index fbcf892a0bde2abd020f1d1fc9a1a031583f0cc5..591cca96bc8211a6c6e7da92e3be94891ce0fe20 100644 (file)
@@ -64,7 +64,6 @@ import org.apache.fop.area.inline.TextArea;
 import org.apache.fop.area.inline.WordArea;
 import org.apache.fop.datatypes.URISpecification;
 import org.apache.fop.events.ResourceEventProducer;
-import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.extensions.ExtensionAttachment;
 import org.apache.fop.fo.extensions.xmp.XMPMetadata;
 import org.apache.fop.fonts.Font;
@@ -541,172 +540,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer implements PDFConf
     /** {@inheritDoc} */
     protected void drawBorderLine(float x1, float y1, float x2, float y2,
             boolean horz, boolean startOrBefore, int style, Color col) {
-        float w = x2 - x1;
-        float h = y2 - y1;
-        if ((w < 0) || (h < 0)) {
-            log.error("Negative extent received (w=" + w + ", h=" + h
-                    + "). Border won't be painted.");
-            return;
-        }
-        switch (style) {
-            case Constants.EN_DASHED:
-                generator.setColor(col, false);
-                if (horz) {
-                    float unit = Math.abs(2 * h);
-                    int rep = (int)(w / unit);
-                    if (rep % 2 == 0) {
-                        rep++;
-                    }
-                    unit = w / rep;
-                    generator.add("[" + format(unit) + "] 0 d ");
-                    generator.add(format(h) + " w\n");
-                    float ym = y1 + (h / 2);
-                    generator.add(format(x1) + " " + format(ym) + " m "
-                            + format(x2) + " " + format(ym) + " l S\n");
-                } else {
-                    float unit = Math.abs(2 * w);
-                    int rep = (int)(h / unit);
-                    if (rep % 2 == 0) {
-                        rep++;
-                    }
-                    unit = h / rep;
-                    generator.add("[" + format(unit) + "] 0 d ");
-                    generator.add(format(w) + " w\n");
-                    float xm = x1 + (w / 2);
-                    generator.add(format(xm) + " " + format(y1) + " m "
-                            + format(xm) + " " + format(y2) + " l S\n");
-                }
-                break;
-            case Constants.EN_DOTTED:
-                generator.setColor(col, false);
-                generator.add("1 J ");
-                if (horz) {
-                    float unit = Math.abs(2 * h);
-                    int rep = (int)(w / unit);
-                    if (rep % 2 == 0) {
-                        rep++;
-                    }
-                    unit = w / rep;
-                    generator.add("[0 " + format(unit) + "] 0 d ");
-                    generator.add(format(h) + " w\n");
-                    float ym = y1 + (h / 2);
-                    generator.add(format(x1) + " " + format(ym) + " m "
-                            + format(x2) + " " + format(ym) + " l S\n");
-                } else {
-                    float unit = Math.abs(2 * w);
-                    int rep = (int)(h / unit);
-                    if (rep % 2 == 0) {
-                        rep++;
-                    }
-                    unit = h / rep;
-                    generator.add("[0 " + format(unit) + " ] 0 d ");
-                    generator.add(format(w) + " w\n");
-                    float xm = x1 + (w / 2);
-                    generator.add(format(xm) + " " + format(y1) + " m "
-                            + format(xm) + " " + format(y2) + " l S\n");
-                }
-                break;
-            case Constants.EN_DOUBLE:
-                generator.setColor(col, false);
-                generator.add("[] 0 d ");
-                if (horz) {
-                    float h3 = h / 3;
-                    generator.add(format(h3) + " w\n");
-                    float ym1 = y1 + (h3 / 2);
-                    float ym2 = ym1 + h3 + h3;
-                    generator.add(format(x1) + " " + format(ym1) + " m "
-                            + format(x2) + " " + format(ym1) + " l S\n");
-                    generator.add(format(x1) + " " + format(ym2) + " m "
-                            + format(x2) + " " + format(ym2) + " l S\n");
-                } else {
-                    float w3 = w / 3;
-                    generator.add(format(w3) + " w\n");
-                    float xm1 = x1 + (w3 / 2);
-                    float xm2 = xm1 + w3 + w3;
-                    generator.add(format(xm1) + " " + format(y1) + " m "
-                            + format(xm1) + " " + format(y2) + " l S\n");
-                    generator.add(format(xm2) + " " + format(y1) + " m "
-                            + format(xm2) + " " + format(y2) + " l S\n");
-                }
-                break;
-            case Constants.EN_GROOVE:
-            case Constants.EN_RIDGE:
-            {
-                float colFactor = (style == EN_GROOVE ? 0.4f : -0.4f);
-                generator.add("[] 0 d ");
-                if (horz) {
-                    Color uppercol = lightenColor(col, -colFactor);
-                    Color lowercol = lightenColor(col, colFactor);
-                    float h3 = h / 3;
-                    generator.add(format(h3) + " w\n");
-                    float ym1 = y1 + (h3 / 2);
-                    generator.setColor(uppercol, false);
-                    generator.add(format(x1) + " " + format(ym1) + " m "
-                            + format(x2) + " " + format(ym1) + " l S\n");
-                    generator.setColor(col, false);
-                    generator.add(format(x1) + " " + format(ym1 + h3) + " m "
-                                        + format(x2) + " " + format(ym1 + h3) + " l S\n");
-                    generator.setColor(lowercol, false);
-                    generator.add(format(x1) + " " + format(ym1 + h3 + h3) + " m "
-                                        + format(x2) + " " + format(ym1 + h3 + h3) + " l S\n");
-                } else {
-                    Color leftcol = lightenColor(col, -colFactor);
-                    Color rightcol = lightenColor(col, colFactor);
-                    float w3 = w / 3;
-                    generator.add(format(w3) + " w\n");
-                    float xm1 = x1 + (w3 / 2);
-                    generator.setColor(leftcol, false);
-                    generator.add(format(xm1) + " " + format(y1) + " m "
-                            + format(xm1) + " " + format(y2) + " l S\n");
-                    generator.setColor(col, false);
-                    generator.add(format(xm1 + w3) + " " + format(y1) + " m "
-                                        + format(xm1 + w3) + " " + format(y2) + " l S\n");
-                    generator.setColor(rightcol, false);
-                    generator.add(format(xm1 + w3 + w3) + " " + format(y1) + " m "
-                                        + format(xm1 + w3 + w3) + " " + format(y2) + " l S\n");
-                }
-                break;
-            }
-            case Constants.EN_INSET:
-            case Constants.EN_OUTSET:
-            {
-                float colFactor = (style == EN_OUTSET ? 0.4f : -0.4f);
-                generator.add("[] 0 d ");
-                Color c = col;
-                if (horz) {
-                    c = lightenColor(c, (startOrBefore ? 1 : -1) * colFactor);
-                    generator.add(format(h) + " w\n");
-                    float ym1 = y1 + (h / 2);
-                    generator.setColor(c, false);
-                    generator.add(format(x1) + " " + format(ym1) + " m "
-                            + format(x2) + " " + format(ym1) + " l S\n");
-                } else {
-                    c = lightenColor(c, (startOrBefore ? 1 : -1) * colFactor);
-                    generator.add(format(w) + " w\n");
-                    float xm1 = x1 + (w / 2);
-                    generator.setColor(c, false);
-                    generator.add(format(xm1) + " " + format(y1) + " m "
-                            + format(xm1) + " " + format(y2) + " l S\n");
-                }
-                break;
-            }
-            case Constants.EN_HIDDEN:
-                break;
-            default:
-                generator.setColor(col, false);
-                generator.add("[] 0 d ");
-                if (horz) {
-                    generator.add(format(h) + " w\n");
-                    float ym = y1 + (h / 2);
-                    generator.add(format(x1) + " " + format(ym) + " m "
-                            + format(x2) + " " + format(ym) + " l S\n");
-                } else {
-                    generator.add(format(w) + " w\n");
-                    float xm = x1 + (w / 2);
-                    generator.add(format(xm) + " " + format(y1) + " m "
-                            + format(xm) + " " + format(y2) + " l S\n");
-                }
-        }
+        PDFBorderPainter.drawBorderLine(generator, x1, y1, x2, y2, horz, startOrBefore, style, col);
     }
 
     /** {@inheritDoc} */
index fe566bf930e5d187766b1f9fbaebbd8d846eb907..a7ce20c51957cc69f2edea24081e37167370b15a 100644 (file)
@@ -51,6 +51,7 @@ import org.apache.fop.render.intermediate.AbstractXMLWritingIFPainter;
 import org.apache.fop.render.intermediate.IFConstants;
 import org.apache.fop.render.intermediate.IFException;
 import org.apache.fop.render.intermediate.IFState;
+import org.apache.fop.traits.BorderProps;
 import org.apache.fop.util.ColorUtil;
 
 /**
@@ -300,6 +301,12 @@ public abstract class AbstractSVGPainter extends AbstractXMLWritingIFPainter
         }
     }
 
+    /** {@inheritDoc} */
+    public void drawBorderRect(Rectangle rect, BorderProps before, BorderProps after,
+            BorderProps start, BorderProps end) throws IFException {
+        // TODO Auto-generated method stub
+    }
+
     /** {@inheritDoc} */
     public void drawText(int x, int y, int[] dx, int[] dy, String text) throws IFException {
         try {
index 1f022f9fd65d898a6d7789d6164f6428f635e6df..f82861b49739603dafc135cfcae6652e3f24c64b 100644 (file)
@@ -6,6 +6,18 @@
   
   <renderers>
     <renderer mime="application/pdf">
+      <filterList type="tiff">
+        <value>ascii-85</value>
+      </filterList>
+      <filterList type="default">
+        <value>null</value>
+      </filterList>
+      <filterList type="image">
+        <value>null</value>
+      </filterList>
+      <filterList type="content">
+        <value>null</value>
+      </filterList>
       <fonts>
         <font metrics-url="test/resources/fonts/glb12.ttf.xml" embed-url="test/resources/fonts/glb12.ttf">
           <font-triplet name="Gladiator" style="normal" weight="normal"/>