diff -ru ../orig/fop-0.20.5\src\org\apache\fop\datatypes\ColorType.java fop-0.20.5\src\org\apache\fop\datatypes\ColorType.java
--- ../orig/fop-0.20.5\src\org\apache\fop\datatypes\ColorType.java	Tue Jul 15 04:03:20 2003
+++ fop-0.20.5\src\org\apache\fop\datatypes\ColorType.java	Tue Sep 07 20:36:14 2004
@@ -84,6 +84,16 @@
         this.blue = blue;
     }
 
+	public boolean equals( Object obj )	{
+        if (obj == null || !(obj instanceof ColorType)) {
+            return false;
+        }
+
+        final ColorType other = (ColorType)obj;
+        return blue == other.blue && green == other.green && red == other.red &&
+                alpha == other.alpha;
+	}
+    
     /**
      * set the colour given a particular String specifying either a
      * colour name or #RGB or #RRGGBB
diff -ru ../orig/fop-0.20.5\src\org\apache\fop\render\pdf\PDFRenderer.java fop-0.20.5\src\org\apache\fop\render\pdf\PDFRenderer.java
--- ../orig/fop-0.20.5\src\org\apache\fop\render\pdf\PDFRenderer.java	Tue Jul 15 04:03:26 2003
+++ fop-0.20.5\src\org\apache\fop\render\pdf\PDFRenderer.java	Tue Sep 07 21:07:46 2004
@@ -61,6 +61,7 @@
 import org.apache.fop.pdf.*;
 import org.apache.fop.layout.*;
 import org.apache.fop.image.*;
+import org.apache.fop.datatypes.ColorType;
 import org.apache.fop.extensions.*;
 import org.apache.fop.render.pdf.fonts.LazyFont;
 
@@ -391,6 +392,205 @@
                     + xObjectNum + " Do\nQ\nBT\n");
         }
     }
+    
+    static class BorderPainter {
+        PDFStream currentStream;
+        
+        int innerLeft;
+        int innerTop;
+        int innerRight;
+        int innerBottom;
+        
+        int outerLeft;
+        int outerTop;
+        int outerRight;
+        int outerBottom;
+        
+        boolean gapT, gapR, gapB, gapL;
+       
+        ColorType t, r, b, l;
+        
+        BorderPainter(PDFStream currentStream,
+                BorderAndPadding bp, int x, int y, int w, int h) {
+            this.currentStream = currentStream;
+            
+            int leftBorderWidth = bp.getBorderLeftWidth(false);
+            int rightBorderWidth = bp.getBorderRightWidth(false);
+            int topBorderWidth = bp.getBorderTopWidth(false);
+            int bottomBorderWidth = bp.getBorderBottomWidth(false);
+            
+            innerLeft = x;
+            innerTop = y;
+            innerRight = x + w;
+            innerBottom = y - h;
+            
+            outerLeft = innerLeft - leftBorderWidth;
+            outerTop = innerTop + topBorderWidth;
+            outerRight = innerRight + rightBorderWidth;
+            outerBottom = innerBottom - bottomBorderWidth;
+            
+            t = topBorderWidth > 0 ?
+                    bp.getBorderColor(BorderAndPadding.TOP) : null;
+            l = leftBorderWidth > 0 ?
+                    bp.getBorderColor(BorderAndPadding.LEFT) : null;
+            r = rightBorderWidth > 0 ?
+                    bp.getBorderColor(BorderAndPadding.RIGHT) : null;
+            b = bottomBorderWidth > 0 ?
+                    bp.getBorderColor(BorderAndPadding.BOTTOM) : null;
+                    
+            /* A gap is a place where border terminates or changes color.
+             * gapT is gap before top edge - e.g. between top edge and left edge.
+             * We also set gapX to true if both borders are absent.
+             */
+            gapT = t == null || l == null || !t.equals(l);
+            gapR = r == null || t == null || !r.equals(t);
+            gapB = b == null || r == null || !b.equals(r);
+            gapL = l == null || b == null || !l.equals(b);
+        }
+
+        boolean willPaint() {
+            return t != null || l != null || b != null || r != null;   
+        }
+        
+        void paint() {
+            /* Are all borders present and of the same color? */
+            if (!gapT && !gapR && !gapB && !gapL) {
+                paintAllInOneColor();
+                return;
+            }
+            
+            if (gapT && t != null) {
+                m(innerLeft, innerTop);
+                l(innerRight, innerTop);
+                if (!gapR) {
+                     l(innerRight, innerBottom);
+                     if (!gapB) {
+                          l(innerLeft, innerBottom);
+                          l(outerLeft, outerBottom);
+                     }
+                     l(outerRight, outerBottom);
+                }
+                l(outerRight, outerTop);
+                l(outerLeft, outerTop);
+                paint(t);
+            }
+            
+            if (gapR && r != null) {
+                m(innerRight, innerTop);
+                l(innerRight, innerBottom);
+                if (!gapB) {
+                     l(innerLeft, innerBottom);
+                     if (!gapL) {
+                          l(innerLeft, innerTop);
+                          l(outerLeft, outerTop);
+                     }
+                     l(outerLeft, outerBottom);
+                }
+                l(outerRight, outerBottom);
+                l(outerRight, outerTop);
+                paint(r);
+            }
+            
+            if (gapB && b != null) {
+                 m(innerRight, innerBottom);
+                 l(innerLeft, innerBottom);
+                 if (!gapL) {
+                     l(innerLeft, innerTop);
+                     if (!gapT) {
+                         l(innerRight, innerTop);
+                         l(outerRight, outerTop);
+                     }
+                     l(outerLeft, outerTop);
+                 }
+                 l(outerLeft, outerBottom);
+                 l(outerRight, outerBottom);
+                 paint(b);
+            }
+            
+            if (gapL && l != null) {
+                m(innerLeft, innerBottom);
+                l(innerLeft, innerTop);
+                if (!gapT) {
+                     l(innerRight, innerTop);
+                     if (!gapR) {
+                          l(innerRight, innerBottom);
+                          l(outerRight, outerBottom);
+                     }
+                     l(outerRight, outerTop);
+                }
+                l(outerLeft, outerTop);
+                l(outerLeft, outerBottom);
+                paint(l);
+            }
+        }
+        
+        private void paintAllInOneColor() {
+        	m(innerLeft, innerTop);
+            l(innerRight, innerTop);
+            l(innerRight, innerBottom);
+            l(innerLeft, innerBottom);
+            currentStream.add("h\n");
+            m(outerLeft, outerTop);
+            l(outerLeft, outerBottom);
+            l(outerRight, outerBottom);
+            l(outerRight, outerTop);
+            currentStream.add("h\n");
+            paint(t);
+        }
+
+        private void m(int x, int y) {
+            currentStream.add((x / 1000f) + " " + (y / 1000f) + " m\n");
+        }
+        
+        private void l(int x, int y) {
+            currentStream.add((x / 1000f) + " " + (y / 1000f) + " l\n");
+        }
+        
+        private void paint(ColorType color) {
+            PDFColor pdfColor = new PDFColor(color);
+            currentStream.add(pdfColor.getColorSpaceOut(true));
+            currentStream.add("h f\n");
+        }
+    }
+    /**
+     * Paint the border as prescribed by <code>bp</code>
+     * just outside of (innerLeft, innerTop, w, h) rectangle.
+     * 
+     * This method paints borders as filled shapes.
+     * Corner areas are divided between adjacent borders
+     * by diagonal. By experiment it has been found out
+     * that such division allowes Acrobat Reader 6 to avoid
+     * certain pixel errors related to antialiasing which it
+     * makes if we parint each of 4 borders as a separate
+     * rectangle. This also helps to gracefully handle the
+     * situation when adjacent borders are of different colors.
+     * 
+     * Another option would be just to paint 4 lines, then
+     * we would be able to handle line patterns. On the downside
+     * then we would be unable to handle colors gracefully.
+     * It's always a trade-off.
+     * 
+     * Hmm.. would simulating line patter by outputting multiple
+     * small painter areas really help us? Or would impact
+     * performance and size of generated files too dramatically?
+     */
+	protected void doBorder( BorderAndPadding bp,
+            int x, int y,
+            int w, int h )
+	{
+        if (bp == null)
+            return;
+        
+        BorderPainter painter = new BorderPainter(currentStream,
+                bp, x, y, w, h);
+        
+        if (painter.willPaint()) {
+            closeText();
+            currentStream.add("ET\nq\n");
+            painter.paint();
+            currentStream.add("\nQ\nBT\n");
+        }
+	}
 
     /**
      * Renders an image, clipping it as specified.
diff -ru ../orig/fop-0.20.5\src\org\apache\fop\render\PrintRenderer.java fop-0.20.5\src\org\apache\fop\render\PrintRenderer.java
--- ../orig/fop-0.20.5\src\org\apache\fop\render\PrintRenderer.java	Tue Jul 15 04:03:14 2003
+++ fop-0.20.5\src\org\apache\fop\render\PrintRenderer.java	Tue Sep 07 18:36:40 2004
@@ -219,6 +219,38 @@
         addRect(x, y, w, h, pdfcol, pdfcol);
     }
 
+    /**
+     * Draw frame around (rx,ry,w,h) area as prescribed by <code>bp</code>.
+     * 
+     * This is just the default implementation, subclasses are encouraged to
+     * override this implementation in order to provider better respect to line
+     * style, etc.
+     */
+    protected void doBorder(BorderAndPadding bp, int rx, int ry, int w, int h) {
+        if (bp == null)
+            return;
+        int left = bp.getBorderLeftWidth(false);
+        int right = bp.getBorderRightWidth(false);
+        int top = bp.getBorderTopWidth(false);
+        int bottom = bp.getBorderBottomWidth(false);
+        
+        if (top != 0)
+            addFilledRect(rx, ry, w, top,
+                          new PDFColor(bp.getBorderColor(BorderAndPadding.TOP)));
+        if (left != 0)
+            addFilledRect(rx - left, ry - h - bottom, left, h + top + bottom,
+                          new PDFColor(bp.getBorderColor(BorderAndPadding.LEFT)));
+        if (right != 0)
+            addFilledRect(rx + w, ry - h - bottom, right, h + top + bottom,
+                          new PDFColor(bp.getBorderColor(BorderAndPadding.RIGHT)));
+        if (bottom != 0)
+            addFilledRect(rx, ry - h - bottom, w, bottom,
+                          new PDFColor(bp.getBorderColor(BorderAndPadding.BOTTOM)));
+    }
+
+    /**
+     * Draw filled frame
+     */
     protected void doFrame(Area area) {
         int w, h;
         int rx = this.currentAreaContainerXPosition;
@@ -235,49 +267,9 @@
 
         doBackground(area, rx, ry, w, h);
 
-        // rx = rx - area.getBorderLeftWidth();
-        // ry = ry + area.getBorderTopWidth();
-        // w = w + area.getBorderLeftWidth() + area.getBorderRightWidth();
-        // h = h + area.getBorderTopWidth() + area.getBorderBottomWidth();
-
-        // Handle line style
-        // Offset for haft the line width!
         BorderAndPadding bp = area.getBorderAndPadding();
-        // int left = rx - area.getBorderLeftWidth() / 2;
-        // int right = rx + w + area.getBorderRightWidth() / 2;
-        // int top = ry + area.getBorderTopWidth() / 2;
-        // int bottom = ry - h - area.getBorderBottomWidth() / 2;
-        // if (area.getBorderTopWidth() != 0)
-        // addLine(left, top, right, top, area.getBorderTopWidth(),
-        // new PDFColor(bp.getBorderColor(BorderAndPadding.TOP)));
-        // if (area.getBorderLeftWidth() != 0)
-        // addLine(left, ry + area.getBorderTopWidth(), left, bottom, area.getBorderLeftWidth(),
-        // new PDFColor(bp.getBorderColor(BorderAndPadding.LEFT)));
-        // if (area.getBorderRightWidth() != 0)
-        // addLine(right, ry + area.getBorderTopWidth(), right, bottom, area.getBorderRightWidth(),
-        // new PDFColor(bp.getBorderColor(BorderAndPadding.RIGHT)));
-        // if (area.getBorderBottomWidth() != 0)
-        // addLine(rx - area.getBorderLeftWidth(), bottom, rx + w + area.getBorderRightWidth(), bottom, area.getBorderBottomWidth(),
-        // new PDFColor(bp.getBorderColor(BorderAndPadding.BOTTOM)));
-        // Try using rectangles instead of lines. Line style will be a
-        // problem though?
-        int left = area.getBorderLeftWidth();
-        int right = area.getBorderRightWidth();
-        int top = area.getBorderTopWidth();
-        int bottom = area.getBorderBottomWidth();
-        // If style is solid, use filled rectangles
-        if (top != 0)
-            addFilledRect(rx, ry, w, top,
-                          new PDFColor(bp.getBorderColor(BorderAndPadding.TOP)));
-        if (left != 0)
-            addFilledRect(rx - left, ry - h - bottom, left, h + top + bottom,
-                          new PDFColor(bp.getBorderColor(BorderAndPadding.LEFT)));
-        if (right != 0)
-            addFilledRect(rx + w, ry - h - bottom, right, h + top + bottom,
-                          new PDFColor(bp.getBorderColor(BorderAndPadding.RIGHT)));
-        if (bottom != 0)
-            addFilledRect(rx, ry - h - bottom, w, bottom,
-                          new PDFColor(bp.getBorderColor(BorderAndPadding.BOTTOM)));
+
+        doBorder(bp, rx, ry, w, h);
     }
 
     /**
