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 ga...@apache.org on 2012/02/26 03:29:29 UTC

svn commit: r1293736 [20/38] - in /xmlgraphics/fop/trunk: ./ src/codegen/java/org/apache/fop/tools/ src/codegen/unicode/java/org/apache/fop/complexscripts/ src/codegen/unicode/java/org/apache/fop/complexscripts/bidi/ src/documentation/content/xdocs/tru...

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java Sun Feb 26 02:29:01 2012
@@ -73,29 +73,31 @@ public abstract class AbstractPathOrient
      * @param block the block to render the traits
      */
     protected void handleBlockTraits(Block block) {
-        int borderPaddingStart = block.getBorderAndPaddingWidthStart();
-        int borderPaddingBefore = block.getBorderAndPaddingWidthBefore();
+        float borderPaddingStart = block.getBorderAndPaddingWidthStart() / 1000f;
+        float borderPaddingEnd = block.getBorderAndPaddingWidthEnd() / 1000f;
+        float borderPaddingBefore = block.getBorderAndPaddingWidthBefore() / 1000f;
+        float borderPaddingAfter = block.getBorderAndPaddingWidthAfter() / 1000f;
 
         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;
+        int level = block.getBidiLevel();
+        if ( ( level == -1 ) || ( ( level & 1 ) == 0 ) ) {
+            startx += block.getStartIndent() / 1000f; 
+            startx -= borderPaddingStart;
+        } else {
+            startx += block.getEndIndent() / 1000f; 
+            startx -= borderPaddingEnd;
+        }
 
-        drawBackAndBorders(block, startx, starty,
-            width, height);
+        width += borderPaddingStart;
+        width += borderPaddingEnd;
+        height += borderPaddingBefore;
+        height += borderPaddingAfter;
+
+        drawBackAndBorders(block, startx, starty, width, height);
     }
 
     /**
@@ -114,7 +116,12 @@ public abstract class AbstractPathOrient
 
         // adjust the current position according to region borders and padding
         currentBPPosition = referenceArea.getBorderAndPaddingWidthBefore();
-        currentIPPosition = referenceArea.getBorderAndPaddingWidthStart();
+        int level = region.getBidiLevel();
+        if ( ( level == -1 ) || ( ( level & 1 ) == 0 ) ) {
+            currentIPPosition = referenceArea.getBorderAndPaddingWidthStart();
+        } else {
+            currentIPPosition = referenceArea.getBorderAndPaddingWidthEnd();
+        }
         // draw background (traits are in the RegionViewport)
         // and borders (traits are in the RegionReference)
         drawBackAndBorders(region, referenceArea, startx, starty, width, height);
@@ -161,9 +168,9 @@ public abstract class AbstractPathOrient
 
         drawBackground(startx, starty, width, height,
                 (Trait.Background) backgroundArea.getTrait(Trait.BACKGROUND),
-                bpsBefore, bpsAfter, bpsStart, bpsEnd);
+                    bpsBefore, bpsAfter, bpsStart, bpsEnd, backgroundArea.getBidiLevel());
         drawBorders(startx, starty, width, height,
-                bpsBefore, bpsAfter, bpsStart, bpsEnd);
+                    bpsBefore, bpsAfter, bpsStart, bpsEnd, borderArea.getBidiLevel());
     }
 
     /**
@@ -179,11 +186,44 @@ public abstract class AbstractPathOrient
      * @param bpsAfter the border-after traits
      * @param bpsStart the border-start traits
      * @param bpsEnd the border-end traits
+     * @param level of bidirectional embedding
      */
     protected void drawBackground(                               // CSOK: ParameterNumber
             float startx, float starty, float width, float height, Trait.Background back,
             BorderProps bpsBefore, BorderProps bpsAfter,
-            BorderProps bpsStart, BorderProps bpsEnd) {
+            BorderProps bpsStart, BorderProps bpsEnd, int level) {
+        BorderProps bpsTop = bpsBefore;
+        BorderProps bpsBottom = bpsAfter;
+        BorderProps bpsLeft;
+        BorderProps bpsRight;
+        if ( ( level == -1 ) || ( ( level & 1 ) == 0 ) ) {
+            bpsLeft = bpsStart;
+            bpsRight = bpsEnd;
+        } else {
+            bpsLeft = bpsEnd;
+            bpsRight = bpsStart;
+        }
+        drawBackground(startx, starty, width, height, back, bpsTop, bpsBottom, bpsLeft, bpsRight);
+    }
+
+    /**
+     * Draw the background.
+     * This draws the background given the position and the traits.
+     *
+     * @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
+     * @param back the background traits
+     * @param bpsTop the border specification on the top edge
+     * @param bpsBottom the border traits associated with bottom edge
+     * @param bpsLeft the border specification on the left edge
+     * @param bpsRight the border specification on the right edge
+     */
+    protected void drawBackground(                               // CSOK: ParameterNumber
+            float startx, float starty, float width, float height, Trait.Background back,
+            BorderProps bpsTop, BorderProps bpsBottom,
+            BorderProps bpsLeft, BorderProps bpsRight) {
         if (back != null) {
             endTextObject();
 
@@ -192,19 +232,19 @@ public abstract class AbstractPathOrient
             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 (bpsLeft != null) {
+                sx += bpsLeft.width / 1000f;
+                paddRectWidth -= bpsLeft.width / 1000f;
+            }
+            if (bpsTop != null) {
+                sy += bpsTop.width / 1000f;
+                paddRectHeight -= bpsTop.width / 1000f;
             }
-            if (bpsEnd != null) {
-                paddRectWidth -= bpsEnd.width / 1000f;
+            if (bpsRight != null) {
+                paddRectWidth -= bpsRight.width / 1000f;
             }
-            if (bpsAfter != null) {
-                paddRectHeight -= bpsAfter.width / 1000f;
+            if (bpsBottom != null) {
+                paddRectHeight -= bpsBottom.width / 1000f;
             }
 
             if (back.getColor() != null) {
@@ -264,86 +304,99 @@ public abstract class AbstractPathOrient
      * @param starty the start y position
      * @param width the width of the area
      * @param height the height of the area
-     * @param bpsBefore the border-before traits
-     * @param bpsAfter the border-after traits
-     * @param bpsStart the border-start traits
-     * @param bpsEnd the border-end traits
+     * @param bpsBefore the border traits associated with before edge
+     * @param bpsAfter the border traits associated with after edge
+     * @param bpsStart the border traits associated with start edge
+     * @param bpsEnd the border traits associated with end edge
+     * @param level of bidirectional embedding
      */
     protected void drawBorders(                                  // CSOK: ParameterNumber
             float startx, float starty, float width, float height,
             BorderProps bpsBefore, BorderProps bpsAfter,
-            BorderProps bpsStart, BorderProps bpsEnd) {
+            BorderProps bpsStart, BorderProps bpsEnd, int level) {
         Rectangle2D.Float borderRect = new Rectangle2D.Float(startx, starty, width, height);
-        drawBorders(borderRect, bpsBefore, bpsAfter, bpsStart, bpsEnd);
+        BorderProps bpsTop = bpsBefore;
+        BorderProps bpsBottom = bpsAfter;
+        BorderProps bpsLeft;
+        BorderProps bpsRight;
+        if ( ( level == -1 ) || ( ( level & 1 ) == 0 ) ) {
+            bpsLeft = bpsStart;
+            bpsRight = bpsEnd;
+        } else {
+            bpsLeft = bpsEnd;
+            bpsRight = bpsStart;
+        }
+        drawBorders(borderRect, bpsTop, bpsBottom, bpsLeft, bpsRight);
     }
 
-    private static final int BEFORE = 0;
-    private static final int END = 1;
-    private static final int AFTER = 2;
-    private static final int START = 3;
+    private static final int TOP = 0;
+    private static final int RIGHT = 1;
+    private static final int BOTTOM = 2;
+    private static final int LEFT = 3;
 
     /**
      * 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
+     * @param bpsTop the border specification on the top edge
+     * @param bpsBottom the border traits associated with bottom edge
+     * @param bpsLeft the border specification on the left edge
+     * @param bpsRight the border specification on the right edge
      */
     protected void drawBorders(                                  // CSOK: MethodLength
             Rectangle2D.Float borderRect,
-            BorderProps bpsBefore, BorderProps bpsAfter, BorderProps bpsStart, BorderProps bpsEnd) {
+            BorderProps bpsTop, BorderProps bpsBottom, BorderProps bpsLeft, BorderProps bpsRight) {
         //TODO generalize each of the four conditions into using a parameterized drawBorder()
         boolean[] border = new boolean[] {
-                (bpsBefore != null), (bpsEnd != null),
-                (bpsAfter != null), (bpsStart != null)};
+                (bpsTop != null), (bpsRight != null),
+                (bpsBottom != null), (bpsLeft != null)};
         float startx = borderRect.x;
         float starty = borderRect.y;
         float width = borderRect.width;
         float height = borderRect.height;
         float[] borderWidth = new float[] {
-            (border[BEFORE] ? bpsBefore.width / 1000f : 0.0f),
-            (border[END] ? bpsEnd.width / 1000f : 0.0f),
-            (border[AFTER] ? bpsAfter.width / 1000f : 0.0f),
-            (border[START] ? bpsStart.width / 1000f : 0.0f)};
+            (border[TOP] ? bpsTop.width / 1000f : 0.0f),
+            (border[RIGHT] ? bpsRight.width / 1000f : 0.0f),
+            (border[BOTTOM] ? bpsBottom.width / 1000f : 0.0f),
+            (border[LEFT] ? bpsLeft.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[BEFORE];
-        height -= clipw[BEFORE];
-        height -= clipw[AFTER];
-        startx += clipw[START];
-        width -= clipw[START];
-        width -= clipw[END];
+            BorderProps.getClippedWidth(bpsTop) / 1000f,
+            BorderProps.getClippedWidth(bpsRight) / 1000f,
+            BorderProps.getClippedWidth(bpsBottom) / 1000f,
+            BorderProps.getClippedWidth(bpsLeft) / 1000f};
+
+        starty += clipw[TOP];
+        height -= clipw[TOP];
+        height -= clipw[BOTTOM];
+        startx += clipw[LEFT];
+        width -= clipw[LEFT];
+        width -= clipw[RIGHT];
 
         boolean[] slant = new boolean[] {
-            (border[START] && border[BEFORE]),
-            (border[BEFORE] && border[END]),
-            (border[END] && border[AFTER]),
-            (border[AFTER] && border[START])};
-        if (bpsBefore != null) {
+            (border[LEFT] && border[TOP]),
+            (border[TOP] && border[RIGHT]),
+            (border[RIGHT] && border[BOTTOM]),
+            (border[BOTTOM] && border[LEFT])};
+        if (bpsTop != null) {
             endTextObject();
 
             float sx1 = startx;
-            float sx2 = (slant[BEFORE] ? sx1 + borderWidth[START] - clipw[START] : sx1);
+            float sx2 = (slant[TOP] ? sx1 + borderWidth[LEFT] - clipw[LEFT] : sx1);
             float ex1 = startx + width;
-            float ex2 = (slant[END] ? ex1 - borderWidth[END] + clipw[END] : ex1);
-            float outery = starty - clipw[BEFORE];
-            float clipy = outery + clipw[BEFORE];
-            float innery = outery + borderWidth[BEFORE];
+            float ex2 = (slant[RIGHT] ? ex1 - borderWidth[RIGHT] + clipw[RIGHT] : ex1);
+            float outery = starty - clipw[TOP];
+            float clipy = outery + clipw[TOP];
+            float innery = outery + borderWidth[TOP];
 
             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[START];
+            if (bpsTop.mode == BorderProps.COLLAPSE_OUTER) {
+                if (bpsLeft != null && bpsLeft.mode == BorderProps.COLLAPSE_OUTER) {
+                    sx1a -= clipw[LEFT];
                 }
-                if (bpsEnd != null && bpsEnd.mode == BorderProps.COLLAPSE_OUTER) {
-                    ex1a += clipw[END];
+                if (bpsRight != null && bpsRight.mode == BorderProps.COLLAPSE_OUTER) {
+                    ex1a += clipw[RIGHT];
                 }
                 lineTo(sx1a, outery);
                 lineTo(ex1a, outery);
@@ -354,30 +407,30 @@ public abstract class AbstractPathOrient
             closePath();
             clip();
             drawBorderLine(sx1a, outery, ex1a, innery, true, true,
-                    bpsBefore.style, bpsBefore.color);
+                    bpsTop.style, bpsTop.color);
             restoreGraphicsState();
         }
-        if (bpsEnd != null) {
+        if (bpsRight != null) {
             endTextObject();
 
             float sy1 = starty;
-            float sy2 = (slant[END] ? sy1 + borderWidth[BEFORE] - clipw[BEFORE] : sy1);
+            float sy2 = (slant[RIGHT] ? sy1 + borderWidth[TOP] - clipw[TOP] : sy1);
             float ey1 = starty + height;
-            float ey2 = (slant[AFTER] ? ey1 - borderWidth[AFTER] + clipw[AFTER] : ey1);
-            float outerx = startx + width + clipw[END];
-            float clipx = outerx - clipw[END];
-            float innerx = outerx - borderWidth[END];
+            float ey2 = (slant[BOTTOM] ? ey1 - borderWidth[BOTTOM] + clipw[BOTTOM] : ey1);
+            float outerx = startx + width + clipw[RIGHT];
+            float clipx = outerx - clipw[RIGHT];
+            float innerx = outerx - borderWidth[RIGHT];
 
             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[BEFORE];
+            if (bpsRight.mode == BorderProps.COLLAPSE_OUTER) {
+                if (bpsTop != null && bpsTop.mode == BorderProps.COLLAPSE_OUTER) {
+                    sy1a -= clipw[TOP];
                 }
-                if (bpsAfter != null && bpsAfter.mode == BorderProps.COLLAPSE_OUTER) {
-                    ey1a += clipw[AFTER];
+                if (bpsBottom != null && bpsBottom.mode == BorderProps.COLLAPSE_OUTER) {
+                    ey1a += clipw[BOTTOM];
                 }
                 lineTo(outerx, sy1a);
                 lineTo(outerx, ey1a);
@@ -387,30 +440,31 @@ public abstract class AbstractPathOrient
             lineTo(innerx, sy2);
             closePath();
             clip();
-            drawBorderLine(innerx, sy1a, outerx, ey1a, false, false, bpsEnd.style, bpsEnd.color);
+            drawBorderLine(innerx, sy1a, outerx, ey1a, false, false,
+                           bpsRight.style, bpsRight.color);
             restoreGraphicsState();
         }
-        if (bpsAfter != null) {
+        if (bpsBottom != null) {
             endTextObject();
 
             float sx1 = startx;
-            float sx2 = (slant[START] ? sx1 + borderWidth[START] - clipw[START] : sx1);
+            float sx2 = (slant[LEFT] ? sx1 + borderWidth[LEFT] - clipw[LEFT] : sx1);
             float ex1 = startx + width;
-            float ex2 = (slant[AFTER] ? ex1 - borderWidth[END] + clipw[END] : ex1);
-            float outery = starty + height + clipw[AFTER];
-            float clipy = outery - clipw[AFTER];
-            float innery = outery - borderWidth[AFTER];
+            float ex2 = (slant[BOTTOM] ? ex1 - borderWidth[RIGHT] + clipw[RIGHT] : ex1);
+            float outery = starty + height + clipw[BOTTOM];
+            float clipy = outery - clipw[BOTTOM];
+            float innery = outery - borderWidth[BOTTOM];
 
             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[START];
+            if (bpsBottom.mode == BorderProps.COLLAPSE_OUTER) {
+                if (bpsLeft != null && bpsLeft.mode == BorderProps.COLLAPSE_OUTER) {
+                    sx1a -= clipw[LEFT];
                 }
-                if (bpsEnd != null && bpsEnd.mode == BorderProps.COLLAPSE_OUTER) {
-                    ex1a += clipw[END];
+                if (bpsRight != null && bpsRight.mode == BorderProps.COLLAPSE_OUTER) {
+                    ex1a += clipw[RIGHT];
                 }
                 lineTo(ex1a, outery);
                 lineTo(sx1a, outery);
@@ -420,30 +474,31 @@ public abstract class AbstractPathOrient
             lineTo(ex2, innery);
             closePath();
             clip();
-            drawBorderLine(sx1a, innery, ex1a, outery, true, false, bpsAfter.style, bpsAfter.color);
+            drawBorderLine(sx1a, innery, ex1a, outery, true, false,
+                           bpsBottom.style, bpsBottom.color);
             restoreGraphicsState();
         }
-        if (bpsStart != null) {
+        if (bpsLeft != null) {
             endTextObject();
 
             float sy1 = starty;
-            float sy2 = (slant[BEFORE] ? sy1 + borderWidth[BEFORE] - clipw[BEFORE] : sy1);
+            float sy2 = (slant[TOP] ? sy1 + borderWidth[TOP] - clipw[TOP] : sy1);
             float ey1 = sy1 + height;
-            float ey2 = (slant[START] ? ey1 - borderWidth[AFTER] + clipw[AFTER] : ey1);
-            float outerx = startx - clipw[START];
-            float clipx = outerx + clipw[START];
-            float innerx = outerx + borderWidth[START];
+            float ey2 = (slant[LEFT] ? ey1 - borderWidth[BOTTOM] + clipw[BOTTOM] : ey1);
+            float outerx = startx - clipw[LEFT];
+            float clipx = outerx + clipw[LEFT];
+            float innerx = outerx + borderWidth[LEFT];
 
             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[BEFORE];
+            if (bpsLeft.mode == BorderProps.COLLAPSE_OUTER) {
+                if (bpsTop != null && bpsTop.mode == BorderProps.COLLAPSE_OUTER) {
+                    sy1a -= clipw[TOP];
                 }
-                if (bpsAfter != null && bpsAfter.mode == BorderProps.COLLAPSE_OUTER) {
-                    ey1a += clipw[AFTER];
+                if (bpsBottom != null && bpsBottom.mode == BorderProps.COLLAPSE_OUTER) {
+                    ey1a += clipw[BOTTOM];
                 }
                 lineTo(outerx, ey1a);
                 lineTo(outerx, sy1a);
@@ -453,7 +508,7 @@ public abstract class AbstractPathOrient
             lineTo(innerx, ey2);
             closePath();
             clip();
-            drawBorderLine(outerx, sy1a, innerx, ey1a, false, true, bpsStart.style, bpsStart.color);
+            drawBorderLine(outerx, sy1a, innerx, ey1a, false, true, bpsLeft.style, bpsLeft.color);
             restoreGraphicsState();
         }
     }
@@ -466,16 +521,16 @@ public abstract class AbstractPathOrient
      */
     protected void renderInlineAreaBackAndBorders(InlineArea area) {
         float borderPaddingStart = area.getBorderAndPaddingWidthStart() / 1000f;
+        float borderPaddingEnd = area.getBorderAndPaddingWidthEnd() / 1000f;
         float borderPaddingBefore = area.getBorderAndPaddingWidthBefore() / 1000f;
-        float bpwidth = borderPaddingStart
-                + (area.getBorderAndPaddingWidthEnd() / 1000f);
-        float bpheight = borderPaddingBefore
-                + (area.getBorderAndPaddingWidthAfter() / 1000f);
+        float borderPaddingAfter = area.getBorderAndPaddingWidthAfter() / 1000f;
+        float bpwidth = borderPaddingStart + borderPaddingEnd;
+        float bpheight = borderPaddingBefore + borderPaddingAfter;
 
         float height = area.getBPD() / 1000f;
         if (height != 0.0f || bpheight != 0.0f && bpwidth != 0.0f) {
             float x = currentIPPosition / 1000f;
-            float y = (currentBPPosition + area.getOffset()) / 1000f;
+            float y = (currentBPPosition + area.getBlockProgressionOffset()) / 1000f;
             float width = area.getIPD() / 1000f;
             drawBackAndBorders(area, x, y - borderPaddingBefore
                                 , width + bpwidth
@@ -512,10 +567,16 @@ public abstract class AbstractPathOrient
             AffineTransform positionTransform = new AffineTransform();
             positionTransform.translate(bv.getXOffset(), bv.getYOffset());
 
+            int level = bv.getBidiLevel();
             int borderPaddingStart = bv.getBorderAndPaddingWidthStart();
+            int borderPaddingEnd = bv.getBorderAndPaddingWidthEnd();
 
             //"left/"top" (bv.getX/YOffset()) specify the position of the content rectangle
-            positionTransform.translate(-borderPaddingStart, -borderPaddingBefore);
+            if ( ( level == -1 ) || ( ( level & 1 ) == 0 ) ) {
+                positionTransform.translate(-borderPaddingStart, -borderPaddingBefore);
+            } else {
+                positionTransform.translate(-borderPaddingEnd, -borderPaddingBefore);
+            }
 
             //Free transformation for the block-container viewport
             String transf;
@@ -536,14 +597,18 @@ public abstract class AbstractPathOrient
 
             //Background and borders
             float borderPaddingWidth
-                = (borderPaddingStart + bv.getBorderAndPaddingWidthEnd()) / 1000f;
+                = (borderPaddingStart + borderPaddingEnd) / 1000f;
             float borderPaddingHeight
                 = (borderPaddingBefore + bv.getBorderAndPaddingWidthAfter()) / 1000f;
             drawBackAndBorders(bv, 0, 0, width + borderPaddingWidth, height + borderPaddingHeight);
 
             //Shift to content rectangle after border painting
             AffineTransform contentRectTransform = new AffineTransform();
-            contentRectTransform.translate(borderPaddingStart, borderPaddingBefore);
+            if ( ( level == -1 ) || ( ( level & 1 ) == 0 ) ) {
+                contentRectTransform.translate(borderPaddingStart, borderPaddingBefore);
+            } else {
+                contentRectTransform.translate(borderPaddingEnd, borderPaddingBefore);
+            }
 
             if (!contentRectTransform.isIdentity()) {
                 establishTransformationMatrix(contentRectTransform);
@@ -694,25 +759,28 @@ public abstract class AbstractPathOrient
      * @param viewport the viewport to handle
      */
     public void renderInlineViewport(InlineViewport viewport) {
-
+        int level = viewport.getBidiLevel();
         float x = currentIPPosition / 1000f;
-        float y = (currentBPPosition + viewport.getOffset()) / 1000f;
+        float y = (currentBPPosition + viewport.getBlockProgressionOffset()) / 1000f;
         float width = viewport.getIPD() / 1000f;
         float height = viewport.getBPD() / 1000f;
         // TODO: Calculate the border rect correctly.
         float borderPaddingStart = viewport.getBorderAndPaddingWidthStart() / 1000f;
+        float borderPaddingEnd = viewport.getBorderAndPaddingWidthEnd() / 1000f;
         float borderPaddingBefore = viewport.getBorderAndPaddingWidthBefore() / 1000f;
-        float bpwidth = borderPaddingStart
-                + (viewport.getBorderAndPaddingWidthEnd() / 1000f);
-        float bpheight = borderPaddingBefore
-                + (viewport.getBorderAndPaddingWidthAfter() / 1000f);
+        float borderPaddingAfter = viewport.getBorderAndPaddingWidthAfter() / 1000f;
+        float bpwidth = borderPaddingStart + borderPaddingEnd;
+        float bpheight = borderPaddingBefore + borderPaddingAfter;
 
         drawBackAndBorders(viewport, x, y, width + bpwidth, height + bpheight);
 
         if (viewport.hasClip()) {
             saveGraphicsState();
-
-            clipRect(x + borderPaddingStart, y + borderPaddingBefore, width, height);
+            if ( ( level == -1 ) || ( ( level & 1 ) == 0 ) ) {
+                clipRect(x + borderPaddingStart, y + borderPaddingBefore, width, height);
+            } else {
+                clipRect(x + borderPaddingEnd, y + borderPaddingBefore, width, height);
+            }
         }
         super.renderInlineViewport(viewport);
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/AbstractRenderer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/AbstractRenderer.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/AbstractRenderer.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/AbstractRenderer.java Sun Feb 26 02:29:01 2012
@@ -57,6 +57,7 @@ import org.apache.fop.area.RegionViewpor
 import org.apache.fop.area.Span;
 import org.apache.fop.area.Trait;
 import org.apache.fop.area.inline.Container;
+import org.apache.fop.area.inline.FilledArea;
 import org.apache.fop.area.inline.ForeignObject;
 import org.apache.fop.area.inline.Image;
 import org.apache.fop.area.inline.InlineArea;
@@ -402,22 +403,34 @@ public abstract class AbstractRenderer
      * @param mr  The main reference area
      */
     protected void renderMainReference(MainReference mr) {
-        int saveIPPos = currentIPPosition;
-
         Span span = null;
         List spans = mr.getSpans();
         int saveBPPos = currentBPPosition;
         int saveSpanBPPos = saveBPPos;
+        int saveIPPos = currentIPPosition;
         for (int count = 0; count < spans.size(); count++) {
             span = (Span) spans.get(count);
+            int level = span.getBidiLevel();
+            if ( level < 0 ) {
+                level = 0;
+            }
+            if ( ( level & 1 ) == 1 ) {
+                currentIPPosition += span.getIPD();
+                currentIPPosition += mr.getColumnGap();
+            }
             for (int c = 0; c < span.getColumnCount(); c++) {
                 NormalFlow flow = span.getNormalFlow(c);
-
                 if (flow != null) {
                     currentBPPosition = saveSpanBPPos;
+                    if ( ( level & 1 ) == 1 ) {
+                        currentIPPosition -= flow.getIPD();
+                        currentIPPosition -= mr.getColumnGap();
+                    }
                     renderFlow(flow);
-                    currentIPPosition += flow.getIPD();
-                    currentIPPosition += mr.getColumnGap();
+                    if ( ( level & 1 ) == 0 ) {
+                        currentIPPosition += flow.getIPD();
+                        currentIPPosition += mr.getColumnGap();
+                    }
                 }
             }
             currentIPPosition = saveIPPos;
@@ -512,17 +525,10 @@ public abstract class AbstractRenderer
      */
     protected void renderBlocks(Block parent, List blocks) {
         int saveIP = currentIPPosition;
-//        int saveBP = currentBPPosition;
 
         // Calculate the position of the content rectangle.
         if (parent != null && !parent.getTraitAsBoolean(Trait.IS_VIEWPORT_AREA)) {
             currentBPPosition += parent.getBorderAndPaddingWidthBefore();
-            /* This is unnecessary now as we're going to use the *-indent traits
-            currentIPPosition += parent.getBorderAndPaddingWidthStart();
-            Integer spaceStart = (Integer) parent.getTrait(Trait.SPACE_START);
-            if (spaceStart != null) {
-                currentIPPosition += spaceStart.intValue();
-            }*/
         }
 
         // the position of the containing block is used for
@@ -541,15 +547,19 @@ public abstract class AbstractRenderer
                 renderBlock((Block) obj);
                 containingBPPosition = contBP;
                 containingIPPosition = contIP;
-            } else {
+            } else if (obj instanceof LineArea) {
                 // a line area is rendered from the top left position
                 // of the line, each inline object is offset from there
                 LineArea line = (LineArea) obj;
-                currentIPPosition = contIP
-                        + parent.getStartIndent()
-                        + line.getStartIndent();
+                if ( parent != null ) {
+                    int level = parent.getBidiLevel();
+                    if ( ( level == -1 ) || ( ( level & 1 ) == 0 ) ) {
+                        currentIPPosition += parent.getStartIndent(); 
+                    } else {
+                        currentIPPosition += parent.getEndIndent(); 
+                    }
+                }
                 renderLineArea(line);
-                //InlineArea child = (InlineArea) line.getInlineAreas().get(0);
                 currentBPPosition += line.getAllocBPD();
             }
             currentIPPosition = saveIP;
@@ -562,6 +572,7 @@ public abstract class AbstractRenderer
      * @param block  The block area
      */
     protected void renderBlock(Block block) {
+        assert block != null;
         List children = block.getChildAreas();
         if (block instanceof BlockViewport) {
             if (children != null) {
@@ -611,13 +622,40 @@ public abstract class AbstractRenderer
         List children = line.getInlineAreas();
         int saveBP = currentBPPosition;
         currentBPPosition += line.getSpaceBefore();
-        for (int count = 0; count < children.size(); count++) {
-            InlineArea inline = (InlineArea) children.get(count);
+        int bl = line.getBidiLevel();
+        if ( bl >= 0 ) {
+            if ( ( bl & 1 ) == 0 ) {
+                currentIPPosition += line.getStartIndent(); 
+            } else {
+                currentIPPosition += line.getEndIndent(); 
+                // if line's content overflows line area, then
+                // ensure that overflow is drawn (extends)
+                // outside of left side of line area
+                int overflow = computeInlinesOverflow ( line );
+                if ( overflow > 0 ) {
+                    currentIPPosition -= overflow;
+                }
+            }
+        } else {
+            currentIPPosition += line.getStartIndent(); 
+        }
+        for (int i = 0, l = children.size(); i < l; i++) {
+            InlineArea inline = (InlineArea) children.get(i);
             renderInlineArea(inline);
         }
         currentBPPosition = saveBP;
     }
 
+    private int computeInlinesOverflow ( LineArea line ) {
+        List children = line.getInlineAreas();
+        int ipdConsumed = 0;
+        for (int i = 0, l = children.size(); i < l; i++) {
+            InlineArea inline = (InlineArea) children.get(i);
+            ipdConsumed += inline.getIPD();
+        }
+        return ipdConsumed - line.getIPD();
+    }
+
     /**
      * Render the given InlineArea.
      * @param inlineArea inline area text to render
@@ -678,11 +716,12 @@ public abstract class AbstractRenderer
      * @param text the text to render
      */
     protected void renderText(TextArea text) {
+        List children = text.getChildAreas();
         int saveIP = currentIPPosition;
         int saveBP = currentBPPosition;
-        Iterator iter = text.getChildAreas().iterator();
-        while (iter.hasNext()) {
-            renderInlineArea((InlineArea) iter.next());
+        for (int i = 0, l = children.size(); i < l; i++) {
+            InlineArea inline = (InlineArea) children.get(i);
+            renderInlineArea(inline);
         }
         currentIPPosition = saveIP + text.getAllocIPD();
     }
@@ -708,14 +747,39 @@ public abstract class AbstractRenderer
      * @param ip the inline parent to render
      */
     protected void renderInlineParent(InlineParent ip) {
+        int level = ip.getBidiLevel();
+        List children = ip.getChildAreas();
         renderInlineAreaBackAndBorders(ip);
         int saveIP = currentIPPosition;
         int saveBP = currentBPPosition;
-        currentIPPosition += ip.getBorderAndPaddingWidthStart();
-        currentBPPosition += ip.getOffset();
-        Iterator iter = ip.getChildAreas().iterator();
-        while (iter.hasNext()) {
-            renderInlineArea((InlineArea) iter.next());
+        // if inline parent is a filled area (generated by Leader), and if
+        // it is right-to-left, then adjust starting ip position in order to
+        // align children to starting (right) edge of filled area
+        int ipAdjust;
+        if ( ( ip instanceof FilledArea ) && ( ( level & 1 ) != 0 ) ) {
+            int ipdChildren = 0;
+            for (int i = 0, l = children.size(); i < l; i++) {
+                InlineArea inline = (InlineArea) children.get(i);
+                ipdChildren += inline.getAllocIPD();
+            }
+            ipAdjust = ip.getAllocIPD() - ipdChildren;
+        } else {
+            ipAdjust = 0;
+        }
+        // perform inline position adjustments
+        if ( ( level == -1 ) || ( ( level & 1 ) == 0 ) ) {
+            currentIPPosition += ip.getBorderAndPaddingWidthStart();
+        } else {
+            currentIPPosition += ip.getBorderAndPaddingWidthEnd();
+            if ( ipAdjust > 0 ) {
+                currentIPPosition += ipAdjust;
+            }
+        }
+        currentBPPosition += ip.getBlockProgressionOffset();
+        // render children inlines
+        for (int i = 0, l = children.size(); i < l; i++) {
+            InlineArea inline = (InlineArea) children.get(i);
+            renderInlineArea(inline);
         }
         currentIPPosition = saveIP + ip.getAllocIPD();
         currentBPPosition = saveBP;
@@ -726,11 +790,16 @@ public abstract class AbstractRenderer
      * @param ibp the inline block parent to render
      */
     protected void renderInlineBlockParent(InlineBlockParent ibp) {
+        int level = ibp.getBidiLevel();
         renderInlineAreaBackAndBorders(ibp);
-        currentIPPosition += ibp.getBorderAndPaddingWidthStart();
+        if ( ( level == -1 ) || ( ( level & 1 ) == 0 ) ) {
+            currentIPPosition += ibp.getBorderAndPaddingWidthStart();
+        } else {
+            currentIPPosition += ibp.getBorderAndPaddingWidthEnd();
+        }
         // For inline content the BP position is updated by the enclosing line area
         int saveBP = currentBPPosition;
-        currentBPPosition += ibp.getOffset();
+        currentBPPosition += ibp.getBlockProgressionOffset();
         renderBlock(ibp.getChildArea());
         currentBPPosition = saveBP;
     }
@@ -742,7 +811,7 @@ public abstract class AbstractRenderer
     protected void renderInlineViewport(InlineViewport viewport) {
         Area content = viewport.getContent();
         int saveBP = currentBPPosition;
-        currentBPPosition += viewport.getOffset();
+        currentBPPosition += viewport.getBlockProgressionOffset();
         Rectangle2D contpos = viewport.getContentPosition();
         if (content instanceof Image) {
             renderImage((Image) content, contpos);

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/DefaultFontResolver.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/DefaultFontResolver.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/DefaultFontResolver.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/DefaultFontResolver.java Sun Feb 26 02:29:01 2012
@@ -44,4 +44,9 @@ public class DefaultFontResolver impleme
         return userAgent.resolveURI(href, userAgent.getFactory().getFontManager().getFontBaseURL());
     }
 
+    /** {@inheritDoc} */
+    public boolean isComplexScriptFeaturesEnabled() {
+        return userAgent.isComplexScriptFeaturesEnabled();
+    }
+
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/PrintRenderer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/PrintRenderer.java?rev=1293736&r1=1293735&r2=1293736&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 Feb 26 02:29:01 2012
@@ -91,7 +91,8 @@ public abstract class PrintRenderer exte
         FontManager fontManager = userAgent.getFactory().getFontManager();
         FontCollection[] fontCollections = new FontCollection[] {
                 new Base14FontCollection(fontManager.isBase14KerningEnabled()),
-                new CustomFontCollection(getFontResolver(), getFontList())
+                new CustomFontCollection(getFontResolver(), getFontList(),
+                                         userAgent.isComplexScriptFeaturesEnabled())
         };
         fontManager.setup(getFontInfo(), fontCollections);
     }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/PrintRendererConfigurator.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/PrintRendererConfigurator.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/PrintRendererConfigurator.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/PrintRendererConfigurator.java Sun Feb 26 02:29:01 2012
@@ -95,7 +95,9 @@ public class PrintRendererConfigurator e
         FontManager fontManager = factory.getFontManager();
         if (fontResolver == null) {
             //Ensure that we have minimal font resolution capabilities
-            fontResolver = FontManager.createMinimalFontResolver();
+            fontResolver
+                = FontManager.createMinimalFontResolver
+                    ( userAgent.isComplexScriptFeaturesEnabled() );
         }
 
         boolean strict = factory.validateUserConfigStrictly();
@@ -128,7 +130,8 @@ public class PrintRendererConfigurator e
             FontEventListener listener = new FontEventAdapter(
                     userAgent.getEventBroadcaster());
             List<EmbedFontInfo> fontList = buildFontList(cfg, fontResolver, listener);
-            fontCollections.add(new CustomFontCollection(fontResolver, fontList));
+            fontCollections.add(new CustomFontCollection(fontResolver, fontList,
+                                userAgent.isComplexScriptFeaturesEnabled()));
         }
 
         fontManager.setup(fontInfo,

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPPainter.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPPainter.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPPainter.java Sun Feb 26 02:29:01 2012
@@ -57,6 +57,7 @@ import org.apache.fop.render.intermediat
 import org.apache.fop.render.intermediate.IFContext;
 import org.apache.fop.render.intermediate.IFException;
 import org.apache.fop.render.intermediate.IFState;
+import org.apache.fop.render.intermediate.IFUtil;
 import org.apache.fop.traits.BorderProps;
 import org.apache.fop.traits.RuleStyle;
 import org.apache.fop.util.CharUtilities;
@@ -259,11 +260,11 @@ public class AFPPainter extends Abstract
 
     /** {@inheritDoc} */
     @Override
-    public void drawBorderRect(Rectangle rect, BorderProps before, BorderProps after,
-            BorderProps start, BorderProps end) throws IFException {
-        if (before != null || after != null || start != null || end != null) {
+    public void drawBorderRect(Rectangle rect, BorderProps top, BorderProps bottom,
+            BorderProps left, BorderProps right) throws IFException {
+        if (top != null || bottom != null || left != null || right != null) {
             try {
-                this.borderPainter.drawBorders(rect, before, after, start, end);
+                this.borderPainter.drawBorders(rect, top, bottom, left, right);
             } catch (IOException ife) {
                 throw new IFException("IO error while painting borders", ife);
             }
@@ -354,8 +355,8 @@ public class AFPPainter extends Abstract
 
     /** {@inheritDoc} */
     public void drawText(                                        // CSOK: MethodLength
-            int x, int y, final int letterSpacing, final int wordSpacing, final int[] dx,
-            final String text) throws IFException {
+            int x, int y, final int letterSpacing, final int wordSpacing,
+            final int[][] dp, final String text) throws IFException {
         final int fontSize = this.state.getFontSize();
         getPaintingState().setFontSize(fontSize);
 
@@ -404,6 +405,7 @@ public class AFPPainter extends Abstract
                     builder.setCodedFont((byte)fontReference);
 
                     int l = text.length();
+                    int[] dx = IFUtil.convertDPToDX ( dp );
                     int dxl = (dx != null ? dx.length : 0);
                     StringBuffer sb = new StringBuffer();
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/bitmap/BitmapRendererConfigurator.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/bitmap/BitmapRendererConfigurator.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/bitmap/BitmapRendererConfigurator.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/bitmap/BitmapRendererConfigurator.java Sun Feb 26 02:29:01 2012
@@ -129,7 +129,8 @@ public class BitmapRendererConfigurator 
             FontEventListener listener = new FontEventAdapter(
                     userAgent.getEventBroadcaster());
             List fontList = buildFontList(cfg, fontResolver, listener);
-            fontCollections.add(new ConfiguredFontCollection(fontResolver, fontList));
+            fontCollections.add(new ConfiguredFontCollection(fontResolver, fontList,
+                                userAgent.isComplexScriptFeaturesEnabled()));
         }
 
         fontManager.setup(fontInfo,

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java Sun Feb 26 02:29:01 2012
@@ -315,55 +315,55 @@ public abstract class AbstractIFPainter 
     }
 
     /** {@inheritDoc} */
-    public void drawBorderRect(Rectangle rect, BorderProps before, BorderProps after,
-            BorderProps start, BorderProps end) throws IFException {
-        if (before != null) {
+    public void drawBorderRect(Rectangle rect, BorderProps top, BorderProps bottom,
+            BorderProps left, BorderProps right) throws IFException {
+        if (top != null) {
             Rectangle b = new Rectangle(
                     rect.x, rect.y,
-                    rect.width, before.width);
-            fillRect(b, before.color);
+                    rect.width, top.width);
+            fillRect(b, top.color);
         }
-        if (end != null) {
+        if (right != null) {
             Rectangle b = new Rectangle(
-                    rect.x + rect.width - end.width, rect.y,
-                    end.width, rect.height);
-            fillRect(b, end.color);
+                    rect.x + rect.width - right.width, rect.y,
+                    right.width, rect.height);
+            fillRect(b, right.color);
         }
-        if (after != null) {
+        if (bottom != null) {
             Rectangle b = new Rectangle(
-                    rect.x, rect.y + rect.height - after.width,
-                    rect.width, after.width);
-            fillRect(b, after.color);
+                    rect.x, rect.y + rect.height - bottom.width,
+                    rect.width, bottom.width);
+            fillRect(b, bottom.color);
         }
-        if (start != null) {
+        if (left != null) {
             Rectangle b = new Rectangle(
                     rect.x, rect.y,
-                    start.width, rect.height);
-            fillRect(b, start.color);
+                    left.width, rect.height);
+            fillRect(b, left.color);
         }
     }
 
     /**
      * Indicates whether the given border segments (if present) have only solid borders, i.e.
      * could be painted in a simplified fashion keeping the output file smaller.
-     * @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)
+     * @param top the border segment on the top edge
+     * @param bottom the border segment on the bottom edge
+     * @param left the border segment on the left edge
+     * @param right the border segment on the right edge
      * @return true if any border segment has a non-solid border style
      */
-    protected boolean hasOnlySolidBorders(BorderProps before, BorderProps after,
-            BorderProps start, BorderProps end) {
-        if (before != null && before.style != Constants.EN_SOLID) {
+    protected boolean hasOnlySolidBorders(BorderProps top, BorderProps bottom,
+            BorderProps left, BorderProps right) {
+        if (top != null && top.style != Constants.EN_SOLID) {
             return false;
         }
-        if (after != null && after.style != Constants.EN_SOLID) {
+        if (bottom != null && bottom.style != Constants.EN_SOLID) {
             return false;
         }
-        if (start != null && start.style != Constants.EN_SOLID) {
+        if (left != null && left.style != Constants.EN_SOLID) {
             return false;
         }
-        if (end != null && end.style != Constants.EN_SOLID) {
+        if (right != null && right.style != Constants.EN_SOLID) {
             return false;
         }
         return true;

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/BorderPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/BorderPainter.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/BorderPainter.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/BorderPainter.java Sun Feb 26 02:29:01 2012
@@ -35,35 +35,35 @@ 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
+     * @param bpsTop the border specification on the top side
+     * @param bpsBottom the border specification on the bottom side
+     * @param bpsLeft the border specification on the left side
+     * @param bpsRight the border specification on the end side
      * @throws IOException if an I/O error occurs while creating the borders
      */
     public void drawBorders(Rectangle borderRect,               // CSOK: MethodLength
-            BorderProps bpsBefore, BorderProps bpsAfter,
-            BorderProps bpsStart, BorderProps bpsEnd) throws IOException {
+            BorderProps bpsTop, BorderProps bpsBottom,
+            BorderProps bpsLeft, BorderProps bpsRight) throws IOException {
         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)};
+            (bpsTop != null), (bpsRight != null),
+            (bpsBottom != null), (bpsLeft != 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)};
+            (b[0] ? bpsTop.width : 0),
+            (b[1] ? bpsRight.width : 0),
+            (b[2] ? bpsBottom.width : 0),
+            (b[3] ? bpsLeft.width : 0)};
         int[] clipw = new int[] {
-            BorderProps.getClippedWidth(bpsBefore),
-            BorderProps.getClippedWidth(bpsEnd),
-            BorderProps.getClippedWidth(bpsAfter),
-            BorderProps.getClippedWidth(bpsStart)};
+            BorderProps.getClippedWidth(bpsTop),
+            BorderProps.getClippedWidth(bpsRight),
+            BorderProps.getClippedWidth(bpsBottom),
+            BorderProps.getClippedWidth(bpsLeft)};
         starty += clipw[0];
         height -= clipw[0];
         height -= clipw[2];
@@ -73,7 +73,7 @@ public abstract class BorderPainter {
 
         boolean[] slant = new boolean[] {
             (b[3] && b[0]), (b[0] && b[1]), (b[1] && b[2]), (b[2] && b[3])};
-        if (bpsBefore != null) {
+        if (bpsTop != null) {
             int sx1 = startx;
             int sx2 = (slant[0] ? sx1 + bw[3] - clipw[3] : sx1);
             int ex1 = startx + width;
@@ -86,11 +86,11 @@ public abstract class BorderPainter {
             moveTo(sx1, clipy);
             int sx1a = sx1;
             int ex1a = ex1;
-            if (bpsBefore.mode == BorderProps.COLLAPSE_OUTER) {
-                if (bpsStart != null && bpsStart.mode == BorderProps.COLLAPSE_OUTER) {
+            if (bpsTop.mode == BorderProps.COLLAPSE_OUTER) {
+                if (bpsLeft != null && bpsLeft.mode == BorderProps.COLLAPSE_OUTER) {
                     sx1a -= clipw[3];
                 }
-                if (bpsEnd != null && bpsEnd.mode == BorderProps.COLLAPSE_OUTER) {
+                if (bpsRight != null && bpsRight.mode == BorderProps.COLLAPSE_OUTER) {
                     ex1a += clipw[1];
                 }
                 lineTo(sx1a, outery);
@@ -102,10 +102,10 @@ public abstract class BorderPainter {
             closePath();
             clip();
             drawBorderLine(sx1a, outery, ex1a, innery, true, true,
-                    bpsBefore.style, bpsBefore.color);
+                    bpsTop.style, bpsTop.color);
             restoreGraphicsState();
         }
-        if (bpsEnd != null) {
+        if (bpsRight != null) {
             int sy1 = starty;
             int sy2 = (slant[1] ? sy1 + bw[0] - clipw[0] : sy1);
             int ey1 = starty + height;
@@ -118,11 +118,11 @@ public abstract class BorderPainter {
             moveTo(clipx, sy1);
             int sy1a = sy1;
             int ey1a = ey1;
-            if (bpsEnd.mode == BorderProps.COLLAPSE_OUTER) {
-                if (bpsBefore != null && bpsBefore.mode == BorderProps.COLLAPSE_OUTER) {
+            if (bpsRight.mode == BorderProps.COLLAPSE_OUTER) {
+                if (bpsTop != null && bpsTop.mode == BorderProps.COLLAPSE_OUTER) {
                     sy1a -= clipw[0];
                 }
-                if (bpsAfter != null && bpsAfter.mode == BorderProps.COLLAPSE_OUTER) {
+                if (bpsBottom != null && bpsBottom.mode == BorderProps.COLLAPSE_OUTER) {
                     ey1a += clipw[2];
                 }
                 lineTo(outerx, sy1a);
@@ -133,10 +133,11 @@ public abstract class BorderPainter {
             lineTo(innerx, sy2);
             closePath();
             clip();
-            drawBorderLine(innerx, sy1a, outerx, ey1a, false, false, bpsEnd.style, bpsEnd.color);
+            drawBorderLine(innerx, sy1a, outerx, ey1a, false, false,
+                           bpsRight.style, bpsRight.color);
             restoreGraphicsState();
         }
-        if (bpsAfter != null) {
+        if (bpsBottom != null) {
             int sx1 = startx;
             int sx2 = (slant[3] ? sx1 + bw[3] - clipw[3] : sx1);
             int ex1 = startx + width;
@@ -149,11 +150,11 @@ public abstract class BorderPainter {
             moveTo(ex1, clipy);
             int sx1a = sx1;
             int ex1a = ex1;
-            if (bpsAfter.mode == BorderProps.COLLAPSE_OUTER) {
-                if (bpsStart != null && bpsStart.mode == BorderProps.COLLAPSE_OUTER) {
+            if (bpsBottom.mode == BorderProps.COLLAPSE_OUTER) {
+                if (bpsLeft != null && bpsLeft.mode == BorderProps.COLLAPSE_OUTER) {
                     sx1a -= clipw[3];
                 }
-                if (bpsEnd != null && bpsEnd.mode == BorderProps.COLLAPSE_OUTER) {
+                if (bpsRight != null && bpsRight.mode == BorderProps.COLLAPSE_OUTER) {
                     ex1a += clipw[1];
                 }
                 lineTo(ex1a, outery);
@@ -164,10 +165,11 @@ public abstract class BorderPainter {
             lineTo(ex2, innery);
             closePath();
             clip();
-            drawBorderLine(sx1a, innery, ex1a, outery, true, false, bpsAfter.style, bpsAfter.color);
+            drawBorderLine(sx1a, innery, ex1a, outery, true, false,
+                           bpsBottom.style, bpsBottom.color);
             restoreGraphicsState();
         }
-        if (bpsStart != null) {
+        if (bpsLeft != null) {
             int sy1 = starty;
             int sy2 = (slant[0] ? sy1 + bw[0] - clipw[0] : sy1);
             int ey1 = sy1 + height;
@@ -180,11 +182,11 @@ public abstract class BorderPainter {
             moveTo(clipx, ey1);
             int sy1a = sy1;
             int ey1a = ey1;
-            if (bpsStart.mode == BorderProps.COLLAPSE_OUTER) {
-                if (bpsBefore != null && bpsBefore.mode == BorderProps.COLLAPSE_OUTER) {
+            if (bpsLeft.mode == BorderProps.COLLAPSE_OUTER) {
+                if (bpsTop != null && bpsTop.mode == BorderProps.COLLAPSE_OUTER) {
                     sy1a -= clipw[0];
                 }
-                if (bpsAfter != null && bpsAfter.mode == BorderProps.COLLAPSE_OUTER) {
+                if (bpsBottom != null && bpsBottom.mode == BorderProps.COLLAPSE_OUTER) {
                     ey1a += clipw[2];
                 }
                 lineTo(outerx, ey1a);
@@ -195,7 +197,7 @@ public abstract class BorderPainter {
             lineTo(innerx, ey2);
             closePath();
             clip();
-            drawBorderLine(outerx, sy1a, innerx, ey1a, false, true, bpsStart.style, bpsStart.color);
+            drawBorderLine(outerx, sy1a, innerx, ey1a, false, true, bpsLeft.style, bpsLeft.color);
             restoreGraphicsState();
         }
     }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/IFPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/IFPainter.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/IFPainter.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/IFPainter.java Sun Feb 26 02:29:01 2012
@@ -151,12 +151,14 @@ public interface IFPainter {
      * @param y Y-coordinate of the starting point of the text
      * @param letterSpacing additional spacing between characters (may be 0)
      * @param wordSpacing additional spacing between words (may be 0)
-     * @param dx an array of adjustment values for each character in X-direction (may be null)
+     * @param dp an array of 4-tuples, expressing [X,Y] placment
+     * adjustments and [X,Y] advancement adjustments, in that order (may be null); if
+     * not null, then adjustments.length must be the same as text.length()
      * @param text the text
      * @throws IFException if an error occurs while handling this event
      */
     void drawText(int x, int y, int letterSpacing, int wordSpacing,
-            int[] dx, String text) throws IFException;
+            int[][] dp, String text) throws IFException;
 
     /**
      * Restricts the current clipping region with the given rectangle.
@@ -178,15 +180,15 @@ public interface IFPainter {
      * Draws a border rectangle. The border segments are specified through {@link 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)
+     * @param top the border segment on the top edge
+     * @param bottom the border segment on the bottom edge
+     * @param left the border segment on the left edge
+     * @param right the border segment on the right edge
      * @throws IFException if an error occurs while handling this event
      */
     void drawBorderRect(Rectangle rect,
-            BorderProps before, BorderProps after,
-            BorderProps start, BorderProps end) throws IFException;
+            BorderProps top, BorderProps bottom,
+            BorderProps left, BorderProps right) throws IFException;
 
     /**
      * Draws a line. NOTE: Currently, only horizontal lines are implemented!

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/IFParser.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/IFParser.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/IFParser.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/IFParser.java Sun Feb 26 02:29:01 2012
@@ -618,8 +618,14 @@ public class IFParser implements IFConst
                 s = lastAttributes.getValue("word-spacing");
                 int wordSpacing = (s != null ? Integer.parseInt(s) : 0);
                 int[] dx = XMLUtil.getAttributeAsIntArray(lastAttributes, "dx");
+                int[][] dp = XMLUtil.getAttributeAsPositionAdjustments(lastAttributes, "dp");
+                // if only DX present, then convert DX to DP; otherwise use only DP,
+                // effectively ignoring DX
+                if ( ( dp == null ) && ( dx != null ) ) {
+                    dp = IFUtil.convertDXToDP ( dx );
+                }
                 establishStructureTreeElement(lastAttributes);
-                painter.drawText(x, y, letterSpacing, wordSpacing, dx, content.toString());
+                painter.drawText(x, y, letterSpacing, wordSpacing, dp, content.toString());
                 resetStructureTreeElement();
             }
 
@@ -679,7 +685,7 @@ public class IFParser implements IFConst
 
         }
 
-        private static final String[] SIDES = new String[] {"before", "after", "start", "end"};
+        private static final String[] SIDES = new String[] {"top", "bottom", "left", "right"};
 
         private class BorderRectHandler extends AbstractElementHandler {
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/IFRenderer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/IFRenderer.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/IFRenderer.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/IFRenderer.java Sun Feb 26 02:29:01 2012
@@ -61,6 +61,7 @@ import org.apache.fop.area.BlockViewport
 import org.apache.fop.area.BookmarkData;
 import org.apache.fop.area.CTM;
 import org.apache.fop.area.DestinationData;
+import org.apache.fop.area.LineArea;
 import org.apache.fop.area.OffDocumentExtensionAttachment;
 import org.apache.fop.area.OffDocumentItem;
 import org.apache.fop.area.PageSequence;
@@ -488,7 +489,8 @@ public class IFRenderer extends Abstract
         if (hasDocumentNavigation() && id != null) {
             int extraMarginBefore = 5000; // millipoints
             int ipp = currentIPPosition;
-            int bpp = currentBPPosition + inlineArea.getOffset() - extraMarginBefore;
+            int bpp = currentBPPosition
+                + inlineArea.getBlockProgressionOffset() - extraMarginBefore;
             saveAbsolutePosition(id, ipp, bpp);
         }
     }
@@ -919,7 +921,7 @@ public class IFRenderer extends Abstract
         AbstractAction action = null;
         // make sure the rect is determined *before* calling super!
         int ipp = currentIPPosition;
-        int bpp = currentBPPosition + ip.getOffset();
+        int bpp = currentBPPosition + ip.getBlockProgressionOffset();
         ipRect = new Rectangle(ipp, bpp, ip.getIPD(), ip.getBPD());
         AffineTransform transform = graphicContext.getTransform();
         ipRect = transform.createTransformedShape(ipRect).getBounds();
@@ -1031,7 +1033,7 @@ public class IFRenderer extends Abstract
         }
 
         int rx = currentIPPosition + text.getBorderAndPaddingWidthStart();
-        int bl = currentBPPosition + text.getOffset() + text.getBaselineOffset();
+        int bl = currentBPPosition + text.getBlockProgressionOffset() + text.getBaselineOffset();
         textUtil.flush();
         textUtil.setStartPosition(rx, bl);
         textUtil.setSpacing(text.getTextLetterSpaceAdjust(), text.getTextWordSpaceAdjust());
@@ -1047,7 +1049,12 @@ public class IFRenderer extends Abstract
         Font font = getFontFromArea(word.getParentArea());
         String s = word.getWord();
 
-        renderText(s, word.getLetterAdjustArray(),
+        int[][] dp = word.getGlyphPositionAdjustments();
+        if ( dp == null ) {
+            dp = IFUtil.convertDXToDP ( word.getLetterAdjustArray() );
+        }
+
+        renderText(s, dp, word.isReversed(),
                 font, (AbstractTextArea)word.getParentArea());
 
         super.renderWord(word);
@@ -1059,7 +1066,7 @@ public class IFRenderer extends Abstract
         String s = space.getSpace();
 
         AbstractTextArea textArea = (AbstractTextArea)space.getParentArea();
-        renderText(s, null, font, textArea);
+        renderText(s, null, false, font, textArea);
 
         if (textUtil.combined && space.isAdjustable()) {
             //Used for justified text, for example
@@ -1072,24 +1079,32 @@ public class IFRenderer extends Abstract
         super.renderSpace(space);
     }
 
+    private void renderText(String s,
+                              int[][] dp, boolean reversed,
+                              Font font, AbstractTextArea parentArea) {
+        if ( ( dp == null ) || IFUtil.isDPOnlyDX ( dp ) ) {
+            int[] dx = IFUtil.convertDPToDX ( dp );
+            renderTextWithAdjustments ( s, dx, reversed, font, parentArea );
+        } else {
+            renderTextWithAdjustments ( s, dp, reversed, font, parentArea );
+        }
+    }
+
     /**
-     * Does low-level rendering of text.
+     * Does low-level rendering of text using DX only position adjustments.
      * @param s text to render
-     * @param letterAdjust an array of widths for letter adjustment (may be null)
+     * @param dx an array of widths for letter adjustment (may be null)
+     * @param reversed if true then text has been reversed (from logical order)
      * @param font to font in use
      * @param parentArea the parent text area to retrieve certain traits from
      */
-    protected void renderText(String s,
-                           int[] letterAdjust,
-                           Font font, AbstractTextArea parentArea) {
+    private void renderTextWithAdjustments(String s,
+                              int[] dx, boolean reversed,
+                              Font font, AbstractTextArea parentArea) {
         int l = s.length();
         if (l == 0) {
             return;
         }
-
-        if (letterAdjust != null) {
-            textUtil.adjust(letterAdjust[0]);
-        }
         for (int i = 0; i < l; i++) {
             char ch = s.charAt(i);
             textUtil.addChar(ch);
@@ -1098,18 +1113,38 @@ public class IFRenderer extends Abstract
                 int tls = (i < l - 1 ? parentArea.getTextLetterSpaceAdjust() : 0);
                 glyphAdjust += tls;
             }
-            if (letterAdjust != null && i < l - 1) {
-                glyphAdjust += letterAdjust[i + 1];
+            if (dx != null && i < l) {
+                glyphAdjust += dx[i];
             }
-
             textUtil.adjust(glyphAdjust);
         }
     }
 
+    /**
+     * Does low-level rendering of text using generalized position adjustments.
+     * @param s text to render
+     * @param dp an array of 4-tuples, expressing [X,Y] placment
+     * adjustments and [X,Y] advancement adjustments, in that order (may be null)
+     * @param reversed if true then text has been reversed (from logical order)
+     * @param font to font in use
+     * @param parentArea the parent text area to retrieve certain traits from
+     */
+    private void renderTextWithAdjustments(String s,
+                              int[][] dp, boolean reversed,
+                              Font font, AbstractTextArea parentArea) {
+        assert !textUtil.combined;
+        for ( int i = 0, n = s.length(); i < n; i++ ) {
+            textUtil.addChar ( s.charAt ( i ) );
+            if ( dp != null ) {
+                textUtil.adjust ( dp[i] );
+            }
+        }
+    }
+
     private class TextUtil {
         private static final int INITIAL_BUFFER_SIZE = 16;
-        private int[] dx = new int[INITIAL_BUFFER_SIZE];
-        private int lastDXPos = 0;
+        private int[][] dp = new int[INITIAL_BUFFER_SIZE][4];
+        // private int lastDPPos = 0; // TBD - not yet used
         private final StringBuffer text = new StringBuffer();
         private int startx, starty;
         private int tls, tws;
@@ -1119,25 +1154,41 @@ public class IFRenderer extends Abstract
             text.append(ch);
         }
 
-        void adjust(int adjust) {
-            if (adjust != 0) {
+        void adjust(int dx) {
+            adjust ( new int[] {
+                    dx,                         // xPlaAdjust
+                    0,                          // yPlaAdjust
+                    dx,                         // xAdvAdjust
+                    0                           // yAdvAdjust
+                } );
+        }
+
+        void adjust(int[] pa) {
+            if ( !IFUtil.isPAIdentity ( pa ) ) {
                 int idx = text.length();
-                if (idx > dx.length - 1) {
-                    int newSize = Math.max(dx.length, idx + 1) + INITIAL_BUFFER_SIZE;
-                    int[] newDX = new int[newSize];
-                    System.arraycopy(dx, 0, newDX, 0, dx.length);
-                    dx = newDX;
+                if (idx > dp.length - 1) {
+                    int newSize = Math.max(dp.length, idx + 1) + INITIAL_BUFFER_SIZE;
+                    int[][] newDP = new int[newSize][];
+                    // reuse prior PA[0]...PA[dp.length-1]
+                    System.arraycopy(dp, 0, newDP, 0, dp.length);
+                    // populate new PA[dp.length]...PA[newDP.length-1]
+                    for ( int i = dp.length, n = newDP.length; i < n; i++ ) {
+                        newDP[i] = new int[4];
+                    }
+                    dp = newDP;
                 }
-                dx[idx] += adjust;
-                lastDXPos = idx;
+                IFUtil.adjustPA ( dp[idx - 1], pa );
+                // lastDPPos = idx;
             }
         }
 
         void reset() {
             if (text.length() > 0) {
                 text.setLength(0);
-                Arrays.fill(dx, 0);
-                lastDXPos = 0;
+                for ( int i = 0, n = dp.length; i < n; i++ ) {
+                    Arrays.fill(dp[i], 0);
+                }
+                // lastDPPos = 0;
             }
         }
 
@@ -1154,16 +1205,12 @@ public class IFRenderer extends Abstract
         void flush() {
             if (text.length() > 0) {
                 try {
-                    int[] effDX = null;
-                    if (lastDXPos > 0) {
-                        int size = lastDXPos + 1;
-                        effDX = new int[size];
-                        System.arraycopy(dx, 0, effDX, 0, size);
-                    }
                     if (combined) {
-                        painter.drawText(startx, starty, 0, 0, effDX, text.toString());
+                        painter.drawText(startx, starty, 0, 0,
+                                         trimAdjustments ( dp, text.length() ), text.toString());
                     } else {
-                        painter.drawText(startx, starty, tls, tws, effDX, text.toString());
+                        painter.drawText(startx, starty, tls, tws,
+                                         trimAdjustments ( dp, text.length() ), text.toString());
                     }
                 } catch (IFException e) {
                     handleIFException(e);
@@ -1171,6 +1218,38 @@ public class IFRenderer extends Abstract
                 reset();
             }
         }
+
+        /**
+         * Trim adjustments array <code>dp</code> to be no greater length than
+         * text length, and where trailing all-zero entries are removed.
+         * @param dp a position adjustments array (or null)
+         * @param textLength the length of the associated text
+         * @return either the original value of <code>dp</code> or a copy
+         * of its first N significant adjustment entries, such that N is
+         * no greater than text length, and the last entry has a non-zero
+         * adjustment.
+         */
+        private int[][] trimAdjustments ( int[][] dp, int textLength ) {
+            if ( dp != null ) {
+                int tl = textLength;
+                int pl = dp.length;
+                int i  = ( tl < pl ) ? tl : pl;
+                while ( i > 0 ) {
+                    int[] pa = dp [ i - 1 ];
+                    if ( !IFUtil.isPAIdentity ( pa ) ) {
+                        break;
+                    } else {
+                        i--;
+                    }
+                }
+                if ( i == 0 ) {
+                    dp = null;
+                } else if ( i < pl ) {
+                    dp = IFUtil.copyDP ( dp, 0, i );
+                }
+            }
+            return dp;
+        }
     }
 
     /** {@inheritDoc} */
@@ -1220,7 +1299,7 @@ public class IFRenderer extends Abstract
         int style = area.getRuleStyle();
         int ruleThickness = area.getRuleThickness();
         int startx = currentIPPosition + area.getBorderAndPaddingWidthStart();
-        int starty = currentBPPosition + area.getOffset() + (ruleThickness / 2);
+        int starty = currentBPPosition + area.getBlockProgressionOffset() + (ruleThickness / 2);
         int endx = currentIPPosition
                         + area.getBorderAndPaddingWidthStart()
                         + area.getIPD();
@@ -1262,10 +1341,21 @@ public class IFRenderer extends Abstract
             float startx, float starty,
             float width, float height,
             BorderProps bpsBefore, BorderProps bpsAfter,
-            BorderProps bpsStart, BorderProps bpsEnd) {
+            BorderProps bpsStart, BorderProps bpsEnd, int level) {
         Rectangle rect = toMillipointRectangle(startx, starty, width, height);
         try {
-            painter.drawBorderRect(rect, bpsBefore, bpsAfter, bpsStart, bpsEnd);
+            BorderProps bpsTop = bpsBefore;
+            BorderProps bpsBottom = bpsAfter;
+            BorderProps bpsLeft;
+            BorderProps bpsRight;
+            if ( ( level == -1 ) || ( ( level & 1 ) == 0 ) ) {
+                bpsLeft = bpsStart;
+                bpsRight = bpsEnd;
+            } else {
+                bpsLeft = bpsEnd;
+                bpsRight = bpsStart;
+            }
+            painter.drawBorderRect(rect, bpsTop, bpsBottom, bpsLeft, bpsRight);
         } catch (IFException ife) {
             handleIFException(ife);
         }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/IFSerializer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/IFSerializer.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/IFSerializer.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/IFSerializer.java Sun Feb 26 02:29:01 2012
@@ -521,9 +521,9 @@ public class IFSerializer extends Abstra
     }
 
     /** {@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) {
+    public void drawBorderRect(Rectangle rect, BorderProps top, BorderProps bottom,
+            BorderProps left, BorderProps right) throws IFException {
+        if (top == null && bottom == null && left == null && right == null) {
             return;
         }
         try {
@@ -532,17 +532,17 @@ public class IFSerializer extends Abstra
             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 (top != null) {
+                addAttribute(atts, "top", top.toString());
             }
-            if (after != null) {
-                addAttribute(atts, "after", after.toString());
+            if (bottom != null) {
+                addAttribute(atts, "bottom", bottom.toString());
             }
-            if (start != null) {
-                addAttribute(atts, "start", start.toString());
+            if (left != null) {
+                addAttribute(atts, "left", left.toString());
             }
-            if (end != null) {
-                addAttribute(atts, "end", end.toString());
+            if (right != null) {
+                addAttribute(atts, "right", right.toString());
             }
             handler.element(EL_BORDER_RECT, atts);
         } catch (SAXException e) {
@@ -571,7 +571,7 @@ public class IFSerializer extends Abstra
 
     /** {@inheritDoc} */
     public void drawText(int x, int y, int letterSpacing, int wordSpacing,
-            int[] dx, String text) throws IFException {
+            int[][] dp, String text) throws IFException {
         try {
             addID();
             AttributesImpl atts = new AttributesImpl();
@@ -583,8 +583,17 @@ public class IFSerializer extends Abstra
             if (wordSpacing != 0) {
                 addAttribute(atts, "word-spacing", Integer.toString(wordSpacing));
             }
-            if (dx != null) {
-                addAttribute(atts, "dx", IFUtil.toString(dx));
+            if (dp != null) {
+                if ( IFUtil.isDPIdentity(dp) ) {
+                    // don't add dx or dp attribute
+                } else if ( IFUtil.isDPOnlyDX(dp) ) {
+                    // add dx attribute only
+                    int[] dx = IFUtil.convertDPToDX(dp);
+                    addAttribute(atts, "dx", IFUtil.toString(dx));
+                } else {
+                    // add dp attribute only
+                    addAttribute(atts, "dp", XMLUtil.encodePositionAdjustments(dp));
+                }
             }
             addStructureReference(atts);
             handler.startElement(EL_TEXT, atts);

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/IFUtil.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/IFUtil.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/IFUtil.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/IFUtil.java Sun Feb 26 02:29:01 2012
@@ -199,4 +199,182 @@ public final class IFUtil {
         return documentHandler.getMimeType();
     }
 
+    /**
+     * Convert the general gpos 'dp' adjustments to the older 'dx' adjustments.
+     * This utility method is used to provide backward compatibility in implementations
+     * of IFPainter that have not yet been upgraded to the general position adjustments format.
+     * @param dp an array of 4-tuples, expressing [X,Y] placment
+     * adjustments and [X,Y] advancement adjustments, in that order (may be null)
+     * @param count if <code>dp</code> is not null, then a count of dp values to convert
+     * @return if <code>dp</code> is not null, then an array of adjustments to the current
+     * x position prior to rendering individual glyphs; otherwise, null
+     */
+    public static int[] convertDPToDX ( int[][] dp, int count ) {
+        int[] dx;
+        if ( dp != null ) {
+            dx = new int [ count ];
+            for ( int i = 0, n = count; i < n; i++ ) {
+                dx [ i ] = dp [ i ] [ 0 ];      // xPlaAdjust[i]
+            }
+        } else {
+            dx = null;
+        }
+        return dx;
+    }
+
+    /**
+     * Convert the general gpos 'dp' adjustments to the older 'dx' adjustments.
+     * This utility method is used to provide backward compatibility in implementations
+     * of IFPainter that have not yet been upgraded to the general position adjustments format.
+     * @param dp an array of 4-tuples, expressing [X,Y] placment
+     * adjustments and [X,Y] advancement adjustments, in that order (may be null)
+     * @return if <code>dp</code> is not null, then an array of adjustments to the current
+     * x position prior to rendering individual glyphs; otherwise, null
+     */
+    public static int[] convertDPToDX ( int[][] dp ) {
+        return convertDPToDX ( dp, ( dp != null ) ? dp.length : 0 );
+    }
+
+    /**
+     * Convert the general gpos 'dp' adjustments to the older 'dx' adjustments.
+     * This utility method is used to provide backward compatibility in implementations
+     * of IFPainter that have not yet been upgraded to the general position adjustments format.
+     * @param dx an array of adjustments to the current x position prior to rendering
+     * individual glyphs or null
+     * @param count if <code>dx</code> is not null, then a count of dx values to convert
+     * @return if <code>dx</code> is not null, then an array of 4-tuples, expressing [X,Y]
+     * placment adjustments and [X,Y] advancement adjustments, in that order; otherwise, null
+     */
+    public static int[][] convertDXToDP ( int[] dx, int count ) {
+        int[][] dp;
+        if ( dx != null ) {
+            dp = new int [ count ] [ 4 ];
+            for ( int i = 0, n = count; i < n; i++ ) {
+                int[] pa = dp [ i ];
+                int   d  = dx [ i ];
+                pa [ 0 ] = d;                   // xPlaAdjust[i]
+                pa [ 2 ] = d;                   // xAdvAdjust[i]
+            }
+        } else {
+            dp = null;
+        }
+        return dp;
+    }
+
+    /**
+     * Convert the general gpos 'dp' adjustments to the older 'dx' adjustments.
+     * This utility method is used to provide backward compatibility in implementations
+     * of IFPainter that have not yet been upgraded to the general position adjustments format.
+     * @param dx an array of adjustments to the current x position prior to rendering
+     * individual glyphs or null
+     * @return if <code>dx</code> is not null, then an array of 4-tuples, expressing [X,Y]
+     * placment adjustments and [X,Y] advancement adjustments, in that order; otherwise, null
+     */
+    public static int[][] convertDXToDP ( int[] dx ) {
+        return convertDXToDP ( dx, ( dx != null ) ? dx.length : 0 );
+    }
+
+    /**
+     * Determine if position adjustment is the identity adjustment, i.e., no non-zero adjustment.
+     * @param pa a 4-tuple, expressing [X,Y] placment and [X,Y] advance adjuustments (may be null)
+     * @return true if <code>dp</code> is null or contains no non-zero adjustment
+     */
+    public static boolean isPAIdentity ( int[] pa ) {
+        if ( pa == null ) {
+            return true;
+        } else {
+            for ( int k = 0; k < 4; k++ ) {
+                if ( pa[k] != 0 ) {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
+    /**
+     * Determine if position adjustments is the identity adjustment, i.e., no non-zero adjustment.
+     * @param dp an array of 4-tuples, expressing [X,Y] placment
+     * adjustments and [X,Y] advancement adjustments, in that order (may be null)
+     * @return true if <code>dp</code> is null or contains no non-zero adjustment
+     */
+    public static boolean isDPIdentity ( int[][] dp ) {
+        if ( dp == null ) {
+            return true;
+        } else {
+            for ( int i = 0, n = dp.length; i < n; i++ ) {
+                if ( !isPAIdentity ( dp[i] ) ) {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
+    /**
+     * Determine if position adjustments comprises only DX adjustments as encoded by
+     * {@link #convertDPToDX}. Note that if given a set of all all zero position
+     * adjustments, both this method and {@link #isDPIdentity} will return true;
+     * however, this method may return true when {@link #isDPIdentity} returns false.
+     * @param dp an array of 4-tuples, expressing [X,Y] placment
+     * adjustments and [X,Y] advancement adjustments, in that order (may be null)
+     * @return true if <code>dp</code> is not null and contains only xPlaAdjust
+     * and xAdvAdjust values consistent with the output of {@link #convertDPToDX}.
+     */
+    public static boolean isDPOnlyDX ( int[][] dp ) {
+        if ( dp == null ) {
+            return false;
+        } else {
+            for ( int i = 0, n = dp.length; i < n; i++ ) {
+                int[] pa = dp[i];
+                if ( pa[0] != pa[2] ) {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
+    /**
+     * Adjust a position adjustments array. If both <code>paDst</code> and <code>paSrc</code> are
+     * non-null, then <code>paSrc[i]</code> is added to <code>paDst[i]</code>.
+     * @param paDst a 4-tuple, expressing [X,Y] placment
+     * and [X,Y] advance adjuustments (may be null)
+     * @param paSrc a 4-tuple, expressing [X,Y] placment
+     * and [X,Y] advance adjuustments (may be null)
+     */
+    public static void adjustPA ( int[] paDst, int[] paSrc ) {
+        if ( ( paDst != null ) && ( paSrc != null ) ) {
+            assert paDst.length == 4; assert paSrc.length == 4;
+            for ( int i = 0; i < 4; i++ ) {
+                paDst[i] += paSrc[i];
+            }
+        }
+    }
+
+    /**
+     * Copy entries from position adjustments.
+     * @param dp an array of 4-tuples, expressing [X,Y] placment
+     * adjustments and [X,Y] advancement adjustments, in that order
+     * @param offset starting offset from which to copy
+     * @param count number of entries to copy
+     * @return a deep copy of the count position adjustment entries start at
+     * offset
+     */
+    public static int[][] copyDP ( int[][] dp, int offset, int count ) {
+        if ( ( dp == null ) || ( offset > dp.length ) || ( ( offset + count ) > dp.length ) ) {
+            throw new IllegalArgumentException();
+        } else {
+            int[][] dpNew = new int [ count ] [ 4 ];
+            for ( int i = 0, n = count; i < n; i++ ) {
+                int[] paDst = dpNew [ i ];
+                int[] paSrc = dp [ i + offset ];
+                for ( int k = 0; k < 4; k++ ) {
+                    paDst [ k ] = paSrc [ k ];
+                }
+            }
+            return dpNew;
+        }
+    }
+
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java Sun Feb 26 02:29:01 2012
@@ -51,13 +51,14 @@ public class ConfiguredFontCollection im
      * Main constructor
      * @param fontResolver a font resolver
      * @param customFonts the list of custom fonts
+     * @param useComplexScriptFeatures true if complex script features enabled
      */
     public ConfiguredFontCollection(FontResolver fontResolver,
-            List/*<EmbedFontInfo>*/ customFonts) {
+            List/*<EmbedFontInfo>*/ customFonts, boolean useComplexScriptFeatures) {
         this.fontResolver = fontResolver;
         if (this.fontResolver == null) {
             //Ensure that we have minimal font resolution capabilities
-            this.fontResolver = FontManager.createMinimalFontResolver();
+            this.fontResolver = FontManager.createMinimalFontResolver(useComplexScriptFeatures);
         }
         this.embedFontInfoList = customFonts;
     }
@@ -89,7 +90,8 @@ public class ConfiguredFontCollection im
                 } else {
                     CustomFont fontMetrics = FontLoader.loadFont(
                             fontFile, null, true, EncodingMode.AUTO,
-                            configFontInfo.getKerning(), fontResolver);
+                            configFontInfo.getKerning(),
+                            configFontInfo.getAdvanced(), fontResolver);
                     font = new CustomFontMetricsMapper(fontMetrics);
                 }
 



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