xmlgraphics-fop-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gad...@apache.org
Subject svn commit: r1293736 [18/38] - in /xmlgraphics/fop/trunk: ./ src/codegen/java/org/apache/fop/tools/ src/codegen/unicode/java/org/apache/fop/complexscripts/ src/codegen/unicode/java/org/apache/fop/complexscripts/bidi/ src/documentation/content/xdocs/tru...
Date Sun, 26 Feb 2012 02:29:29 GMT
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/LazyFont.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/LazyFont.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/LazyFont.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/LazyFont.java Sun Feb 26 02:29:01 2012
@@ -29,28 +29,34 @@ import javax.xml.transform.stream.Stream
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+
 import org.apache.fop.apps.FOPException;
+import org.apache.fop.complexscripts.fonts.Positionable;
+import org.apache.fop.complexscripts.fonts.Substitutable;
+
+
 import org.xml.sax.InputSource;
 
 /**
  * This class is used to defer the loading of a font until it is really used.
  */
-public class LazyFont extends Typeface implements FontDescriptor {
+public class LazyFont extends Typeface implements FontDescriptor, Substitutable, Positionable {
 
     private static Log log = LogFactory.getLog(LazyFont.class);
 
-    private String metricsFileName = null;
-    private String fontEmbedPath = null;
-    private boolean useKerning = false;
+    private String metricsFileName;
+    private String fontEmbedPath;
+    private boolean useKerning;
+    private boolean useAdvanced;
     private EncodingMode encodingMode = EncodingMode.AUTO;
-    private boolean embedded = true;
-    private String subFontName = null;
+    private boolean embedded;
+    private String subFontName;
 
-    private boolean isMetricsLoaded = false;
-    private Typeface realFont = null;
-    private FontDescriptor realFontDescriptor = null;
+    private boolean isMetricsLoaded;
+    private Typeface realFont;
+    private FontDescriptor realFontDescriptor;
 
-    private FontResolver resolver = null;
+    private FontResolver resolver;
 
     /**
      * Main constructor
@@ -62,6 +68,11 @@ public class LazyFont extends Typeface i
         this.metricsFileName = fontInfo.getMetricsFile();
         this.fontEmbedPath = fontInfo.getEmbedFile();
         this.useKerning = fontInfo.getKerning();
+        if ( resolver != null ) {
+            this.useAdvanced = resolver.isComplexScriptFeaturesEnabled();
+        } else {
+            this.useAdvanced = fontInfo.getAdvanced();
+        }
         this.encodingMode = fontInfo.getEncodingMode();
         this.subFontName = fontInfo.getSubFontName();
         this.embedded = fontInfo.isEmbedded();
@@ -70,9 +81,15 @@ public class LazyFont extends Typeface i
 
     /** {@inheritDoc} */
     public String toString() {
-        return ( "metrics-url=" + metricsFileName + ", embed-url=" + fontEmbedPath
-                + ", kerning=" + useKerning );
-    }
+        StringBuffer sbuf = new StringBuffer(super.toString());
+        sbuf.append('{');
+        sbuf.append("metrics-url=" + metricsFileName);
+        sbuf.append(",embed-url=" + fontEmbedPath);
+        sbuf.append(",kerning=" + useKerning);
+        sbuf.append(",advanced=" + useAdvanced);
+        sbuf.append('}');
+        return sbuf.toString();
+    }   
 
     private void load(boolean fail) {
         if (!isMetricsLoaded) {
@@ -120,6 +137,7 @@ public class LazyFont extends Typeface i
                                     new URL(metricsFileName).openStream()));
                     }
                     reader.setKerningEnabled(useKerning);
+                    reader.setAdvancedEnabled(useAdvanced);
                     if (this.embedded) {
                         reader.setFontEmbedPath(fontEmbedPath);
                     }
@@ -130,7 +148,7 @@ public class LazyFont extends Typeface i
                         throw new RuntimeException("Cannot load font. No font URIs available.");
                     }
                     realFont = FontLoader.loadFont(fontEmbedPath, this.subFontName,
-                            this.embedded, this.encodingMode, useKerning, resolver);
+                            this.embedded, this.encodingMode, useKerning, useAdvanced, resolver);
                 }
                 if (realFont instanceof FontDescriptor) {
                     realFontDescriptor = (FontDescriptor) realFont;
@@ -376,6 +394,84 @@ public class LazyFont extends Typeface i
     /**
      * {@inheritDoc}
      */
+    public boolean performsSubstitution() {
+        load(true);
+        if ( realFontDescriptor instanceof Substitutable ) {
+            return ((Substitutable)realFontDescriptor).performsSubstitution();
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public CharSequence performSubstitution ( CharSequence cs, String script, String language ) {
+        load(true);
+        if ( realFontDescriptor instanceof Substitutable ) {
+            return ((Substitutable)realFontDescriptor).performSubstitution(cs, script, language);
+        } else {
+            return cs;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public CharSequence reorderCombiningMarks
+        ( CharSequence cs, int[][] gpa, String script, String language ) {
+        load(true);
+        if ( realFontDescriptor instanceof Substitutable ) {
+            return ((Substitutable)realFontDescriptor).
+                reorderCombiningMarks(cs, gpa, script, language);
+        } else {
+            return cs;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean performsPositioning() {
+        load(true);
+        if ( realFontDescriptor instanceof Positionable ) {
+            return ((Positionable)realFontDescriptor).performsPositioning();
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public int[][]
+        performPositioning ( CharSequence cs, String script, String language, int fontSize ) {
+        load(true);
+        if ( realFontDescriptor instanceof Positionable ) {
+            return ((Positionable)realFontDescriptor)
+                .performPositioning(cs, script, language, fontSize);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public int[][]
+        performPositioning ( CharSequence cs, String script, String language ) {
+        load(true);
+        if ( realFontDescriptor instanceof Positionable ) {
+            return ((Positionable)realFontDescriptor)
+                .performPositioning(cs, script, language);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     public boolean isSubsetEmbedded() {
         load(true);
         return realFont.isMultiByte();

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/MultiByteFont.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/MultiByteFont.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/MultiByteFont.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/MultiByteFont.java Sun Feb 26 02:29:01 2012
@@ -19,14 +19,29 @@
 
 package org.apache.fop.fonts;
 
-//Java
+import java.nio.CharBuffer;
+import java.nio.IntBuffer;
 import java.util.Map;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.complexscripts.fonts.GlyphDefinitionTable;
+import org.apache.fop.complexscripts.fonts.GlyphPositioningTable;
+import org.apache.fop.complexscripts.fonts.GlyphSubstitutionTable;
+import org.apache.fop.complexscripts.fonts.Positionable;
+import org.apache.fop.complexscripts.fonts.Substitutable;
+import org.apache.fop.complexscripts.util.GlyphSequence;
+import org.apache.fop.util.CharUtilities;
 
 /**
  * Generic MultiByte (CID) font
  */
-public class MultiByteFont extends CIDFont {
+public class MultiByteFont extends CIDFont implements Substitutable, Positionable {
+
+    /** logging instance */
+    private static final Log log // CSOK: ConstantNameCheck
+        = LogFactory.getLog(MultiByteFont.class);
 
     private String ttcName = null;
     private String encoding = "Identity-H";
@@ -36,9 +51,28 @@ public class MultiByteFont extends CIDFo
 
     private CIDSubset subset = new CIDSubset();
 
-    /** A map from Unicode indices to glyph indices */
+    /**
+     * A map from Unicode indices to glyph indices. No assumption
+     * about ordering is made below. If lookup is changed to a binary
+     * search (from the current linear search), then addPrivateUseMapping()
+     * needs to be changed to perform ordered inserts.
+     */
     private BFEntry[] bfentries = null;
 
+    /* advanced typographic support */
+    private GlyphDefinitionTable gdef;
+    private GlyphSubstitutionTable gsub;
+    private GlyphPositioningTable gpos;
+
+    /* dynamic private use (character) mappings */
+    private int numMapped;
+    private int numUnmapped;
+    private int nextPrivateUse = 0xE000;
+    private int firstPrivate;
+    private int lastPrivate;
+    private int firstUnmapped;
+    private int lastUnmapped;
+
     /**
      * Default constructor
      */
@@ -132,13 +166,14 @@ public class MultiByteFont extends CIDFo
      * @param c the Unicode character index
      * @return the glyph index (or 0 if the glyph is not available)
      */
-    private int findGlyphIndex(char c) {
-        int idx = (int)c;
+    // [TBD] - needs optimization, i.e., change from linear search to binary search
+    private int findGlyphIndex(int c) {
+        int idx = c;
         int retIdx = SingleByteEncoding.NOT_FOUND_CODE_POINT;
 
         for (int i = 0; (i < bfentries.length) && retIdx == 0; i++) {
             if (bfentries[i].getUnicodeStart() <= idx
-                    && bfentries[i].getUnicodeEnd() >= idx) {
+                && bfentries[i].getUnicodeEnd() >= idx) {
 
                 retIdx = bfentries[i].getGlyphStartIndex()
                     + idx
@@ -148,6 +183,95 @@ public class MultiByteFont extends CIDFo
         return retIdx;
     }
 
+    /**
+     * Add a private use mapping {PU,GI} to the existing BFENTRIES map.
+     * N.B. Does not insert in order, merely appends to end of existing map.
+     */
+    private synchronized void addPrivateUseMapping ( int pu, int gi ) {
+        assert findGlyphIndex ( pu ) == SingleByteEncoding.NOT_FOUND_CODE_POINT;
+        BFEntry[] bfeOld = bfentries;
+        int       bfeCnt = bfeOld.length;
+        BFEntry[] bfeNew = new BFEntry [ bfeCnt + 1 ];
+        System.arraycopy ( bfeOld, 0, bfeNew, 0, bfeCnt );
+        bfeNew [ bfeCnt ] = new BFEntry ( pu, pu, gi );
+        bfentries = bfeNew;
+    }
+
+    /**
+     * Given a glyph index, create a new private use mapping, augmenting the bfentries
+     * table. This is needed to accommodate the presence of an (output) glyph index in a
+     * complex script glyph substitution that does not correspond to a character in the
+     * font's CMAP.  The creation of such private use mappings is deferred until an
+     * attempt is actually made to perform the reverse lookup from the glyph index. This
+     * is necessary in order to avoid exhausting the private use space on fonts containing
+     * many such non-mapped glyph indices, if these mappings had been created statically
+     * at font load time.
+     * @param gi glyph index
+     * @returns unicode scalar value
+     */
+    private int createPrivateUseMapping ( int gi ) {
+        while ( ( nextPrivateUse < 0xF900 )
+                && ( findGlyphIndex(nextPrivateUse) != SingleByteEncoding.NOT_FOUND_CODE_POINT ) ) {
+            nextPrivateUse++;
+        }
+        if ( nextPrivateUse < 0xF900 ) {
+            int pu = nextPrivateUse;
+            addPrivateUseMapping ( pu, gi );
+            if ( firstPrivate == 0 ) {
+                firstPrivate = pu;
+            }
+            lastPrivate = pu;
+            numMapped++;
+            if (log.isDebugEnabled()) {
+                log.debug ( "Create private use mapping from "
+                            + CharUtilities.format ( pu )
+                            + " to glyph index " + gi
+                            + " in font '" + getFullName() + "'" );
+            }
+            return pu;
+        } else {
+            if ( firstUnmapped == 0 ) {
+                firstUnmapped = gi;
+            }
+            lastUnmapped = gi;
+            numUnmapped++;
+            log.warn ( "Exhausted private use area: unable to map "
+                       + numUnmapped + " glyphs in glyph index range ["
+                       + firstUnmapped + "," + lastUnmapped
+                       + "] (inclusive) of font '" + getFullName() + "'" );
+            return 0;
+        }
+    }
+
+    /**
+     * Returns the Unicode scalar value that corresponds to the glyph index. If more than
+     * one correspondence exists, then the first one is returned (ordered by bfentries[]).
+     * @param gi glyph index
+     * @returns unicode scalar value
+     */
+    // [TBD] - needs optimization, i.e., change from linear search to binary search
+    private int findCharacterFromGlyphIndex ( int gi, boolean augment ) {
+        int cc = 0;
+        for ( int i = 0, n = bfentries.length; i < n; i++ ) {
+            BFEntry be = bfentries [ i ];
+            int s = be.getGlyphStartIndex();
+            int e = s + ( be.getUnicodeEnd() - be.getUnicodeStart() );
+            if ( ( gi >= s ) && ( gi <= e ) ) {
+                cc = be.getUnicodeStart() + ( gi - s );
+                break;
+            }
+        }
+        if ( ( cc == 0 ) && augment ) {
+            cc = createPrivateUseMapping ( gi );
+        }
+        return cc;
+    }
+
+    private int findCharacterFromGlyphIndex ( int gi ) {
+        return findCharacterFromGlyphIndex ( gi, true );
+    }
+
+
     /** {@inheritDoc} */
     public char mapChar(char c) {
         notifyMapOperation();
@@ -223,5 +347,220 @@ public class MultiByteFont extends CIDFo
         }
         return subset.getSubsetChars();
     }
+
+    /**
+     * Establishes the glyph definition table.
+     * @param gdef the glyph definition table to be used by this font
+     */
+    public void setGDEF ( GlyphDefinitionTable gdef ) {
+        if ( ( this.gdef == null ) || ( gdef == null ) ) {
+            this.gdef = gdef;
+        } else {
+            throw new IllegalStateException ( "font already associated with GDEF table" );
+        }
+    }
+
+    /**
+     * Obtain glyph definition table.
+     * @return glyph definition table or null if none is associated with font
+     */
+    public GlyphDefinitionTable getGDEF() {
+        return gdef;
+    }
+
+    /**
+     * Establishes the glyph substitution table.
+     * @param gsub the glyph substitution table to be used by this font
+     */
+    public void setGSUB ( GlyphSubstitutionTable gsub ) {
+        if ( ( this.gsub == null ) || ( gsub == null ) ) {
+            this.gsub = gsub;
+        } else {
+            throw new IllegalStateException ( "font already associated with GSUB table" );
+        }
+    }
+
+    /**
+     * Obtain glyph substitution table.
+     * @return glyph substitution table or null if none is associated with font
+     */
+    public GlyphSubstitutionTable getGSUB() {
+        return gsub;
+    }
+
+    /**
+     * Establishes the glyph positioning table.
+     * @param gpos the glyph positioning table to be used by this font
+     */
+    public void setGPOS ( GlyphPositioningTable gpos ) {
+        if ( ( this.gpos == null ) || ( gpos == null ) ) {
+            this.gpos = gpos;
+        } else {
+            throw new IllegalStateException ( "font already associated with GPOS table" );
+        }
+    }
+
+    /**
+     * Obtain glyph positioning table.
+     * @return glyph positioning table or null if none is associated with font
+     */
+    public GlyphPositioningTable getGPOS() {
+        return gpos;
+    }
+
+    /** {@inheritDoc} */
+    public boolean performsSubstitution() {
+        return gsub != null;
+    }
+
+    /** {@inheritDoc} */
+    public CharSequence performSubstitution ( CharSequence cs, String script, String language ) {
+        if ( gsub != null ) {
+            GlyphSequence igs = mapCharsToGlyphs ( cs );
+            GlyphSequence ogs = gsub.substitute ( igs, script, language );
+            CharSequence ocs = mapGlyphsToChars ( ogs );
+            return ocs;
+        } else {
+            return cs;
+        }
+    }
+
+    /** {@inheritDoc} */
+    public CharSequence reorderCombiningMarks
+        ( CharSequence cs, int[][] gpa, String script, String language ) {
+        if ( gdef != null ) {
+            GlyphSequence igs = mapCharsToGlyphs ( cs );
+            GlyphSequence ogs = gdef.reorderCombiningMarks ( igs, gpa, script, language );
+            CharSequence ocs = mapGlyphsToChars ( ogs );
+            return ocs;
+        } else {
+            return cs;
+        }
+    }
+
+    /** {@inheritDoc} */
+    public boolean performsPositioning() {
+        return gpos != null;
+    }
+
+    /** {@inheritDoc} */
+    public int[][]
+        performPositioning ( CharSequence cs, String script, String language, int fontSize ) {
+        if ( gpos != null ) {
+            GlyphSequence gs = mapCharsToGlyphs ( cs );
+            int[][] adjustments = new int [ gs.getGlyphCount() ] [ 4 ];
+            if ( gpos.position ( gs, script, language, fontSize, this.width, adjustments ) ) {
+                return scaleAdjustments ( adjustments, fontSize );
+            } else {
+                return null;
+            }
+        } else {
+            return null;
+        }
+    }
+
+    /** {@inheritDoc} */
+    public int[][] performPositioning ( CharSequence cs, String script, String language ) {
+        throw new UnsupportedOperationException();
+    }
+
+
+    private int[][] scaleAdjustments ( int[][] adjustments, int fontSize ) {
+        if ( adjustments != null ) {
+            for ( int i = 0, n = adjustments.length; i < n; i++ ) {
+                int[] gpa = adjustments [ i ];
+                for ( int k = 0; k < 4; k++ ) {
+                    gpa [ k ] = ( gpa [ k ] * fontSize ) / 1000;
+                }
+            }
+            return adjustments;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Map sequence CS, comprising a sequence of UTF-16 encoded Unicode Code Points, to
+     * an output character sequence GS, comprising a sequence of Glyph Indices. N.B. Unlike
+     * mapChar(), this method does not make use of embedded subset encodings.
+     * @param cs a CharSequence containing UTF-16 encoded Unicode characters
+     * @returns a CharSequence containing glyph indices
+     */
+    private GlyphSequence mapCharsToGlyphs ( CharSequence cs ) {
+        IntBuffer cb = IntBuffer.allocate ( cs.length() );
+        IntBuffer gb = IntBuffer.allocate ( cs.length() );
+        int gi, giMissing = findGlyphIndex ( Typeface.NOT_FOUND );
+        for ( int i = 0, n = cs.length(); i < n; i++ ) {
+            int cc = cs.charAt ( i );
+            if ( ( cc >= 0xD800 ) && ( cc < 0xDC00 ) ) {
+                if ( ( i + 1 ) < n ) {
+                    int sh = cc;
+                    int sl = cs.charAt ( ++i );
+                    if ( ( sl >= 0xDC00 ) && ( sl < 0xE000 ) ) {
+                        cc = 0x10000 + ( ( sh - 0xD800 ) << 10 ) + ( ( sl - 0xDC00 ) << 0 );
+                    } else {
+                        throw new IllegalArgumentException
+                            (  "ill-formed UTF-16 sequence, "
+                               + "contains isolated high surrogate at index " + i );
+                    }
+                } else {
+                    throw new IllegalArgumentException
+                        ( "ill-formed UTF-16 sequence, "
+                          + "contains isolated high surrogate at end of sequence" );
+                }
+            } else if ( ( cc >= 0xDC00 ) && ( cc < 0xE000 ) ) {
+                throw new IllegalArgumentException
+                    ( "ill-formed UTF-16 sequence, "
+                      + "contains isolated low surrogate at index " + i );
+            }
+            notifyMapOperation();
+            gi = findGlyphIndex ( cc );
+            if ( gi == SingleByteEncoding.NOT_FOUND_CODE_POINT ) {
+                warnMissingGlyph ( (char) cc );
+                gi = giMissing;
+            }
+            cb.put ( cc );
+            gb.put ( gi );
+        }
+        cb.flip();
+        gb.flip();
+        return new GlyphSequence ( cb, gb, null );
+    }
+
+    /**
+     * Map sequence GS, comprising a sequence of Glyph Indices, to output sequence CS,
+     * comprising a sequence of UTF-16 encoded Unicode Code Points.
+     * @param gs a GlyphSequence containing glyph indices
+     * @returns a CharSequence containing UTF-16 encoded Unicode characters
+     */
+    private CharSequence mapGlyphsToChars ( GlyphSequence gs ) {
+        int ng = gs.getGlyphCount();
+        CharBuffer cb = CharBuffer.allocate ( ng );
+        int ccMissing = Typeface.NOT_FOUND;
+        for ( int i = 0, n = ng; i < n; i++ ) {
+            int gi = gs.getGlyph ( i );
+            int cc = findCharacterFromGlyphIndex ( gi );
+            if ( ( cc == 0 ) || ( cc > 0x10FFFF ) ) {
+                cc = ccMissing;
+                log.warn("Unable to map glyph index " + gi
+                         + " to Unicode scalar in font '"
+                         + getFullName() + "', substituting missing character '"
+                         + (char) cc + "'");
+            }
+            if ( cc > 0x00FFFF ) {
+                int sh, sl;
+                cc -= 0x10000;
+                sh = ( ( cc >> 10 ) & 0x3FF ) + 0xD800;
+                sl = ( ( cc >>  0 ) & 0x3FF ) + 0xDC00;
+                cb.put ( (char) sh );
+                cb.put ( (char) sl );
+            } else {
+                cb.put ( (char) cc );
+            }
+        }
+        cb.flip();
+        return (CharSequence) cb;
+    }
+
 }
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/MutableFont.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/MutableFont.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/MutableFont.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/MutableFont.java Sun Feb 26 02:29:01 2012
@@ -133,6 +133,12 @@ public interface MutableFont {
     void setKerningEnabled(boolean enabled);
 
     /**
+     * Enables/disabled advanced typographic features.
+     * @param enabled true if advanced typographic features should be enabled if available
+     */
+    void setAdvancedEnabled(boolean enabled);
+
+    /**
      * Adds an entry to the kerning table.
      * @param key Kerning key
      * @param value Kerning value

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/Typeface.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/Typeface.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/Typeface.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/Typeface.java Sun Feb 26 02:29:01 2012
@@ -143,6 +143,10 @@ public abstract class Typeface implement
 
     /** {@inheritDoc} */
     public String toString() {
-        return getFullName();
+        StringBuffer sbuf = new StringBuffer(super.toString());
+        sbuf.append('{');
+        sbuf.append(getFullName());
+        sbuf.append('}');
+        return sbuf.toString();
     }
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/apps/AbstractFontReader.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/apps/AbstractFontReader.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/apps/AbstractFontReader.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/apps/AbstractFontReader.java Sun Feb 26 02:29:01 2012
@@ -67,7 +67,7 @@ public abstract class AbstractFontReader
         List arguments = new java.util.ArrayList();
         for (int i = 0; i < args.length; i++) {
             if (args[i].startsWith("-")) {
-                if ("-d".equals(args[i]) || "-q".equals(args[i])) {
+                if ("-t".equals(args[i]) || "-d".equals(args[i]) || "-q".equals(args[i])) {
                     options.put(args[i], "");
                 } else if ((i + 1) < args.length && !args[i + 1].startsWith("-")) {
                     options.put(args[i], args[i + 1]);
@@ -101,7 +101,9 @@ public abstract class AbstractFontReader
      */
     protected static void determineLogLevel(Map options) {
         //Determine log level
-        if (options.get("-d") != null) {
+        if (options.get("-t") != null) {
+            setLogLevel("trace");
+        } else if (options.get("-d") != null) {
             setLogLevel("debug");
         } else if (options.get("-q") != null) {
             setLogLevel("error");

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/apps/TTFReader.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/apps/TTFReader.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/apps/TTFReader.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/apps/TTFReader.java Sun Feb 26 02:29:01 2012
@@ -21,6 +21,7 @@ package org.apache.fop.fonts.apps;
 
 import java.io.IOException;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -38,6 +39,9 @@ import org.w3c.dom.Element;
 import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
 
+// CSOFF: InnerAssignmentCheck
+// CSOFF: LineLengthCheck
+
 /**
  * A tool which reads TTF files and generates
  * XML font metrics file for use in FOP.
@@ -61,6 +65,7 @@ public class TTFReader extends AbstractF
                 "java " + TTFReader.class.getName() + " [options] fontfile.ttf xmlfile.xml");
         System.out.println();
         System.out.println("where options can be:");
+        System.out.println("-t  Trace mode");
         System.out.println("-d  Debug mode");
         System.out.println("-q  Quiet mode");
         System.out.println("-enc ansi");
@@ -102,6 +107,8 @@ public class TTFReader extends AbstractF
      * you can also include the fontfile in the fop.jar file when building fop.
      * You can use both -ef and -er. The file specified in -ef will be searched first,
      * then the -er file.
+     * -nocs
+     * if complex script features are disabled
      */
     public static void main(String[] args) {
         String embFile = null;
@@ -155,13 +162,19 @@ public class TTFReader extends AbstractF
             className = (String)options.get("-cn");
         }
 
+        boolean useKerning = true;
+        boolean useAdvanced = true;
+        if (options.get("-nocs") != null) {
+            useAdvanced = false;
+        }
+
         if (arguments.length != 2 || options.get("-h") != null
             || options.get("-help") != null || options.get("--help") != null) {
             displayUsage();
         } else {
             try {
                 log.info("Parsing font...");
-                TTFFile ttf = app.loadTTF(arguments[0], ttcName);
+                TTFFile ttf = app.loadTTF(arguments[0], ttcName, useKerning, useAdvanced);
                 if (ttf != null) {
                     org.w3c.dom.Document doc = app.constructFontXML(ttf,
                             fontName, className, embResource, embFile, isCid,
@@ -198,11 +211,13 @@ public class TTFReader extends AbstractF
      *
      * @param  fileName The filename of the TTF file.
      * @param  fontName The name of the font
+     * @param  useKerning true if should load kerning data
+     * @param  useAdvanced true if should load advanced typographic table data
      * @return The TTF as an object, null if the font is incompatible.
      * @throws IOException In case of an I/O problem
      */
-    public TTFFile loadTTF(String fileName, String fontName) throws IOException {
-        TTFFile ttfFile = new TTFFile();
+    public TTFFile loadTTF(String fileName, String fontName, boolean useKerning, boolean useAdvanced) throws IOException {
+        TTFFile ttfFile = new TTFFile(useKerning, useAdvanced);
         log.info("Reading " + fileName + "...");
 
         FontFileReader reader = new FontFileReader(fileName);
@@ -463,7 +478,6 @@ public class TTFReader extends AbstractF
         }
     }
 
-
     /**
      * Bugzilla 40739, check that attr has a metrics-version attribute
      * compatible with ours.

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java Sun Feb 26 02:29:01 2012
@@ -148,7 +148,7 @@ public class FontInfoFinder {
             subFontName = ((MultiByteFont)customFont).getTTCName();
         }
         EmbedFontInfo fontInfo = new EmbedFontInfo(null, customFont.isKerningEnabled(),
-                fontTripletList, embedUrl, subFontName);
+                customFont.isAdvancedEnabled(), fontTripletList, embedUrl, subFontName);
         fontInfo.setPostScriptName(customFont.getFontName());
         if (fontCache != null) {
             fontCache.addFont(fontInfo);
@@ -168,6 +168,9 @@ public class FontInfoFinder {
     public EmbedFontInfo[] find(URL fontURL, FontResolver resolver, FontCache fontCache) {
         String embedURL = null;
         embedURL = fontURL.toExternalForm();
+        boolean useKerning = true;
+        boolean useAdvanced = ( resolver != null )
+            ? resolver.isComplexScriptFeaturesEnabled() : true;
 
         long fileLastModified = -1;
         if (fontCache != null) {
@@ -190,14 +193,14 @@ public class FontInfoFinder {
 
         // try to determine triplet information from font file
         CustomFont customFont = null;
-        if (fontURL.toExternalForm().endsWith(".ttc")) {
+        if (fontURL.toExternalForm().toLowerCase().endsWith(".ttc")) {
             // Get a list of the TTC Font names
             List<String> ttcNames = null;
             String fontFileURL = fontURL.toExternalForm().trim();
             InputStream in = null;
             try {
                 in = FontLoader.openFontUri(resolver, fontFileURL);
-                TTFFile ttf = new TTFFile();
+                TTFFile ttf = new TTFFile(false, false);
                 FontFileReader reader = new FontFileReader(in);
                 ttcNames = ttf.getTTCnames(reader);
             } catch (Exception e) {
@@ -218,7 +221,8 @@ public class FontInfoFinder {
                 }
                 try {
                     TTFFontLoader ttfLoader = new TTFFontLoader(
-                            fontFileURL, fontName, true, EncodingMode.AUTO, true, resolver);
+                            fontFileURL, fontName, true, EncodingMode.AUTO,
+                            useKerning, useAdvanced, resolver);
                     customFont = ttfLoader.getFont();
                     if (this.eventListener != null) {
                         customFont.setEventListener(this.eventListener);

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/TTFDirTabEntry.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/TTFDirTabEntry.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/TTFDirTabEntry.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/TTFDirTabEntry.java Sun Feb 26 02:29:01 2012
@@ -26,7 +26,7 @@ import java.io.UnsupportedEncodingExcept
 /**
  * This class represents an entry to a TrueType font's Dir Tab.
  */
-class TTFDirTabEntry {
+public class TTFDirTabEntry {
 
     private byte[] tag = new byte[4];
     private int checksum;
@@ -34,7 +34,10 @@ class TTFDirTabEntry {
     private long length;
 
     /**
-     * Read Dir Tab, return tag name
+     * Read Dir Tab.
+     * @param in font file reader
+     * @return tag name
+     * @throws IOException upon I/O exception
      */
     public String read(FontFileReader in) throws IOException {
         tag[0] = in.readTTFByte();
@@ -52,6 +55,7 @@ class TTFDirTabEntry {
     }
 
 
+    @Override
     public String toString() {
         return "Read dir tab ["
             + tag[0] + " " + tag[1] + " " + tag[2] + " " + tag[3] + "]"

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/TTFFile.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/TTFFile.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/TTFFile.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/TTFFile.java Sun Feb 26 02:29:01 2012
@@ -28,9 +28,15 @@ import java.util.Set;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.fop.fonts.FontUtil;
 import org.apache.xmlgraphics.fonts.Glyphs;
 
+import org.apache.fop.complexscripts.fonts.AdvancedTypographicTableFormatException;
+import org.apache.fop.complexscripts.fonts.GlyphDefinitionTable;
+import org.apache.fop.complexscripts.fonts.GlyphPositioningTable;
+import org.apache.fop.complexscripts.fonts.GlyphSubstitutionTable;
+import org.apache.fop.complexscripts.fonts.OTFAdvancedTypographicTableReader;
+import org.apache.fop.fonts.FontUtil;
+
 /**
  * Reads a TrueType file or a TrueType Collection.
  * The TrueType spec can be found at the Microsoft.
@@ -43,12 +49,12 @@ public class TTFFile {
     static final int MAX_CHAR_CODE = 255;
     static final int ENC_BUF_SIZE = 1024;
 
-    /** Set to true to get even more debug output than with level DEBUG */
-    public static final boolean TRACE_ENABLED = false;
-
     private final String encoding = "WinAnsiEncoding";    // Default encoding
 
     private final short firstChar = 0;
+
+    private boolean useKerning = false;
+
     private boolean isEmbeddable = true;
     private boolean hasSerifs = true;
     /**
@@ -58,7 +64,7 @@ public class TTFFile {
     private Map<Integer, Map<Integer, Integer>> kerningTab;     // for CIDs
     private Map<Integer, Map<Integer, Integer>> ansiKerningTab; // For winAnsiEncoding
     private List cmaps;
-    private List unicodeMapping;
+    private Set unicodeMappings;
 
     private int upem;                                // unitsPerEm from "head" table
     private int nhmtx;                               // Number of horizontal metrics
@@ -120,15 +126,29 @@ public class TTFFile {
 
     private boolean isCFF;
 
+    // advanced typographic table support
+    private boolean useAdvanced = false;
+    private OTFAdvancedTypographicTableReader advancedTableReader;
+
     /**
      * logging instance
      */
     protected Log log = LogFactory.getLog(TTFFile.class);
 
     /**
+     * Constructor
+     * @param useKerning true if kerning data should be loaded
+     * @param useAdvanced true if advanced typographic tables should be loaded
+     */
+    public TTFFile ( boolean useKerning, boolean useAdvanced ) {
+        this.useKerning = useKerning;
+        this.useAdvanced = useAdvanced;
+    }
+
+    /**
      * Key-value helper class
      */
-    class UnicodeMapping {
+    class UnicodeMapping implements Comparable {
 
         private final int unicodeIndex;
         private final int glyphIndex;
@@ -155,15 +175,67 @@ public class TTFFile {
         public int getUnicodeIndex() {
             return unicodeIndex;
         }
+
+
+        /** {@inheritDoc} */
+        public int hashCode() {
+            int hc = unicodeIndex;
+            hc = 19 * hc + ( hc ^ glyphIndex );
+            return hc;
+        }
+
+        /** {@inheritDoc} */
+        public boolean equals ( Object o ) {
+            if ( o instanceof UnicodeMapping ) {
+                UnicodeMapping m = (UnicodeMapping) o;
+                if ( unicodeIndex != m.unicodeIndex ) {
+                    return false;
+                } else {
+                    return ( glyphIndex == m.glyphIndex );
+                }
+            } else {
+                return false;
+            }
+        }
+
+        /** {@inheritDoc} */
+        public int compareTo ( Object o ) {
+            if ( o instanceof UnicodeMapping ) {
+                UnicodeMapping m = (UnicodeMapping) o;
+                if ( unicodeIndex > m.unicodeIndex ) {
+                    return 1;
+                } else if ( unicodeIndex < m.unicodeIndex ) {
+                    return -1;
+                } else {
+                    return 0;
+                }
+            } else {
+                return -1;
+            }
+        }
+    }
+
+    /**
+     * Obtain directory table entry.
+     * @param name (tag) of entry
+     * @return a directory table entry or null if none found
+     */
+    public TTFDirTabEntry getDirectoryEntry ( String name ) {
+        return (TTFDirTabEntry) dirTabs.get ( name );
     }
 
     /**
      * Position inputstream to position indicated
      * in the dirtab offset + offset
+     * @param in font file reader
+     * @param name (tag) of table
+     * @param offset from start of table
+     * @return true if seek succeeded
+     * @throws IOException if I/O exception occurs during seek
      */
-    boolean seekTab(FontFileReader in, String name,
+    public boolean seekTab(FontFileReader in, String name,
                   long offset) throws IOException {
-        TTFDirTabEntry dt = (TTFDirTabEntry)dirTabs.get(name);
+        TTFDirTabEntry dt = getDirectoryEntry ( name );
         if (dt == null) {
             log.error("Dirtab " + name + " not found.");
             return false;
@@ -203,7 +275,7 @@ public class TTFFile {
      */
     private boolean readCMAP(FontFileReader in) throws IOException {
 
-        unicodeMapping = new java.util.ArrayList();
+        unicodeMappings = new java.util.TreeSet();
 
         seekTab(in, "cmap", 2);
         int numCMap = in.readTTFUShort();    // Number of cmap subtables
@@ -344,7 +416,7 @@ public class TTFFile {
                             glyphIdx = (in.readTTFUShort() + cmapDeltas[i])
                                        & 0xffff;
 
-                            unicodeMapping.add(new UnicodeMapping(glyphIdx, j));
+                            unicodeMappings.add(new UnicodeMapping(glyphIdx, j));
                             mtxTab[glyphIdx].getUnicodeIndex().add(new Integer(j));
 
                             if (encodingID == 0 && j >= 0xF020 && j <= 0xF0FF) {
@@ -354,7 +426,7 @@ public class TTFFile {
                                 int mapped = j - 0xF000;
                                 if (!eightBitGlyphs.get(mapped)) {
                                     //Only map if Unicode code point hasn't been mapped before
-                                    unicodeMapping.add(new UnicodeMapping(glyphIdx, mapped));
+                                    unicodeMappings.add(new UnicodeMapping(glyphIdx, mapped));
                                     mtxTab[glyphIdx].getUnicodeIndex().add(new Integer(mapped));
                                 }
                             }
@@ -395,7 +467,7 @@ public class TTFFile {
                                                    + mtxTab.length);
                             }
 
-                            unicodeMapping.add(new UnicodeMapping(glyphIdx, j));
+                            unicodeMappings.add(new UnicodeMapping(glyphIdx, j));
                             if (glyphIdx < mtxTab.length) {
                                 mtxTab[glyphIdx].getUnicodeIndex().add(new Integer(j));
                             } else {
@@ -554,9 +626,27 @@ public class TTFFile {
         }
         // Create cmaps for bfentries
         createCMaps();
-        // print_max_min();
 
-        readKerning(in);
+        if ( useKerning ) {
+            readKerning(in);
+        }
+
+        // Read advanced typographic tables.
+        if ( useAdvanced ) {
+            try {
+                OTFAdvancedTypographicTableReader atr
+                    = new OTFAdvancedTypographicTableReader ( this, in );
+                atr.readAll();
+                this.advancedTableReader = atr;
+            } catch ( AdvancedTypographicTableFormatException e ) {
+                log.warn (
+                    "Encountered format constraint violation in advanced (typographic) table (AT) "
+                    + "in font '" + getFullName() + "', ignoring AT data: "
+                    + e.getMessage()
+                );
+            }
+        }
+
         guessVerticalMetricsFromGlyphBBox();
         return true;
     }
@@ -565,7 +655,7 @@ public class TTFFile {
         cmaps = new java.util.ArrayList();
         TTFCmapEntry tce = new TTFCmapEntry();
 
-        Iterator e = unicodeMapping.listIterator();
+        Iterator e = unicodeMappings.iterator();
         UnicodeMapping um = (UnicodeMapping)e.next();
         UnicodeMapping lastMapping = um;
 
@@ -927,8 +1017,8 @@ public class TTFFile {
         int mtxSize = Math.max(numberOfGlyphs, nhmtx);
         mtxTab = new TTFMtxEntry[mtxSize];
 
-        if (TRACE_ENABLED) {
-            log.debug("*** Widths array: \n");
+        if (log.isTraceEnabled()) {
+            log.trace("*** Widths array: \n");
         }
         for (int i = 0; i < mtxSize; i++) {
             mtxTab[i] = new TTFMtxEntry();
@@ -937,11 +1027,9 @@ public class TTFFile {
             mtxTab[i].setWx(in.readTTFUShort());
             mtxTab[i].setLsb(in.readTTFUShort());
 
-            if (TRACE_ENABLED) {
-                if (log.isDebugEnabled()) {
-                    log.debug("   width[" + i + "] = "
-                        + convertTTFUnit2PDFUnit(mtxTab[i].getWx()) + ";");
-                }
+            if (log.isTraceEnabled()) {
+                log.trace("   width[" + i + "] = "
+                          + convertTTFUnit2PDFUnit(mtxTab[i].getWx()) + ";");
             }
         }
 
@@ -1045,7 +1133,7 @@ public class TTFFile {
      */
     private void readOS2(FontFileReader in) throws IOException {
         // Check if font is embeddable
-        TTFDirTabEntry os2Entry = (TTFDirTabEntry)dirTabs.get("OS/2");
+        TTFDirTabEntry os2Entry = getDirectoryEntry ( "OS/2" );
         if (os2Entry != null) {
             seekTab(in, "OS/2", 0);
             int version = in.readTTFUShort();
@@ -1133,7 +1221,7 @@ public class TTFFile {
      * @throws IOException In case of a I/O problem
      */
     private void readGlyf(FontFileReader in) throws IOException {
-        TTFDirTabEntry dirTab = (TTFDirTabEntry)dirTabs.get("glyf");
+        TTFDirTabEntry dirTab = getDirectoryEntry ( "glyf" );
         if (dirTab == null) {
             throw new IOException("glyf table not found, cannot continue");
         }
@@ -1153,7 +1241,7 @@ public class TTFFile {
         }
 
 
-        long n = ((TTFDirTabEntry)dirTabs.get("glyf")).getOffset();
+        long n = dirTab.getOffset();
         for (int i = 0; i < numberOfGlyphs; i++) {
             if ((i + 1) >= mtxTab.length
                     || mtxTab[i].getOffset() != mtxTab[i + 1].getOffset()) {
@@ -1259,7 +1347,7 @@ public class TTFFile {
      * @throws IOException In case of a I/O problem
      */
     private boolean readPCLT(FontFileReader in) throws IOException {
-        TTFDirTabEntry dirTab = (TTFDirTabEntry)dirTabs.get("PCLT");
+        TTFDirTabEntry dirTab = getDirectoryEntry ( "PCLT" );
         if (dirTab != null) {
             in.seekSet(dirTab.getOffset() + 4 + 4 + 2);
             xHeight = in.readTTFUShort();
@@ -1380,7 +1468,7 @@ public class TTFFile {
                 capHeight = os2CapHeight;
             }
             if (capHeight == 0) {
-                log.warn("capHeight value could not be determined."
+                log.debug("capHeight value could not be determined."
                         + " The font may not work as expected.");
             }
         }
@@ -1390,7 +1478,7 @@ public class TTFFile {
                 xHeight = os2xHeight;
             }
             if (xHeight == 0) {
-                log.warn("xHeight value could not be determined."
+                log.debug("xHeight value could not be determined."
                         + " The font may not work as expected.");
             }
         }
@@ -1406,7 +1494,7 @@ public class TTFFile {
         // Read kerning
         kerningTab = new java.util.HashMap();
         ansiKerningTab = new java.util.HashMap();
-        TTFDirTabEntry dirTab = (TTFDirTabEntry)dirTabs.get("kern");
+        TTFDirTabEntry dirTab = getDirectoryEntry ( "kern" );
         if (dirTab != null) {
             seekTab(in, "kern", 2);
             for (int n = in.readTTFUShort(); n > 0; n--) {
@@ -1584,11 +1672,9 @@ public class TTFFile {
                 dirOffsets[i] = in.readTTFULong();
             }
 
-            if (log.isDebugEnabled()) {
-                log.debug("This is a TrueType collection file with "
-                        + numDirectories + " fonts");
-                log.debug("Containing the following fonts: ");
-            }
+            log.info("This is a TrueType collection file with "
+                      + numDirectories + " fonts");
+            log.info("Containing the following fonts: ");
 
             for (int i = 0; (i < numDirectories); i++) {
                 in.seekSet(dirOffsets[i]);
@@ -1596,7 +1682,7 @@ public class TTFFile {
 
                 readName(in);
 
-                log.debug(fullName);
+                log.info(fullName);
                 fontNames.add(fullName);
 
                 // Reset names
@@ -1667,9 +1753,8 @@ public class TTFFile {
      *
      * @param glyphIndex
      * @return unicode code point
-     * @throws IOException if glyphIndex not found
      */
-    private Integer glyphToUnicode(int glyphIndex) throws IOException {
+    private Integer glyphToUnicode(int glyphIndex) {
         return (Integer) glyphToUnicodeMap.get(new Integer(glyphIndex));
     }
 
@@ -1678,7 +1763,6 @@ public class TTFFile {
      *
      * @param unicodeIndex unicode code point
      * @return glyph index
-     * @throws IOException if unicodeIndex not found
      */
     private Integer unicodeToGlyph(int unicodeIndex) throws IOException {
         final Integer result
@@ -1691,12 +1775,62 @@ public class TTFFile {
     }
 
     /**
+     * Determine if advanced (typographic) table is present.
+     * @return true if advanced (typographic) table is present
+     */
+    public boolean hasAdvancedTable() {
+        if (  advancedTableReader != null ) {
+            return  advancedTableReader.hasAdvancedTable();
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Returns the GDEF table or null if none present.
+     * @return the GDEF table
+     */
+    public GlyphDefinitionTable getGDEF() {
+        if (  advancedTableReader != null ) {
+            return  advancedTableReader.getGDEF();
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Returns the GSUB table or null if none present.
+     * @return the GSUB table
+     */
+    public GlyphSubstitutionTable getGSUB() {
+        if (  advancedTableReader != null ) {
+            return  advancedTableReader.getGSUB();
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Returns the GPOS table or null if none present.
+     * @return the GPOS table
+     */
+    public GlyphPositioningTable getGPOS() {
+        if (  advancedTableReader != null ) {
+            return  advancedTableReader.getGPOS();
+        } else {
+            return null;
+        }
+    }
+
+    /**
      * Static main method to get info about a TrueType font.
      * @param args The command line arguments
      */
     public static void main(String[] args) {
         try {
-            TTFFile ttfFile = new TTFFile();
+            boolean useKerning = true;
+            boolean useAdvanced = true;
+            TTFFile ttfFile = new TTFFile(useKerning, useAdvanced);
 
             FontFileReader reader = new FontFileReader(args[0]);
 
@@ -1713,4 +1847,4 @@ public class TTFFile {
             ioe.printStackTrace(System.err);
         }
     }
-}
\ No newline at end of file
+}

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java Sun Feb 26 02:29:01 2012
@@ -54,7 +54,7 @@ public class TTFFontLoader extends FontL
      * @param resolver the FontResolver for font URI resolution
      */
     public TTFFontLoader(String fontFileURI, FontResolver resolver) {
-        this(fontFileURI, null, true, EncodingMode.AUTO, true, resolver);
+        this(fontFileURI, null, true, EncodingMode.AUTO, true, true, resolver);
     }
 
     /**
@@ -65,12 +65,13 @@ public class TTFFontLoader extends FontL
      * @param embedded indicates whether the font is embedded or referenced
      * @param encodingMode the requested encoding mode
      * @param useKerning true to enable loading kerning info if available, false to disable
+     * @param useAdvanced true to enable loading advanced info if available, false to disable
      * @param resolver the FontResolver for font URI resolution
      */
     public TTFFontLoader(String fontFileURI, String subFontName,
                 boolean embedded, EncodingMode encodingMode, boolean useKerning,
-                FontResolver resolver) {
-        super(fontFileURI, embedded, useKerning, resolver);
+                boolean useAdvanced, FontResolver resolver) {
+        super(fontFileURI, embedded, useKerning, useAdvanced, resolver);
         this.subFontName = subFontName;
         this.encodingMode = encodingMode;
         if (this.encodingMode == EncodingMode.AUTO) {
@@ -93,7 +94,7 @@ public class TTFFontLoader extends FontL
     private void read(String ttcFontName) throws IOException {
         InputStream in = openFontUri(resolver, this.fontFileURI);
         try {
-            TTFFile ttf = new TTFFile();
+            TTFFile ttf = new TTFFile(useKerning, useAdvanced);
             FontFileReader reader = new FontFileReader(in);
             boolean supported = ttf.readFont(reader, ttcFontName);
             if (!supported) {
@@ -169,6 +170,9 @@ public class TTFFontLoader extends FontL
         if (useKerning) {
             copyKerning(ttf, isCid);
         }
+        if (useAdvanced) {
+            copyAdvanced(ttf);
+        }
         if (this.embedded) {
             if (ttf.isEmbeddable()) {
                 returnFont.setEmbedFileName(this.fontFileURI);
@@ -229,4 +233,17 @@ public class TTFFontLoader extends FontL
             returnFont.putKerningEntry(kpx1, h2);
         }
     }
+
+    /**
+     * Copy advanced typographic information.
+     */
+    private void copyAdvanced ( TTFFile ttf ) {
+        if ( returnFont instanceof MultiByteFont ) {
+            MultiByteFont mbf = (MultiByteFont) returnFont;
+            mbf.setGDEF ( ttf.getGDEF() );
+            mbf.setGSUB ( ttf.getGSUB() );
+            mbf.setGPOS ( ttf.getGPOS() );
+        }
+    }
+
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java Sun Feb 26 02:29:01 2012
@@ -57,6 +57,22 @@ public class TTFSubSetFile extends TTFFi
     private int locaOffset = 0;
 
     /**
+     * Default Constructor
+     */
+    public TTFSubSetFile() {
+        this(false, false);
+    }
+
+    /**
+     * Constructor
+     * @param useKerning true if kerning data should be loaded
+     * @param useAdvanced true if advanced typographic tables should be loaded
+     */
+    public TTFSubSetFile ( boolean useKerning, boolean useAdvanced ) {
+        super(useKerning, useAdvanced);
+    }
+
+    /**
      * Initalize the output array
      */
     private void init(int size) {

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java Sun Feb 26 02:29:01 2012
@@ -52,7 +52,7 @@ public class Type1FontLoader extends Fon
      */
     public Type1FontLoader(String fontFileURI, boolean embedded, boolean useKerning,
             FontResolver resolver) throws IOException {
-        super(fontFileURI, embedded, useKerning, resolver);
+        super(fontFileURI, embedded, useKerning, true, resolver);
     }
 
     private String getPFMURI(String pfbURI) {

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java Sun Feb 26 02:29:01 2012
@@ -448,7 +448,7 @@ public abstract class AbstractLayoutMana
     /** {@inheritDoc} */
     @Override
     public String toString() {
-        return (super.toString() + (fobj != null ? "[fobj=" + fobj.toString() + "]" : ""));
+        return (super.toString() + (fobj != null ? "{fobj = " + fobj.toString() + "}" : ""));
     }
 
     /** {@inheritDoc} */

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java Sun Feb 26 02:29:01 2012
@@ -349,7 +349,12 @@ public class BlockContainerLayoutManager
         contentRectOffsetX = 0;
         contentRectOffsetY = 0;
 
-        contentRectOffsetX += fo.getCommonMarginBlock().startIndent.getValue(this);
+        int level = fo.getBidiLevel();
+        if ( ( level < 0 ) || ( ( level & 1 ) == 0 ) ) {
+            contentRectOffsetX += fo.getCommonMarginBlock().startIndent.getValue(this);
+        } else {
+            contentRectOffsetX += fo.getCommonMarginBlock().endIndent.getValue(this);
+        }
         contentRectOffsetY += fo.getCommonBorderPaddingBackground().getBorderBeforeWidth(false);
         contentRectOffsetY += fo.getCommonBorderPaddingBackground().getPaddingBefore(false, this);
 
@@ -834,10 +839,13 @@ public class BlockContainerLayoutManager
         if (referenceArea == null) {
             boolean switchedProgressionDirection = blockProgressionDirectionChanges();
             boolean allowBPDUpdate = autoHeight && !switchedProgressionDirection;
+            int level = getBlockContainerFO().getBidiLevel();
 
             viewportBlockArea = new BlockViewport(allowBPDUpdate);
             viewportBlockArea.addTrait(Trait.IS_VIEWPORT_AREA, Boolean.TRUE);
-
+            if ( level >= 0 ) {
+                viewportBlockArea.setBidiLevel ( level );
+            }
             viewportBlockArea.setIPD(getContentAreaIPD());
             if (allowBPDUpdate) {
                 viewportBlockArea.setBPD(0);
@@ -872,6 +880,9 @@ public class BlockContainerLayoutManager
 
             referenceArea = new Block();
             referenceArea.addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE);
+            if ( level >= 0 ) {
+                referenceArea.setBidiLevel ( level );
+            }
             TraitSetter.setProducerID(referenceArea, getBlockContainerFO().getId());
 
             if (abProps.absolutePosition == EN_ABSOLUTE) {

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java Sun Feb 26 02:29:01 2012
@@ -359,6 +359,8 @@ public class BlockLayoutManager extends 
 
             curBlockArea.setIPD(super.getContentAreaIPD());
 
+            curBlockArea.setBidiLevel ( getBlockFO().getBidiLevel() );
+
             TraitSetter.addBreaks(curBlockArea,
                     getBlockFO().getBreakBefore(), getBlockFO().getBreakAfter());
 
@@ -503,4 +505,3 @@ public class BlockLayoutManager extends 
     }
 
 }
-

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java Sun Feb 26 02:29:01 2012
@@ -51,6 +51,7 @@ import org.apache.fop.datatypes.URISpeci
 import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.extensions.ExternalDocument;
 import org.apache.fop.layoutmgr.inline.ImageLayout;
+import org.apache.fop.traits.WritingMode;
 
 /**
  * LayoutManager for an external-document extension element.  This class is instantiated by
@@ -184,12 +185,12 @@ public class ExternalDocumentLayoutManag
         TraitSetter.setProducerID(imageArea, fobj.getId());
         transferForeignAttributes(imageArea);
 
-        InlineViewport vp = new InlineViewport(imageArea);
+        InlineViewport vp = new InlineViewport(imageArea, fobj.getBidiLevel());
         TraitSetter.setProducerID(vp, fobj.getId());
         vp.setIPD(imageSize.width);
         vp.setBPD(imageSize.height);
         vp.setContentPosition(imageLayout.getPlacement());
-        vp.setOffset(0);
+        vp.setBlockProgressionOffset(0);
 
         //Link them all together...
         lineArea.addInlineArea(vp);
@@ -230,8 +231,9 @@ public class ExternalDocumentLayoutManag
             referenceRect = new Rectangle(0, 0, imageSize.height, imageSize.width);
         }
         FODimension reldims = new FODimension(0, 0);
+        // [TBD] BIDI ALERT
         CTM pageCTM = CTM.getCTMandRelDims(pageSeq.getReferenceOrientation(),
-            Constants.EN_LR_TB, referenceRect, reldims);
+                                           WritingMode.LR_TB, referenceRect, reldims);
 
         Page page = new Page(referenceRect, pageNumber, pageNumberString, isBlank);
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutContext.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutContext.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutContext.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutContext.java Sun Feb 26 02:29:01 2012
@@ -26,6 +26,7 @@ import org.apache.fop.fo.Constants;
 import org.apache.fop.layoutmgr.inline.AlignmentContext;
 import org.apache.fop.layoutmgr.inline.HyphContext;
 import org.apache.fop.traits.MinOptMax;
+import org.apache.fop.traits.WritingMode;
 
 
 /**
@@ -92,7 +93,7 @@ public class LayoutContext {
     //overlap with refIPD. Need to investigate how best to refactor that.
 
     /** the writing mode established by the nearest ancestor reference area */
-    private int writingMode = Constants.EN_LR_TB;
+    private WritingMode writingMode = WritingMode.LR_TB;
 
     /** Current pending space-after or space-end from preceding area */
     private SpaceSpecifier trailingSpace;
@@ -564,7 +565,7 @@ public class LayoutContext {
      * Get the writing mode of the relevant reference area.
      * @return the applicable writing mode
      */
-    public int getWritingMode() {
+    public WritingMode getWritingMode() {
         return writingMode;
     }
 
@@ -572,7 +573,7 @@ public class LayoutContext {
      * Set the writing mode.
      * @param writingMode the writing mode
      */
-    public void setWritingMode(int writingMode) {
+    public void setWritingMode(WritingMode writingMode) {
         this.writingMode = writingMode;
     }
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java Sun Feb 26 02:29:01 2012
@@ -67,6 +67,7 @@ import org.apache.fop.fo.pagination.Side
 import org.apache.fop.fo.pagination.StaticContent;
 import org.apache.fop.fo.pagination.Title;
 import org.apache.fop.layoutmgr.inline.BasicLinkLayoutManager;
+import org.apache.fop.layoutmgr.inline.BidiLayoutManager;
 import org.apache.fop.layoutmgr.inline.CharacterLayoutManager;
 import org.apache.fop.layoutmgr.inline.ContentLayoutManager;
 import org.apache.fop.layoutmgr.inline.ExternalGraphicLayoutManager;
@@ -246,28 +247,9 @@ public class LayoutManagerMapping implem
     public static class BidiOverrideLayoutManagerMaker extends Maker {
         /** {@inheritDoc} */
         public void make(FONode node, List lms) {
-            /* [GA] remove broken code
-            if (false) {
-                // this is broken; it does nothing
-                // it should make something like an InlineStackingLM
-                super.make(node, lms);
-            } else {
-                ArrayList childList = new ArrayList();
-                // this is broken; it does nothing
-                // it should make something like an InlineStackingLM
-                super.make(node, childList);
-                for (int count = childList.size() - 1; count >= 0; count--) {
-                    LayoutManager lm = (LayoutManager) childList.get(count);
-                    if (lm instanceof InlineLevelLayoutManager) {
-                        LayoutManager blm = new BidiLayoutManager
-                            ((BidiOverride) node, (InlineLayoutManager) lm);
-                        lms.add(blm);
-                    } else {
-                        lms.add(lm);
-                    }
-                }
+            if ( node instanceof BidiOverride ) {
+                lms.add(new BidiLayoutManager((BidiOverride) node));
             }
-            */
         }
     }
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageProvider.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageProvider.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageProvider.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageProvider.java Sun Feb 26 02:29:01 2012
@@ -335,6 +335,7 @@ public class PageProvider implements Con
         //Set unique key obtained from the AreaTreeHandler
         page.getPageViewport().setKey(areaTreeHandler.generatePageViewportKey());
         page.getPageViewport().setForeignAttributes(spm.getForeignAttributes());
+        page.getPageViewport().setWritingModeTraits(pageSeq);
         cachedPages.add(page);
         return page;
     }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java Sun Feb 26 02:29:01 2012
@@ -25,6 +25,7 @@ import org.apache.commons.logging.LogFac
 import org.apache.fop.area.AreaTreeHandler;
 import org.apache.fop.area.AreaTreeModel;
 import org.apache.fop.area.LineArea;
+import org.apache.fop.complexscripts.bidi.BidiResolver;
 import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.pagination.PageSequence;
 import org.apache.fop.fo.pagination.PageSequenceMaster;
@@ -78,8 +79,12 @@ public class PageSequenceLayoutManager e
     public void activateLayout() {
         initialize();
 
-        LineArea title = null;
+        // perform step 5.8 of refinement process (Unicode BIDI Processing)
+        if ( areaTreeHandler.isComplexScriptFeaturesEnabled() ) {
+            BidiResolver.resolveInlineDirectionality(getPageSequence());
+        }
 
+        LineArea title = null;
         if (getPageSequence().getTitleFO() != null) {
             try {
                 ContentLayoutManager clm = getLayoutManagerMaker().

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/AbstractGraphicsLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/AbstractGraphicsLayoutManager.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/AbstractGraphicsLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/AbstractGraphicsLayoutManager.java Sun Feb 26 02:29:01 2012
@@ -59,6 +59,7 @@ public abstract class AbstractGraphicsLa
         Dimension intrinsicSize = new Dimension(
                 fobj.getIntrinsicWidth(),
                 fobj.getIntrinsicHeight());
+        int bidiLevel = fobj.getBidiLevel();
 
         //TODO Investigate if the line-height property has to be taken into the calculation
         //somehow. There was some code here that hints in this direction but it was disabled.
@@ -67,6 +68,7 @@ public abstract class AbstractGraphicsLa
         Rectangle placement = imageLayout.getPlacement();
 
         CommonBorderPaddingBackground borderProps = fobj.getCommonBorderPaddingBackground();
+        setCommonBorderPaddingBackground(borderProps);
 
         //Determine extra BPD from borders and padding
         int beforeBPD = borderProps.getPadding(CommonBorderPaddingBackground.BEFORE, false, this);
@@ -75,30 +77,35 @@ public abstract class AbstractGraphicsLa
         placement.y += beforeBPD;
 
         //Determine extra IPD from borders and padding
-        int startIPD = borderProps.getPadding(CommonBorderPaddingBackground.START, false, this);
-        startIPD += borderProps.getBorderWidth(CommonBorderPaddingBackground.START, false);
-
-        placement.x += startIPD;
+        if ( ( bidiLevel == -1 ) || ( ( bidiLevel & 1 ) == 0 ) ) {
+            int startIPD = borderProps.getPadding(CommonBorderPaddingBackground.START, false, this);
+            startIPD += borderProps.getBorderWidth(CommonBorderPaddingBackground.START, false);
+            placement.x += startIPD;
+        } else {
+            int endIPD = borderProps.getPadding(CommonBorderPaddingBackground.END, false, this);
+            endIPD += borderProps.getBorderWidth(CommonBorderPaddingBackground.END, false);
+            placement.x += endIPD;
+        }
 
         Area viewportArea = getChildArea();
         TraitSetter.setProducerID(viewportArea, fobj.getId());
         transferForeignAttributes(viewportArea);
 
-        InlineViewport vp = new InlineViewport(viewportArea);
+        InlineViewport vp = new InlineViewport(viewportArea, bidiLevel);
         TraitSetter.addStructureTreeElement(vp, fobj.getStructureTreeElement());
         TraitSetter.setProducerID(vp, fobj.getId());
         vp.setIPD(imageLayout.getViewportSize().width);
         vp.setBPD(imageLayout.getViewportSize().height);
         vp.setContentPosition(placement);
         vp.setClip(imageLayout.isClipped());
-        vp.setOffset(0);
+        vp.setBlockProgressionOffset(0);
 
         // Common Border, Padding, and Background Properties
-        TraitSetter.addBorders(vp, fobj.getCommonBorderPaddingBackground()
+        TraitSetter.addBorders(vp, borderProps
                                 , false, false, false, false, this);
-        TraitSetter.addPadding(vp, fobj.getCommonBorderPaddingBackground()
+        TraitSetter.addPadding(vp, borderProps
                                 , false, false, false, false, this);
-        TraitSetter.addBackground(vp, fobj.getCommonBorderPaddingBackground(), this);
+        TraitSetter.addBackground(vp, borderProps, this);
 
         return vp;
     }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/AbstractPageNumberCitationLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/AbstractPageNumberCitationLayoutManager.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/AbstractPageNumberCitationLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/AbstractPageNumberCitationLayoutManager.java Sun Feb 26 02:29:01 2012
@@ -81,10 +81,7 @@ public abstract class AbstractPageNumber
     }
 
     /** {@inheritDoc} */
-    public InlineArea get(LayoutContext context) {
-        curArea = getPageNumberCitationInlineArea();
-        return curArea;
-    }
+    public abstract InlineArea get(LayoutContext context);
 
     /**
      * {@inheritDoc}
@@ -98,35 +95,6 @@ public abstract class AbstractPageNumber
     }
 
     /**
-     * If id can be resolved then simply return a text area, otherwise
-     * return a resolvable area
-     *
-     * @return a corresponding InlineArea
-     */
-    private InlineArea getPageNumberCitationInlineArea() {
-        PageViewport page = getPSLM().getFirstPVWithID(fobj.getRefId());
-        TextArea text;
-        if (page != null) {
-            String str = page.getPageNumberString();
-            // get page string from parent, build area
-            text = new TextArea();
-            int width = getStringWidth(str);
-            text.addWord(str, 0);
-            text.setIPD(width);
-            resolved = true;
-        } else {
-            resolved = false;
-            text = new UnresolvedPageNumber(fobj.getRefId(), font);
-            String str = "MMM"; // reserve three spaces for page number
-            int width = getStringWidth(str);
-            text.setIPD(width);
-        }
-        updateTextAreaTraits(text);
-
-        return text;
-    }
-
-    /**
      * Updates the traits for the generated text area.
      * @param text the text area
      */
@@ -152,5 +120,12 @@ public abstract class AbstractPageNumber
         return width;
     }
 
+    /**
+     * @return bidi level governing abstract page number citation
+     */
+    protected int getBidiLevel() {
+        return fobj.getBidiLevel();
+    }
+
 }
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/AlignmentContext.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/AlignmentContext.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/AlignmentContext.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/AlignmentContext.java Sun Feb 26 02:29:01 2012
@@ -24,6 +24,7 @@ import org.apache.fop.datatypes.LengthBa
 import org.apache.fop.datatypes.SimplePercentBaseContext;
 import org.apache.fop.fo.Constants;
 import org.apache.fop.fonts.Font;
+import org.apache.fop.traits.WritingMode;
 
 /**
  * The alignment context is carried within a LayoutContext and as
@@ -173,7 +174,7 @@ public class AlignmentContext implements
      * @param lineHeight the computed value of the lineHeight property
      * @param writingMode the current writing mode
      */
-    AlignmentContext(Font font, int lineHeight, int writingMode) {
+    AlignmentContext(Font font, int lineHeight, WritingMode writingMode) {
         this.areaHeight = font.getAscender() - font.getDescender();
         this.lineHeight = lineHeight;
         this.xHeight = font.getXHeight();
@@ -299,6 +300,14 @@ public class AlignmentContext implements
     }
 
     /**
+     * Return the writing mode.
+     * @return the writing mode
+     */
+/*    public WritingMode getWritingMode() {
+        return scaledBaselineTable.getWritingMode();
+    }*/
+
+    /**
      * Calculates the baseline shift value based on the baseline-shift
      * property value.
      * @param baselineShift the baseline shift property value
@@ -504,6 +513,10 @@ public class AlignmentContext implements
                     && parentAlignmentContext.usesInitialBaselineTable());
     }
 
+    /* private boolean isHorizontalWritingMode() {
+        return (getWritingMode() == WritingMode.LR_TB || getWritingMode() == WritingMode.RL_TB);
+    }*/
+
     /** {@inheritDoc} */
     public String toString() {
         StringBuffer sb = new StringBuffer(64);

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/BasicLinkLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/BasicLinkLayoutManager.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/BasicLinkLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/BasicLinkLayoutManager.java Sun Feb 26 02:29:01 2012
@@ -69,6 +69,12 @@ public class BasicLinkLayoutManager exte
             res.resolveIDRef(idref, pslm.getFirstPVWithID(idref));
             if (!res.isResolved()) {
                 pslm.addUnresolvedArea(idref, res);
+                if ( area instanceof BasicLinkArea ) {
+                    // establish back-pointer from BasicLinkArea to LinkResolver to
+                    // handle inline area unflattening during line bidi reordering;
+                    // needed to create internal link trait on synthesized basic link area
+                    ((BasicLinkArea)area).setResolver(res);
+                }
             }
         } else if (fobj.hasExternalDestination()) {
             String url = URISpecification.getURL(fobj.getExternalDestination());

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/BidiLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/BidiLayoutManager.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/BidiLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/BidiLayoutManager.java Sun Feb 26 02:29:01 2012
@@ -19,56 +19,19 @@
 
 package org.apache.fop.layoutmgr.inline;
 
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.fop.area.inline.InlineArea;
 import org.apache.fop.fo.flow.BidiOverride;
 
-
 /**
- * If this bidi has a different writing mode direction
- * ltr or rtl than its parent writing mode then this
- * reverses the inline areas (at the character level).
+ * Layout manager for fo:bidi-override.
  */
-public class BidiLayoutManager extends LeafNodeLayoutManager {
-
-    private List children;
+public class BidiLayoutManager extends InlineLayoutManager {
 
     /**
      * Construct bidi layout manager.
-     * @param node bidi override FO
-     * @param cLM parent layout manager
+     * @param node an BidiOverride FONode
      */
-    public BidiLayoutManager(BidiOverride node, InlineLayoutManager cLM) {
+    public BidiLayoutManager(BidiOverride node) {
         super(node);
-        setParent(cLM);
-        children = new ArrayList();
-/*
-        for (int count = cLM.size() - 1; count >= 0; count--) {
-            InlineArea ia = cLM.get(count);
-            if (ia instanceof Word) {
-                // reverse word
-                Word word = (Word) ia;
-                StringBuffer sb = new StringBuffer(word.getWord());
-                word.setWord(sb.reverse().toString());
-            }
-            children.add(ia);
-        }
-*/
-    }
-
-    /** @return number of children */
-    public int size() {
-        return children.size();
-    }
-
-    /**
-     * @param index of child inline area
-     * @return a child inline area
-     */
-    public InlineArea get(int index) {
-        return (InlineArea) children.get(index);
     }
 
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java Sun Feb 26 02:29:01 2012
@@ -77,13 +77,18 @@ public class CharacterLayoutManager exte
     private TextArea getCharacterInlineArea(Character node) {
         TextArea text = new TextArea();
         char ch = node.getCharacter();
+        int ipd = font.getCharWidth(ch);
+        int blockProgressionOffset = 0;
+        int level = node.getBidiLevel();
         if (CharUtilities.isAnySpace(ch)) {
             // add space unless it's zero-width:
             if (!CharUtilities.isZeroWidthSpace(ch)) {
-                text.addSpace(ch, 0, CharUtilities.isAdjustableSpace(ch));
+                text.addSpace(ch, ipd, CharUtilities.isAdjustableSpace(ch),
+                              blockProgressionOffset, level);
             }
         } else {
-            text.addWord(String.valueOf(ch), 0);
+            int[] levels = ( level >= 0 ) ? new int[] {level} : null;
+            text.addWord(String.valueOf(ch), ipd, null, levels, null, blockProgressionOffset);
         }
         TraitSetter.setProducerID(text, node.getId());
         TraitSetter.addTextDecoration(text, node.getTextDecoration());
@@ -105,9 +110,8 @@ public class CharacterLayoutManager exte
 
         Character fobj = (Character)this.fobj;
 
-        ipd = MinOptMax.getInstance(font.getCharWidth(fobj.getCharacter()));
+        ipd = MinOptMax.getInstance(curArea.getIPD());
 
-        curArea.setIPD(ipd.getOpt());
         curArea.setBPD(font.getAscender() - font.getDescender());
 
         TraitSetter.addFontTraits(curArea, font);
@@ -227,4 +231,3 @@ public class CharacterLayoutManager exte
     }
 
 }
-

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java Sun Feb 26 02:29:01 2012
@@ -207,7 +207,7 @@ public class InlineLayoutManager extends
         InlineArea area;
         if (isInline) {
             area = createInlineParent();
-            area.setOffset(0);
+            area.setBlockProgressionOffset(0);
         } else {
             area = new InlineBlockParent();
         }
@@ -482,12 +482,12 @@ public class InlineLayoutManager extends
                                         || lastLM instanceof InlineLevelLayoutManager);
         parent.setBPD(alignmentContext.getHeight());
         if (parent instanceof InlineParent) {
-            parent.setOffset(alignmentContext.getOffset());
+            parent.setBlockProgressionOffset(alignmentContext.getOffset());
         } else if (parent instanceof InlineBlockParent) {
             // All inline elements are positioned by the renderers relative to
             // the before edge of their content rectangle
             if (borderProps != null) {
-                parent.setOffset(borderProps.getPaddingBefore(false, this)
+                parent.setBlockProgressionOffset(borderProps.getPaddingBefore(false, this)
                                 + borderProps.getBorderBeforeWidth(false));
             }
         }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java Sun Feb 26 02:29:01 2012
@@ -180,6 +180,10 @@ public abstract class InlineStackingLayo
                 //getLogger().debug("Add leading space: " + iAdjust);
                 Space ls = new Space();
                 ls.setIPD(iAdjust);
+                int level = parentArea.getBidiLevel();
+                if ( level >= 0 ) {
+                    ls.setBidiLevel ( level );
+                }
                 parentArea.addChildArea(ls);
             }
         }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java Sun Feb 26 02:29:01 2012
@@ -115,7 +115,7 @@ public class LeaderLayoutManager extends
 
     private InlineArea getLeaderInlineArea(LayoutContext context) {
         InlineArea leaderArea = null;
-
+        int level = fobj.getBidiLevel();
         if (fobj.getLeaderPattern() == EN_RULE) {
             if (fobj.getRuleStyle() != EN_NONE) {
                 org.apache.fop.area.inline.Leader leader
@@ -125,28 +125,41 @@ public class LeaderLayoutManager extends
                 leaderArea = leader;
             } else {
                 leaderArea = new Space();
+                if ( level >= 0 ) {
+                    leaderArea.setBidiLevel ( level );
+                }
             }
             leaderArea.setBPD(fobj.getRuleThickness().getValue(this));
             leaderArea.addTrait(Trait.COLOR, fobj.getColor());
+            if ( level >= 0 ) {
+                leaderArea.setBidiLevel ( level );
+            }
         } else if (fobj.getLeaderPattern() == EN_SPACE) {
             leaderArea = new Space();
             leaderArea.setBPD(fobj.getRuleThickness().getValue(this));
+            if ( level >= 0 ) {
+                leaderArea.setBidiLevel ( level );
+            }
         } else if (fobj.getLeaderPattern() == EN_DOTS) {
             TextArea t = new TextArea();
             char dot = '.'; // userAgent.getLeaderDotCharacter();
-
             int width = font.getCharWidth(dot);
-            t.addWord("" + dot, 0);
+            int[] levels = ( level < 0 ) ? null : new int[] {level};
+            t.addWord("" + dot, width, null, levels, null, 0);
             t.setIPD(width);
             t.setBPD(width);
             t.setBaselineOffset(width);
             TraitSetter.addFontTraits(t, font);
             t.addTrait(Trait.COLOR, fobj.getColor());
             Space spacer = null;
-            if (fobj.getLeaderPatternWidth().getValue(this) > width) {
+            int widthLeaderPattern = fobj.getLeaderPatternWidth().getValue(this);
+            if (widthLeaderPattern > width) {
                 spacer = new Space();
-                spacer.setIPD(fobj.getLeaderPatternWidth().getValue(this) - width);
-                width = fobj.getLeaderPatternWidth().getValue(this);
+                spacer.setIPD(widthLeaderPattern - width);
+                if ( level >= 0 ) {
+                    spacer.setBidiLevel ( level );
+                }
+                width = widthLeaderPattern;
             }
             FilledArea fa = new FilledArea();
             fa.setUnitWidth(width);
@@ -155,7 +168,6 @@ public class LeaderLayoutManager extends
                 fa.addChildArea(spacer);
             }
             fa.setBPD(t.getBPD());
-
             leaderArea = fa;
         } else if (fobj.getLeaderPattern() == EN_USECONTENT) {
             if (fobj.getChildNodes() == null) {
@@ -188,6 +200,9 @@ public class LeaderLayoutManager extends
                 if (fobj.getLeaderPatternWidth().getValue(this) > width) {
                     spacer = new Space();
                     spacer.setIPD(fobj.getLeaderPatternWidth().getValue(this) - width);
+                    if ( level >= 0 ) {
+                        spacer.setBidiLevel ( level );
+                    }
                     width = fobj.getLeaderPatternWidth().getValue(this);
                 }
                 fa.setUnitWidth(width);
@@ -199,6 +214,7 @@ public class LeaderLayoutManager extends
                 //Content collapsed to nothing, so use a space
                 leaderArea = new Space();
                 leaderArea.setBPD(fobj.getRuleThickness().getValue(this));
+                leaderArea.setBidiLevel ( fobj.getBidiLevelRecursive() );
             }
         }
         TraitSetter.setProducerID(leaderArea, fobj.getId());

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/LeafNodeLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/LeafNodeLayoutManager.java?rev=1293736&r1=1293735&r2=1293736&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/LeafNodeLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/LeafNodeLayoutManager.java Sun Feb 26 02:29:01 2012
@@ -224,7 +224,7 @@ public abstract class LeafNodeLayoutMana
      * @param context the layout context used for adding the area
      */
     protected void offsetArea(InlineArea area, LayoutContext context) {
-        area.setOffset(alignmentContext.getOffset());
+        area.setBlockProgressionOffset(alignmentContext.getOffset());
     }
 
     /**



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


Mime
View raw message