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 sp...@apache.org on 2011/06/15 20:47:49 UTC

svn commit: r1136146 [1/3] - in /xmlgraphics/fop/branches/Temp_ComplexScripts: src/codegen/complexscripts/ src/java/org/apache/fop/fonts/ test/java/org/apache/fop/complexscripts/arabic/ test/java/org/apache/fop/complexscripts/fonts/ test/java/org/apach...

Author: spepping
Date: Wed Jun 15 18:47:47 2011
New Revision: 1136146

URL: http://svn.apache.org/viewvc?rev=1136146&view=rev
Log:
Patch to revision 1136002 of branch Temp_ComplexScripts by Glenn Adams; see Bugzilla 49687; this commit contains the additions and deletions which should have been part of revision 1136144

Added:
    xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/fonts/DevanagariScriptProcessor.java   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/fonts/IndicScriptProcessor.java   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/arabic/
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/arabic/ArabicScriptTestSuite.java   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/fonts/
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/fonts/FontsTestSuite.java   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/scripts/
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/scripts/ScriptsTestSuite.java   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/util/
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/util/TTXFile.java   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/util/TTXFileTestCase.java   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_background-image_writing-mode_rl.xml   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_external-destination_writing-mode_rl.xml   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_external-destination_writing-mode_rl_2.xml   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_for_toc_writing-mode_rl.xml   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_height_baseline-shift_writing-mode_rl.xml   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_height_inline-child_writing-mode_rl.xml   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_height_multi-child_writing-mode_rl.xml   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_height_multi-line_writing-mode_rl.xml   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_height_writing-mode_rl.xml   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_internal-desination-next-page.xml   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_internal-desination-next-page_writing-mode_rl.xml   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_internal-desination-same-page-after.xml   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_internal-desination-same-page-after_writing-mode_rl.xml   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_internal-desination-same-page-before.xml   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_internal-desination-same-page-before_writing-mode_rl.xml   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/block_text-align_4.xml   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/block_text-align_5.xml   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/character_writing-mode_rl.xml   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/inline_background-color_writing-mode_rl.xml   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/instream-foreign-object_basic_writing-mode_rl.xml   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/instream-foreign-object_border_padding_writing-mode_rl.xml   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/instream-foreign-object_display-align_writing-mode_rl.xml   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/list-block_writing-mode_rl.xml   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/page-number-citation_writing-mode_rl.xml   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/table-column_column-progression-lr.xml   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/table-column_column-progression-rl.xml   (with props)
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/resources/complexscripts/
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/resources/complexscripts/arab/
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/resources/complexscripts/arab/ttx/
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/resources/complexscripts/arab/ttx/arab-001.ttx
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/resources/complexscripts/arab/ttx/arab-002.ttx
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/resources/complexscripts/arab/ttx/arab-003.ttx
    xmlgraphics/fop/branches/Temp_ComplexScripts/test/resources/complexscripts/arab/ttx/arab-004.ttx
Removed:
    xmlgraphics/fop/branches/Temp_ComplexScripts/src/codegen/complexscripts/

Added: xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/fonts/DevanagariScriptProcessor.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/fonts/DevanagariScriptProcessor.java?rev=1136146&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/fonts/DevanagariScriptProcessor.java (added)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/fonts/DevanagariScriptProcessor.java Wed Jun 15 18:47:47 2011
@@ -0,0 +1,534 @@
+/*
+ * 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.fonts;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+// CSOFF: AvoidNestedBlocksCheck
+// CSOFF: NoWhitespaceAfterCheck
+// CSOFF: WhitespaceAfter
+// CSOFF: InnerAssignmentCheck
+// CSOFF: SimplifyBooleanReturnCheck
+// CSOFF: LineLengthCheck
+
+/**
+ * <p>The <code>DevanagariScriptProcessor</code> class implements a script processor for
+ * performing glyph substitution and positioning operations on content associated with the Devanagari script.</p>
+ * @author Glenn Adams
+ */
+public class DevanagariScriptProcessor extends IndicScriptProcessor {
+
+    /** logging instance */
+    private static final Log log = LogFactory.getLog(DevanagariScriptProcessor.class);                                  // CSOK: ConstantNameCheck
+
+    DevanagariScriptProcessor ( String script ) {
+        super ( script );
+    }
+
+    @Override
+    protected Class getSyllabizerClass() {
+        return DevanagariSyllabizer.class;
+    }
+
+    @Override
+    // find rightmost pre-base matra
+    protected int findPreBaseMatra ( GlyphSequence gs ) {
+        int   ng = gs.getGlyphCount();
+        int   lk = -1;
+        for ( int i = ng; i > 0; i-- ) {
+            int k = i - 1;
+            if ( containsPreBaseMatra ( gs, k ) ) {
+                lk = k;
+                break;
+            }
+        }
+        return lk;
+    }
+
+    @Override
+    // find leftmost pre-base matra target, starting from source
+    protected int findPreBaseMatraTarget ( GlyphSequence gs, int source ) {
+        int   ng = gs.getGlyphCount();
+        int   lk = -1;
+        for ( int i = ( source < ng ) ? source : ng; i > 0; i-- ) {
+            int k = i - 1;
+            if ( containsConsonant ( gs, k ) ) {
+                if ( containsHalfConsonant ( gs, k ) ) {
+                    lk = k;
+                } else if ( lk == -1 ) {
+                    lk = k;
+                } else {
+                    break;
+                }
+            }
+        }
+        return lk;
+    }
+
+    private static boolean containsPreBaseMatra ( GlyphSequence gs, int k ) {
+        GlyphSequence.CharAssociation a = gs.getAssociation ( k );
+        int[] ca = gs.getCharacterArray ( false );
+        for ( int i = a.getStart(), e = a.getEnd(); i < e; i++ ) {
+            if ( isPreM ( ca [ i ] ) ) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static boolean containsConsonant ( GlyphSequence gs, int k ) {
+        GlyphSequence.CharAssociation a = gs.getAssociation ( k );
+        int[] ca = gs.getCharacterArray ( false );
+        for ( int i = a.getStart(), e = a.getEnd(); i < e; i++ ) {
+            if ( isC ( ca [ i ] ) ) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static boolean containsHalfConsonant ( GlyphSequence gs, int k ) {
+        Boolean half = (Boolean) gs.getAssociation ( k ) . getPredication ( "half" );
+        return ( half != null ) ? half.booleanValue() : false;
+    }
+
+    @Override
+    protected int findReph ( GlyphSequence gs ) {
+        int   ng = gs.getGlyphCount();
+        int   li = -1;
+        for ( int i = 0; i < ng; i++ ) {
+            if ( containsReph ( gs, i ) ) {
+                li = i;
+                break;
+            }
+        }
+        return li;
+    }
+
+    @Override
+    protected int findRephTarget ( GlyphSequence gs, int source ) {
+        int   ng = gs.getGlyphCount();
+        int   c1 = -1;
+        int   c2 = -1;
+        // first candidate target is after first non-half consonant
+        for ( int i = 0; i < ng; i++ ) {
+            if ( ( i != source ) && containsConsonant ( gs, i ) ) {
+                if ( ! containsHalfConsonant ( gs, i ) ) {
+                    c1 = i + 1;
+                    break;
+                }
+            }
+        }
+        // second candidate target is after last non-prebase matra after first candidate or before first syllable or vedic mark
+        for ( int i = ( c1 >= 0 ) ? c1 : 0; i < ng; i++ ) {
+            if ( containsMatra ( gs, i ) && ! containsPreBaseMatra ( gs, i ) ) {
+                c2 = i + 1;
+            } else if ( containsOtherMark ( gs, i ) ) {
+                c2 = i;
+                break;
+            }
+        }
+        if ( c2 >= 0 ) {
+            return c2;
+        } else if ( c1 >= 0 ) {
+            return c1;
+        } else {
+            return source;
+        }
+    }
+
+    private static boolean containsReph ( GlyphSequence gs, int k ) {
+        Boolean rphf = (Boolean) gs.getAssociation ( k ) . getPredication ( "rphf" );
+        return ( rphf != null ) ? rphf.booleanValue() : false;
+    }
+
+    private static boolean containsMatra ( GlyphSequence gs, int k ) {
+        GlyphSequence.CharAssociation a = gs.getAssociation ( k );
+        int[] ca = gs.getCharacterArray ( false );
+        for ( int i = a.getStart(), e = a.getEnd(); i < e; i++ ) {
+            if ( isM ( ca [ i ] ) ) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static boolean containsOtherMark ( GlyphSequence gs, int k ) {
+        GlyphSequence.CharAssociation a = gs.getAssociation ( k );
+        int[] ca = gs.getCharacterArray ( false );
+        for ( int i = a.getStart(), e = a.getEnd(); i < e; i++ ) {
+            switch ( typeOf ( ca [ i ] ) ) {
+            case C_T:   // tone (e.g., udatta, anudatta)
+            case C_A:   // accent (e.g., acute, grave)
+            case C_O:   // other (e.g., candrabindu, anusvara, visarga, etc)
+                return true;
+            default:
+                break;
+            }
+        }
+        return false;
+    }
+
+    private static class DevanagariSyllabizer extends DefaultSyllabizer {
+        DevanagariSyllabizer ( String script, String language ) {
+            super ( script, language );
+        }
+        @Override
+        // | C ...
+        protected int findStartOfSyllable ( int[] ca, int s, int e ) {
+            if ( ( s < 0 ) || ( s >= e ) ) {
+                return -1;
+            } else {
+                while ( s < e ) {
+                    int c = ca [ s ];
+                    if ( isC ( c ) ) {
+                        break;
+                    } else {
+                        s++;
+                    }
+                }
+                return s;
+            }
+        }
+        @Override
+        // D* L? | ...
+        protected int findEndOfSyllable ( int[] ca, int s, int e ) {
+            if ( ( s < 0 ) || ( s >= e ) ) {
+                return -1;
+            } else {
+                int nd = 0;
+                int nl = 0;
+                int i;
+                // consume dead consonants
+                while ( ( i = isDeadConsonant ( ca, s, e ) ) > s ) {
+                    s = i; nd++;
+                }
+                // consume zero or one live consonant
+                if ( ( i = isLiveConsonant ( ca, s, e ) ) > s ) {
+                    s = i; nl++;
+                }
+                return ( ( nd > 0 ) || ( nl > 0 ) ) ? s : -1;
+            }
+        }
+        // D := ( C N? H )?
+        private int isDeadConsonant ( int[] ca, int s, int e ) {
+            if ( s < 0 ) {
+                return -1;
+            } else {
+                int c, i = 0;
+                int nc = 0, nh = 0;
+                do {
+                    // C
+                    if ( ( s + i ) < e ) {
+                        c = ca [ s + i ];
+                        if ( isC ( c ) ) {
+                            i++;
+                            nc++;
+                        } else {
+                            break;
+                        }
+                    }
+                    // N?
+                    if ( ( s + i ) < e ) {
+                        c = ca [ s + 1 ];
+                        if ( isN ( c ) ) {
+                            i++;
+                        }
+                    }
+                    // H
+                    if ( ( s + i ) < e ) {
+                        c = ca [ s + i ];
+                        if ( isH ( c ) ) {
+                            i++;
+                            nh++;
+                        } else {
+                            break;
+                        }
+                    }
+                } while ( false );
+                return ( nc > 0 ) && ( nh > 0 ) ? s + i : -1;
+            }
+        }
+        // L := ( (C|V) N? X* )?; where X = ( MATRA | ACCENT MARK | TONE MARK | OTHER MARK )
+        private int isLiveConsonant ( int[] ca, int s, int e ) {
+            if ( s < 0 ) {
+                return -1;
+            } else {
+                int c, i = 0;
+                int nc = 0, nv = 0, nx = 0;
+                do {
+                    // C
+                    if ( ( s + i ) < e ) {
+                        c = ca [ s + i ];
+                        if ( isC ( c ) ) {
+                            i++;
+                            nc++;
+                        } else if ( isV ( c ) ) {
+                            i++;
+                            nv++;
+                        } else {
+                            break;
+                        }
+                    }
+                    // N?
+                    if ( ( s + i ) < e ) {
+                        c = ca [ s + i ];
+                        if ( isN ( c ) ) {
+                            i++;
+                        }
+                    }
+                    // X*
+                    while ( ( s + i ) < e ) {
+                        c = ca [ s + i ];
+                        if ( isX ( c ) ) {
+                            i++;
+                            nx++;
+                        } else {
+                            break;
+                        }
+                    }
+                } while ( false );
+                // if no X but has H, then ignore C|I
+                if ( nx == 0 ) {
+                    if ( ( s + i ) < e ) {
+                        c = ca [ s + i ];
+                        if ( isH ( c ) ) {
+                            if ( nc > 0 ) {
+                                nc--;
+                            } else if ( nv > 0 ) {
+                                nv--;
+                            }
+                        }
+                    }
+                }
+                return ( ( nc > 0 ) || ( nv > 0 ) ) ? s + i : -1;
+            }
+        }
+    }
+
+    // devanagari character types
+    static final short C_U          = 0;            // unassigned
+    static final short C_C          = 1;            // consonant
+    static final short C_V          = 2;            // vowel
+    static final short C_M          = 3;            // vowel sign (matra)
+    static final short C_S          = 4;            // symbol or sign
+    static final short C_T          = 5;            // tone mark
+    static final short C_A          = 6;            // accent mark
+    static final short C_P          = 7;            // punctuation
+    static final short C_D          = 8;            // digit
+    static final short C_H          = 9;            // halant (virama)
+    static final short C_O          = 10;           // other signs
+    static final short C_N          = 0x0100;       // nukta(ized)
+    static final short C_R          = 0x0200;       // reph(ized)
+    static final short C_PRE        = 0x0400;       // pre-base
+    static final short C_M_TYPE     = 0x00FF;       // type mask
+    static final short C_M_FLAGS    = 0x7F00;       // flag mask
+    // devanagari block range
+    static final int ccaStart       =  0x0900;      // first code point mapped by cca                                   // CSOK: ConstantNameCheck
+    static final int ccaEnd         =  0x0980;      // last code point + 1 mapped by cca                                // CSOK: ConstantNameCheck
+    // devanagari character type lookups
+    static final short[] cca = {                                                                                        // CSOK: ConstantNameCheck
+        C_O,                        // 0x0900       // INVERTED CANDRABINDU
+        C_O,                        // 0x0901       // CANDRABINDU
+        C_O,                        // 0x0902       // ANUSVARA
+        C_O,                        // 0x0903       // VISARGA
+        C_V,                        // 0x0904       // SHORT A
+        C_V,                        // 0x0905       // A
+        C_V,                        // 0x0906       // AA
+        C_V,                        // 0x0907       // I
+        C_V,                        // 0x0908       // II
+        C_V,                        // 0x0909       // U
+        C_V,                        // 0x090A       // UU
+        C_V,                        // 0x090B       // VOCALIC R
+        C_V,                        // 0x090C       // VOCALIC L
+        C_V,                        // 0x090D       // CANDRA E
+        C_V,                        // 0x090E       // SHORT E
+        C_V,                        // 0x090F       // E
+        C_V,                        // 0x0910       // AI
+        C_V,                        // 0x0911       // CANDRA O
+        C_V,                        // 0x0912       // SHORT O
+        C_V,                        // 0x0913       // O
+        C_V,                        // 0x0914       // AU
+        C_C,                        // 0x0915       // KA
+        C_C,                        // 0x0916       // KHA
+        C_C,                        // 0x0917       // GA
+        C_C,                        // 0x0918       // GHA
+        C_C,                        // 0x0919       // NGA
+        C_C,                        // 0x091A       // CA
+        C_C,                        // 0x091B       // CHA
+        C_C,                        // 0x091C       // JA
+        C_C,                        // 0x091D       // JHA
+        C_C,                        // 0x091E       // NYA
+        C_C,                        // 0x091F       // TTA
+        C_C,                        // 0x0920       // TTHA
+        C_C,                        // 0x0921       // DDA
+        C_C,                        // 0x0922       // DDHA
+        C_C,                        // 0x0923       // NNA
+        C_C,                        // 0x0924       // TA
+        C_C,                        // 0x0925       // THA
+        C_C,                        // 0x0926       // DA
+        C_C,                        // 0x0927       // DHA
+        C_C,                        // 0x0928       // NA
+        C_C,                        // 0x0929       // NNNA
+        C_C,                        // 0x092A       // PA
+        C_C,                        // 0x092B       // PHA
+        C_C,                        // 0x092C       // BA
+        C_C,                        // 0x092D       // BHA
+        C_C,                        // 0x092E       // MA
+        C_C,                        // 0x092F       // YA
+        C_C|C_R,                    // 0x0930       // RA                                                               // CSOK: WhitespaceAround
+        C_C|C_R|C_N,                // 0x0931       // RRA          = 0930+093C                                         // CSOK: WhitespaceAround
+        C_C,                        // 0x0932       // LA
+        C_C,                        // 0x0933       // LLA
+        C_C,                        // 0x0934       // LLLA
+        C_C,                        // 0x0935       // VA
+        C_C,                        // 0x0936       // SHA
+        C_C,                        // 0x0937       // SSA
+        C_C,                        // 0x0938       // SA
+        C_C,                        // 0x0939       // HA
+        C_M,                        // 0x093A       // OE (KASHMIRI)
+        C_M,                        // 0x093B       // OOE (KASHMIRI)
+        C_N,                        // 0x093C       // NUKTA
+        C_S,                        // 0x093D       // AVAGRAHA
+        C_M,                        // 0x093E       // AA
+        C_M|C_PRE,                  // 0x093F       // I                                                               // CSOK: WhitespaceAround
+        C_M,                        // 0x0940       // II
+        C_M,                        // 0x0941       // U
+        C_M,                        // 0x0942       // UU
+        C_M,                        // 0x0943       // VOCALIC R
+        C_M,                        // 0x0944       // VOCALIC RR
+        C_M,                        // 0x0945       // CANDRA E
+        C_M,                        // 0x0946       // SHORT E
+        C_M,                        // 0x0947       // E
+        C_M,                        // 0x0948       // AI
+        C_M,                        // 0x0949       // CANDRA O
+        C_M,                        // 0x094A       // SHORT O
+        C_M,                        // 0x094B       // O
+        C_M,                        // 0x094C       // AU
+        C_H,                        // 0x094D       // VIRAMA (HALANT)
+        C_M,                        // 0x094E       // PRISHTHAMATRA E
+        C_M,                        // 0x094F       // AW
+        C_S,                        // 0x0950       // OM
+        C_T,                        // 0x0951       // UDATTA
+        C_T,                        // 0x0952       // ANUDATTA
+        C_A,                        // 0x0953       // GRAVE
+        C_A,                        // 0x0954       // ACUTE
+        C_M,                        // 0x0955       // CANDRA LONG E
+        C_M,                        // 0x0956       // UE
+        C_M,                        // 0x0957       // UUE
+        C_C|C_N,                    // 0x0958       // QA                                                               // CSOK: WhitespaceAround
+        C_C|C_N,                    // 0x0959       // KHHA                                                             // CSOK: WhitespaceAround
+        C_C|C_N,                    // 0x095A       // GHHA                                                             // CSOK: WhitespaceAround
+        C_C|C_N,                    // 0x095B       // ZA                                                               // CSOK: WhitespaceAround
+        C_C|C_N,                    // 0x095C       // DDDHA                                                            // CSOK: WhitespaceAround
+        C_C|C_N,                    // 0x095D       // RHA                                                              // CSOK: WhitespaceAround
+        C_C|C_N,                    // 0x095E       // FA                                                               // CSOK: WhitespaceAround
+        C_C|C_N,                    // 0x095F       // YYA                                                              // CSOK: WhitespaceAround
+        C_V,                        // 0x0960       // VOCALIC RR
+        C_V,                        // 0x0961       // VOCALIC LL
+        C_M,                        // 0x0962       // VOCALIC RR
+        C_M,                        // 0x0963       // VOCALIC LL
+        C_P,                        // 0x0964       // DANDA
+        C_P,                        // 0x0965       // DOUBLE DANDA
+        C_D,                        // 0x0966       // ZERO
+        C_D,                        // 0x0967       // ONE
+        C_D,                        // 0x0968       // TWO
+        C_D,                        // 0x0969       // THREE
+        C_D,                        // 0x096A       // FOUR
+        C_D,                        // 0x096B       // FIVE
+        C_D,                        // 0x096C       // SIX
+        C_D,                        // 0x096D       // SEVEN
+        C_D,                        // 0x096E       // EIGHT
+        C_D,                        // 0x096F       // NINE
+        C_S,                        // 0x0970       // ABBREVIATION SIGN
+        C_S,                        // 0x0971       // HIGH SPACING DOT
+        C_V,                        // 0x0972       // CANDRA A (MARATHI)
+        C_V,                        // 0x0973       // OE (KASHMIRI)
+        C_V,                        // 0x0974       // OOE (KASHMIRI)
+        C_V,                        // 0x0975       // AW (KASHMIRI)
+        C_V,                        // 0x0976       // UE (KASHMIRI)
+        C_V,                        // 0x0977       // UUE (KASHMIRI)
+        C_U,                        // 0x0978       // UNASSIGNED
+        C_C,                        // 0x0979       // ZHA
+        C_C,                        // 0x097A       // HEAVY YA
+        C_C,                        // 0x097B       // GGAA (SINDHI)
+        C_C,                        // 0x097C       // JJA (SINDHI)
+        C_C,                        // 0x097D       // GLOTTAL STOP (LIMBU)
+        C_C,                        // 0x097E       // DDDA (SINDHI)
+        C_C                         // 0x097F       // BBA (SINDHI)
+    };
+    static int typeOf(int c) {
+        if ( ( c >= ccaStart ) && ( c < ccaEnd ) ) {
+            return cca [ c - ccaStart ] & C_M_TYPE;
+        } else {
+            return C_U;
+        }
+    }
+    static boolean isType(int c, int t) {
+        return typeOf ( c ) == t;
+    }
+    static boolean hasFlag(int c, int f) {
+        if ( ( c >= ccaStart ) && ( c < ccaEnd ) ) {
+            return ( cca [ c - ccaStart ] & f ) == f;
+        } else {
+            return false;
+        }
+    }
+    static boolean isC(int c) {
+        return isType(c,C_C);
+    }
+    static boolean isR(int c) {
+        return isType(c,C_C) && hasR(c);
+    }
+    static boolean isV(int c) {
+        return isType(c,C_V);
+    }
+    static boolean isN(int c) {
+        return c == 0x093C;
+    }
+    static boolean isH(int c) {
+        return c == 0x094D;
+    }
+    static boolean isM(int c) {
+        return isType(c,C_M);
+    }
+    static boolean isPreM(int c) {
+        return isType(c,C_M) && hasFlag(c,C_PRE);
+    }
+    static boolean isX(int c) {
+        switch ( typeOf ( c ) ) {
+        case C_M: // matra (combining vowel)
+        case C_A: // accent mark
+        case C_T: // tone mark
+        case C_O: // other (modifying) mark
+            return true;
+        default:
+            return false;
+        }
+    }
+    static boolean hasR(int c) {
+        return hasFlag(c,C_R);
+    }
+    static boolean hasN(int c) {
+        return hasFlag(c,C_N);
+    }
+
+}

Propchange: xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/fonts/DevanagariScriptProcessor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/fonts/DevanagariScriptProcessor.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/fonts/IndicScriptProcessor.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/fonts/IndicScriptProcessor.java?rev=1136146&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/fonts/IndicScriptProcessor.java (added)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/fonts/IndicScriptProcessor.java Wed Jun 15 18:47:47 2011
@@ -0,0 +1,581 @@
+/*
+ * 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.fonts;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.util.CharUtilities;
+
+// CSOFF: AvoidNestedBlocksCheck
+// CSOFF: NoWhitespaceAfterCheck
+// CSOFF: InnerAssignmentCheck
+// CSOFF: SimplifyBooleanReturnCheck
+// CSOFF: EmptyForIteratorPadCheck
+// CSOFF: WhitespaceAfterCheck
+// CSOFF: ParameterNumberCheck
+// CSOFF: LineLengthCheck
+
+/**
+ * <p>The <code>IndicScriptProcessor</code> class implements a script processor for
+ * performing glyph substitution and positioning operations on content associated with the Indic script.</p>
+ * @author Glenn Adams
+ */
+public class IndicScriptProcessor extends DefaultScriptProcessor {
+
+    /** logging instance */
+    private static final Log log = LogFactory.getLog(IndicScriptProcessor.class);                                      // CSOK: ConstantNameCheck
+
+    /** required features to use for substitutions */
+    private static final String[] gsubReqFeatures =                                                                    // CSOK: ConstantNameCheck
+    {
+        "abvf",                                                 // above base forms
+        "abvs",                                                 // above base substitutions
+        "akhn",                                                 // akhand
+        "blwf",                                                 // below base forms
+        "blws",                                                 // below base substitutions
+        "ccmp",                                                 // glyph composition/decomposition
+        "cjct",                                                 // conjunct forms
+        "clig",                                                 // contextual ligatures
+        "half",                                                 // half forms
+        "haln",                                                 // halant forms
+        "locl",                                                 // localized forms
+        "nukt",                                                 // nukta forms
+        "pref",                                                 // pre-base forms
+        "pres",                                                 // pre-base substitutions
+        "pstf",                                                 // post-base forms
+        "psts",                                                 // post-base substitutions
+        "rkrf",                                                 // rakar forms
+        "rphf",                                                 // reph form
+        "vatu"                                                  // vattu variants
+    };
+
+    /** optional features to use for substitutions */
+    private static final String[] gsubOptFeatures =                                                                     // CSOK: ConstantNameCheck
+    {
+        "afrc",                                                 // alternative fractions
+        "calt",                                                 // contextual alternatives
+        "dlig"                                                  // discretionary ligatures
+    };
+
+    /** required features to use for positioning */
+    private static final String[] gposReqFeatures =                                                                     // CSOK: ConstantNameCheck
+    {
+        "abvm",                                                 // above base marks
+        "blwm",                                                 // below base marks
+        "dist",                                                 // distance (adjustment)
+        "kern"                                                  // kerning
+    };
+
+    /** required features to use for positioning */
+    private static final String[] gposOptFeatures =                                                                     // CSOK: ConstantNameCheck
+    {
+    };
+
+    private static class SubstitutionScriptContextTester implements ScriptContextTester {
+        private static Map/*<String,GlyphContextTester>*/ testerMap = new HashMap/*<String,GlyphContextTester>*/();
+        public GlyphContextTester getTester ( String feature ) {
+            return (GlyphContextTester) testerMap.get ( feature );
+        }
+    }
+
+    private static class PositioningScriptContextTester implements ScriptContextTester {
+        private static Map/*<String,GlyphContextTester>*/ testerMap = new HashMap/*<String,GlyphContextTester>*/();
+        public GlyphContextTester getTester ( String feature ) {
+            return (GlyphContextTester) testerMap.get ( feature );
+        }
+    }
+
+    /**
+     * Make script specific flavor of Indic script processor.
+     * @param script tag
+     * @return script processor instance
+     */
+    public static ScriptProcessor makeProcessor ( String script ) {
+        switch ( CharUtilities.scriptCodeFromTag ( script ) ) {
+        case CharUtilities.SCRIPT_DEVANAGARI:
+        case CharUtilities.SCRIPT_DEVANAGARI_2:
+            return new DevanagariScriptProcessor ( script );
+        // [TBD] implement other script processors
+        default:
+            return new IndicScriptProcessor ( script );
+        }
+    }
+
+    private final ScriptContextTester subContextTester;
+    private final ScriptContextTester posContextTester;
+
+    IndicScriptProcessor ( String script ) {
+        super ( script );
+        this.subContextTester = new SubstitutionScriptContextTester();
+        this.posContextTester = new PositioningScriptContextTester();
+    }
+
+    /** {@inheritDoc} */
+    public String[] getSubstitutionFeatures() {
+        return gsubReqFeatures;
+    }
+
+    /** {@inheritDoc} */
+    public String[] getOptionalSubstitutionFeatures() {
+        return gsubOptFeatures;
+    }
+
+    /** {@inheritDoc} */
+    public ScriptContextTester getSubstitutionContextTester() {
+        return subContextTester;
+    }
+
+    /** {@inheritDoc} */
+    public String[] getPositioningFeatures() {
+        return gposReqFeatures;
+    }
+
+    /** {@inheritDoc} */
+    public String[] getOptionalPositioningFeatures() {
+        return gposOptFeatures;
+    }
+
+    /** {@inheritDoc} */
+    public ScriptContextTester getPositioningContextTester() {
+        return posContextTester;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public GlyphSequence substitute ( GlyphSequence gs, String script, String language, GlyphTable.UseSpec[] usa, ScriptContextTester sct ) {
+        assert usa != null;
+        // 1. syllabize
+        GlyphSequence[] sa = syllabize ( gs, script, language );
+        // 2. process each syllable
+        for ( int i = 0, n = sa.length; i < n; i++ ) {
+            GlyphSequence s = sa [ i ];
+            // apply basic shaping subs
+            for ( int j = 0, m = usa.length; j < m; j++ ) {
+                GlyphTable.UseSpec us = usa [ j ];
+                if ( isBasicShapingUse ( us ) ) {
+                    s.setPredications ( true );
+                    s = us.substitute ( s, script, language, sct );
+                }
+            }
+            // reorder pre-base matra
+            s = reorderPreBaseMatra ( s );
+            // reorder reph
+            s = reorderReph ( s );
+            // apply presentation subs
+            for ( int j = 0, m = usa.length; j < m; j++ ) {
+                GlyphTable.UseSpec us = usa [ j ];
+                if ( isPresentationUse ( us ) ) {
+                    s.setPredications ( true );
+                    s = us.substitute ( s, script, language, sct );
+                }
+            }
+            // record result
+            sa [ i ] = s;
+        }
+        // 3. return reassembled substituted syllables
+        return unsyllabize ( gs, sa );
+    }
+
+    /**
+     * Get script specific syllabizer class.
+     * @return a syllabizer class object or null
+     */
+    protected Class getSyllabizerClass() {
+        return null;
+    }
+
+    private GlyphSequence[] syllabize ( GlyphSequence gs, String script, String language ) {
+        return Syllabizer.getSyllabizer ( script, language, getSyllabizerClass() ) . syllabize ( gs );
+    }
+
+    private GlyphSequence unsyllabize ( GlyphSequence gs, GlyphSequence[] sa ) {
+        return GlyphSequence.join ( gs, sa );
+    }
+
+    private static Set<String> basicShapingFeatures;
+    private static final String[] basicShapingFeatureStrings = {                                                        // CSOK: ConstantNameCheck
+        "abvf",
+        "akhn",
+        "blwf",
+        "cjct",
+        "half",
+        "locl",
+        "nukt",
+        "pref",
+        "pstf",
+        "rkrf",
+        "rphf",
+        "vatu",
+    };
+    static {
+        basicShapingFeatures = new HashSet<String>();
+        for ( String s : basicShapingFeatureStrings ) {
+            basicShapingFeatures.add ( s );
+        }
+    }
+    private boolean isBasicShapingUse ( GlyphTable.UseSpec us ) {
+        assert us != null;
+        if ( basicShapingFeatures != null ) {
+            return basicShapingFeatures.contains ( us.getFeature() );
+        } else {
+            return false;
+        }
+    }
+
+    private static  Set<String> presentationFeatures;
+    private static final String[] presentationFeatureStrings = {                                                        // CSOK: ConstantNameCheck
+        "abvs",
+        "blws",
+        "calt",
+        "haln",
+        "pres",
+        "psts",
+    };
+    static {
+        presentationFeatures = new HashSet<String>();
+        for ( String s : presentationFeatureStrings ) {
+            presentationFeatures.add ( s );
+        }
+    }
+    private boolean isPresentationUse ( GlyphTable.UseSpec us ) {
+        assert us != null;
+        if ( presentationFeatures != null ) {
+            return presentationFeatures.contains ( us.getFeature() );
+        } else {
+            return false;
+        }
+    }
+
+    private GlyphSequence reorderPreBaseMatra ( GlyphSequence gs ) {
+        int source;
+        if ( ( source = findPreBaseMatra ( gs ) ) >= 0 ) {
+            int target;
+            if ( ( target = findPreBaseMatraTarget ( gs, source ) ) >= 0 ) {
+                if ( target != source ) {
+                    gs = reorder ( gs, source, target );
+                }
+            }
+        }
+        return gs;
+    }
+
+    /**
+     * Find pre-base matra in sequence.
+     * @param gs input sequence
+     * @return index of pre-base matra or -1 if not found
+     */
+    protected int findPreBaseMatra ( GlyphSequence gs ) {
+        return -1;
+    }
+
+    /**
+     * Find pre-base matra target in sequence.
+     * @param gs input sequence
+     * @param source index of pre-base matra
+     * @return index of pre-base matra target or -1
+     */
+    protected int findPreBaseMatraTarget ( GlyphSequence gs, int source ) {
+        return -1;
+    }
+
+    private GlyphSequence reorderReph ( GlyphSequence gs ) {
+        int source;
+        if ( ( source = findReph ( gs ) ) >= 0 ) {
+            int target;
+            if ( ( target = findRephTarget ( gs, source ) ) >= 0 ) {
+                if ( target != source ) {
+                    gs = reorder ( gs, source, target );
+                }
+            }
+        }
+        return gs;
+    }
+
+    /**
+     * Find reph in sequence.
+     * @param gs input sequence
+     * @return index of reph or -1 if not found
+     */
+    protected int findReph ( GlyphSequence gs ) {
+        return -1;
+    }
+
+    /**
+     * Find reph target in sequence.
+     * @param gs input sequence
+     * @param source index of reph
+     * @return index of reph target or -1
+     */
+    protected int findRephTarget ( GlyphSequence gs, int source ) {
+        return -1;
+    }
+
+    private GlyphSequence reorder ( GlyphSequence gs, int source, int target ) {
+        return GlyphSequence.reorder ( gs, source, 1, target );
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean position ( GlyphSequence gs, String script, String language, int fontSize, GlyphTable.UseSpec[] usa, int[] widths, int[][] adjustments, ScriptContextTester sct ) {
+        boolean adjusted = super.position ( gs, script, language, fontSize, usa, widths, adjustments, sct );
+        return adjusted;
+    }
+
+    /** Abstract syllabizer. */
+    protected abstract static class Syllabizer {
+        private String script;
+        private String language;
+        Syllabizer ( String script, String language ) {
+            this.script = script;
+            this.language = language;
+        }
+        /**
+         * Subdivide glyph sequence GS into syllabic segments each represented by a distinct
+         * output glyph sequence.
+         * @param gs input glyph sequence
+         * @return segmented syllabic glyph sequences
+         */
+        abstract GlyphSequence[] syllabize ( GlyphSequence gs );
+        /** {@inheritDoc} */
+        public int hashCode() {
+            int hc = 0;
+            hc =  7 * hc + ( hc ^ script.hashCode() );
+            hc = 11 * hc + ( hc ^ language.hashCode() );
+            return hc;
+        }
+        /** {@inheritDoc} */
+        public boolean equals ( Object o ) {
+            if ( o instanceof Syllabizer ) {
+                Syllabizer s = (Syllabizer) o;
+                if ( ! s.script.equals ( script ) ) {
+                    return false;
+                } else if ( ! s.language.equals ( language ) ) {
+                    return false;
+                } else {
+                    return true;
+                }
+            } else {
+                return false;
+            }
+        }
+        /** {@inheritDoc} */
+        public int compareTo ( Object o ) {
+            int d;
+            if ( o instanceof Syllabizer ) {
+                Syllabizer s = (Syllabizer) o;
+                if ( ( d = script.compareTo ( s.script ) ) == 0 ) {
+                    if ( ( d = language.compareTo ( s.language ) ) == 0 ) {
+                        d = 0;
+                    }
+                }
+            } else {
+                d = -1;
+            }
+            return d;
+        }
+        private static Map<String,Syllabizer> syllabizers = new HashMap<String,Syllabizer>();
+        static Syllabizer getSyllabizer ( String script, String language, Class syllabizerClass ) {
+            String sid = makeSyllabizerId ( script, language );
+            Syllabizer s = syllabizers.get ( sid );
+            if ( s == null ) {
+                if ( ( s = makeSyllabizer ( script, language, syllabizerClass ) ) == null ) {
+                    s = new DefaultSyllabizer ( script, language );
+                }
+                syllabizers.put ( sid, s );
+            }
+            return s;
+        }
+        static String makeSyllabizerId ( String script, String language ) {
+            return script + ":" + language;
+        }
+        static Syllabizer makeSyllabizer ( String script, String language, Class syllabizerClass ) {
+            Syllabizer s;
+            try {
+                Constructor cf = syllabizerClass.getDeclaredConstructor ( new Class[] { String.class, String.class } );
+                s = (Syllabizer) cf.newInstance ( script, language );
+            } catch ( NoSuchMethodException e ) {
+                s = null;
+            } catch ( InstantiationException e ) {
+                s = null;
+            } catch ( IllegalAccessException e ) {
+                s = null;
+            } catch ( InvocationTargetException e ) {
+                s = null;
+            }
+            return s;
+        }
+    }
+
+    /** Default syllabizer. */
+    protected static class DefaultSyllabizer extends Syllabizer {
+        DefaultSyllabizer ( String script, String language ) {
+            super ( script, language );
+        }
+        /** {@inheritDoc} */
+        @Override
+        GlyphSequence[] syllabize ( GlyphSequence gs ) {
+            int[] ca = gs.getCharacterArray ( false );
+            int   nc = gs.getCharacterCount();
+            if ( nc == 0 ) {
+                return new GlyphSequence[] { gs };
+            } else {
+                return segmentize ( gs, segmentize ( ca, nc ) );
+            }
+        }
+        /**
+         * Construct array of segements from original character array (associated with original glyph sequence)
+         * @param ca input character sequence
+         * @param nc number of characters in sequence
+         * @return array of syllable segments
+         */
+        protected Segment[] segmentize ( int[] ca, int nc ) {
+            Vector<Segment> sv = new Vector<Segment> ( nc );
+            for ( int s = 0, e = nc; s < e; ) {
+                int i;
+                if ( ( i = findStartOfSyllable ( ca, s, e ) ) > s ) {
+                    // from s to i is non-syllable segment
+                    sv.add ( new Segment ( s, i, Segment.OTHER ) );
+                    s = i; // move s to start of syllable
+                } else if ( i > s ) {
+                    // from s to e is non-syllable segment
+                    sv.add ( new Segment ( s, e, Segment.OTHER ) );
+                    s = e; // move s to end of input sequence
+                }
+                if ( ( i = findEndOfSyllable ( ca, s, e ) ) > s ) {
+                    // from s to i is syllable segment
+                    sv.add ( new Segment ( s, i, Segment.SYLLABLE ) );
+                    s = i; // move s to end of syllable
+                } else {
+                    // from s to e is non-syllable segment
+                    sv.add ( new Segment ( s, e, Segment.OTHER ) );
+                    s = e; // move s to end of input sequence
+                }
+            }
+            return sv.toArray ( new Segment [ sv.size() ] );
+        }
+        /**
+         * Construct array of glyph sequences from original glyph sequence and segment array.
+         * @param gs original input glyph sequence
+         * @param sa segment array
+         * @return array of glyph sequences each belonging to an (ordered) segment in SA
+         */
+        protected GlyphSequence[] segmentize ( GlyphSequence gs, Segment[] sa ) {
+            int   ng = gs.getGlyphCount();
+            int[] ga = gs.getGlyphArray ( false );
+            GlyphSequence.CharAssociation[] aa = gs.getAssociations ( 0, -1 );
+            Vector<GlyphSequence> nsv = new Vector<GlyphSequence>();
+            for ( int i = 0, ns = sa.length; i < ns; i++ ) {
+                Segment s = sa [ i ];
+                Vector<Integer> ngv = new Vector<Integer> ( ng );
+                Vector<GlyphSequence.CharAssociation> nav = new Vector<GlyphSequence.CharAssociation> ( ng );
+                for ( int j = 0; j < ng; j++ ) {
+                    GlyphSequence.CharAssociation ca = aa [ j ];
+                    if ( ca.contained ( s.getOffset(), s.getCount() ) ) {
+                        ngv.add ( ga [ j ] );
+                        nav.add ( ca );
+                    }
+                }
+                if ( ngv.size() > 0 ) {
+                    nsv.add ( new GlyphSequence ( gs, null, toIntArray ( ngv ), null, null, nav.toArray ( new GlyphSequence.CharAssociation [ nav.size() ] ), null ) );
+                }
+            }
+            if ( nsv.size() > 0 ) {
+                return nsv.toArray ( new GlyphSequence [ nsv.size() ] );
+            } else {
+                return new GlyphSequence[] { gs };
+            }
+        }
+        /**
+         * Find start of syllable in character array, starting at S, ending at E.
+         * @param ca character array
+         * @param s start index
+         * @param e end index
+         * @return index of start or E if no start found
+         */
+        protected int findStartOfSyllable ( int[] ca, int s, int e ) {
+            return e;
+        }
+        /**
+         * Find end of syllable in character array, starting at S, ending at E.
+         * @param ca character array
+         * @param s start index
+         * @param e end index
+         * @return index of start or S if no end found
+         */
+        protected int findEndOfSyllable ( int[] ca, int s, int e ) {
+            return s;
+        }
+        private static int[] toIntArray ( Vector<Integer> iv ) {
+            int ni = iv.size();
+            int[] ia = new int [ iv.size() ];
+            for ( int i = 0, n = ni; i < n; i++ ) {
+                ia [ i ] = (int) iv.get ( i );
+            }
+            return ia;
+        }
+    }
+
+    /** Syllabic segment. */
+    protected static class Segment {
+
+        static final int OTHER = 0;            // other (non-syllable) characters
+        static final int SYLLABLE = 1;         // (orthographic) syllable
+
+        private int start;
+        private int end;
+        private int type;
+
+        Segment ( int start, int end, int type ) {
+            this.start = start;
+            this.end = end;
+            this.type = type;
+        }
+
+        int getStart() {
+            return start;
+        }
+
+        int getEnd() {
+            return end;
+        }
+
+        int getOffset() {
+            return start;
+        }
+
+        int getCount() {
+            return end - start;
+        }
+
+        int getType() {
+            return type;
+        }
+    }
+}

Propchange: xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/fonts/IndicScriptProcessor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/fonts/IndicScriptProcessor.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/arabic/ArabicScriptTestSuite.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/arabic/ArabicScriptTestSuite.java?rev=1136146&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/arabic/ArabicScriptTestSuite.java (added)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/arabic/ArabicScriptTestSuite.java Wed Jun 15 18:47:47 2011
@@ -0,0 +1,42 @@
+/*
+ * 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.arabic;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * Test suite for functionality related to the arabic script.
+ */
+public class ArabicScriptTestSuite {
+
+    /**
+     * Builds the test suite
+     * @return the test suite
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite(
+            "Basic functionality test suite for the arabic script");
+        //$JUnit-BEGIN$
+        //$JUnit-END$
+        return suite;
+    }
+
+}

Propchange: xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/arabic/ArabicScriptTestSuite.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/arabic/ArabicScriptTestSuite.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/fonts/FontsTestSuite.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/fonts/FontsTestSuite.java?rev=1136146&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/fonts/FontsTestSuite.java (added)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/fonts/FontsTestSuite.java Wed Jun 15 18:47:47 2011
@@ -0,0 +1,45 @@
+/*
+ * 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.fonts;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.apache.fop.complexscripts.util.TTXFileTestCase;
+
+/**
+ * Test suite for fonts functionality related to complex scripts.
+ */
+public class FontsTestSuite {
+
+    /**
+     * Builds the test suite
+     * @return the test suite
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite(
+            "Basic functionality test suite for complex scripts fonts related functionality");
+        //$JUnit-BEGIN$
+        suite.addTest(new TestSuite(TTXFileTestCase.class));
+        //$JUnit-END$
+        return suite;
+    }
+
+}

Propchange: xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/fonts/FontsTestSuite.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/fonts/FontsTestSuite.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/scripts/ScriptsTestSuite.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/scripts/ScriptsTestSuite.java?rev=1136146&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/scripts/ScriptsTestSuite.java (added)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/scripts/ScriptsTestSuite.java Wed Jun 15 18:47:47 2011
@@ -0,0 +1,45 @@
+/*
+ * 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.scripts;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.apache.fop.complexscripts.arabic.ArabicScriptTestSuite;
+
+/**
+ * Test suite for script specific functionality related to complex scripts.
+ */
+public class ScriptsTestSuite {
+
+    /**
+     * Builds the test suite
+     * @return the test suite
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite(
+            "Basic functionality test suite for script specific functionality.");
+        //$JUnit-BEGIN$
+        suite.addTest(ArabicScriptTestSuite.suite());
+        //$JUnit-END$
+        return suite;
+    }
+
+}

Propchange: xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/scripts/ScriptsTestSuite.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/scripts/ScriptsTestSuite.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/util/TTXFile.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/util/TTXFile.java?rev=1136146&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/util/TTXFile.java (added)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/util/TTXFile.java Wed Jun 15 18:47:47 2011
@@ -0,0 +1,266 @@
+/*
+ * 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.util;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.xml.parsers.FactoryConfigurationError;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.fonts.GlyphDefinitionTable;
+import org.apache.fop.fonts.GlyphSubstitutionTable;
+import org.apache.fop.fonts.GlyphPositioningTable;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+
+// CSOFF: InnerAssignmentCheck
+// CSOFF: LineLengthCheck
+// CSOFF: NoWhitespaceAfterCheck
+
+/**
+ * This class supports a subset of the <code>TTX</code> file as produced by the Adobe FLEX
+ * SDK (AFDKO). In particular, it is used to parse a <code>TTX</code> file in order to
+ * extract character to glyph code mapping data, glyph definition data, glyph substitution
+ * data, and glyph positioning data.
+ *
+ * <code>TTX</code> files are used in FOP for testing and debugging purposes only. Such
+ * files are used to represent font data employed by complex script processing, and
+ * normally extracted directly from an opentype (or truetype) file. However, due to
+ * copyright restrictions, it is not possible to include most opentype (or truetype) font
+ * files directly in the FOP distribution. In such cases, <code>TTX</code> files are used
+ * to distribute a subset of the complex script advanced table information contained in
+ * certain font files to facilitate testing. This can be done because no glyph outline or
+ * other proprietary information is included in the distributed <code>TTX</code> files.
+ *
+ * @author Glenn Adams
+ */
+public class TTXFile {
+
+    /** logging instance */
+    private static final Log log = LogFactory.getLog(TTXFile.class);                                                    // CSOK: ConstantNameCheck
+
+    public TTXFile() {
+    }
+
+    public void parse ( String filename ) {
+        parse ( new File ( filename ) );
+    }
+
+    public void parse ( File f ) {
+        assert f != null;
+        try {
+            SAXParserFactory spf = SAXParserFactory.newInstance();
+            SAXParser sp = spf.newSAXParser();
+            sp.parse ( f, new Handler() );
+        } catch ( FactoryConfigurationError e ) {
+            throw new RuntimeException ( e.getMessage() );
+        } catch ( ParserConfigurationException e ) {
+            throw new RuntimeException ( e.getMessage() );
+        } catch ( SAXException e ) {
+            throw new RuntimeException ( e.getMessage() );
+        } catch ( IOException e ) {
+            throw new RuntimeException ( e.getMessage() );
+        }
+    }
+
+    private class Handler extends DefaultHandler {
+        private Handler() {
+        }
+        @Override
+        public void startDocument() {
+        }
+        @Override
+        public void endDocument() {
+        }
+        @Override
+        public void startElement ( String uri, String localName, String qName, Attributes attrs )
+            throws SAXException {
+            if ( qName.equals ( "Alternate" ) ) {
+            } else if ( qName.equals ( "AlternateSet" ) ) {
+            } else if ( qName.equals ( "AlternateSubst" ) ) {
+            } else if ( qName.equals ( "BacktrackCoverage" ) ) {
+            } else if ( qName.equals ( "BaseAnchor" ) ) {
+            } else if ( qName.equals ( "BaseArray" ) ) {
+            } else if ( qName.equals ( "BaseCoverage" ) ) {
+            } else if ( qName.equals ( "BaseRecord" ) ) {
+            } else if ( qName.equals ( "ChainContextPos" ) ) {
+            } else if ( qName.equals ( "ChainContextSubst" ) ) {
+            } else if ( qName.equals ( "Class" ) ) {
+            } else if ( qName.equals ( "ClassDef" ) ) {
+                // child of GlyphClassDef
+                // child of MarkAttachClassDef
+            } else if ( qName.equals ( "ComponentRecord" ) ) {
+            } else if ( qName.equals ( "Coverage" ) ) {
+                // child of LigCaretList
+                // child of MultipleSubst
+                // child of CursivePos
+            } else if ( qName.equals ( "CursivePos" ) ) {
+            } else if ( qName.equals ( "DefaultLangSys" ) ) {
+            } else if ( qName.equals ( "EntryAnchor" ) ) {
+            } else if ( qName.equals ( "EntryExitRecord" ) ) {
+            } else if ( qName.equals ( "ExitAnchor" ) ) {
+            } else if ( qName.equals ( "Feature" ) ) {
+            } else if ( qName.equals ( "FeatureIndex" ) ) {
+                // child of DefaultLangSys
+                // child of LangSys
+            } else if ( qName.equals ( "FeatureList" ) ) {
+                // child of GSUB
+                // child of GPOS
+            } else if ( qName.equals ( "FeatureRecord" ) ) {
+            } else if ( qName.equals ( "FeatureTag" ) ) {
+            } else if ( qName.equals ( "GDEF" ) ) {
+            } else if ( qName.equals ( "GPOS" ) ) {
+            } else if ( qName.equals ( "GSUB" ) ) {
+            } else if ( qName.equals ( "Glyph" ) ) {
+                // child of Coverage
+                // child of InputCoverage
+                // child of LookAheadCoverage
+                // child of BacktrackCoverage
+                // child of MarkCoverage
+                // child of Mark1Coverage
+                // child of Mark2Coverage
+                // child of BaseCoverage
+                // child of LigatureCoverage
+            } else if ( qName.equals ( "GlyphClassDef" ) ) {
+            } else if ( qName.equals ( "GlyphID" ) ) {
+            } else if ( qName.equals ( "GlyphOrder" ) ) {
+            } else if ( qName.equals ( "InputCoverage" ) ) {
+            } else if ( qName.equals ( "LangSys" ) ) {
+            } else if ( qName.equals ( "LangSysRecord" ) ) {
+            } else if ( qName.equals ( "LangSysTag" ) ) {
+            } else if ( qName.equals ( "LigCaretList" ) ) {
+            } else if ( qName.equals ( "Ligature" ) ) {
+            } else if ( qName.equals ( "LigatureAnchor" ) ) {
+            } else if ( qName.equals ( "LigatureArray" ) ) {
+            } else if ( qName.equals ( "LigatureAttach" ) ) {
+            } else if ( qName.equals ( "LigatureCoverage" ) ) {
+            } else if ( qName.equals ( "LigatureSet" ) ) {
+            } else if ( qName.equals ( "LigatureSubst" ) ) {
+            } else if ( qName.equals ( "LookAheadCoverage" ) ) {
+            } else if ( qName.equals ( "Lookup" ) ) {
+            } else if ( qName.equals ( "LookupFlag" ) ) {
+            } else if ( qName.equals ( "LookupList" ) ) {
+                // child of GSUB
+                // child of GPOS
+            } else if ( qName.equals ( "LookupListIndex" ) ) {
+                // child of Feature
+                // child of SubstLookupRecord
+            } else if ( qName.equals ( "LookupType" ) ) {
+            } else if ( qName.equals ( "Mark1Array" ) ) {
+            } else if ( qName.equals ( "Mark1Coverage" ) ) {
+            } else if ( qName.equals ( "Mark2Anchor" ) ) {
+            } else if ( qName.equals ( "Mark2Array" ) ) {
+            } else if ( qName.equals ( "Mark2Coverage" ) ) {
+            } else if ( qName.equals ( "Mark2Record" ) ) {
+            } else if ( qName.equals ( "MarkAnchor" ) ) {
+            } else if ( qName.equals ( "MarkArray" ) ) {
+            } else if ( qName.equals ( "MarkAttachClassDef" ) ) {
+            } else if ( qName.equals ( "MarkBasePos" ) ) {
+            } else if ( qName.equals ( "MarkCoverage" ) ) {
+            } else if ( qName.equals ( "MarkLigPos" ) ) {
+            } else if ( qName.equals ( "MarkMarkPos" ) ) {
+            } else if ( qName.equals ( "MarkRecord" ) ) {
+            } else if ( qName.equals ( "MultipleSubst" ) ) {
+            } else if ( qName.equals ( "PairPos" ) ) {
+            } else if ( qName.equals ( "PairSet" ) ) {
+            } else if ( qName.equals ( "PairValueRecord" ) ) {
+            } else if ( qName.equals ( "PosLookupRecord" ) ) {
+            } else if ( qName.equals ( "ReqFeatureIndex" ) ) {
+                // child of DefaultLangSys
+                // child of LangSys
+            } else if ( qName.equals ( "Script" ) ) {
+            } else if ( qName.equals ( "ScriptList" ) ) {
+                // child of GSUB
+                // child of GPOS
+            } else if ( qName.equals ( "ScriptRecord" ) ) {
+            } else if ( qName.equals ( "ScriptTag" ) ) {
+            } else if ( qName.equals ( "SecondGlyph" ) ) {
+            } else if ( qName.equals ( "Sequence" ) ) {
+            } else if ( qName.equals ( "SequenceIndex" ) ) {
+            } else if ( qName.equals ( "SinglePos" ) ) {
+            } else if ( qName.equals ( "SingleSubst" ) ) {
+            } else if ( qName.equals ( "SubstLookupRecord" ) ) {
+            } else if ( qName.equals ( "Substitute" ) ) {
+            } else if ( qName.equals ( "Substitution" ) ) {
+            } else if ( qName.equals ( "Value" ) ) {
+            } else if ( qName.equals ( "Value1" ) ) {
+            } else if ( qName.equals ( "Value2" ) ) {
+            } else if ( qName.equals ( "ValueFormat" ) ) {
+            } else if ( qName.equals ( "ValueFormat1" ) ) {
+            } else if ( qName.equals ( "ValueFormat2" ) ) {
+            } else if ( qName.equals ( "Version" ) ) {
+                // child of GDEF
+                // child of GSUB
+                // child of GPOS
+            } else if ( qName.equals ( "XCoordinate" ) ) {
+                // child of EntryAnchor
+                // child of MarkAnchor
+            } else if ( qName.equals ( "YCoordinate" ) ) {
+                // child of EntryAnchor
+                // child of MarkAnchor
+                // child of BaseAnchor
+            } else if ( qName.equals ( "checkSumAdjustment" ) ) {
+            } else if ( qName.equals ( "cmap" ) ) {
+            } else if ( qName.equals ( "cmap_format_0" ) ) {
+            } else if ( qName.equals ( "cmap_format_4" ) ) {
+            } else if ( qName.equals ( "created" ) ) {
+            } else if ( qName.equals ( "flags" ) ) {
+            } else if ( qName.equals ( "fontDirectionHint" ) ) {
+            } else if ( qName.equals ( "fontRevision" ) ) {
+            } else if ( qName.equals ( "glyphDataFormat" ) ) {
+            } else if ( qName.equals ( "head" ) ) {
+            } else if ( qName.equals ( "hmtx" ) ) {
+            } else if ( qName.equals ( "indexToLocFormat" ) ) {
+            } else if ( qName.equals ( "lowestRecPPEM" ) ) {
+            } else if ( qName.equals ( "macStyle" ) ) {
+            } else if ( qName.equals ( "magicNumber" ) ) {
+            } else if ( qName.equals ( "map" ) ) {
+            } else if ( qName.equals ( "modified" ) ) {
+            } else if ( qName.equals ( "mtx" ) ) {
+            } else if ( qName.equals ( "tableVersion" ) ) {
+            } else if ( qName.equals ( "tableVersion" ) ) {
+            } else if ( qName.equals ( "ttFont" ) ) {
+            } else if ( qName.equals ( "unitsPerEm" ) ) {
+            } else if ( qName.equals ( "xMax" ) ) {
+            } else if ( qName.equals ( "xMin" ) ) {
+            } else if ( qName.equals ( "yMax" ) ) {
+            } else if ( qName.equals ( "yMin" ) ) {
+            } else {
+                throw new SAXException ( "unknown element type {" + uri + "," + qName + "}" );
+            }
+        }
+        @Override
+        public void endElement ( String uri, String localName, String qName ) {
+        }
+        @Override
+        public void characters ( char[] chars, int start, int length ) {
+        }
+    }
+
+}

Propchange: xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/util/TTXFile.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/util/TTXFile.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/util/TTXFileTestCase.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/util/TTXFileTestCase.java?rev=1136146&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/util/TTXFileTestCase.java (added)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/util/TTXFileTestCase.java Wed Jun 15 18:47:47 2011
@@ -0,0 +1,48 @@
+/*
+ * 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.util;
+
+import java.io.File;
+
+import junit.framework.TestCase;
+
+public class TTXFileTestCase extends TestCase {
+
+    private static String ttxFilesRoot = "test/resources/complexscripts";
+
+    private static String[] ttxFiles = {
+        "arab/ttx/arab-001.ttx",
+        "arab/ttx/arab-002.ttx",
+        "arab/ttx/arab-003.ttx",
+        "arab/ttx/arab-004.ttx",
+    };
+
+    public void testTTXFiles() throws Exception {
+        for ( String tfn : ttxFiles ) {
+            try {
+                TTXFile tf = new TTXFile();
+                tf.parse ( ttxFilesRoot + File.separator + tfn );
+            } catch ( Exception e ) {
+                fail ( e.getMessage() );
+            }
+        }
+    }
+
+}

Propchange: xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/util/TTXFileTestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/branches/Temp_ComplexScripts/test/java/org/apache/fop/complexscripts/util/TTXFileTestCase.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_background-image_writing-mode_rl.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_background-image_writing-mode_rl.xml?rev=1136146&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_background-image_writing-mode_rl.xml (added)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_background-image_writing-mode_rl.xml Wed Jun 15 18:47:47 2011
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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$ -->
+<testcase>
+  <info>
+    <p>
+      This test checks background image on a fo:basic-link.
+    </p>
+  </info>
+  <variables>
+    <img>../../resources/images/bgimg300dpi.jpg</img>
+  </variables>
+  <fo>
+    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+      <fo:layout-master-set>
+        <fo:simple-page-master master-name="normal" page-width="5in" page-height="5in">
+          <fo:region-body/>
+        </fo:simple-page-master>
+      </fo:layout-master-set>
+      <fo:page-sequence master-reference="normal" white-space-collapse="true" writing-mode="rl">
+        <fo:flow flow-name="xsl-region-body">
+          <fo:block>
+            Why is <fo:basic-link external-destination="http://xmlgraphics.apache.org/fop" font-size="96pt" background-color="yellow" background-repeat="no-repeat" background-position-horizontal="center" background-position-vertical="center" background-image="##img">FOP</fo:basic-link> so cool?
+          </fo:block>
+        </fo:flow>
+      </fo:page-sequence>
+    </fo:root>
+  </fo>
+  <checks>
+    <eval expected="197376" xpath="//flow/block/lineArea/inlineparent/@ipd"/>
+    <eval expected="88800" xpath="//flow/block/lineArea/inlineparent/@bpd"/>
+    <eval expected="color=#ffff00,url=../../resources/images/bgimg300dpi.jpg,repeat=no-repeat,horiz=75648,vertical=21360" xpath="//flow/block/lineArea/inlineparent/@background"/>
+  </checks>
+  <if-checks xmlns:n="http://xmlgraphics.apache.org/fop/intermediate/document-navigation">
+    <eval expected="page-trailer" xpath="local-name(//n:link/..)"/>
+    <eval expected="121272 1650 197376 88800" xpath="//n:link/@rect"/>
+    <eval expected="http://xmlgraphics.apache.org/fop" xpath="//n:link/n:goto-uri/@uri"/>
+  </if-checks>
+</testcase>

Propchange: xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_background-image_writing-mode_rl.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_background-image_writing-mode_rl.xml
------------------------------------------------------------------------------
    svn:keywords = Id

Added: xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_external-destination_writing-mode_rl.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_external-destination_writing-mode_rl.xml?rev=1136146&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_external-destination_writing-mode_rl.xml (added)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_external-destination_writing-mode_rl.xml Wed Jun 15 18:47:47 2011
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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$ -->
+<testcase>
+  <info>
+    <p>
+      This test checks external-destination on a fo:basic-link.
+    </p>
+  </info>
+  <fo>
+    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+      <fo:layout-master-set>
+        <fo:simple-page-master master-name="normal" page-width="5in" page-height="5in">
+          <fo:region-body/>
+        </fo:simple-page-master>
+      </fo:layout-master-set>
+      <fo:page-sequence master-reference="normal" writing-mode="rl">
+        <fo:flow flow-name="xsl-region-body">
+          <fo:block><fo:basic-link external-destination="http://xmlgraphics.apache.org/fop/">FOP</fo:basic-link></fo:block>
+          <fo:block><fo:basic-link external-destination="url(http://xmlgraphics.apache.org/fop/)">FOP</fo:basic-link></fo:block>
+          <fo:block><fo:basic-link show-destination="replace" external-destination="url(http://xmlgraphics.apache.org/fop/)">FOP</fo:basic-link></fo:block>
+          <fo:block><fo:basic-link show-destination="new" external-destination="url(http://xmlgraphics.apache.org/fop/)">FOP</fo:basic-link></fo:block>
+        </fo:flow>
+      </fo:page-sequence>
+    </fo:root>
+  </fo>
+  <checks>
+    <eval expected="http://xmlgraphics.apache.org/fop/" xpath="substring-after(//flow/block[1]/lineArea/inlineparent/@external-link,'dest=')"/>
+    <eval expected="http://xmlgraphics.apache.org/fop/" xpath="substring-after(//flow/block[2]/lineArea/inlineparent/@external-link,'dest=')"/>
+    <eval expected="false" xpath="substring-before(substring-after(//flow/block[3]/lineArea/inlineparent/@external-link,'newWindow='), ',')"/>
+    <eval expected="true" xpath="substring-before(substring-after(//flow/block[4]/lineArea/inlineparent/@external-link,'newWindow='), ',')"/>
+  </checks>
+</testcase>

Propchange: xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_external-destination_writing-mode_rl.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_external-destination_writing-mode_rl.xml
------------------------------------------------------------------------------
    svn:keywords = Id

Added: xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_external-destination_writing-mode_rl_2.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_external-destination_writing-mode_rl_2.xml?rev=1136146&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_external-destination_writing-mode_rl_2.xml (added)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/test/layoutengine/standard-testcases/basic-link_external-destination_writing-mode_rl_2.xml Wed Jun 15 18:47:47 2011
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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$ -->
+<testcase>
+  <info>
+    <p>
+      This test checks a fo:basic-link with an external-destination wrapping an SVG graphic.
+    </p>
+  </info>
+  <fo>
+    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg">
+      <fo:layout-master-set>
+        <fo:simple-page-master master-name="normal" page-width="5in" page-height="5in">
+          <fo:region-body/>
+        </fo:simple-page-master>
+      </fo:layout-master-set>
+      <fo:page-sequence master-reference="normal" writing-mode="rl">
+        <fo:flow flow-name="xsl-region-body">
+          <fo:block>before before before</fo:block>
+          <fo:block>
+            start
+            <fo:basic-link id="link" external-destination="http://xmlgraphics.apache.org/fop/"><fo:instream-foreign-object background-color="yellow">
+                <svg:svg width="2in" height="2in" viewBox="0 0 30 30">
+                  <svg:circle cx="15" cy="15" r="14" fill="#0000ff" stroke="none"/>
+                </svg:svg>
+              </fo:instream-foreign-object></fo:basic-link>
+            end
+          </fo:block>
+          <fo:block>after after after</fo:block>
+        </fo:flow>
+      </fo:page-sequence>
+    </fo:root>
+  </fo>
+  <checks>
+    <eval expected="144000" xpath="//inlineparent[@prod-id='link']/@ipd"/>
+    <eval expected="144000" xpath="//inlineparent[@prod-id='link']/@bpd"/>
+    <eval expected="0"      xpath="//inlineparent[@prod-id='link']/@offset"/>
+
+    <eval expected="144000" xpath="//inlineparent[@prod-id='link']/viewport/@ipd"/>
+    <eval expected="144000" xpath="//inlineparent[@prod-id='link']/viewport/@bpd"/>
+    <eval expected="0"      xpath="//inlineparent[@prod-id='link']/viewport/@offset"/>
+  </checks>
+</testcase>



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