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 [4/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/trun...

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/RegionViewport.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/RegionViewport.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/RegionViewport.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/RegionViewport.java Sun Feb 26 02:29:01 2012
@@ -19,6 +19,8 @@
 
 package org.apache.fop.area;
 
+import org.apache.fop.traits.WritingModeTraitsGetter;
+
 import java.awt.Rectangle;
 import java.awt.geom.Rectangle2D;
 import java.io.IOException;
@@ -106,7 +108,7 @@ public class RegionViewport extends Area
         out.writeFloat((float) viewArea.getWidth());
         out.writeFloat((float) viewArea.getHeight());
         out.writeBoolean(clip);
-        out.writeObject(props);
+        out.writeObject(traits);
         out.writeObject(regionReference);
     }
 
@@ -115,7 +117,7 @@ public class RegionViewport extends Area
         viewArea = new Rectangle2D.Float(in.readFloat(), in.readFloat(),
                                          in.readFloat(), in.readFloat());
         clip = in.readBoolean();
-        props = (HashMap)in.readObject();
+        traits = (HashMap)in.readObject();
         setRegionReference((RegionReference) in.readObject());
     }
 
@@ -128,13 +130,25 @@ public class RegionViewport extends Area
     public Object clone() {
         RegionViewport rv = new RegionViewport((Rectangle2D)viewArea.clone());
         rv.regionReference = (RegionReference)regionReference.clone();
-        if (props != null) {
-            rv.props = new HashMap(props);
+        if (traits != null) {
+            rv.traits = new HashMap(traits);
         }
         if (foreignAttributes != null) {
             rv.foreignAttributes = new HashMap(foreignAttributes);
         }
         return rv;
     }
+
+    /**
+     * Sets the writing mode traits for the region reference of
+     * this region viewport
+     * @param wmtg a WM traits getter
+     */
+    public void setWritingModeTraits(WritingModeTraitsGetter wmtg) {
+        if (regionReference != null) {
+            regionReference.setWritingModeTraits(wmtg);
+        }
+    }
+
 }
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Span.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Span.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Span.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Span.java Sun Feb 26 02:29:01 2012
@@ -19,8 +19,12 @@
 
 package org.apache.fop.area;
 
+import java.util.Iterator;
 import java.util.List;
 
+import org.apache.fop.fo.Constants;
+import org.apache.fop.traits.WritingModeTraitsGetter;
+
 /**
  * The span-reference-area.
  * This is a block-area with 0 border and padding that is stacked
@@ -183,6 +187,28 @@ public class Span extends Area {
         return (areaCount == 0);
     }
 
+    /**
+     * Sets the writing mode traits for the main reference area of
+     * this span area.
+     * @param wmtg a WM traits getter
+     */
+    public void setWritingModeTraits(WritingModeTraitsGetter wmtg) {
+        switch ( wmtg.getColumnProgressionDirection().getEnumValue() ) {
+        case Constants.EN_RL:
+            setBidiLevel(1);
+            for ( Iterator<NormalFlow> it = flowAreas.iterator(); it.hasNext();) {
+                it.next().setBidiLevel(1);
+            }
+            break;
+        default:
+            resetBidiLevel();
+            for ( Iterator<NormalFlow> it = flowAreas.iterator(); it.hasNext();) {
+                it.next().resetBidiLevel();
+            }
+            break;
+        }
+    }
+
     /** {@inheritDoc} */
     @Override
     public String toString() {

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Trait.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Trait.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Trait.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Trait.java Sun Feb 26 02:29:01 2012
@@ -26,6 +26,8 @@ import org.apache.xmlgraphics.image.load
 
 import org.apache.fop.fonts.FontTriplet;
 import org.apache.fop.traits.BorderProps;
+import org.apache.fop.traits.Direction;
+import org.apache.fop.traits.WritingMode;
 import org.apache.fop.util.ColorUtil;
 
 import static org.apache.fop.fo.Constants.EN_REPEAT;
@@ -156,8 +158,19 @@ public final class Trait implements Seri
     /** For navigation in the document structure. */
     public static final Integer STRUCTURE_TREE_ELEMENT = 37;
 
+    /** writing mode trait */
+    public static final Integer WRITING_MODE = 38;
+    /** inline progression direction trait */
+    public static final Integer INLINE_PROGRESSION_DIRECTION = 39;
+    /** block progression direction trait */
+    public static final Integer BLOCK_PROGRESSION_DIRECTION = 40;
+    /** column progression direction trait */
+    public static final Integer COLUMN_PROGRESSION_DIRECTION = 41;
+    /** shift direction trait */
+    public static final Integer SHIFT_DIRECTION = 42;
+
     /** Maximum value used by trait keys */
-    public static final int MAX_TRAIT_KEY = 37;
+    public static final int MAX_TRAIT_KEY = 42;
 
     private static final TraitInfo[] TRAIT_INFO = new TraitInfo[MAX_TRAIT_KEY + 1];
 
@@ -221,6 +234,14 @@ public final class Trait implements Seri
         put(SPACE_AFTER,    new TraitInfo("space-after", Integer.class));
         put(IS_REFERENCE_AREA,  new TraitInfo("is-reference-area", Boolean.class));
         put(IS_VIEWPORT_AREA,   new TraitInfo("is-viewport-area", Boolean.class));
+        put(WRITING_MODE,
+                new TraitInfo("writing-mode", WritingMode.class));
+        put(INLINE_PROGRESSION_DIRECTION,
+                new TraitInfo("inline-progression-direction", Direction.class));
+        put(BLOCK_PROGRESSION_DIRECTION,
+                new TraitInfo("block-progression-direction", Direction.class));
+        put(SHIFT_DIRECTION,
+                new TraitInfo("shift-direction", Direction.class));
 
     }
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/AbstractTextArea.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/AbstractTextArea.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/AbstractTextArea.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/AbstractTextArea.java Sun Feb 26 02:29:01 2012
@@ -188,7 +188,7 @@ public abstract class AbstractTextArea e
 
     @Override
     int getVirtualOffset() {
-        return getOffset();
+        return getBlockProgressionOffset();
     }
 
     @Override

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/BasicLinkArea.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/BasicLinkArea.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/BasicLinkArea.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/BasicLinkArea.java Sun Feb 26 02:29:01 2012
@@ -20,6 +20,7 @@
 package org.apache.fop.area.inline;
 
 import org.apache.fop.area.Area;
+import org.apache.fop.area.LinkResolver;
 
 /**
  * An inline area produced by an fo:basic-link element. This class implements a different
@@ -33,6 +34,8 @@ public class BasicLinkArea extends Inlin
 
     private static final long serialVersionUID = 5183753430412208151L;
 
+    private LinkResolver resolver;
+
     @Override
     public void setParentArea(Area parentArea) {
         super.setParentArea(parentArea);
@@ -42,12 +45,28 @@ public class BasicLinkArea extends Inlin
          * called after all of the children areas have been added to this area.
          */
         /* Make this area start at its beforest child. */
-        setOffset(getOffset() + minChildOffset);
+        setBlockProgressionOffset(getBlockProgressionOffset() + minChildOffset);
         /* Update children offsets accordingly. */
         for (InlineArea inline : inlines) {
-            inline.setOffset(inline.getOffset() - minChildOffset);
+            inline.setBlockProgressionOffset(inline.getBlockProgressionOffset() - minChildOffset);
         }
         setBPD(getVirtualBPD());
     }
 
+    /**
+     * Establish (or remove) back-pointer to link resolver.
+     * @param resolver the link resolver that will resolve this basic link or null
+     */
+    public void setResolver(LinkResolver resolver) {
+        assert ( resolver == null ) || ( this.resolver == null );
+        this.resolver = resolver;
+    }
+
+    /**
+     * Obtain back-pointer to link resolver.
+     * @return resolver the link resolver that will resolve this basic link or null
+     */
+    public LinkResolver getResolver() {
+        return this.resolver;
+    }
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/FilledArea.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/FilledArea.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/FilledArea.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/FilledArea.java Sun Feb 26 02:29:01 2012
@@ -50,10 +50,9 @@ public class FilledArea extends InlinePa
      * @param v the offset
      */
     /*
-    public void setOffset(int v) {
+    public void setBlockProgressionOffset(int v) {
         setChildOffset(inlines.listIterator(), v);
     }
-    */
 
     private void setChildOffset(ListIterator childrenIterator, int v) {
         while (childrenIterator.hasNext()) {
@@ -63,10 +62,11 @@ public class FilledArea extends InlinePa
             } else if (child instanceof InlineViewport) {
                 // nothing
             } else {
-                child.setOffset(v);
+                child.setBlockProgressionOffset(v);
             }
         }
     }
+    */
 
     /**
      * Set the unit width for the areas to fill the full width.
@@ -129,5 +129,6 @@ public class FilledArea extends InlinePa
         setIPD(getIPD() + adjustingInfo.applyVariationFactor(variationFactor));
         return false;
     }
+
 }
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/InlineArea.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/InlineArea.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/InlineArea.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/InlineArea.java Sun Feb 26 02:29:01 2012
@@ -20,10 +20,12 @@
 package org.apache.fop.area.inline;
 
 import java.io.Serializable;
+import java.util.List;
 
 import org.apache.fop.area.Area;
 import org.apache.fop.area.LineArea;
 import org.apache.fop.area.Trait;
+import org.apache.fop.complexscripts.bidi.InlineRun;
 
 /**
  * Inline Area
@@ -79,7 +81,7 @@ public class InlineArea extends Area {
     /**
      * offset position from before edge of parent area
      */
-    protected int offset = 0;
+    protected int blockProgressionOffset = 0;
 
     /**
      * parent area
@@ -101,6 +103,23 @@ public class InlineArea extends Area {
     protected InlineAdjustingInfo adjustingInfo = null;
 
     /**
+     * Default constructor for inline area.
+     */
+    public InlineArea() {
+        this (  0, -1 );
+    }
+
+    /**
+     * Instantiate inline area.
+     * @param blockProgressionOffset a block progression offset or zero
+     * @param bidiLevel a resolved bidi level or -1
+     */
+    protected InlineArea ( int blockProgressionOffset, int bidiLevel ) {
+        this.blockProgressionOffset = blockProgressionOffset;
+        setBidiLevel(bidiLevel);
+    }
+
+    /**
      * @return the adjustment information object
      */
     public InlineAdjustingInfo getAdjustingInfo() {
@@ -138,25 +157,25 @@ public class InlineArea extends Area {
     }
 
     /**
-     * Set the offset of this inline area.
+     * Set the block progression offset of this inline area.
      * This is used to set the offset of the inline area
      * which is relative to the before edge of the parent area.
      *
-     * @param offset the offset
+     * @param blockProgressionOffset the offset
      */
-    public void setOffset(int offset) {
-        this.offset = offset;
+    public void setBlockProgressionOffset(int blockProgressionOffset) {
+        this.blockProgressionOffset = blockProgressionOffset;
     }
 
     /**
-     * Get the offset of this inline area.
+     * Get the block progression offset of this inline area.
      * This returns the offset of the inline area
-     * which is relative to the before edge of the parent area.
+     * relative to the before edge of the parent area.
      *
-     * @return the offset
+     * @return the blockProgressionOffset
      */
-    public int getOffset() {
-        return offset;
+    public int getBlockProgressionOffset() {
+        return blockProgressionOffset;
     }
 
     /**
@@ -266,7 +285,7 @@ public class InlineArea extends Area {
      * @see BasicLinkArea
      */
     int getVirtualOffset() {
-        return getOffset();
+        return getBlockProgressionOffset();
     }
 
     /**
@@ -278,5 +297,43 @@ public class InlineArea extends Area {
     int getVirtualBPD() {
         return getBPD();
     }
-}
 
+    /**
+     * Collection bidi inline runs.
+     * @param runs current list of inline runs
+     * @return modified list of inline runs, having appended new run
+     */
+    public List collectInlineRuns ( List runs ) {
+        assert runs != null;
+        runs.add ( new InlineRun ( this, new int[] {getBidiLevel()}) );
+        return runs;
+    }
+
+    /**
+     * Determine if inline area IA is an ancestor inline area or same as this area.
+     * @param ia inline area to test
+     * @return true if specified inline area is an ancestor or same as this area
+     */
+    public boolean isAncestorOrSelf ( InlineArea ia ) {
+        return ( ia == this ) || isAncestor ( ia );
+    }
+
+    /**
+     * Determine if inline area IA is an ancestor inline area of this area.
+     * @param ia inline area to test
+     * @return true if specified inline area is an ancestor of this area
+     */
+    public boolean isAncestor ( InlineArea ia ) {
+        for ( Area p = getParentArea(); p != null;) {
+            if ( p == ia ) {
+                return true;
+            } else if ( p instanceof InlineArea ) {
+                p = ( (InlineArea) p ).getParentArea();
+            } else {
+                p = null;
+            }
+        }
+        return false;
+    }
+
+}

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/InlineParent.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/InlineParent.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/InlineParent.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/InlineParent.java Sun Feb 26 02:29:01 2012
@@ -20,6 +20,7 @@
 package org.apache.fop.area.inline;
 
 import java.util.List;
+import java.util.Iterator;
 
 import org.apache.fop.area.Area;
 
@@ -62,6 +63,7 @@ public class InlineParent extends Inline
         if (autoSize) {
             increaseIPD(childArea.getAllocIPD());
         }
+        updateLevel ( childArea.getBidiLevel() );
         int childOffset = childArea.getVirtualOffset();
         minChildOffset = Math.min(minChildOffset, childOffset);
         maxAfterEdge = Math.max(maxAfterEdge, childOffset + childArea.getVirtualBPD());
@@ -69,7 +71,7 @@ public class InlineParent extends Inline
 
     @Override
     int getVirtualOffset() {
-        return getOffset() + minChildOffset;
+        return getBlockProgressionOffset() + minChildOffset;
     }
 
     @Override
@@ -110,5 +112,37 @@ public class InlineParent extends Inline
         return hasUnresolvedAreas;
     }
 
-}
+    @Override
+    public List collectInlineRuns ( List runs ) {
+        for ( Iterator<InlineArea> it = getChildAreas().iterator(); it.hasNext();) {
+            InlineArea ia = it.next();
+            runs = ia.collectInlineRuns ( runs );
+        }
+        return runs;
+    }
+
+    /**
+     * Reset bidirectionality level of all children to default (-1),
+     * signalling that they will inherit the level of their parent text area.
+     */
+    public void resetChildrenLevel() {
+        for ( Iterator it = inlines.iterator(); it.hasNext();) {
+            ( (InlineArea) it.next() ) .resetBidiLevel();
+        }
+    }
 
+    private void updateLevel ( int newLevel ) {
+        if ( newLevel >= 0 ) {
+            int curLevel = getBidiLevel();
+            if ( curLevel >= 0 ) {
+                if ( newLevel < curLevel ) {
+                    setBidiLevel ( newLevel );
+                }
+            } else {
+                setBidiLevel ( newLevel );
+            }
+        }
+    }
+
+
+}

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/InlineViewport.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/InlineViewport.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/InlineViewport.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/InlineViewport.java Sun Feb 26 02:29:01 2012
@@ -50,6 +50,17 @@ public class InlineViewport extends Inli
      * @param child the child content area of this viewport
      */
     public InlineViewport(Area child) {
+        this(child, -1);
+    }
+
+    /**
+     * Create a new viewport area with the content area.
+     *
+     * @param child the child content area of this viewport
+     * @param bidiLevel the bidirectional embedding level (or -1 if not defined)
+     */
+    public InlineViewport(Area child, int bidiLevel) {
+        super(0, bidiLevel);
         this.content = child;
     }
 
@@ -121,7 +132,7 @@ public class InlineViewport extends Inli
             out.writeFloat((float) contentPosition.getHeight());
         }
         out.writeBoolean(clip);
-        out.writeObject(props);
+        out.writeObject(traits);
         out.writeObject(content);
     }
 
@@ -134,7 +145,7 @@ public class InlineViewport extends Inli
                                                     in.readFloat());
         }
         this.clip = in.readBoolean();
-        this.props = (HashMap) in.readObject();
+        this.traits = (HashMap) in.readObject();
         this.content = (Area) in.readObject();
     }
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/Space.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/Space.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/Space.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/Space.java Sun Feb 26 02:29:01 2012
@@ -27,4 +27,10 @@ public class Space extends InlineArea {
 
     private static final long serialVersionUID = -8748265505356839796L;
 
+    /**
+     * Default constructor.
+     */
+    public Space() {
+    }
+
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/SpaceArea.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/SpaceArea.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/SpaceArea.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/SpaceArea.java Sun Feb 26 02:29:01 2012
@@ -38,14 +38,15 @@ public class SpaceArea extends InlineAre
 
     /**
      * Create a space area
-     * @param s the space character
-     * @param o the offset for the next area
-     * @param a is this space adjustable?
+     * @param space the space character
+     * @param blockProgressionOffset the offset for the next area
+     * @param adjustable is this space adjustable?
+     * @param bidiLevel the bidirectional embedding level (or -1 if not defined)
      */
-    public SpaceArea(char s, int o, boolean a) {
-        space = s;
-        offset = o;
-        isAdjustable = a;
+    public SpaceArea(int blockProgressionOffset, int bidiLevel, char space, boolean adjustable) {
+        super ( blockProgressionOffset, bidiLevel );
+        this.space = space;
+        this.isAdjustable = adjustable;
     }
 
     /** @return Returns the space. */
@@ -57,4 +58,5 @@ public class SpaceArea extends InlineAre
     public boolean isAdjustable() {
         return this.isAdjustable;
     }
+
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/TextArea.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/TextArea.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/TextArea.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/TextArea.java Sun Feb 26 02:29:01 2012
@@ -19,6 +19,10 @@
 
 package org.apache.fop.area.inline;
 
+import java.util.Arrays;
+
+import org.apache.fop.util.CharUtilities;
+
 /**
  * A text inline area.
  */
@@ -57,7 +61,7 @@ public class TextArea extends AbstractTe
      * @param offset the offset for the next area
      */
     public void addWord(String word, int offset) {
-        addWord(word, offset, null);
+        addWord(word, 0, null, null, null, offset);
     }
 
     /**
@@ -65,25 +69,51 @@ public class TextArea extends AbstractTe
      *
      * @param word   the word string
      * @param offset the offset for the next area
-     * @param letterAdjust the letter adjustment array (may be null)
+     * @param level  bidirectional level that applies to entire word
      */
-    public void addWord(String word, int offset, int[] letterAdjust) {
-        WordArea wordArea = new WordArea(word, offset, letterAdjust);
+    public void addWord(String word, int offset, int level) {
+        addWord(word, 0, null, makeLevels(level, word.length()), null, offset);
+    }
+
+    /**
+     * Create and add a WordArea child to this TextArea.
+     *
+     * @param word the word string
+     * @param ipd the word's ipd
+     * @param letterAdjust the letter adjustment array (may be null)
+     * @param levels array of resolved bidirectional levels of word characters,
+     * or null if default level
+     * @param gposAdjustments array of general position adjustments or null if none apply
+     * @param blockProgressionOffset the offset for the next area
+     */
+    public void addWord
+        ( String word, int ipd, int[] letterAdjust, int[] levels,
+          int[][] gposAdjustments, int blockProgressionOffset ) {
+        int minWordLevel = findMinLevel ( levels );
+        WordArea wordArea = new WordArea
+            ( blockProgressionOffset, minWordLevel, word, letterAdjust, levels, gposAdjustments );
+        wordArea.setIPD ( ipd );
         addChildArea(wordArea);
         wordArea.setParentArea(this);
+        updateLevel(minWordLevel);
     }
 
     /**
      * Create and add a SpaceArea child to this TextArea
      *
-     * @param space      the space character
-     * @param offset     the offset for the next area
+     * @param space the space character
+     * @param ipd the space's ipd
+     * @param blockProgressionOffset     the offset for the next area
      * @param adjustable is this space adjustable?
+     * @param level resolved bidirection level of space character
      */
-    public void addSpace(char space, int offset, boolean adjustable) {
-        SpaceArea spaceArea = new SpaceArea(space, offset, adjustable);
+    public void addSpace
+        ( char space, int ipd, boolean adjustable, int blockProgressionOffset, int level ) {
+        SpaceArea spaceArea = new SpaceArea(blockProgressionOffset, level, space, adjustable);
+        spaceArea.setIPD ( ipd );
         addChildArea(spaceArea);
         spaceArea.setParentArea(this);
+        updateLevel(level);
     }
 
     /**
@@ -113,7 +143,55 @@ public class TextArea extends AbstractTe
     /** {@inheritDoc} */
     @Override
     public String toString() {
-        return "TextArea{text=" + getText() + "}";
+        StringBuffer sb = new StringBuffer(super.toString());
+        sb.append(" {text=\"");
+        sb.append(CharUtilities.toNCRefs(getText()));
+        sb.append("\"");
+        sb.append("}");
+        return sb.toString();
+    }
+
+    private void updateLevel ( int newLevel ) {
+        if ( newLevel >= 0 ) {
+            int curLevel = getBidiLevel();
+            if ( curLevel >= 0 ) {
+                if ( newLevel < curLevel ) {
+                    setBidiLevel ( newLevel );
+                }
+            } else {
+                setBidiLevel ( newLevel );
+            }
+        }
+    }
+
+    private static int findMinLevel ( int[] levels ) {
+        if ( levels != null ) {
+            int lMin = Integer.MAX_VALUE;
+            for ( int i = 0, n = levels.length; i < n; i++ ) {
+                int l = levels [ i ];
+                if ( ( l >= 0 ) && ( l < lMin ) ) {
+                    lMin = l;
+                }
+            }
+            if ( lMin == Integer.MAX_VALUE ) {
+                return -1;
+            } else {
+                return lMin;
+            }
+        } else {
+            return -1;
+        }
+    }
+
+    private int[] makeLevels ( int level, int count ) {
+        if ( level >= 0 ) {
+            int[] levels = new int [ count ];
+            Arrays.fill ( levels, level );
+            return levels;
+        } else {
+            return null;
+        }
     }
+
 }
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/UnresolvedPageNumber.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/UnresolvedPageNumber.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/UnresolvedPageNumber.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/UnresolvedPageNumber.java Sun Feb 26 02:29:01 2012
@@ -19,12 +19,13 @@
 
 package org.apache.fop.area.inline;
 
+import java.util.List;
+
 import org.apache.fop.area.PageViewport;
 import org.apache.fop.area.Resolvable;
+import org.apache.fop.complexscripts.bidi.InlineRun;
 import org.apache.fop.fonts.Font;
 
-import java.util.List;
-
 /**
  * Unresolvable page number area.
  * This is a word area that resolves itself to a page number
@@ -83,12 +84,24 @@ public class UnresolvedPageNumber extend
     }
 
     /**
+     * Get the (resolved or unresolved) text.
+     *
+     * @return the text
+     */
+    public String getText() {
+        return text;
+    }
+
+    /**
      * Resolve the page number idref
      * This resolves the idref for this object by getting the page number
      * string from the first page in the list of pages that apply
      * for this ID.  The page number text is then set to the String value
      * of the page number.
      *
+     * TODO: [GA] May need to run bidi algorithm and script processor
+     * on resolved page number.
+     *
      * @param id an id whose PageViewports have been determined
      * @param pages the list of PageViewports associated with this ID
      */
@@ -103,7 +116,7 @@ public class UnresolvedPageNumber extend
             // replace the text
             removeText();
             text = page.getPageNumberString();
-            addWord(text, 0);
+            addWord(text, 0, getBidiLevel());
             // update ipd
             if (font != null) {
                 handleIPDVariation(font.getWordWidth(text) - getIPD());
@@ -137,4 +150,21 @@ public class UnresolvedPageNumber extend
                                         int lineStretch, int lineShrink) {
         return true;
     }
+
+    /**
+     * Collection bidi inline runs.
+     * Override of @{link InlineParent} implementation.
+     *
+     * N.B. [GA] without this override, the page-number-citation_writing_mode_rl
+     * layout engine test will fail. It may be that the test needs to
+     * be updated rather than using this override.
+     * @param runs current list of inline runs
+     * @return modified list of inline runs, having appended new run
+     */
+    @Override
+    public List collectInlineRuns ( List runs ) {
+        assert runs != null;
+        runs.add ( new InlineRun ( this, new int[] {getBidiLevel()}) );
+        return runs;
+    }
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/WordArea.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/WordArea.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/WordArea.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/WordArea.java Sun Feb 26 02:29:01 2012
@@ -19,6 +19,12 @@
 
 package org.apache.fop.area.inline;
 
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.fop.complexscripts.bidi.InlineRun;
+import org.apache.fop.complexscripts.util.CharMirror;
+
 /**
  * A string of characters without spaces
  */
@@ -29,22 +35,63 @@ public class WordArea extends InlineArea
     /** The text for this word area */
     protected String word;
 
-    /** The correction offset for the next area */
-    protected int offset = 0;
-
     /** An array of width for adjusting the individual letters (optional) */
     protected int[] letterAdjust;
 
     /**
+     * An array of resolved bidirectional levels corresponding to each character
+     * in word (optional)
+     */
+    protected int[] levels;
+
+    /**
+     * An array of glyph positioning adjustments to apply to each glyph 'char' in word (optional)
+     */
+    protected int[][] gposAdjustments;
+
+    /**
+     * A flag indicating whether the content of word is reversed in relation to
+     * its original logical order.
+     */
+    protected boolean reversed;
+
+    /**
+     * Create a word area
+     * @param blockProgressionOffset the offset for this area
+     * @param level the bidirectional embedding level (or -1 if not defined) for word as a group
+     * @param word the word string
+     * @param letterAdjust the letter adjust array (may be null)
+     * @param levels array of per-character (glyph) bidirectional levels,
+     * in case word area is heterogenously leveled
+     * @param gposAdjustments array of general position adjustments or null if none apply
+     * @param reversed true if word is known to be reversed at construction time
+     */
+    public WordArea
+        ( int blockProgressionOffset, int level, String word, int[] letterAdjust, int[] levels,
+          int[][] gposAdjustments, boolean reversed ) {
+        super ( blockProgressionOffset, level );
+        int length = ( word != null ) ? word.length() : 0;
+        this.word = word;
+        this.letterAdjust = maybeAdjustLength ( letterAdjust, length );
+        this.levels = maybePopulateLevels ( levels, level, length );
+        this.gposAdjustments = maybeAdjustLength ( gposAdjustments, length );
+        this.reversed = reversed;
+    }
+
+    /**
      * Create a word area
-     * @param w the word string
-     * @param o the offset for the next area
-     * @param la the letter adjust array (may be null)
-     */
-    public WordArea(String w, int o, int[] la) {
-        word = w;
-        offset = o;
-        this.letterAdjust = la;
+     * @param blockProgressionOffset the offset for this area
+     * @param level the bidirectional embedding level (or -1 if not defined) for word as a group
+     * @param word the word string
+     * @param letterAdjust the letter adjust array (may be null)
+     * @param levels array of per-character (glyph) bidirectional levels,
+     * in case word area is heterogenously leveled
+     * @param gposAdjustments array of general position adjustments or null if none apply
+     */
+    public WordArea
+        ( int blockProgressionOffset, int level, String word, int[] letterAdjust, int[] levels,
+          int[][] gposAdjustments ) {
+        this ( blockProgressionOffset, level, word, letterAdjust, levels, gposAdjustments, false );
     }
 
     /** @return Returns the word. */
@@ -52,20 +99,211 @@ public class WordArea extends InlineArea
         return word;
     }
 
-    /** @return Returns the offset. */
-    @Override
-    public int getOffset() {
-        return offset;
+    /** @return the array of letter adjust widths */
+    public int[] getLetterAdjustArray() {
+        return this.letterAdjust;
+    }
+
+    /**
+     * Obtain per-character (glyph) bidi levels.
+     * @return a (possibly empty) array of levels or null (if none resolved)
+     */
+    public int[] getBidiLevels() {
+        return levels;
+    }
+
+    /**
+     * <p>Obtain per-character (glyph) bidi levels over a specified subsequence.</p>
+     * <p>If word has been reversed, then the subsequence is over the reversed word.</p>
+     * @param start starting (inclusive) index of subsequence
+     * @param end ending (exclusive) index of subsequence
+     * @return a (possibly null) array of per-character (glyph) levels over the specified
+     * sequence
+     */
+    public int[] getBidiLevels ( int start, int end ) {
+        assert start <= end;
+        if ( this.levels != null ) {
+            int n = end - start;
+            int[] levels = new int [ n ];
+            for ( int i = 0; i < n; i++ ) {
+                levels[i] = this.levels [ start + i ];
+            }
+            return levels;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * <p>Obtain per-character (glyph) level at a specified index position.</p>
+     * <p>If word has been reversed, then the position is relative to the reversed word.</p>
+     * @param position the index of the (possibly reversed) character from which to obtain the
+     * level
+     * @return a resolved bidirectional level or, if not specified, then -1
+     */
+    public int bidiLevelAt ( int position ) {
+        if ( position > word.length() ) {
+            throw new IndexOutOfBoundsException();
+        } else if ( levels != null ) {
+            return levels [ position ];
+        } else {
+            return -1;
+        }
     }
-    /** @param o The offset to set. */
+
     @Override
-    public void setOffset(int o) {
-        offset = o;
+    public List collectInlineRuns ( List runs ) {
+        assert runs != null;
+        InlineRun r;
+        if ( getBidiLevels() != null ) {
+            r = new InlineRun ( this, getBidiLevels() );
+        } else {
+            r = new InlineRun ( this, -1, word.length() );
+        }
+        runs.add ( r );
+        return runs;
     }
 
-    /** @return the array of letter adjust widths */
-    public int[] getLetterAdjustArray() {
-        return this.letterAdjust;
+    /**
+     * Obtain per-character (glyph) position adjustments.
+     * @return a (possibly empty) array of adjustments, each having four elements, or null
+     * if no adjustments apply
+     */
+    public int[][] getGlyphPositionAdjustments() {
+        return gposAdjustments;
+    }
+
+    /**
+     * <p>Obtain per-character (glyph) position adjustments at a specified index position.</p>
+     * <p>If word has been reversed, then the position is relative to the reversed word.</p>
+     * @param position the index of the (possibly reversed) character from which to obtain the
+     * level
+     * @return an array of adjustments or null if none applies
+     */
+    public int[] glyphPositionAdjustmentsAt ( int position ) {
+        if ( position > word.length() ) {
+            throw new IndexOutOfBoundsException();
+        } else if ( gposAdjustments != null ) {
+            return gposAdjustments [ position ];
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * <p>Reverse characters and corresponding per-character levels and glyph position
+     * adjustments.</p>
+     * @param mirror if true, then perform mirroring if mirrorred characters
+     */
+    public void reverse ( boolean mirror ) {
+        if ( word.length() > 0 ) {
+            word = ( ( new StringBuffer ( word ) ) .reverse() ) .toString();
+            if ( levels != null ) {
+                reverse ( levels );
+            }
+            if ( gposAdjustments != null ) {
+                reverse ( gposAdjustments );
+            }
+            reversed = !reversed;
+            if ( mirror ) {
+                word = CharMirror.mirror ( word );
+            }
+        }
+    }
+
+    /**
+     * <p>Perform mirroring on mirrorable characters.</p>
+     */
+    public void mirror() {
+        if ( word.length() > 0 ) {
+            word = CharMirror.mirror ( word );
+        }
+    }
+
+    /**
+     * <p>Determined if word has been reversed (in relation to original logical order).</p>
+     * <p>If a word is reversed, then both its characters (glyphs) and corresponding per-character
+     * levels are in reverse order.</p>
+     * <p>Note: this information is used in order to process non-spacing marks during rendering as
+     * well as provide hints for caret direction.</p>
+     * @return true if word is reversed
+     */
+    public boolean isReversed() {
+        return reversed;
+    }
+
+    /*
+     * If int[] array is not of specified length, then create
+     * a new copy of the first length entries.
+     */
+    private static int[] maybeAdjustLength ( int[] ia, int length ) {
+        if ( ia != null ) {
+            if ( ia.length == length ) {
+                return ia;
+            } else {
+                int[] iaNew = new int [ length ];
+                for ( int i = 0, n = ia.length; i < n; i++ ) {
+                    if ( i < length ) {
+                        iaNew [ i ] = ia [ i ];
+                    } else {
+                        break;
+                    }
+                }
+                return iaNew;
+            }
+        } else {
+            return ia;
+        }
+    }
+
+    /*
+     * If int[][] matrix is not of specified length, then create
+     * a new shallow copy of the first length entries.
+     */
+    private static int[][] maybeAdjustLength ( int[][] im, int length ) {
+        if ( im != null ) {
+            if ( im.length == length ) {
+                return im;
+            } else {
+                int[][] imNew = new int [ length ][];
+                for ( int i = 0, n = im.length; i < n; i++ ) {
+                    if ( i < length ) {
+                        imNew [ i ] = im [ i ];
+                    } else {
+                        break;
+                    }
+                }
+                return imNew;
+            }
+        } else {
+            return im;
+        }
+    }
+
+    private static int[] maybePopulateLevels ( int[] levels, int level, int count ) {
+        if ( ( levels == null ) && ( level >= 0 ) ) {
+            levels = new int[count];
+            Arrays.fill ( levels, level );
+        }
+        return maybeAdjustLength ( levels, count );
+    }
+
+    private static void reverse ( int[] a ) {
+        for ( int i = 0, n = a.length, m = n / 2; i < m; i++ ) {
+            int k = n - i - 1;
+            int t = a [ k ];
+            a [ k ] = a [ i ];
+            a [ i ] = t;
+        }
+    }
+
+    private static void reverse ( int[][] aa ) {
+        for ( int i = 0, n = aa.length, m = n / 2; i < m; i++ ) {
+            int k = n - i - 1;
+            int[] t = aa [ k ];
+            aa [ k ] = aa [ i ];
+            aa [ i ] = t;
+        }
     }
 
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/cli/CommandLineOptions.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/cli/CommandLineOptions.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/cli/CommandLineOptions.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/cli/CommandLineOptions.java Sun Feb 26 02:29:01 2012
@@ -118,6 +118,8 @@ public class CommandLineOptions {
     private int targetResolution = 0;
     /* control memory-conservation policy */
     private boolean conserveMemoryPolicy = false;
+    /* true if a complex script features are enabled */
+    private boolean useComplexScriptFeatures = true;
 
     private FopFactory factory = FopFactory.newInstance();
     private FOUserAgent foUserAgent;
@@ -181,6 +183,9 @@ public class CommandLineOptions {
                 addXSLTParameter("fop-output-format", getOutputFormat());
                 addXSLTParameter("fop-version", Version.getVersion());
                 foUserAgent.setConserveMemoryPolicy(conserveMemoryPolicy);
+                if (!useComplexScriptFeatures) {
+                    foUserAgent.setComplexScriptFeaturesEnabled(false);
+                }
             } else {
                 return false;
             }
@@ -378,6 +383,8 @@ public class CommandLineOptions {
                 getPDFEncryptionParams().setAllowEditContent(false);
             } else if (args[i].equals("-noannotations")) {
                 getPDFEncryptionParams().setAllowEditAnnotations(false);
+            } else if (args[i].equals("-nocs")) {
+                useComplexScriptFeatures = false;
             } else if (args[i].equals("-nofillinforms")) {
                 getPDFEncryptionParams().setAllowFillInForms(false);
             } else if (args[i].equals("-noaccesscontent")) {
@@ -1175,6 +1182,7 @@ public class CommandLineOptions {
             + "  -q                quiet mode  \n"
             + "  -c cfg.xml        use additional configuration file cfg.xml\n"
             + "  -l lang           the language to use for user information \n"
+            + "  -nocs             disable complex script features\n"
             + "  -r                relaxed/less strict validation (where available)\n"
             + "  -dpi xxx          target resolution in dots per inch (dpi) where xxx is a number\n"
             + "  -s                for area tree XML, down to block areas only\n"

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/bidi/BidiClass.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/bidi/BidiClass.java?rev=1293736&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/bidi/BidiClass.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/bidi/BidiClass.java Sun Feb 26 02:29:01 2012
@@ -0,0 +1,271 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id: License.java 1039179 2010-11-25 21:04:09Z vhennebert $ */
+
+package org.apache.fop.complexscripts.bidi;
+
+import java.util.Arrays;
+import org.apache.fop.complexscripts.bidi.BidiConstants;
+
+// CSOFF: WhitespaceAfterCheck
+// CSOFF: LineLengthCheck
+
+/*
+ * !!! THIS IS A GENERATED FILE !!!
+ * If updates to the source are needed, then:
+ * - apply the necessary modifications to
+ *   'src/codegen/unicode/java/org/apache/fop/complexscripts/bidi/GenerateBidiClass.java'
+ * - run 'ant codegen-unicode', which will generate a new BidiClass.java
+ *   in 'src/java/org/apache/fop/complexscripts/bidi'
+ * - commit BOTH changed files
+ */
+
+/** Bidirectional class utilities. */
+public final class BidiClass {
+
+private BidiClass() {
+}
+
+private static byte[] bcL1 = {
+15,15,15,15,15,15,15,15,15,17,16,17,18,16,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16,16,16,17,18,19,19,11,11,11,19,19,19,
+19,19,10,13,10,13,13,9,9,9,9,9,9,9,9,9,9,13,19,19,19,19,19,19,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,19,19,19,
+19,19,19,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,19,19,19,19,15,15,15,15,15,15,16,15,15,15,15,15,15,15,15,15,15,
+15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,13,19,11,11,11,11,19,19,19,19,1,19,19,15,19,19,11,11,9,9,19,1,19,19,19,9,1,
+19,19,19,19,19,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,19,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,19,1,1,1,1,1,1,1,1
+};
+
+private static byte[] bcR1 = {
+4,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
+14,14,14,14,14,4,14,4,14,14,4,14,14,4,14,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
+4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,12,12,12,12,5,5,19,19,5,11,11,5,13,5,19,19,14,14,14,14,14,14,14,14,14,14,14,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
+14,14,14,14,14,14,14,12,12,12,12,12,12,12,12,12,12,11,12,12,5,5,5,14,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,14,14,14,14,14,14,14,12,19,14,14,14,14,14,14,5,5,14,14,19,14,14,14,14,5,5,9,9,9,9,9,9,9,9,9,9,5,
+5,5,5,5,5
+};
+
+private static int[] bcS1 = {
+256,443,444,448,452,660,661,688,697,699,706,710,720,722,736,741,748,749,750,751,768,880,884,885,886,890,891,894,900,902,903,
+904,908,910,931,1014,1015,1154,1155,1160,1162,1329,1369,1370,1377,1417,1418,1792,1806,1807,1808,1809,1810,1840,1867,1869,1958,
+1969,1970,1984,1994,2027,2036,2038,2039,2042,2043,2048,2070,2074,2075,2084,2085,2088,2089,2094,2096,2111,2112,2137,2140,2142,
+2143,2304,2307,2308,2362,2363,2364,2365,2366,2369,2377,2381,2382,2384,2385,2392,2402,2404,2406,2416,2417,2418,2425,2433,2434,
+2437,2447,2451,2474,2482,2486,2492,2493,2494,2497,2503,2507,2509,2510,2519,2524,2527,2530,2534,2544,2546,2548,2554,2555,2561,
+2563,2565,2575,2579,2602,2610,2613,2616,2620,2622,2625,2631,2635,2641,2649,2654,2662,2672,2674,2677,2689,2691,2693,2703,2707,
+2730,2738,2741,2748,2749,2750,2753,2759,2761,2763,2765,2768,2784,2786,2790,2801,2817,2818,2821,2831,2835,2858,2866,2869,2876,
+2877,2878,2879,2880,2881,2887,2891,2893,2902,2903,2908,2911,2914,2918,2928,2929,2930,2946,2947,2949,2958,2962,2969,2972,2974,
+2979,2984,2990,3006,3008,3009,3014,3018,3021,3024,3031,3046,3056,3059,3065,3066,3073,3077,3086,3090,3114,3125,3133,3134,3137,
+3142,3146,3157,3160,3168,3170,3174,3192,3199,3202,3205,3214,3218,3242,3253,3260,3261,3262,3263,3264,3270,3271,3274,3276,3285,
+3294,3296,3298,3302,3313,3330,3333,3342,3346,3389,3390,3393,3398,3402,3405,3406,3415,3424,3426,3430,3440,3449,3450,3458,3461,
+3482,3507,3517,3520,3530,3535,3538,3542,3544,3570,3572,3585,3633,3634,3636,3647,3648,3654,3655,3663,3664,3674,3713,3716,3719,
+3722,3725,3732,3737,3745,3749,3751,3754,3757,3761,3762,3764,3771,3773,3776,3782,3784,3792,3804,3840,3841,3844,3859,3864,3866,
+3872,3882,3892,3893,3894,3895,3896,3897,3898,3899,3900,3901,3902,3904,3913,3953,3967,3968,3973,3974,3976,3981,3993,4030,4038,
+4039,4046,4048,4053,4057,4096,4139,4141,4145,4146,4152,4153,4155,4157,4159,4160,4170,4176,4182,4184,4186,4190,4193,4194,4197,
+4199,4206,4209,4213,4226,4227,4229,4231,4237,4238,4239,4240,4250,4253,4254,4256,4304,4347,4348,4352,4682,4688,4696,4698,4704,
+4746,4752,4786,4792,4800,4802,4808,4824,4882,4888,4957,4960,4961,4969,4992,5008,5024,5120,5121,5741,5743,5760,5761,5787,5788,
+5792,5867,5870,5888,5902,5906,5920,5938,5941,5952,5970,5984,5998,6002,6016,6068,6070,6071,6078,6086,6087,6089,6100,6103,6104,
+6107,6108,6109,6112,6128,6144,6150,6151,6155,6158,6160,6176,6211,6212,6272,6313,6314,6320,6400,6432,6435,6439,6441,6448,6450,
+6451,6457,6464,6468,6470,6480,6512,6528,6576,6593,6600,6608,6618,6622,6656,6679,6681,6686,6688,6741,6742,6743,6744,6752,6753,
+6754,6755,6757,6765,6771,6783,6784,6800,6816,6823,6824,6912,6916,6917,6964,6965,6966,6971,6972,6973,6978,6979,6981,6992,7002,
+7009,7019,7028,7040,7042,7043,7073,7074,7078,7080,7082,7086,7088,7104,7142,7143,7144,7146,7149,7150,7151,7154,7164,7168,7204,
+7212,7220,7222,7227,7232,7245,7248,7258,7288,7294,7376,7379,7380,7393,7394,7401,7405,7406,7410,7424,7468,7522,7544,7545,7579,
+7616,7676,7680,7960,7968,8008,8016,8025,8027,8029,8031,8064,8118,8125,8126,8127,8130,8134,8141,8144,8150,8157,8160,8173,8178,
+8182,8189,8192,8203,8206,8207,8208,8214,8216,8217,8218,8219,8221,8222,8223,8224,8232,8233,8234,8235,8236,8237,8238,8239,8240,
+8245,8249,8250,8251,8255,8257,8260,8261,8262,8263,8274,8275,8276,8277,8287,8288,8293,8298,8304,8305,8308,8314,8316,8317,8318,
+8319,8320,8330,8332,8333,8334,8336,8352,8400,8413,8417,8418,8421,8448,8450,8451,8455,8456,8458,8468,8469,8470,8472,8473,8478,
+8484,8485,8486,8487,8488,8489,8490,8494,8495,8501,8505,8506,8508,8512,8517,8522,8523,8524,8526,8527,8528,8544,8579,8581,8585,
+8592,8597,8602,8604,8608,8609,8611,8612,8614,8615,8622,8623,8654,8656,8658,8659,8660,8661,8692,8722,8723,8724,8960,8968,8972,
+8992,8994,9001,9002,9003,9014,9083,9084,9085,9109,9110,9115,9140,9180,9186,9216,9280,9312,9352,9372,9450,9472,9655,9656,9665,
+9666,9720,9728,9839,9840,9900,9901,9985,10088,10089,10090,10091,10092,10093,10094,10095,10096,10097,10098,10099,10100,10101,
+10102,10132,10176,10181,10182,10183,10188,10190,10214,10215,10216,10217,10218,10219,10220,10221,10222,10223,10224,10240,10496,
+10627,10628,10629,10630,10631,10632,10633,10634,10635,10636,10637,10638,10639,10640,10641,10642,10643,10644,10645,10646,10647,
+10648,10649,10712,10713,10714,10715,10716,10748,10749,10750,11008,11056,11077,11079,11088,11264,11312,11360,11389,11390,11493,
+11499,11503,11513,11517,11518,11520,11568,11631,11632,11647,11648,11680,11688,11696,11704,11712,11720,11728,11736,11744,11776,
+11778,11779,11780,11781,11782,11785,11786,11787,11788,11789,11790,11799,11800,11802,11803,11804,11805,11806,11808,11809,11810,
+11811,11812,11813,11814,11815,11816,11817,11818,11823,11824,11904,11931,12032,12272,12288,12289,12292,12293,12294,12295,12296,
+12297,12298,12299,12300,12301,12302,12303,12304,12305,12306,12308,12309,12310,12311,12312,12313,12314,12315,12316,12317,12318,
+12320,12321,12330,12336,12337,12342,12344,12347,12348,12349,12350,12353,12441,12443,12445,12447,12448,12449,12539,12540,12543,
+12549,12593,12688,12690,12694,12704,12736,12784,12800,12829,12832,12842,12880,12881,12896,12924,12927,12928,12938,12977,12992,
+13004,13008,13056,13175,13179,13278,13280,13311,13312,19904,19968,40960,40981,40982,42128,42192,42232,42238,42240,42508,42509,
+42512,42528,42538,42560,42606,42607,42608,42611,42620,42622,42623,42624,42656,42726,42736,42738,42752,42775,42784,42786,42864,
+42865,42888,42889,42891,42896,42912,43002,43003,43010,43011,43014,43015,43019,43020,43043,43045,43047,43048,43056,43062,43064,
+43065,43072,43124,43136,43138,43188,43204,43214,43216,43232,43250,43256,43259,43264,43274,43302,43310,43312,43335,43346,43359,
+43360,43392,43395,43396,43443,43444,43446,43450,43452,43453,43457,43471,43472,43486,43520,43561,43567,43569,43571,43573,43584,
+43587,43588,43596,43597,43600,43612,43616,43632,43633,43639,43642,43643,43648,43696,43697,43698,43701,43703,43705,43710,43712,
+43713,43714,43739,43741,43742,43777,43785,43793,43808,43816,43968,44003,44005,44006,44008,44009,44011,44012,44013,44016,44032,
+55216,55243,57344,63744,64048,64112,64256,64275,64285,64286,64287,64297,64298,64311,64312,64317,64318,64319,64320,64322,64323,
+64325,64326,64336,64434,64450,64467,64830,64831,64832,64848,64912,64914,64968,64976,65008,65020,65021,65022,65024,65040,65047,
+65048,65049,65056,65072,65073,65075,65077,65078,65079,65080,65081,65082,65083,65084,65085,65086,65087,65088,65089,65090,65091,
+65092,65093,65095,65096,65097,65101,65104,65105,65106,65108,65109,65110,65112,65113,65114,65115,65116,65117,65118,65119,65120,
+65122,65123,65124,65128,65129,65130,65131,65136,65141,65142,65277,65279,65281,65283,65284,65285,65286,65288,65289,65290,65291,
+65292,65293,65294,65296,65306,65307,65308,65311,65313,65339,65340,65341,65342,65343,65344,65345,65371,65372,65373,65374,65375,
+65376,65377,65378,65379,65380,65382,65392,65393,65438,65440,65474,65482,65490,65498,65504,65506,65507,65508,65509,65512,65513,
+65517,65520,65529,65532,65534,65536,65549,65576,65596,65599,65616,65664,65792,65793,65794,65799,65847,65856,65909,65913,65930,
+65936,66000,66045,66176,66208,66304,66336,66352,66369,66370,66378,66432,66463,66464,66504,66512,66513,66560,66640,66720,67584,
+67590,67592,67593,67594,67638,67639,67641,67644,67645,67647,67670,67671,67672,67680,67840,67862,67868,67871,67872,67898,67903,
+67904,68096,68097,68100,68101,68103,68108,68112,68116,68117,68120,68121,68148,68152,68155,68159,68160,68168,68176,68185,68192,
+68221,68223,68224,68352,68406,68409,68416,68438,68440,68448,68467,68472,68480,68608,68681,69216,69247,69632,69633,69634,69635,
+69688,69703,69714,69734,69760,69762,69763,69808,69811,69815,69817,69819,69821,69822,73728,74752,74864,77824,92160,110592,118784,
+119040,119081,119141,119143,119146,119149,119155,119163,119171,119173,119180,119210,119214,119296,119362,119365,119552,119648,
+119808,119894,119966,119970,119973,119977,119982,119995,119997,120005,120071,120077,120086,120094,120123,120128,120134,120138,
+120146,120488,120513,120514,120539,120540,120571,120572,120597,120598,120629,120630,120655,120656,120687,120688,120713,120714,
+120745,120746,120771,120772,120782,124928,126976,127024,127136,127153,127169,127185,127232,127248,127280,127344,127462,127504,
+127552,127568,127744,127792,127799,127872,127904,127942,127968,128000,128064,128066,128140,128141,128249,128256,128292,128293,
+128336,128507,128513,128530,128534,128536,128538,128540,128544,128552,128557,128560,128565,128581,128640,128768,131070,131072,
+173824,177984,194560,196606,262142,327678,393214,458750,524286,589822,655358,720894,786430,851966,917502,917505,917506,917536,
+917632,917760,918000,983038,983040,1048574,1048576,1114110
+};
+
+private static int[] bcE1 = {
+442,443,447,451,659,660,687,696,698,705,709,719,721,735,740,747,748,749,750,767,879,883,884,885,887,890,893,894,901,902,903,
+906,908,929,1013,1014,1153,1154,1159,1161,1319,1366,1369,1375,1415,1417,1418,1805,1806,1807,1808,1809,1839,1866,1868,1957,
+1968,1969,1983,1993,2026,2035,2037,2038,2041,2042,2047,2069,2073,2074,2083,2084,2087,2088,2093,2095,2110,2111,2136,2139,2141,
+2142,2303,2306,2307,2361,2362,2363,2364,2365,2368,2376,2380,2381,2383,2384,2391,2401,2403,2405,2415,2416,2417,2423,2431,2433,
+2435,2444,2448,2472,2480,2482,2489,2492,2493,2496,2500,2504,2508,2509,2510,2519,2525,2529,2531,2543,2545,2547,2553,2554,2555,
+2562,2563,2570,2576,2600,2608,2611,2614,2617,2620,2624,2626,2632,2637,2641,2652,2654,2671,2673,2676,2677,2690,2691,2701,2705,
+2728,2736,2739,2745,2748,2749,2752,2757,2760,2761,2764,2765,2768,2785,2787,2799,2801,2817,2819,2828,2832,2856,2864,2867,2873,
+2876,2877,2878,2879,2880,2884,2888,2892,2893,2902,2903,2909,2913,2915,2927,2928,2929,2935,2946,2947,2954,2960,2965,2970,2972,
+2975,2980,2986,3001,3007,3008,3010,3016,3020,3021,3024,3031,3055,3058,3064,3065,3066,3075,3084,3088,3112,3123,3129,3133,3136,
+3140,3144,3149,3158,3161,3169,3171,3183,3198,3199,3203,3212,3216,3240,3251,3257,3260,3261,3262,3263,3268,3270,3272,3275,3277,
+3286,3294,3297,3299,3311,3314,3331,3340,3344,3386,3389,3392,3396,3400,3404,3405,3406,3415,3425,3427,3439,3445,3449,3455,3459,
+3478,3505,3515,3517,3526,3530,3537,3540,3542,3551,3571,3572,3632,3633,3635,3642,3647,3653,3654,3662,3663,3673,3675,3714,3716,
+3720,3722,3725,3735,3743,3747,3749,3751,3755,3760,3761,3763,3769,3772,3773,3780,3782,3789,3801,3805,3840,3843,3858,3863,3865,
+3871,3881,3891,3892,3893,3894,3895,3896,3897,3898,3899,3900,3901,3903,3911,3948,3966,3967,3972,3973,3975,3980,3991,4028,4037,
+4038,4044,4047,4052,4056,4058,4138,4140,4144,4145,4151,4152,4154,4156,4158,4159,4169,4175,4181,4183,4185,4189,4192,4193,4196,
+4198,4205,4208,4212,4225,4226,4228,4230,4236,4237,4238,4239,4249,4252,4253,4255,4293,4346,4347,4348,4680,4685,4694,4696,4701,
+4744,4749,4784,4789,4798,4800,4805,4822,4880,4885,4954,4959,4960,4968,4988,5007,5017,5108,5120,5740,5742,5759,5760,5786,5787,
+5788,5866,5869,5872,5900,5905,5908,5937,5940,5942,5969,5971,5996,6000,6003,6067,6069,6070,6077,6085,6086,6088,6099,6102,6103,
+6106,6107,6108,6109,6121,6137,6149,6150,6154,6157,6158,6169,6210,6211,6263,6312,6313,6314,6389,6428,6434,6438,6440,6443,6449,
+6450,6456,6459,6464,6469,6479,6509,6516,6571,6592,6599,6601,6617,6618,6655,6678,6680,6683,6687,6740,6741,6742,6743,6750,6752,
+6753,6754,6756,6764,6770,6780,6783,6793,6809,6822,6823,6829,6915,6916,6963,6964,6965,6970,6971,6972,6977,6978,6980,6987,7001,
+7008,7018,7027,7036,7041,7042,7072,7073,7077,7079,7081,7082,7087,7097,7141,7142,7143,7145,7148,7149,7150,7153,7155,7167,7203,
+7211,7219,7221,7223,7231,7241,7247,7257,7287,7293,7295,7378,7379,7392,7393,7400,7404,7405,7409,7410,7467,7521,7543,7544,7578,
+7615,7654,7679,7957,7965,8005,8013,8023,8025,8027,8029,8061,8116,8124,8125,8126,8129,8132,8140,8143,8147,8155,8159,8172,8175,
+8180,8188,8190,8202,8205,8206,8207,8213,8215,8216,8217,8218,8220,8221,8222,8223,8231,8232,8233,8234,8235,8236,8237,8238,8239,
+8244,8248,8249,8250,8254,8256,8259,8260,8261,8262,8273,8274,8275,8276,8286,8287,8292,8297,8303,8304,8305,8313,8315,8316,8317,
+8318,8319,8329,8331,8332,8333,8334,8348,8377,8412,8416,8417,8420,8432,8449,8450,8454,8455,8457,8467,8468,8469,8471,8472,8477,
+8483,8484,8485,8486,8487,8488,8489,8493,8494,8500,8504,8505,8507,8511,8516,8521,8522,8523,8525,8526,8527,8543,8578,8580,8584,
+8585,8596,8601,8603,8607,8608,8610,8611,8613,8614,8621,8622,8653,8655,8657,8658,8659,8660,8691,8721,8722,8723,8959,8967,8971,
+8991,8993,9000,9001,9002,9013,9082,9083,9084,9108,9109,9114,9139,9179,9185,9203,9254,9290,9351,9371,9449,9471,9654,9655,9664,
+9665,9719,9727,9838,9839,9899,9900,9983,10087,10088,10089,10090,10091,10092,10093,10094,10095,10096,10097,10098,10099,10100,
+10101,10131,10175,10180,10181,10182,10186,10188,10213,10214,10215,10216,10217,10218,10219,10220,10221,10222,10223,10239,10495,
+10626,10627,10628,10629,10630,10631,10632,10633,10634,10635,10636,10637,10638,10639,10640,10641,10642,10643,10644,10645,10646,
+10647,10648,10711,10712,10713,10714,10715,10747,10748,10749,11007,11055,11076,11078,11084,11097,11310,11358,11388,11389,11492,
+11498,11502,11505,11516,11517,11519,11557,11621,11631,11632,11647,11670,11686,11694,11702,11710,11718,11726,11734,11742,11775,
+11777,11778,11779,11780,11781,11784,11785,11786,11787,11788,11789,11798,11799,11801,11802,11803,11804,11805,11807,11808,11809,
+11810,11811,11812,11813,11814,11815,11816,11817,11822,11823,11825,11929,12019,12245,12283,12288,12291,12292,12293,12294,12295,
+12296,12297,12298,12299,12300,12301,12302,12303,12304,12305,12307,12308,12309,12310,12311,12312,12313,12314,12315,12316,12317,
+12319,12320,12329,12335,12336,12341,12343,12346,12347,12348,12349,12351,12438,12442,12444,12446,12447,12448,12538,12539,12542,
+12543,12589,12686,12689,12693,12703,12730,12771,12799,12828,12830,12841,12879,12880,12895,12923,12926,12927,12937,12976,12991,
+13003,13007,13054,13174,13178,13277,13279,13310,13311,19893,19967,40907,40980,40981,42124,42182,42231,42237,42239,42507,42508,
+42511,42527,42537,42539,42605,42606,42607,42610,42611,42621,42622,42623,42647,42725,42735,42737,42743,42774,42783,42785,42863,
+42864,42887,42888,42890,42894,42897,42921,43002,43009,43010,43013,43014,43018,43019,43042,43044,43046,43047,43051,43061,43063,
+43064,43065,43123,43127,43137,43187,43203,43204,43215,43225,43249,43255,43258,43259,43273,43301,43309,43311,43334,43345,43347,
+43359,43388,43394,43395,43442,43443,43445,43449,43451,43452,43456,43469,43471,43481,43487,43560,43566,43568,43570,43572,43574,
+43586,43587,43595,43596,43597,43609,43615,43631,43632,43638,43641,43642,43643,43695,43696,43697,43700,43702,43704,43709,43711,
+43712,43713,43714,43740,43741,43743,43782,43790,43798,43814,43822,44002,44004,44005,44007,44008,44010,44011,44012,44013,44025,
+55203,55238,55291,63743,64045,64109,64217,64262,64279,64285,64286,64296,64297,64310,64311,64316,64317,64318,64319,64321,64322,
+64324,64325,64335,64433,64449,64466,64829,64830,64831,64847,64911,64913,64967,64975,65007,65019,65020,65021,65023,65039,65046,
+65047,65048,65049,65062,65072,65074,65076,65077,65078,65079,65080,65081,65082,65083,65084,65085,65086,65087,65088,65089,65090,
+65091,65092,65094,65095,65096,65100,65103,65104,65105,65106,65108,65109,65111,65112,65113,65114,65115,65116,65117,65118,65119,
+65121,65122,65123,65126,65128,65129,65130,65131,65140,65141,65276,65278,65279,65282,65283,65284,65285,65287,65288,65289,65290,
+65291,65292,65293,65295,65305,65306,65307,65310,65312,65338,65339,65340,65341,65342,65343,65344,65370,65371,65372,65373,65374,
+65375,65376,65377,65378,65379,65381,65391,65392,65437,65439,65470,65479,65487,65495,65500,65505,65506,65507,65508,65510,65512,
+65516,65518,65528,65531,65533,65535,65547,65574,65594,65597,65613,65629,65786,65792,65793,65794,65843,65855,65908,65912,65929,
+65930,65947,66044,66045,66204,66256,66334,66339,66368,66369,66377,66378,66461,66463,66499,66511,66512,66517,66639,66717,66729,
+67589,67591,67592,67593,67637,67638,67640,67643,67644,67646,67669,67670,67671,67679,67839,67861,67867,67870,67871,67897,67902,
+67903,68095,68096,68099,68100,68102,68107,68111,68115,68116,68119,68120,68147,68151,68154,68158,68159,68167,68175,68184,68191,
+68220,68222,68223,68351,68405,68408,68415,68437,68439,68447,68466,68471,68479,68607,68680,69215,69246,69631,69632,69633,69634,
+69687,69702,69709,69733,69743,69761,69762,69807,69810,69814,69816,69818,69820,69821,69825,74606,74850,74867,78894,92728,110593,
+119029,119078,119140,119142,119145,119148,119154,119162,119170,119172,119179,119209,119213,119261,119361,119364,119365,119638,
+119665,119892,119964,119967,119970,119974,119980,119993,119995,120003,120069,120074,120084,120092,120121,120126,120132,120134,
+120144,120485,120512,120513,120538,120539,120570,120571,120596,120597,120628,120629,120654,120655,120686,120687,120712,120713,
+120744,120745,120770,120771,120779,120831,126975,127019,127123,127150,127166,127183,127199,127242,127278,127337,127386,127490,
+127546,127560,127569,127776,127797,127868,127891,127940,127946,127984,128062,128064,128139,128140,128247,128252,128291,128292,
+128317,128359,128511,128528,128532,128534,128536,128538,128542,128549,128555,128557,128563,128576,128591,128709,128883,131071,
+173782,177972,178205,195101,196607,262143,327679,393215,458751,524287,589823,655359,720895,786431,851967,917504,917505,917535,
+917631,917759,917999,921599,983039,1048573,1048575,1114109,1114111
+};
+
+private static byte[] bcC1 = {
+1,1,1,1,1,1,1,1,19,1,19,19,1,19,1,19,19,19,1,19,14,1,19,19,1,1,1,19,19,1,19,1,1,1,1,19,1,1,14,14,1,1,1,1,1,1,19,5,5,12,5,14,
+5,14,5,5,14,5,5,4,4,14,4,19,19,4,4,4,14,4,14,4,14,4,14,4,4,4,4,14,4,4,4,14,1,1,14,1,14,1,1,14,1,14,1,1,14,1,14,1,1,1,1,1,1,
+14,1,1,1,1,1,1,1,14,1,1,14,1,1,14,1,1,1,1,14,1,1,11,1,1,11,14,1,1,1,1,1,1,1,1,14,1,14,14,14,14,1,1,1,14,1,14,14,1,1,1,1,1,
+1,1,14,1,1,14,14,1,1,14,1,1,14,1,11,14,1,1,1,1,1,1,1,14,1,1,14,1,14,1,1,14,14,1,1,1,14,1,1,1,1,14,1,1,1,1,1,1,1,1,1,1,1,14,
+1,1,1,14,1,1,1,1,19,11,19,1,1,1,1,1,1,1,14,1,14,14,14,1,1,14,1,19,1,1,1,1,1,1,1,14,1,1,1,1,1,1,1,14,1,1,1,14,1,1,1,1,1,1,1,
+1,14,1,1,14,1,1,1,14,1,1,1,1,1,1,1,1,1,1,14,1,14,14,1,1,1,1,14,1,14,11,1,1,14,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,14,1,14,14,1,1,
+1,14,1,1,1,1,1,1,14,1,1,1,1,14,1,14,1,14,19,19,19,19,1,1,1,14,1,14,1,14,1,14,14,1,14,1,1,1,1,1,1,1,14,1,14,1,14,1,14,1,1,1,
+1,1,14,1,14,1,1,1,1,1,14,1,14,1,14,1,14,1,1,1,1,14,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,14,1,1,1,1,19,1,19,1,1,1,18,1,
+19,19,1,1,1,1,1,14,1,14,1,1,14,1,1,14,1,1,1,14,1,14,1,14,1,1,1,11,1,14,1,19,19,19,19,14,18,1,1,1,1,1,14,1,1,1,14,1,14,1,1,
+14,1,14,19,19,1,1,1,1,1,1,1,1,1,19,1,14,1,1,1,1,14,1,14,14,1,14,1,14,1,14,14,1,1,1,1,1,14,1,1,14,1,14,1,14,1,14,1,1,1,1,1,
+14,1,14,1,1,1,14,1,14,1,1,1,1,14,1,14,1,14,1,14,1,1,1,1,14,1,14,1,1,1,1,1,1,1,14,1,14,1,14,1,14,1,1,1,1,1,1,1,1,14,14,1,1,
+1,1,1,1,1,1,1,1,1,19,1,19,1,1,19,1,1,19,1,19,1,1,19,18,15,1,4,19,19,19,19,19,19,19,19,19,19,18,16,2,6,8,3,7,13,11,19,19,19,
+19,19,19,13,19,19,19,19,19,19,19,18,15,15,15,9,1,9,10,19,19,19,1,9,10,19,19,19,1,11,14,14,14,14,14,19,1,19,1,19,1,19,1,19,
+19,1,19,1,19,1,19,1,19,1,11,1,1,1,19,1,19,1,19,19,19,1,1,19,1,1,1,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
+19,10,11,19,19,19,19,19,19,19,19,19,1,19,19,19,1,19,19,19,19,19,19,19,19,9,1,19,19,19,19,19,19,19,19,19,19,1,19,19,19,19,19,
+19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,1,19,19,19,19,19,19,19,19,19,19,
+19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,1,1,1,1,1,19,1,14,19,19,19,1,1,1,1,14,1,1,
+1,1,1,1,1,1,1,14,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
+19,18,19,19,1,1,1,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,1,14,19,1,19,1,1,1,19,19,1,14,19,1,
+1,19,1,19,1,1,1,1,1,1,1,1,19,1,1,19,1,1,19,19,1,19,1,1,1,19,1,19,1,1,19,1,19,1,19,1,19,1,1,1,1,19,1,1,1,1,1,19,1,1,1,1,1,14,
+14,19,14,19,19,1,1,1,14,1,19,19,19,1,1,1,19,1,1,1,1,1,1,14,1,14,1,14,1,1,14,1,19,1,1,11,11,1,19,1,1,1,14,1,1,14,1,1,1,1,1,
+14,1,1,14,1,1,1,14,1,1,14,1,14,1,14,1,1,1,1,1,1,14,1,14,1,14,1,14,1,14,1,1,1,1,1,1,1,1,1,1,14,1,14,1,14,1,14,1,14,1,1,1,1,
+1,1,1,1,1,1,1,14,1,14,1,1,1,14,1,1,1,1,1,1,1,1,1,1,4,14,4,10,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,19,19,5,5,5,5,5,15,5,5,19,5,14,
+19,19,19,19,14,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,13,19,13,19,13,19,19,19,19,19,19,19,
+19,11,19,10,10,19,19,11,11,19,5,5,5,5,15,19,11,11,11,19,19,19,19,10,13,10,13,9,13,19,19,19,1,19,19,19,19,19,19,1,19,19,19,
+19,19,19,19,19,19,19,1,1,1,1,1,1,1,1,1,11,19,19,19,11,19,19,19,15,19,19,15,1,1,1,1,1,1,1,1,19,1,1,1,19,19,19,19,19,1,14,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,19,4,4,4,4,4,14,4,14,4,14,4,4,4,4,4,4,14,4,14,4,4,4,4,
+4,4,4,4,4,4,19,4,4,4,4,4,4,4,4,4,12,4,1,14,1,1,14,1,19,1,14,1,1,1,14,1,14,1,1,1,1,1,1,1,1,1,1,1,1,1,14,1,1,15,14,1,14,1,14,
+1,19,14,19,19,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,19,1,1,1,19,1,1,1,19,1,1,1,19,1,1,1,19,1,9,4,19,19,19,19,19,19,
+9,1,1,1,1,1,1,1,19,19,19,19,19,19,19,19,19,19,1,19,19,19,1,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,15,1,1,1,1,15,
+15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,14,15,15,1,15,1,15
+};
+
+/**
+ * Lookup bidi class for character expressed as unicode scalar value.
+ * @param ch a unicode scalar value
+ * @return bidi class
+ */
+public static int getBidiClass ( int ch ) {
+  if ( ch <= 0x00FF ) {
+    return bcL1 [ ch - 0x0000 ];
+  } else if ( ( ch >= 0x0590 ) && ( ch <= 0x06FF ) ) {
+    return bcR1 [ ch - 0x0590 ];
+  } else {
+    return getBidiClass ( ch, bcS1, bcE1, bcC1 );
+  }
+}
+
+private static int getBidiClass ( int ch, int[] sa, int[] ea, byte[] ca ) {
+  int k = Arrays.binarySearch ( sa, ch );
+  if ( k >= 0 ) {
+    return ca [ k ];
+  } else {
+    k = - ( k + 1 );
+    if ( k == 0 ) {
+      return BidiConstants.L;
+    } else if ( ch <= ea [ k - 1 ] ) {
+      return ca [ k - 1 ];
+    } else {
+      return BidiConstants.L;
+    }
+  }
+}
+
+}

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/bidi/BidiConstants.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/bidi/BidiConstants.java?rev=1293736&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/bidi/BidiConstants.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/bidi/BidiConstants.java Sun Feb 26 02:29:01 2012
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.complexscripts.bidi;
+
+
+/**
+ * Constants used for bidirectional processing.
+ * @author Glenn Adams
+ */
+public interface BidiConstants {
+
+    // bidi character class
+
+    /** first external (official) category */
+    int FIRST       = 1;
+
+    // strong category
+    /** left-to-right class */
+    int L           = 1;
+    /** left-to-right embedding class */
+    int LRE         = 2;
+    /** left-to-right override class */
+    int LRO         = 3;
+    /** right-to-left  class */
+    int R           = 4;
+    /** right-to-left arabic class */
+    int AL          = 5;
+    /** right-to-left embedding class */
+    int RLE         = 6;
+    /** right-to-left override class */
+    int RLO         = 7;
+
+    // weak category
+    /** pop directional formatting class */
+    int PDF         = 8;
+    /** european number class */
+    int EN          = 9;
+    /** european number separator class */
+    int ES          = 10;
+    /** european number terminator class */
+    int ET          = 11;
+    /** arabic number class */
+    int AN          = 12;
+    /** common number separator class */
+    int CS          = 13;
+    /** non-spacing mark class */
+    int NSM         = 14;
+    /** boundary neutral class */
+    int BN          = 15;
+
+    // neutral category
+    /** paragraph separator class */
+    int B           = 16;
+    /** segment separator class */
+    int S           = 17;
+    /** whitespace class */
+    int WS          = 18;
+    /** other neutrals class */
+    int ON          = 19;
+
+    /** last external (official) category */
+    int LAST        = 19;
+
+    // implementation specific categories
+    /** placeholder for low surrogate */
+    int SURROGATE   = 20;
+
+    // other constants
+    /** last 
+    /** maximum bidirectional levels */
+    int MAX_LEVELS  = 61;
+    /** override flag */
+    int OVERRIDE    = 128;
+}

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/bidi/BidiResolver.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/bidi/BidiResolver.java?rev=1293736&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/bidi/BidiResolver.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/bidi/BidiResolver.java Sun Feb 26 02:29:01 2012
@@ -0,0 +1,242 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.complexscripts.bidi;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Stack;
+import java.util.Vector;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.area.LineArea;
+import org.apache.fop.area.inline.InlineArea;
+import org.apache.fop.fo.pagination.PageSequence;
+
+// CSOFF: EmptyForIteratorPadCheck
+// CSOFF: InnerAssignmentCheck
+// CSOFF: LineLengthCheck
+// CSOFF: NoWhitespaceAfterCheck
+// CSOFF: SimplifyBooleanReturnCheck
+
+/**
+ * <p>A utility class for performing bidirectional resolution processing.</p>
+ *
+ * @author Glenn Adams
+ */
+public final class BidiResolver {
+
+    /**
+     * logging instance
+     */
+    private static final Log log = LogFactory.getLog(BidiResolver.class);                                                   // CSOK: ConstantNameCheck
+
+    private BidiResolver() {
+    }
+
+    /**
+     * Resolve inline directionality.
+     * @param ps a page sequence FO instance
+     */
+    public static void resolveInlineDirectionality ( PageSequence ps ) {
+        if (log.isDebugEnabled()) {
+            log.debug ( "BD: RESOLVE: " + ps );
+        }
+        List ranges = pruneEmptyRanges ( ps.collectDelimitedTextRanges ( new Stack() ) );
+        resolveInlineDirectionality ( ranges );
+    }
+
+    /**
+     * Reorder line area.
+     * @param la a line area instance
+     */
+    public static void reorder ( LineArea la ) {
+
+        // 1. collect inline levels
+        List runs = collectRuns ( la.getInlineAreas(), new Vector() );
+        if (log.isDebugEnabled()) {
+            dumpRuns ( "BD: REORDER: INPUT:", runs );
+        }
+
+        // 2. split heterogeneous inlines
+        runs = splitRuns ( runs );
+        if (log.isDebugEnabled()) {
+            dumpRuns ( "BD: REORDER: SPLIT INLINES:", runs );
+        }
+
+        // 3. determine minimum and maximum levels
+        int[] mm = computeMinMaxLevel ( runs, null );
+        if (log.isDebugEnabled()) {
+            log.debug( "BD: REORDER: { min = " + mm[0] + ", max = " + mm[1] + "}" );
+        }
+
+        // 4. reorder from maximum level to minimum odd level
+        int mn = mm[0];
+        int mx = mm[1];
+        if ( mx > 0 ) {
+            for ( int l1 = mx, l2 = ( ( mn & 1 ) == 0 ) ? ( mn + 1 ) : mn; l1 >= l2; l1-- ) {
+                runs = reorderRuns ( runs, l1 );
+            }
+        }
+        if (log.isDebugEnabled()) {
+            dumpRuns ( "BD: REORDER: REORDERED RUNS:", runs );
+        }
+
+        // 5. reverse word consituents (characters and glyphs) while mirroring
+        boolean mirror = true;
+        reverseWords ( runs, mirror );
+        if (log.isDebugEnabled()) {
+            dumpRuns ( "BD: REORDER: REORDERED WORDS:", runs );
+        }
+
+        // 6. replace line area's inline areas with reordered runs' inline areas
+        replaceInlines ( la, replicateSplitWords ( runs ) );
+    }
+
+    private static void resolveInlineDirectionality ( List ranges ) {
+        for ( Iterator it = ranges.iterator(); it.hasNext(); ) {
+            DelimitedTextRange r = (DelimitedTextRange) it.next();
+            r.resolve();
+            if (log.isDebugEnabled()) {
+                log.debug ( r );
+            }
+        }
+    }
+
+    private static List collectRuns ( List inlines, List runs ) {
+        for ( Iterator it = inlines.iterator(); it.hasNext(); ) {
+            InlineArea ia = (InlineArea) it.next();
+            runs = ia.collectInlineRuns ( runs );
+        }
+        return runs;
+    }
+
+    private static List splitRuns ( List runs ) {
+        List runsNew = new Vector();
+        for ( Iterator it = runs.iterator(); it.hasNext(); ) {
+            InlineRun ir = (InlineRun) it.next();
+            if ( ir.isHomogenous() ) {
+                runsNew.add ( ir );
+            } else {
+                runsNew.addAll ( ir.split() );
+            }
+        }
+        if ( ! runsNew.equals ( runs ) ) {
+            runs = runsNew;
+        }
+        return runs;
+    }
+
+    private static int[] computeMinMaxLevel ( List runs, int[] mm ) {
+        if ( mm == null ) {
+            mm = new int[] {Integer.MAX_VALUE, Integer.MIN_VALUE};
+        }
+        for ( Iterator it = runs.iterator(); it.hasNext(); ) {
+            InlineRun ir = (InlineRun) it.next();
+            ir.updateMinMax ( mm );
+        }
+        return mm;
+    }
+    private static List reorderRuns ( List runs, int level ) {
+        assert level >= 0;
+        List runsNew = new Vector();
+        for ( int i = 0, n = runs.size(); i < n; i++ ) {
+            InlineRun iri = (InlineRun) runs.get(i);
+            if ( iri.getMinLevel() < level ) {
+                runsNew.add ( iri );
+            } else {
+                int s = i;
+                int e = s;
+                while ( e < n ) {
+                    InlineRun ire = (InlineRun) runs.get(e);
+                    if ( ire.getMinLevel() < level ) {
+                        break;
+                    } else {
+                        e++;
+                    }
+                }
+                if ( s < e ) {
+                    runsNew.addAll ( reverseRuns ( runs, s, e ) );
+                }
+                i = e - 1;
+            }
+        }
+        if ( ! runsNew.equals ( runs ) ) {
+            runs = runsNew;
+        }
+        return runs;
+    }
+    private static List reverseRuns ( List runs, int s, int e ) {
+        int n = e - s;
+        Vector runsNew = new Vector ( n );
+        if ( n > 0 ) {
+            for ( int i = 0; i < n; i++ ) {
+                int k = ( n - i - 1 );
+                InlineRun ir = (InlineRun) runs.get(s + k);
+                ir.reverse();
+                runsNew.add ( ir );
+            }
+        }
+        return runsNew;
+    }
+    private static void reverseWords ( List runs, boolean mirror ) {
+        for ( Iterator it = runs.iterator(); it.hasNext(); ) {
+            InlineRun ir = (InlineRun) it.next();
+            ir.maybeReverseWord ( mirror );
+        }
+    }
+    private static List replicateSplitWords ( List runs ) {
+        // [TBD] for each run which inline word area appears multiple times in
+        // runs, replicate that word
+        return runs;
+    }
+    private static void replaceInlines ( LineArea la, List runs ) {
+        List<InlineArea> inlines = new ArrayList<InlineArea>();
+        for ( Iterator it = runs.iterator(); it.hasNext(); ) {
+            InlineRun ir = (InlineRun) it.next();
+            inlines.add ( ir.getInline() );
+        }
+        la.setInlineAreas ( unflattenInlines ( inlines ) );
+    }
+    private static List unflattenInlines ( List<InlineArea> inlines ) {
+        return new UnflattenProcessor ( inlines ) .unflatten();
+    }
+    private static void dumpRuns ( String header, List runs ) {
+        log.debug ( header );
+        for ( Iterator it = runs.iterator(); it.hasNext(); ) {
+            InlineRun ir = (InlineRun) it.next();
+            log.debug ( ir );
+        }
+    }
+
+    private static List pruneEmptyRanges ( Stack ranges ) {
+        Vector rv = new Vector();
+        for ( Iterator it = ranges.iterator(); it.hasNext(); ) {
+            DelimitedTextRange r = (DelimitedTextRange) it.next();
+            if ( ! r.isEmpty() ) {
+                rv.add ( r );
+            }
+        }
+        return rv;
+    }
+
+}



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