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 vh...@apache.org on 2014/03/17 10:31:20 UTC

svn commit: r1578276 [9/14] - in /xmlgraphics/fop/branches/Temp_WhitespaceManagement: ./ lib/ src/codegen/fonts/ src/java/org/apache/fop/ src/java/org/apache/fop/afp/ src/java/org/apache/fop/afp/fonts/ src/java/org/apache/fop/afp/goca/ src/java/org/apa...

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java Mon Mar 17 09:31:13 2014
@@ -30,12 +30,11 @@ import org.apache.commons.logging.LogFac
 
 import org.apache.fop.area.Trait;
 import org.apache.fop.area.inline.TextArea;
-import org.apache.fop.complexscripts.fonts.GlyphPositioningTable;
-import org.apache.fop.complexscripts.util.CharScript;
 import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.FOText;
 import org.apache.fop.fonts.Font;
 import org.apache.fop.fonts.FontSelector;
+import org.apache.fop.fonts.GlyphMapping;
 import org.apache.fop.layoutmgr.InlineKnuthSequence;
 import org.apache.fop.layoutmgr.KnuthBox;
 import org.apache.fop.layoutmgr.KnuthElement;
@@ -65,91 +64,15 @@ public class TextLayoutManager extends L
     private static final int SOFT_HYPHEN_PENALTY = 1;
 
     /**
-     * Store information about each potential text area.
-     * Index of character which ends the area, IPD of area, including
-     * any word-space and letter-space.
-     * Number of word-spaces?
-     */
-    private class AreaInfo {
-
-        private final int startIndex;
-        private final int breakIndex;
-        private int wordCharLength;
-        private final int wordSpaceCount;
-        private int letterSpaceCount;
-        private MinOptMax areaIPD;
-        private final boolean isHyphenated;
-        private final boolean isSpace;
-        private boolean breakOppAfter;
-        private final Font font;
-        private final int level;
-        private final int[][] gposAdjustments;
-
-        AreaInfo(
-            int startIndex, int breakIndex, int wordSpaceCount, int letterSpaceCount,
-             MinOptMax areaIPD, boolean isHyphenated, boolean isSpace, boolean breakOppAfter,
-             Font font, int level, int[][] gposAdjustments) {
-            assert startIndex <= breakIndex;
-            this.startIndex = startIndex;
-            this.breakIndex = breakIndex;
-            this.wordCharLength = -1;
-            this.wordSpaceCount = wordSpaceCount;
-            this.letterSpaceCount = letterSpaceCount;
-            this.areaIPD = areaIPD;
-            this.isHyphenated = isHyphenated;
-            this.isSpace = isSpace;
-            this.breakOppAfter = breakOppAfter;
-            this.font = font;
-            this.level = level;
-            this.gposAdjustments = gposAdjustments;
-        }
-
-        /**
-         * Obtain number of 'characters' contained in word. If word
-         * is mapped, then this number may be less than or greater than the
-         * original length (breakIndex - startIndex). We compute and
-         * memoize thius length upon first invocation of this method.
-         */
-        private int getWordLength() {
-            if (wordCharLength == -1) {
-                if (foText.hasMapping(startIndex, breakIndex)) {
-                    wordCharLength = foText.getMapping(startIndex, breakIndex).length();
-                } else {
-                    assert breakIndex >= startIndex;
-                    wordCharLength = breakIndex - startIndex;
-                }
-            }
-            return wordCharLength;
-        }
-
-        private void addToAreaIPD(MinOptMax idp) {
-            areaIPD = areaIPD.plus(idp);
-        }
-
-        public String toString() {
-            return super.toString() + "{"
-                    + "interval = [" + startIndex + "," + breakIndex + "]"
-                    + ", isSpace = " + isSpace
-                    + ", level = " + level
-                    + ", areaIPD = " + areaIPD
-                    + ", letterSpaceCount = " + letterSpaceCount
-                    + ", wordSpaceCount = " + wordSpaceCount
-                    + ", isHyphenated = " + isHyphenated
-                    + ", font = " + font
-                    + "}";
-        }
-    }
-
-    /**
      * this class stores information about changes in vecAreaInfo which are not yet applied
      */
     private final class PendingChange {
 
-        private final AreaInfo areaInfo;
+        private final GlyphMapping mapping;
         private final int index;
 
-        private PendingChange(final AreaInfo areaInfo, final int index) {
-            this.areaInfo = areaInfo;
+        private PendingChange(final GlyphMapping mapping, final int index) {
+            this.mapping = mapping;
             this.index = index;
         }
     }
@@ -160,7 +83,7 @@ public class TextLayoutManager extends L
     private static final Log LOG = LogFactory.getLog(TextLayoutManager.class);
 
     // Hold all possible breaks for the text in this LM's FO.
-    private final List areaInfos;
+    private final List<GlyphMapping> mappings;
 
     /** Non-space characters on which we can end a line. */
     private static final String BREAK_CHARS = "-/";
@@ -216,7 +139,7 @@ public class TextLayoutManager extends L
     public TextLayoutManager(FOText node) {
         foText = node;
         letterSpaceAdjustArray = new MinOptMax[node.length() + 1];
-        areaInfos = new ArrayList();
+        mappings = new ArrayList<GlyphMapping>();
     }
 
     private KnuthPenalty makeZeroWidthPenalty(int penaltyValue) {
@@ -274,61 +197,61 @@ public class TextLayoutManager extends L
     public void addAreas(final PositionIterator posIter, final LayoutContext context) {
 
         // Add word areas
-        AreaInfo areaInfo;
+        GlyphMapping mapping;
         int wordSpaceCount = 0;
         int letterSpaceCount = 0;
-        int firstAreaInfoIndex = -1;
-        int lastAreaInfoIndex = 0;
+        int firstMappingIndex = -1;
+        int lastMappingIndex = 0;
         MinOptMax realWidth = MinOptMax.ZERO;
 
         /* On first area created, add any leading space.
          * Calculate word-space stretch value.
          */
-        AreaInfo lastAreaInfo = null;
+        GlyphMapping lastMapping = null;
         while (posIter.hasNext()) {
             final LeafPosition tbpNext = (LeafPosition) posIter.next();
             if (tbpNext == null) {
                 continue; //Ignore elements without Positions
             }
             if (tbpNext.getLeafPos() != -1) {
-                areaInfo = (AreaInfo) areaInfos.get(tbpNext.getLeafPos());
-                if (lastAreaInfo == null
-                    || (areaInfo.font != lastAreaInfo.font)
-                    || (areaInfo.level != lastAreaInfo.level)) {
-                    if (lastAreaInfo != null) {
-                        addAreaInfoAreas(lastAreaInfo, wordSpaceCount,
-                                letterSpaceCount, firstAreaInfoIndex,
-                                lastAreaInfoIndex, realWidth, context);
+                mapping = mappings.get(tbpNext.getLeafPos());
+                if (lastMapping == null
+                    || (mapping.font != lastMapping.font)
+                    || (mapping.level != lastMapping.level)) {
+                    if (lastMapping != null) {
+                        addMappingAreas(lastMapping, wordSpaceCount,
+                                letterSpaceCount, firstMappingIndex,
+                                lastMappingIndex, realWidth, context);
                     }
-                    firstAreaInfoIndex = tbpNext.getLeafPos();
+                    firstMappingIndex = tbpNext.getLeafPos();
                     wordSpaceCount = 0;
                     letterSpaceCount = 0;
                     realWidth = MinOptMax.ZERO;
                 }
-                wordSpaceCount += areaInfo.wordSpaceCount;
-                letterSpaceCount += areaInfo.letterSpaceCount;
-                realWidth = realWidth.plus(areaInfo.areaIPD);
-                lastAreaInfoIndex = tbpNext.getLeafPos();
-                lastAreaInfo = areaInfo;
+                wordSpaceCount += mapping.wordSpaceCount;
+                letterSpaceCount += mapping.letterSpaceCount;
+                realWidth = realWidth.plus(mapping.areaIPD);
+                lastMappingIndex = tbpNext.getLeafPos();
+                lastMapping = mapping;
             }
         }
-        if (lastAreaInfo != null) {
-            addAreaInfoAreas(lastAreaInfo, wordSpaceCount, letterSpaceCount, firstAreaInfoIndex,
-                    lastAreaInfoIndex, realWidth, context);
+        if (lastMapping != null) {
+            addMappingAreas(lastMapping, wordSpaceCount, letterSpaceCount, firstMappingIndex,
+                    lastMappingIndex, realWidth, context);
         }
 
     }
 
-    private void addAreaInfoAreas(AreaInfo areaInfo, int wordSpaceCount, int letterSpaceCount,
-                                  int firstAreaInfoIndex, int lastAreaInfoIndex,
+    private void addMappingAreas(GlyphMapping mapping, int wordSpaceCount, int letterSpaceCount,
+                                  int firstMappingIndex, int lastMappingIndex,
                                   MinOptMax realWidth, LayoutContext context) {
 
         // TODO: These two statements (if, for) were like this before my recent
-        // changes. However, it seems as if they should use the AreaInfo from
-        // firstAreaInfoIndex.. lastAreaInfoIndex rather than just the last areaInfo.
+        // changes. However, it seems as if they should use the GlyphMapping from
+        // firstMappingIndex.. lastMappingIndex rather than just the last mapping.
         // This needs to be checked.
-        int textLength = areaInfo.getWordLength();
-        if (areaInfo.letterSpaceCount == textLength && !areaInfo.isHyphenated
+        int textLength = mapping.getWordLength();
+        if (mapping.letterSpaceCount == textLength && !mapping.isHyphenated
                 && context.isLastArea()) {
             // the line ends at a character like "/" or "-";
             // remove the letter space after the last character
@@ -336,7 +259,7 @@ public class TextLayoutManager extends L
             letterSpaceCount--;
         }
 
-        for (int i = areaInfo.startIndex; i < areaInfo.breakIndex; i++) {
+        for (int i = mapping.startIndex; i < mapping.endIndex; i++) {
             MinOptMax letterSpaceAdjustment = letterSpaceAdjustArray[i + 1];
             if (letterSpaceAdjustment != null && letterSpaceAdjustment.isElastic()) {
                 letterSpaceCount++;
@@ -344,7 +267,7 @@ public class TextLayoutManager extends L
         }
 
         // add hyphenation character if the last word is hyphenated
-        if (context.isLastArea() && areaInfo.isHyphenated) {
+        if (context.isLastArea() && mapping.isHyphenated) {
             realWidth = realWidth.plus(hyphIPD);
         }
 
@@ -385,8 +308,8 @@ public class TextLayoutManager extends L
             totalAdjust = difference;
         }
 
-        TextArea textArea = new TextAreaBuilder(realWidth, totalAdjust, context, firstAreaInfoIndex,
-                lastAreaInfoIndex, context.isLastArea(), areaInfo.font).build();
+        TextArea textArea = new TextAreaBuilder(realWidth, totalAdjust, context, firstMappingIndex,
+                lastMappingIndex, context.isLastArea(), mapping.font).build();
 
         // wordSpaceDim is computed in relation to wordSpaceIPD.opt
         // but the renderer needs to know the adjustment in relation
@@ -417,15 +340,15 @@ public class TextLayoutManager extends L
         private final MinOptMax width;          // content ipd
         private final int adjust;               // content ipd adjustment
         private final LayoutContext context;    // layout context
-        private final int firstIndex;           // index of first AreaInfo
-        private final int lastIndex;            // index of last AreaInfo
+        private final int firstIndex;           // index of first GlyphMapping
+        private final int lastIndex;            // index of last GlyphMapping
         private final boolean isLastArea;       // true if last inline area in line area
         private final Font font;                // applicable font
 
         // other, non-constructor state
         private TextArea textArea;              // text area being constructed
         private int blockProgressionDimension;  // calculated bpd
-        private AreaInfo areaInfo;              // current area info when iterating over words
+        private GlyphMapping mapping;           // current mapping when iterating over words
         private StringBuffer wordChars;         // current word's character buffer
         private int[] letterSpaceAdjust;        // current word's letter space adjustments
         private int letterSpaceAdjustIndex;     // last written letter space adjustment index
@@ -442,8 +365,8 @@ public class TextLayoutManager extends L
          * @param width      the MinOptMax width of the content
          * @param adjust     the total ipd adjustment with respect to the optimal width
          * @param context    the layout context
-         * @param firstIndex the index of the first AreaInfo used for the TextArea
-         * @param lastIndex  the index of the last AreaInfo used for the TextArea
+         * @param firstIndex the index of the first GlyphMapping used for the TextArea
+         * @param lastIndex  the index of the last GlyphMapping used for the TextArea
          * @param isLastArea is this TextArea the last in a line?
          * @param font       Font to be used in this particular TextArea
          */
@@ -516,30 +439,30 @@ public class TextLayoutManager extends L
          * Sets the text of the TextArea, split into words and spaces.
          */
         private void setText() {
-            int areaInfoIndex = -1;
+            int mappingIndex = -1;
             int wordCharLength = 0;
             for (int wordIndex = firstIndex; wordIndex <= lastIndex; wordIndex++) {
-                areaInfo = getAreaInfo(wordIndex);
-                if (areaInfo.isSpace) {
+                mapping = getGlyphMapping(wordIndex);
+                if (mapping.isSpace) {
                     addSpaces();
                 } else {
-                    // areaInfo stores information about a word fragment
-                    if (areaInfoIndex == -1) {
+                    // mapping stores information about a word fragment
+                    if (mappingIndex == -1) {
                         // here starts a new word
-                        areaInfoIndex = wordIndex;
+                        mappingIndex = wordIndex;
                         wordCharLength = 0;
                     }
-                    wordCharLength += areaInfo.getWordLength();
+                    wordCharLength += mapping.getWordLength();
                     if (isWordEnd(wordIndex)) {
-                        addWord(areaInfoIndex, wordIndex, wordCharLength);
-                        areaInfoIndex = -1;
+                        addWord(mappingIndex, wordIndex, wordCharLength);
+                        mappingIndex = -1;
                     }
                 }
             }
         }
 
-        private boolean isWordEnd(int areaInfoIndex) {
-            return areaInfoIndex == lastIndex || getAreaInfo(areaInfoIndex + 1).isSpace;
+        private boolean isWordEnd(int mappingIndex) {
+            return mappingIndex == lastIndex || getGlyphMapping(mappingIndex + 1).isSpace;
         }
 
         /**
@@ -564,10 +487,10 @@ public class TextLayoutManager extends L
             // iterate over word's fragments, adding word chars (with bidi
             // levels), letter space adjustments, and glyph position adjustments
             for (int i = startIndex; i <= endIndex; i++) {
-                AreaInfo wordAreaInfo = getAreaInfo(i);
-                addWordChars(wordAreaInfo);
-                addLetterAdjust(wordAreaInfo);
-                if (addGlyphPositionAdjustments(wordAreaInfo)) {
+                GlyphMapping wordMapping = getGlyphMapping(i);
+                addWordChars(wordMapping);
+                addLetterAdjust(wordMapping);
+                if (addGlyphPositionAdjustments(wordMapping)) {
                     gposAdjusted = true;
                 }
             }
@@ -617,7 +540,7 @@ public class TextLayoutManager extends L
         }
 
         private boolean isHyphenated(int endIndex) {
-            return isLastArea && endIndex == lastIndex && areaInfo.isHyphenated;
+            return isLastArea && endIndex == lastIndex && mapping.isHyphenated;
         }
 
         private void addHyphenationChar() {
@@ -632,21 +555,54 @@ public class TextLayoutManager extends L
          * (1) concatenate (possibly mapped) word characters to word character buffer;
          * (2) concatenante (possibly mapped) word bidi levels to levels buffer;
          * (3) update word's IPD with optimal IPD of fragment.
-         * @param wordAreaInfo fragment info
+         * @param wordMapping fragment info
          */
-        private void addWordChars(AreaInfo wordAreaInfo) {
-            int s = wordAreaInfo.startIndex;
-            int e = wordAreaInfo.breakIndex;
-            if (foText.hasMapping(s, e)) {
-                wordChars.append(foText.getMapping(s, e));
-                addWordLevels(foText.getMappingBidiLevels(s, e));
+        private void addWordChars(GlyphMapping wordMapping) {
+            int s = wordMapping.startIndex;
+            int e = wordMapping.endIndex;
+            if (wordMapping.mapping != null) {
+                wordChars.append(wordMapping.mapping);
+                addWordLevels(getMappingBidiLevels(wordMapping));
             } else {
                 for (int i = s; i < e; i++) {
                     wordChars.append(foText.charAt(i));
                 }
                 addWordLevels(foText.getBidiLevels(s, e));
             }
-            wordIPD += wordAreaInfo.areaIPD.getOpt();
+            wordIPD += wordMapping.areaIPD.getOpt();
+        }
+
+        /**
+         * Obtain bidirectional levels of mapping of characters over specific interval.
+         * @param start index in character buffer
+         * @param end index in character buffer
+         * @return a (possibly empty) array of bidi levels or null
+         * in case no bidi levels have been assigned
+         */
+        private int[] getMappingBidiLevels(GlyphMapping mapping) {
+            if (mapping.mapping != null) {
+                int nc = mapping.endIndex - mapping.startIndex;
+                int nm = mapping.mapping.length();
+                int[] la = foText.getBidiLevels(mapping.startIndex, mapping.endIndex);
+                if (la == null) {
+                    return null;
+                } else if (nm == nc) { // mapping is same length as mapped range
+                    return la;
+                } else if (nm > nc) { // mapping is longer than mapped range
+                    int[] ma = new int[nm];
+                    System.arraycopy(la, 0, ma, 0, la.length);
+                    for (int i = la.length, n = ma.length, l = (i > 0) ? la[i - 1] : 0; i < n; i++) {
+                        ma[i] = l;
+                    }
+                    return ma;
+                } else { // mapping is shorter than mapped range
+                    int[] ma = new int[nm];
+                    System.arraycopy(la, 0, ma, 0, ma.length);
+                    return ma;
+                }
+            } else {
+                return foText.getBidiLevels(mapping.startIndex, mapping.endIndex);
+            }
         }
 
         /**
@@ -672,16 +628,16 @@ public class TextLayoutManager extends L
         /**
          * Given a word area info associated with a word fragment,
          * concatenate letter space adjustments for each (possibly mapped) character.
-         * @param wordAreaInfo fragment info
+         * @param wordMapping fragment info
          */
-        private void addLetterAdjust(AreaInfo wordAreaInfo) {
-            int letterSpaceCount = wordAreaInfo.letterSpaceCount;
-            int wordLength = wordAreaInfo.getWordLength();
+        private void addLetterAdjust(GlyphMapping wordMapping) {
+            int letterSpaceCount = wordMapping.letterSpaceCount;
+            int wordLength = wordMapping.getWordLength();
             int taAdjust = textArea.getTextLetterSpaceAdjust();
             for (int i = 0, n = wordLength; i < n; i++) {
                 int j = letterSpaceAdjustIndex + i;
                 if (j > 0) {
-                    int k = wordAreaInfo.startIndex + i;
+                    int k = wordMapping.startIndex + i;
                     MinOptMax adj = (k < letterSpaceAdjustArray.length)
                         ? letterSpaceAdjustArray [ k ] : null;
                     letterSpaceAdjust [ j ] = (adj == null) ? 0 : adj.getOpt();
@@ -697,14 +653,14 @@ public class TextLayoutManager extends L
         /**
          * Given a word area info associated with a word fragment,
          * concatenate glyph position adjustments for each (possibly mapped) character.
-         * @param wordAreaInfo fragment info
+         * @param wordMapping fragment info
          * @return true if an adjustment was non-zero
          */
-        private boolean addGlyphPositionAdjustments(AreaInfo wordAreaInfo) {
+        private boolean addGlyphPositionAdjustments(GlyphMapping wordMapping) {
             boolean adjusted = false;
-            int[][] gpa = wordAreaInfo.gposAdjustments;
+            int[][] gpa = wordMapping.gposAdjustments;
             int numAdjusts = (gpa != null) ? gpa.length : 0;
-            int wordLength = wordAreaInfo.getWordLength();
+            int wordLength = wordMapping.getWordLength();
             if (numAdjusts > 0) {
                 int need = gposAdjustmentsIndex + numAdjusts;
                 if (need <= gposAdjustments.length) {
@@ -733,7 +689,7 @@ public class TextLayoutManager extends L
         }
 
         /**
-         * The <code>AreaInfo</code> stores information about spaces.
+         * The <code>GlyphMapping</code> stores information about spaces.
          * <p/>
          * Add the spaces - except zero-width spaces - to the TextArea.
          */
@@ -743,16 +699,16 @@ public class TextLayoutManager extends L
             // divide the area info's allocated IPD evenly among the
             // non-zero-width space characters
             int numZeroWidthSpaces = 0;
-            for (int i = areaInfo.startIndex; i < areaInfo.breakIndex; i++) {
+            for (int i = mapping.startIndex; i < mapping.endIndex; i++) {
                 char spaceChar = foText.charAt(i);
                 if (CharUtilities.isZeroWidthSpace(spaceChar)) {
                     numZeroWidthSpaces++;
                 }
             }
-            int numSpaces = areaInfo.breakIndex - areaInfo.startIndex - numZeroWidthSpaces;
-            int spaceIPD = areaInfo.areaIPD.getOpt() / ((numSpaces > 0) ? numSpaces : 1);
+            int numSpaces = mapping.endIndex - mapping.startIndex - numZeroWidthSpaces;
+            int spaceIPD = mapping.areaIPD.getOpt() / ((numSpaces > 0) ? numSpaces : 1);
             // add space area children, one for each non-zero-width space character
-            for (int i = areaInfo.startIndex; i < areaInfo.breakIndex; i++) {
+            for (int i = mapping.startIndex; i < mapping.endIndex; i++) {
                 char spaceChar = foText.charAt(i);
                 int level = foText.bidiLevelAt(i);
                 if (!CharUtilities.isZeroWidthSpace(spaceChar)) {
@@ -766,39 +722,20 @@ public class TextLayoutManager extends L
 
     }
 
-    private void addAreaInfo(AreaInfo ai) {
-        addAreaInfo(areaInfos.size(), ai);
-    }
-
-    private void addAreaInfo(int index, AreaInfo ai) {
-        areaInfos.add(index, ai);
+    private void addGlyphMapping(GlyphMapping mapping) {
+        addGlyphMapping(mappings.size(), mapping);
     }
 
-    private void removeAreaInfo(int index) {
-        areaInfos.remove(index);
+    private void addGlyphMapping(int index, GlyphMapping mapping) {
+        mappings.add(index, mapping);
     }
 
-    private AreaInfo getAreaInfo(int index) {
-        return (AreaInfo) areaInfos.get(index);
+    private void removeGlyphMapping(int index) {
+        mappings.remove(index);
     }
 
-    private void addToLetterAdjust(int index, int width) {
-        if (letterSpaceAdjustArray[index] == null) {
-            letterSpaceAdjustArray[index] = MinOptMax.getInstance(width);
-        } else {
-            letterSpaceAdjustArray[index] = letterSpaceAdjustArray[index].plus(width);
-        }
-    }
-
-    /**
-     * Indicates whether a character is a space in terms of this layout manager.
-     * @param ch the character
-     * @return true if it's a space
-     */
-    private static boolean isSpace(final char ch) {
-        return ch == CharUtilities.SPACE
-                || CharUtilities.isNonBreakableSpace(ch)
-                || CharUtilities.isFixedWidthSpace(ch);
+    private GlyphMapping getGlyphMapping(int index) {
+        return mappings.get(index);
     }
 
     /** {@inheritDoc} */
@@ -810,8 +747,8 @@ public class TextLayoutManager extends L
 
         final List returnList = new LinkedList();
         KnuthSequence sequence = new InlineKnuthSequence();
-        AreaInfo areaInfo = null;
-        AreaInfo prevAreaInfo = null;
+        GlyphMapping mapping = null;
+        GlyphMapping prevMapping = null;
         returnList.add(sequence);
 
         if (LOG.isDebugEnabled()) {
@@ -857,24 +794,24 @@ public class TextLayoutManager extends L
             }
             if (inWord) {
                 if (breakOpportunity
-                     || TextLayoutManager.isSpace(ch)
+                     || GlyphMapping.isSpace(ch)
                      || CharUtilities.isExplicitBreak(ch)
                      || ((prevLevel != -1) && (level != prevLevel))) {
                     // this.foText.charAt(lastIndex) == CharUtilities.SOFT_HYPHEN
-                    prevAreaInfo = processWord(alignment, sequence, prevAreaInfo, ch,
+                    prevMapping = processWord(alignment, sequence, prevMapping, ch,
                             breakOpportunity, true, prevLevel);
                 }
             } else if (inWhitespace) {
                 if (ch != CharUtilities.SPACE || breakOpportunity) {
-                    prevAreaInfo = processWhitespace(alignment, sequence,
+                    prevMapping = processWhitespace(alignment, sequence,
                                                      breakOpportunity, prevLevel);
                 }
             } else {
-                if (areaInfo != null) {
-                    prevAreaInfo = areaInfo;
-                    processLeftoverAreaInfo(alignment, sequence, areaInfo,
+                if (mapping != null) {
+                    prevMapping = mapping;
+                    processLeftoverGlyphMapping(alignment, sequence, mapping,
                             ch == CharUtilities.SPACE || breakOpportunity);
-                    areaInfo = null;
+                    mapping = null;
                 }
                 if (breakAction == LineBreakStatus.EXPLICIT_BREAK) {
                     sequence = processLinebreak(returnList, sequence);
@@ -888,15 +825,15 @@ public class TextLayoutManager extends L
                         this.foText, this);
                 font.mapChar(ch);
                 // preserved space or non-breaking space:
-                // create the AreaInfo object
-                areaInfo = new AreaInfo(nextStart, nextStart + 1, 1, 0, wordSpaceIPD, false, true,
+                // create the GlyphMapping object
+                mapping = new GlyphMapping(nextStart, nextStart + 1, 1, 0, wordSpaceIPD, false, true,
                                         breakOpportunity, spaceFont, level, null);
                 thisStart = nextStart + 1;
             } else if (CharUtilities.isFixedWidthSpace(ch) || CharUtilities.isZeroWidthSpace(ch)) {
-                // create the AreaInfo object
+                // create the GlyphMapping object
                 Font font = FontSelector.selectFontForCharacterInText(ch, foText, this);
                 MinOptMax ipd = MinOptMax.getInstance(font.getCharWidth(ch));
-                areaInfo = new AreaInfo(nextStart, nextStart + 1, 0, 0, ipd, false, true,
+                mapping = new GlyphMapping(nextStart, nextStart + 1, 0, 0, ipd, false, true,
                                         breakOpportunity, font, level, null);
                 thisStart = nextStart + 1;
             } else if (CharUtilities.isExplicitBreak(ch)) {
@@ -904,7 +841,7 @@ public class TextLayoutManager extends L
                 thisStart = nextStart + 1;
             }
 
-            inWord = !TextLayoutManager.isSpace(ch) && !CharUtilities.isExplicitBreak(ch);
+            inWord = !GlyphMapping.isSpace(ch) && !CharUtilities.isExplicitBreak(ch);
             inWhitespace = ch == CharUtilities.SPACE
                     && foText.getWhitespaceTreatment() != Constants.EN_PRESERVE;
             prevLevel = level;
@@ -913,11 +850,11 @@ public class TextLayoutManager extends L
 
         // Process any last elements
         if (inWord) {
-            processWord(alignment, sequence, prevAreaInfo, ch, false, false, prevLevel);
+            processWord(alignment, sequence, prevMapping, ch, false, false, prevLevel);
         } else if (inWhitespace) {
             processWhitespace(alignment, sequence, !keepTogether, prevLevel);
-        } else if (areaInfo != null) {
-            processLeftoverAreaInfo(alignment, sequence, areaInfo,
+        } else if (mapping != null) {
+            processLeftoverGlyphMapping(alignment, sequence, mapping,
                     ch == CharUtilities.ZERO_WIDTH_SPACE);
         } else if (CharUtilities.isExplicitBreak(ch)) {
             this.processLinebreak(returnList, sequence);
@@ -948,15 +885,14 @@ public class TextLayoutManager extends L
         return sequence;
     }
 
-    private void processLeftoverAreaInfo(int alignment,
-                                         KnuthSequence sequence, AreaInfo areaInfo,
-                                         boolean breakOpportunityAfter) {
-        addAreaInfo(areaInfo);
-        areaInfo.breakOppAfter = breakOpportunityAfter;
-        addElementsForASpace(sequence, alignment, areaInfo, areaInfos.size() - 1);
+    private void processLeftoverGlyphMapping(int alignment, KnuthSequence sequence,
+            GlyphMapping mapping, boolean breakOpportunityAfter) {
+        addGlyphMapping(mapping);
+        mapping.breakOppAfter = breakOpportunityAfter;
+        addElementsForASpace(sequence, alignment, mapping, mappings.size() - 1);
     }
 
-    private AreaInfo processWhitespace(final int alignment,
+    private GlyphMapping processWhitespace(final int alignment,
             final KnuthSequence sequence, final boolean breakOpportunity, int level) {
 
         if (LOG.isDebugEnabled()) {
@@ -964,209 +900,24 @@ public class TextLayoutManager extends L
         }
 
         // End of whitespace
-        // create the AreaInfo object
+        // create the GlyphMapping object
         assert nextStart >= thisStart;
-        AreaInfo areaInfo = new AreaInfo(
-            thisStart, nextStart, nextStart - thisStart, 0,
+        GlyphMapping mapping = new GlyphMapping(
+              thisStart, nextStart, nextStart - thisStart, 0,
               wordSpaceIPD.mult(nextStart - thisStart),
               false, true, breakOpportunity, spaceFont, level, null);
 
-        addAreaInfo(areaInfo);
+        addGlyphMapping(mapping);
 
         // create the elements
-        addElementsForASpace(sequence, alignment, areaInfo, areaInfos.size() - 1);
+        addElementsForASpace(sequence, alignment, mapping, mappings.size() - 1);
 
         thisStart = nextStart;
-        return areaInfo;
+        return mapping;
     }
 
-    private AreaInfo processWordMapping(
-        int lastIndex, final Font font, AreaInfo prevAreaInfo, final char breakOpportunityChar,
-          final boolean endsWithHyphen, int level) {
-        int s = this.thisStart; // start index of word in FOText character buffer
-        int e = lastIndex;      // end index of word in FOText character buffer
-        int nLS = 0;            // # of letter spaces
-        String script = foText.getScript();
-        String language = foText.getLanguage();
-
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("PW: [" + thisStart + "," + lastIndex + "]: {"
-                        + " +M"
-                        + ", level = " + level
-                        + " }");
-        }
-
-        // 1. extract unmapped character sequence
-        CharSequence ics = foText.subSequence(s, e);
-
-        // 2. if script is not specified (by FO property) or it is specified as 'auto',
-        // then compute dominant script
-        if ((script == null) || "auto".equals(script)) {
-            script = CharScript.scriptTagFromCode(CharScript.dominantScript(ics));
-        }
-        if ((language == null) || "none".equals(language)) {
-            language = "dflt";
-        }
-
-        // 3. perform mapping of chars to glyphs ... to glyphs ... to chars
-        CharSequence mcs = font.performSubstitution(ics, script, language);
-
-        // 4. compute glyph position adjustments on (substituted) characters
-        int[][] gpa;
-        if (font.performsPositioning()) {
-            // handle GPOS adjustments
-            gpa = font.performPositioning(mcs, script, language);
-        } else if (font.hasKerning()) {
-            // handle standard (non-GPOS) kerning adjustments
-            gpa = getKerningAdjustments(mcs, font);
-        } else {
-            gpa = null;
-        }
-
-        // 5. reorder combining marks so that they precede (within the mapped char sequence) the
-        // base to which they are applied; N.B. position adjustments (gpa) are reordered in place
-        mcs = font.reorderCombiningMarks(mcs, gpa, script, language);
-
-        // 6. if mapped sequence differs from input sequence, then memoize mapped sequence
-        if (!CharUtilities.isSameSequence(mcs, ics)) {
-            foText.addMapping(s, e, mcs);
-        }
-
-        // 7. compute word ipd based on final position adjustments
-        MinOptMax ipd = MinOptMax.ZERO;
-        for (int i = 0, n = mcs.length(); i < n; i++) {
-            int c = mcs.charAt(i);
-            // TODO !BMP
-            int  w = font.getCharWidth(c);
-            if (w < 0) {
-                w = 0;
-            }
-            if (gpa != null) {
-                w += gpa [ i ] [ GlyphPositioningTable.Value.IDX_X_ADVANCE ];
-            }
-            ipd = ipd.plus(w);
-        }
-
-        // [TBD] - handle letter spacing
-
-        return new AreaInfo(
-            s, e, 0, nLS, ipd, endsWithHyphen, false,
-              breakOpportunityChar != 0, font, level, gpa);
-    }
-
-    /**
-     * Given a mapped character sequence MCS, obtain glyph position adjustments
-     * from the font's kerning data.
-     * @param mcs mapped character sequence
-     * @param font applicable font
-     * @return glyph position adjustments (or null if no kerning)
-     */
-    private int[][] getKerningAdjustments(CharSequence mcs, final Font font) {
-        int nc = mcs.length();
-        // extract kerning array
-        int[] ka = new int [ nc ]; // kerning array
-        for (int i = 0, n = nc, cPrev = -1; i < n; i++) {
-            int c = mcs.charAt(i);
-            // TODO !BMP
-            if (cPrev >= 0) {
-                ka[i] = font.getKernValue(cPrev, c);
-            }
-            cPrev = c;
-        }
-        // was there a non-zero kerning?
-        boolean hasKerning = false;
-        for (int i = 0, n = nc; i < n; i++) {
-            if (ka[i] != 0) {
-                hasKerning = true;
-                break;
-            }
-        }
-        // if non-zero kerning, then create and return glyph position adjustment array
-        if (hasKerning) {
-            int[][] gpa = new int [ nc ] [ 4 ];
-            for (int i = 0, n = nc; i < n; i++) {
-                if (i > 0) {
-                    gpa [ i - 1 ] [ GlyphPositioningTable.Value.IDX_X_ADVANCE ] = ka [ i ];
-                }
-            }
-            return gpa;
-        } else {
-            return null;
-        }
-    }
-
-    private AreaInfo processWordNoMapping(int lastIndex, final Font font, AreaInfo prevAreaInfo,
-            final char breakOpportunityChar, final boolean endsWithHyphen, int level) {
-        boolean kerning = font.hasKerning();
-        MinOptMax wordIPD = MinOptMax.ZERO;
-
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("PW: [" + thisStart + "," + lastIndex + "]: {"
-                        + " -M"
-                        + ", level = " + level
-                        + " }");
-        }
-
-        for (int i = thisStart; i < lastIndex; i++) {
-            char currentChar = foText.charAt(i);
-
-            //character width
-            int charWidth = font.getCharWidth(currentChar);
-            wordIPD = wordIPD.plus(charWidth);
-
-            //kerning
-            if (kerning) {
-                int kern = 0;
-                if (i > thisStart) {
-                    char previousChar = foText.charAt(i - 1);
-                    kern = font.getKernValue(previousChar, currentChar);
-                } else if (prevAreaInfo != null
-                           && !prevAreaInfo.isSpace && prevAreaInfo.breakIndex > 0) {
-                    char previousChar = foText.charAt(prevAreaInfo.breakIndex - 1);
-                    kern = font.getKernValue(previousChar, currentChar);
-                }
-                if (kern != 0) {
-                    addToLetterAdjust(i, kern);
-                    wordIPD = wordIPD.plus(kern);
-                }
-            }
-        }
-        if (kerning
-                && (breakOpportunityChar != 0)
-                && !TextLayoutManager.isSpace(breakOpportunityChar)
-                && lastIndex > 0
-                && endsWithHyphen) {
-            int kern = font.getKernValue(foText.charAt(lastIndex - 1), breakOpportunityChar);
-            if (kern != 0) {
-                addToLetterAdjust(lastIndex, kern);
-                //TODO: add kern to wordIPD?
-            }
-        }
-        // shy+chars at start of word: wordLength == 0 && breakOpportunity
-        // shy only characters in word: wordLength == 0 && !breakOpportunity
-        int wordLength = lastIndex - thisStart;
-        int letterSpaces = 0;
-        if (wordLength != 0) {
-            letterSpaces = wordLength - 1;
-            // if there is a break opportunity and the next one (break character)
-            // is not a space, it could be used as a line end;
-            // add one more letter space, in case other text follows
-            if ((breakOpportunityChar != 0) && !TextLayoutManager.isSpace(breakOpportunityChar)) {
-                  letterSpaces++;
-            }
-        }
-        assert letterSpaces >= 0;
-        wordIPD = wordIPD.plus(letterSpaceIPD.mult(letterSpaces));
-
-        // create and return the AreaInfo object
-        return new AreaInfo(thisStart, lastIndex, 0,
-                            letterSpaces, wordIPD,
-                            endsWithHyphen,
-                            false, breakOpportunityChar != 0, font, level, null);
-    }
-
-    private AreaInfo processWord(final int alignment, final KnuthSequence sequence,
-            AreaInfo prevAreaInfo, final char ch, final boolean breakOpportunity,
+    private GlyphMapping processWord(final int alignment, final KnuthSequence sequence,
+            GlyphMapping prevMapping, final char ch, final boolean breakOpportunity,
             final boolean checkEndsWithHyphen, int level) {
 
         //Word boundary found, process widths and kerning
@@ -1178,23 +929,20 @@ public class TextLayoutManager extends L
                 && foText.charAt(lastIndex) == CharUtilities.SOFT_HYPHEN;
         Font font = FontSelector.selectFontForCharactersInText(
             foText, thisStart, lastIndex, foText, this);
-        AreaInfo areaInfo;
-        if (font.performsSubstitution() || font.performsPositioning()) {
-            areaInfo = processWordMapping(
-                lastIndex, font, prevAreaInfo, breakOpportunity ? ch : 0, endsWithHyphen, level);
-        } else {
-            areaInfo = processWordNoMapping(
-                lastIndex, font, prevAreaInfo, breakOpportunity ? ch : 0, endsWithHyphen, level);
-        }
-        prevAreaInfo = areaInfo;
-        addAreaInfo(areaInfo);
+        char breakOpportunityChar = breakOpportunity ? ch : 0;
+        char precedingChar = prevMapping != null && !prevMapping.isSpace
+                && prevMapping.endIndex > 0 ? foText.charAt(prevMapping.endIndex - 1) : 0;
+        GlyphMapping mapping = GlyphMapping.doGlyphMapping(foText, thisStart, lastIndex, font,
+                letterSpaceIPD, letterSpaceAdjustArray, precedingChar, breakOpportunityChar, endsWithHyphen, level);
+        prevMapping = mapping;
+        addGlyphMapping(mapping);
         tempStart = nextStart;
 
         //add the elements
-        addElementsForAWordFragment(sequence, alignment, areaInfo, areaInfos.size() - 1);
+        addElementsForAWordFragment(sequence, alignment, mapping, mappings.size() - 1);
         thisStart = nextStart;
 
-        return prevAreaInfo;
+        return prevMapping;
     }
 
     /** {@inheritDoc} */
@@ -1214,9 +962,9 @@ public class TextLayoutManager extends L
         int index = leafPos.getLeafPos();
         //element could refer to '-1' position, for non-collapsed spaces (?)
         if (index > -1) {
-            AreaInfo areaInfo = getAreaInfo(index);
-            areaInfo.letterSpaceCount++;
-            areaInfo.addToAreaIPD(letterSpaceIPD);
+            GlyphMapping mapping = getGlyphMapping(index);
+            mapping.letterSpaceCount++;
+            mapping.addToAreaIPD(letterSpaceIPD);
             if (TextLayoutManager.BREAK_CHARS.indexOf(foText.charAt(tempStart - 1)) >= 0) {
                 // the last character could be used as a line break
                 // append new elements to oldList
@@ -1227,13 +975,13 @@ public class TextLayoutManager extends L
             } else if (letterSpaceIPD.isStiff()) {
                 // constant letter space: replace the box
                 // give it the unwrapped position of the replaced element
-                oldListIterator.set(new KnuthInlineBox(areaInfo.areaIPD.getOpt(),
+                oldListIterator.set(new KnuthInlineBox(mapping.areaIPD.getOpt(),
                         alignmentContext, pos, false));
             } else {
                 // adjustable letter space: replace the glue
                 oldListIterator.next(); // this would return the penalty element
                 oldListIterator.next(); // this would return the glue element
-                oldListIterator.set(new KnuthGlue(letterSpaceIPD.mult(areaInfo.letterSpaceCount),
+                oldListIterator.set(new KnuthGlue(letterSpaceIPD.mult(mapping.letterSpaceCount),
                         auxiliaryPosition, true));
             }
         }
@@ -1242,26 +990,26 @@ public class TextLayoutManager extends L
 
     /** {@inheritDoc} */
     public void hyphenate(Position pos, HyphContext hyphContext) {
-        AreaInfo areaInfo = getAreaInfo(((LeafPosition) pos).getLeafPos() + changeOffset);
-        int startIndex = areaInfo.startIndex;
+        GlyphMapping mapping = getGlyphMapping(((LeafPosition) pos).getLeafPos() + changeOffset);
+        int startIndex = mapping.startIndex;
         int stopIndex;
         boolean nothingChanged = true;
-        Font font = areaInfo.font;
+        Font font = mapping.font;
 
-        while (startIndex < areaInfo.breakIndex) {
+        while (startIndex < mapping.endIndex) {
             MinOptMax newIPD = MinOptMax.ZERO;
             boolean hyphenFollows;
 
             stopIndex = startIndex + hyphContext.getNextHyphPoint();
-            if (hyphContext.hasMoreHyphPoints() && stopIndex <= areaInfo.breakIndex) {
+            if (hyphContext.hasMoreHyphPoints() && stopIndex <= mapping.endIndex) {
                 // stopIndex is the index of the first character
                 // after a hyphenation point
                 hyphenFollows = true;
             } else {
                 // there are no more hyphenation points,
-                // or the next one is after areaInfo.breakIndex
+                // or the next one is after mapping.breakIndex
                 hyphenFollows = false;
-                stopIndex = areaInfo.breakIndex;
+                stopIndex = mapping.endIndex;
             }
 
             hyphContext.updateOffset(stopIndex - startIndex);
@@ -1286,18 +1034,18 @@ public class TextLayoutManager extends L
 
             // add letter spaces
             boolean isWordEnd
-                = (stopIndex == areaInfo.breakIndex)
-                && (areaInfo.letterSpaceCount < areaInfo.getWordLength());
+                = (stopIndex == mapping.endIndex)
+                && (mapping.letterSpaceCount < mapping.getWordLength());
             int letterSpaceCount = isWordEnd ? stopIndex - startIndex - 1 : stopIndex - startIndex;
 
             assert letterSpaceCount >= 0;
             newIPD = newIPD.plus(letterSpaceIPD.mult(letterSpaceCount));
 
-            if (!(nothingChanged && stopIndex == areaInfo.breakIndex && !hyphenFollows)) {
-                // the new AreaInfo object is not equal to the old one
+            if (!(nothingChanged && stopIndex == mapping.endIndex && !hyphenFollows)) {
+                // the new GlyphMapping object is not equal to the old one
                 changeList.add(
                     new PendingChange(
-                      new AreaInfo(startIndex, stopIndex, 0,
+                      new GlyphMapping(startIndex, stopIndex, 0,
                                      letterSpaceCount, newIPD, hyphenFollows,
                                      false, false, font, -1, null),
                         ((LeafPosition) pos).getLeafPos() + changeOffset));
@@ -1324,7 +1072,7 @@ public class TextLayoutManager extends L
             return false;
         }
 
-        // Find the first and last positions in oldList that point to an AreaInfo
+        // Find the first and last positions in oldList that point to a GlyphMapping
         // (i.e. getLeafPos() != -1)
         LeafPosition startPos = null;
         LeafPosition endPos = null;
@@ -1349,8 +1097,8 @@ public class TextLayoutManager extends L
         returnedIndices[0] = (startPos != null ? startPos.getLeafPos() : -1) + changeOffset;
         returnedIndices[1] = (endPos != null ? endPos.getLeafPos() : -1) + changeOffset;
 
-        int areaInfosAdded = 0;
-        int areaInfosRemoved = 0;
+        int mappingsAdded = 0;
+        int mappingsRemoved = 0;
 
         if (!changeList.isEmpty()) {
             int oldIndex = -1;
@@ -1360,24 +1108,24 @@ public class TextLayoutManager extends L
             while (changeListIterator.hasNext()) {
                 currChange = (PendingChange) changeListIterator.next();
                 if (currChange.index == oldIndex) {
-                    areaInfosAdded++;
-                    changeIndex = currChange.index + areaInfosAdded - areaInfosRemoved;
+                    mappingsAdded++;
+                    changeIndex = currChange.index + mappingsAdded - mappingsRemoved;
                 } else {
-                    areaInfosRemoved++;
-                    areaInfosAdded++;
+                    mappingsRemoved++;
+                    mappingsAdded++;
                     oldIndex = currChange.index;
-                    changeIndex = currChange.index + areaInfosAdded - areaInfosRemoved;
-                    removeAreaInfo(changeIndex);
+                    changeIndex = currChange.index + mappingsAdded - mappingsRemoved;
+                    removeGlyphMapping(changeIndex);
                 }
-                addAreaInfo(changeIndex, currChange.areaInfo);
+                addGlyphMapping(changeIndex, currChange.mapping);
             }
             changeList.clear();
         }
 
         // increase the end index for getChangedKnuthElements()
-        returnedIndices[1] += (areaInfosAdded - areaInfosRemoved);
+        returnedIndices[1] += (mappingsAdded - mappingsRemoved);
         // increase offset to use for subsequent paragraphs
-        changeOffset += (areaInfosAdded - areaInfosRemoved);
+        changeOffset += (mappingsAdded - mappingsRemoved);
 
         return hasChanged;
     }
@@ -1391,16 +1139,16 @@ public class TextLayoutManager extends L
         final LinkedList returnList = new LinkedList();
 
         for (; returnedIndices[0] <= returnedIndices[1]; returnedIndices[0]++) {
-            AreaInfo areaInfo = getAreaInfo(returnedIndices[0]);
-            if (areaInfo.wordSpaceCount == 0) {
-                // areaInfo refers either to a word or a word fragment
-                addElementsForAWordFragment(returnList, alignment, areaInfo, returnedIndices[0]);
+            GlyphMapping mapping = getGlyphMapping(returnedIndices[0]);
+            if (mapping.wordSpaceCount == 0) {
+                // mapping refers either to a word or a word fragment
+                addElementsForAWordFragment(returnList, alignment, mapping, returnedIndices[0]);
             } else {
-                // areaInfo refers to a space
-                addElementsForASpace(returnList, alignment, areaInfo, returnedIndices[0]);
+                // mapping refers to a space
+                addElementsForASpace(returnList, alignment, mapping, returnedIndices[0]);
             }
         }
-        setFinished(returnedIndices[0] == areaInfos.size() - 1);
+        setFinished(returnedIndices[0] == mappings.size() - 1);
         //ElementListObserver.observe(returnList, "text-changed", null);
         return returnList;
     }
@@ -1409,9 +1157,9 @@ public class TextLayoutManager extends L
     public String getWordChars(Position pos) {
         int leafValue = ((LeafPosition) pos).getLeafPos() + changeOffset;
         if (leafValue != -1) {
-            AreaInfo areaInfo = getAreaInfo(leafValue);
-            StringBuffer buffer = new StringBuffer(areaInfo.getWordLength());
-            for (int i = areaInfo.startIndex; i < areaInfo.breakIndex; i++) {
+            GlyphMapping mapping = getGlyphMapping(leafValue);
+            StringBuffer buffer = new StringBuffer(mapping.getWordLength());
+            for (int i = mapping.startIndex; i < mapping.endIndex; i++) {
                 buffer.append(foText.charAt(i));
             }
             return buffer.toString();
@@ -1420,41 +1168,39 @@ public class TextLayoutManager extends L
         }
     }
 
-    private void addElementsForASpace(List baseList, int alignment, AreaInfo areaInfo,
+    private void addElementsForASpace(List baseList, int alignment, GlyphMapping mapping,
                                       int leafValue) {
         LeafPosition mainPosition = new LeafPosition(this, leafValue);
 
-        if (!areaInfo.breakOppAfter) {
+        if (!mapping.breakOppAfter) {
             // a non-breaking space
             if (alignment == Constants.EN_JUSTIFY) {
                 // the space can stretch and shrink, and must be preserved
                 // when starting a line
                 baseList.add(makeAuxiliaryZeroWidthBox());
                 baseList.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
-                baseList.add(new KnuthGlue(areaInfo.areaIPD, mainPosition, false));
+                baseList.add(new KnuthGlue(mapping.areaIPD, mainPosition, false));
             } else {
                 // the space does not need to stretch or shrink, and must be
                 // preserved when starting a line
-                baseList.add(new KnuthInlineBox(areaInfo.areaIPD.getOpt(), null, mainPosition,
+                baseList.add(new KnuthInlineBox(mapping.areaIPD.getOpt(), null, mainPosition,
                         true));
             }
         } else {
-            if (foText.charAt(areaInfo.startIndex) != CharUtilities.SPACE
+            if (foText.charAt(mapping.startIndex) != CharUtilities.SPACE
                     || foText.getWhitespaceTreatment() == Constants.EN_PRESERVE) {
                 // a breaking space that needs to be preserved
-                baseList
-                    .addAll(getElementsForBreakingSpace(alignment, areaInfo, auxiliaryPosition, 0,
-                        mainPosition, areaInfo.areaIPD.getOpt(), true));
+                baseList.addAll(getElementsForBreakingSpace(alignment, mapping, auxiliaryPosition, 0,
+                        mainPosition, mapping.areaIPD.getOpt(), true));
             } else {
                 // a (possible block) of breaking spaces
-                baseList
-                    .addAll(getElementsForBreakingSpace(alignment, areaInfo, mainPosition,
-                        areaInfo.areaIPD.getOpt(), auxiliaryPosition, 0, false));
+                baseList.addAll(getElementsForBreakingSpace(alignment, mapping, mainPosition,
+                        mapping.areaIPD.getOpt(), auxiliaryPosition, 0, false));
             }
         }
     }
 
-    private List getElementsForBreakingSpace(int alignment, AreaInfo areaInfo, Position pos2,
+    private List getElementsForBreakingSpace(int alignment, GlyphMapping mapping, Position pos2,
                                              int p2WidthOffset, Position pos3,
                                              int p3WidthOffset, boolean skipZeroCheck) {
         List elements = new ArrayList();
@@ -1504,7 +1250,7 @@ public class TextLayoutManager extends L
                 elements.add(g);
                 elements.add(makeZeroWidthPenalty(0));
                 g = new KnuthGlue(
-                    areaInfo.areaIPD.getOpt(),
+                    mapping.areaIPD.getOpt(),
                      -3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, pos2, false);
                 elements.add(g);
             }
@@ -1513,25 +1259,24 @@ public class TextLayoutManager extends L
         case EN_JUSTIFY:
             // justified text:
             // the stretch and shrink depends on the space width
-            elements.addAll(getElementsForJustifiedText(areaInfo, pos2, p2WidthOffset, pos3,
-                    p3WidthOffset, skipZeroCheck, areaInfo.areaIPD.getShrink()));
+            elements.addAll(getElementsForJustifiedText(mapping, pos2, p2WidthOffset, pos3,
+                    p3WidthOffset, skipZeroCheck, mapping.areaIPD.getShrink()));
             break;
 
         default:
             // last line justified, the other lines unjustified:
             // use only the space stretch
-            elements.addAll(getElementsForJustifiedText(areaInfo, pos2, p2WidthOffset, pos3,
+            elements.addAll(getElementsForJustifiedText(mapping, pos2, p2WidthOffset, pos3,
                     p3WidthOffset, skipZeroCheck, 0));
         }
         return elements;
     }
 
-    private List getElementsForJustifiedText(
-        AreaInfo areaInfo, Position pos2, int p2WidthOffset,
-         Position pos3, int p3WidthOffset, boolean skipZeroCheck,
-         int shrinkability) {
+    private List getElementsForJustifiedText(GlyphMapping mapping, Position pos2, int p2WidthOffset,
+                                             Position pos3, int p3WidthOffset, boolean skipZeroCheck,
+                                             int shrinkability) {
 
-        int stretchability = areaInfo.areaIPD.getStretch();
+        int stretchability = mapping.areaIPD.getStretch();
 
         List elements = new ArrayList();
         if (skipZeroCheck || lineStartBAP != 0 || lineEndBAP != 0) {
@@ -1543,34 +1288,34 @@ public class TextLayoutManager extends L
             elements.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
             elements.add(new KnuthGlue(lineStartBAP + p3WidthOffset, 0, 0, pos3, false));
         } else {
-            elements.add(new KnuthGlue(areaInfo.areaIPD.getOpt(), stretchability, shrinkability,
+            elements.add(new KnuthGlue(mapping.areaIPD.getOpt(), stretchability, shrinkability,
                     pos2, false));
         }
         return elements;
     }
 
-    private void addElementsForAWordFragment(List baseList, int alignment, AreaInfo areaInfo,
+    private void addElementsForAWordFragment(List baseList, int alignment, GlyphMapping mapping,
                                              int leafValue) {
         LeafPosition mainPosition = new LeafPosition(this, leafValue);
 
         // if the last character of the word fragment is '-' or '/',
         // the fragment could end a line; in this case, it loses one
         // of its letter spaces;
-        boolean suppressibleLetterSpace = areaInfo.breakOppAfter && !areaInfo.isHyphenated;
+        boolean suppressibleLetterSpace = mapping.breakOppAfter && !mapping.isHyphenated;
 
         if (letterSpaceIPD.isStiff()) {
             // constant letter spacing
             baseList.add(new KnuthInlineBox(suppressibleLetterSpace
-                    ? areaInfo.areaIPD.getOpt() - letterSpaceIPD.getOpt()
-                    : areaInfo.areaIPD.getOpt(),
+                    ? mapping.areaIPD.getOpt() - letterSpaceIPD.getOpt()
+                    : mapping.areaIPD.getOpt(),
                     alignmentContext, notifyPos(mainPosition), false));
         } else {
             // adjustable letter spacing
             int unsuppressibleLetterSpaces = suppressibleLetterSpace
-                    ? areaInfo.letterSpaceCount - 1
-                    : areaInfo.letterSpaceCount;
-            baseList.add(new KnuthInlineBox(areaInfo.areaIPD.getOpt()
-                    - areaInfo.letterSpaceCount * letterSpaceIPD.getOpt(),
+                    ? mapping.letterSpaceCount - 1
+                    : mapping.letterSpaceCount;
+            baseList.add(new KnuthInlineBox(mapping.areaIPD.getOpt()
+                    - mapping.letterSpaceCount * letterSpaceIPD.getOpt(),
                             alignmentContext, notifyPos(mainPosition), false));
             baseList.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
             baseList.add(new KnuthGlue(letterSpaceIPD.mult(unsuppressibleLetterSpaces),
@@ -1580,19 +1325,19 @@ public class TextLayoutManager extends L
 
         // extra-elements if the word fragment is the end of a syllable,
         // or it ends with a character that can be used as a line break
-        if (areaInfo.isHyphenated) {
+        if (mapping.isHyphenated) {
             MinOptMax widthIfNoBreakOccurs = null;
-            if (areaInfo.breakIndex < foText.length()) {
+            if (mapping.endIndex < foText.length()) {
                 //Add in kerning in no-break condition
-                widthIfNoBreakOccurs = letterSpaceAdjustArray[areaInfo.breakIndex];
+                widthIfNoBreakOccurs = letterSpaceAdjustArray[mapping.endIndex];
             }
-            //if (areaInfo.breakIndex)
+            //if (mapping.breakIndex)
 
             // the word fragment ends at the end of a syllable:
             // if a break occurs the content width increases,
             // otherwise nothing happens
             addElementsForAHyphen(baseList, alignment, hyphIPD, widthIfNoBreakOccurs,
-                    areaInfo.breakOppAfter && areaInfo.isHyphenated);
+                    mapping.breakOppAfter && mapping.isHyphenated);
         } else if (suppressibleLetterSpace) {
             // the word fragment ends with a character that acts as a hyphen
             // if a break occurs the width does not increase,

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java Mon Mar 17 09:31:13 2014
@@ -28,16 +28,15 @@ import org.apache.commons.logging.LogFac
 import org.apache.fop.area.Area;
 import org.apache.fop.area.Block;
 import org.apache.fop.fo.flow.ListBlock;
+import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
 import org.apache.fop.fo.properties.KeepProperty;
-import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
-import org.apache.fop.layoutmgr.ConditionalElementListener;
 import org.apache.fop.layoutmgr.ElementListUtils;
 import org.apache.fop.layoutmgr.LayoutContext;
 import org.apache.fop.layoutmgr.LayoutManager;
 import org.apache.fop.layoutmgr.NonLeafPosition;
 import org.apache.fop.layoutmgr.Position;
 import org.apache.fop.layoutmgr.PositionIterator;
-import org.apache.fop.layoutmgr.RelSide;
+import org.apache.fop.layoutmgr.SpacedBorderedPaddedBlockLayoutManager;
 import org.apache.fop.layoutmgr.TraitSetter;
 import org.apache.fop.traits.MinOptMax;
 import org.apache.fop.traits.SpaceVal;
@@ -47,21 +46,13 @@ import org.apache.fop.traits.SpaceVal;
  * A list block contains list items which are stacked within
  * the list block area..
  */
-public class ListBlockLayoutManager extends BlockStackingLayoutManager
-                implements ConditionalElementListener {
+public class ListBlockLayoutManager extends SpacedBorderedPaddedBlockLayoutManager {
 
     /** logging instance */
     private static Log log = LogFactory.getLog(ListBlockLayoutManager.class);
 
     private Block curBlockArea;
 
-    private boolean discardBorderBefore;
-    private boolean discardBorderAfter;
-    private boolean discardPaddingBefore;
-    private boolean discardPaddingAfter;
-    private MinOptMax effSpaceBefore;
-    private MinOptMax effSpaceAfter;
-
     /**
      * Create a new list block layout manager.
      * @param node list-block to create the layout manager for
@@ -70,6 +61,11 @@ public class ListBlockLayoutManager exte
         super(node);
     }
 
+    @Override
+    protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() {
+        return getListBlockFO().getCommonBorderPaddingBackground();
+    }
+
     /**
      * Convenience method.
      * @return the ListBlock node
@@ -279,50 +275,5 @@ public class ListBlockLayoutManager exte
         return getListBlockFO().getKeepWithNext();
     }
 
-    /** {@inheritDoc} */
-    public void notifySpace(RelSide side, MinOptMax effectiveLength) {
-        if (RelSide.BEFORE == side) {
-            if (log.isDebugEnabled()) {
-                log.debug(this + ": Space " + side + ", "
-                        + this.effSpaceBefore + "-> " + effectiveLength);
-            }
-            this.effSpaceBefore = effectiveLength;
-        } else {
-            if (log.isDebugEnabled()) {
-                log.debug(this + ": Space " + side + ", "
-                        + this.effSpaceAfter + "-> " + effectiveLength);
-            }
-            this.effSpaceAfter = effectiveLength;
-        }
-    }
-
-    /** {@inheritDoc} */
-    public void notifyBorder(RelSide side, MinOptMax effectiveLength) {
-        if (effectiveLength == null) {
-            if (RelSide.BEFORE == side) {
-                this.discardBorderBefore = true;
-            } else {
-                this.discardBorderAfter = true;
-            }
-        }
-        if (log.isDebugEnabled()) {
-            log.debug(this + ": Border " + side + " -> " + effectiveLength);
-        }
-    }
-
-    /** {@inheritDoc} */
-    public void notifyPadding(RelSide side, MinOptMax effectiveLength) {
-        if (effectiveLength == null) {
-            if (RelSide.BEFORE == side) {
-                this.discardPaddingBefore = true;
-            } else {
-                this.discardPaddingAfter = true;
-            }
-        }
-        if (log.isDebugEnabled()) {
-            log.debug(this + ": Padding " + side + " -> " + effectiveLength);
-        }
-    }
-
 }
 

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java Mon Mar 17 09:31:13 2014
@@ -32,12 +32,11 @@ import org.apache.fop.area.Block;
 import org.apache.fop.fo.flow.ListItem;
 import org.apache.fop.fo.flow.ListItemBody;
 import org.apache.fop.fo.flow.ListItemLabel;
+import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
 import org.apache.fop.fo.properties.KeepProperty;
-import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
 import org.apache.fop.layoutmgr.BreakElement;
 import org.apache.fop.layoutmgr.BreakOpportunity;
 import org.apache.fop.layoutmgr.BreakOpportunityHelper;
-import org.apache.fop.layoutmgr.ConditionalElementListener;
 import org.apache.fop.layoutmgr.ElementListObserver;
 import org.apache.fop.layoutmgr.ElementListUtils;
 import org.apache.fop.layoutmgr.FootnoteBodyLayoutManager;
@@ -53,10 +52,9 @@ import org.apache.fop.layoutmgr.ListElem
 import org.apache.fop.layoutmgr.NonLeafPosition;
 import org.apache.fop.layoutmgr.Position;
 import org.apache.fop.layoutmgr.PositionIterator;
-import org.apache.fop.layoutmgr.RelSide;
 import org.apache.fop.layoutmgr.SpaceResolver;
+import org.apache.fop.layoutmgr.SpacedBorderedPaddedBlockLayoutManager;
 import org.apache.fop.layoutmgr.TraitSetter;
-import org.apache.fop.traits.MinOptMax;
 import org.apache.fop.traits.SpaceVal;
 import org.apache.fop.util.BreakUtil;
 
@@ -64,8 +62,8 @@ import org.apache.fop.util.BreakUtil;
  * LayoutManager for a list-item FO.
  * The list item contains a list item label and a list item body.
  */
-public class ListItemLayoutManager extends BlockStackingLayoutManager implements ConditionalElementListener,
-        BreakOpportunity {
+public class ListItemLayoutManager extends SpacedBorderedPaddedBlockLayoutManager
+        implements BreakOpportunity {
 
     /** logging instance */
     private static Log log = LogFactory.getLog(ListItemLayoutManager.class);
@@ -78,13 +76,6 @@ public class ListItemLayoutManager exten
     private List<ListElement> labelList = null;
     private List<ListElement> bodyList = null;
 
-    private boolean discardBorderBefore;
-    private boolean discardBorderAfter;
-    private boolean discardPaddingBefore;
-    private boolean discardPaddingAfter;
-    private MinOptMax effSpaceBefore;
-    private MinOptMax effSpaceAfter;
-
     private Keep keepWithNextPendingOnLabel;
     private Keep keepWithNextPendingOnBody;
 
@@ -145,6 +136,11 @@ public class ListItemLayoutManager exten
         setBody(node.getBody());
     }
 
+    @Override
+    protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() {
+        return getListItemFO().getCommonBorderPaddingBackground();
+    }
+
     /**
      * Convenience method.
      * @return the ListBlock node
@@ -475,6 +471,23 @@ public class ListItemLayoutManager exten
         return returnedList;
     }
 
+
+    @Override
+    public boolean hasLineAreaDescendant() {
+        return label.hasLineAreaDescendant() || body.hasLineAreaDescendant();
+    }
+
+    @Override
+    public int getBaselineOffset() {
+        if (label.hasLineAreaDescendant()) {
+            return label.getBaselineOffset();
+        } else if (body.hasLineAreaDescendant()) {
+            return body.getBaselineOffset();
+        } else {
+            throw newNoLineAreaDescendantException();
+        }
+    }
+
     /**
      * Add the areas for the break points.
      *
@@ -655,51 +668,6 @@ public class ListItemLayoutManager exten
     }
 
     /** {@inheritDoc} */
-    public void notifySpace(RelSide side, MinOptMax effectiveLength) {
-        if (RelSide.BEFORE == side) {
-            if (log.isDebugEnabled()) {
-                log.debug(this + ": Space " + side + ", "
-                        + this.effSpaceBefore + "-> " + effectiveLength);
-            }
-            this.effSpaceBefore = effectiveLength;
-        } else {
-            if (log.isDebugEnabled()) {
-                log.debug(this + ": Space " + side + ", "
-                        + this.effSpaceAfter + "-> " + effectiveLength);
-            }
-            this.effSpaceAfter = effectiveLength;
-        }
-    }
-
-    /** {@inheritDoc} */
-    public void notifyBorder(RelSide side, MinOptMax effectiveLength) {
-        if (effectiveLength == null) {
-            if (RelSide.BEFORE == side) {
-                this.discardBorderBefore = true;
-            } else {
-                this.discardBorderAfter = true;
-            }
-        }
-        if (log.isDebugEnabled()) {
-            log.debug(this + ": Border " + side + " -> " + effectiveLength);
-        }
-    }
-
-    /** {@inheritDoc} */
-    public void notifyPadding(RelSide side, MinOptMax effectiveLength) {
-        if (effectiveLength == null) {
-            if (RelSide.BEFORE == side) {
-                this.discardPaddingBefore = true;
-            } else {
-                this.discardPaddingAfter = true;
-            }
-        }
-        if (log.isDebugEnabled()) {
-            log.debug(this + ": Padding " + side + " -> " + effectiveLength);
-        }
-    }
-
-    /** {@inheritDoc} */
     @Override
     public void reset() {
         super.reset();

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java Mon Mar 17 09:31:13 2014
@@ -117,6 +117,7 @@ public class TableCellLayoutManager exte
      */
     public TableCellLayoutManager(TableCell node, PrimaryGridUnit pgu) {
         super(node);
+        setGeneratesBlockArea(true);
         this.primaryGridUnit = pgu;
         this.isDescendantOfTableHeader = node.getParent().getParent() instanceof TableHeader
                 || node.getParent() instanceof TableHeader;

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java Mon Mar 17 09:31:13 2014
@@ -39,12 +39,11 @@ import org.apache.fop.fo.flow.Markers;
 import org.apache.fop.fo.flow.RetrieveTableMarker;
 import org.apache.fop.fo.flow.table.Table;
 import org.apache.fop.fo.flow.table.TableColumn;
+import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
 import org.apache.fop.fo.properties.KeepProperty;
 import org.apache.fop.layoutmgr.BlockLevelEventProducer;
-import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
 import org.apache.fop.layoutmgr.BreakElement;
 import org.apache.fop.layoutmgr.BreakOpportunity;
-import org.apache.fop.layoutmgr.ConditionalElementListener;
 import org.apache.fop.layoutmgr.KnuthElement;
 import org.apache.fop.layoutmgr.KnuthGlue;
 import org.apache.fop.layoutmgr.LayoutContext;
@@ -52,7 +51,7 @@ import org.apache.fop.layoutmgr.LeafPosi
 import org.apache.fop.layoutmgr.ListElement;
 import org.apache.fop.layoutmgr.Position;
 import org.apache.fop.layoutmgr.PositionIterator;
-import org.apache.fop.layoutmgr.RelSide;
+import org.apache.fop.layoutmgr.SpacedBorderedPaddedBlockLayoutManager;
 import org.apache.fop.layoutmgr.TraitSetter;
 import org.apache.fop.traits.MinOptMax;
 import org.apache.fop.traits.SpaceVal;
@@ -66,8 +65,8 @@ import org.apache.fop.util.BreakUtil;
  * The table then creates areas for the columns, bodies and rows
  * the render background.
  */
-public class TableLayoutManager extends BlockStackingLayoutManager
-                implements ConditionalElementListener, BreakOpportunity {
+public class TableLayoutManager extends SpacedBorderedPaddedBlockLayoutManager
+        implements BreakOpportunity {
 
     /**
      * logging instance
@@ -82,13 +81,6 @@ public class TableLayoutManager extends 
     private double tableUnit;
     private boolean autoLayout = true;
 
-    private boolean discardBorderBefore;
-    private boolean discardBorderAfter;
-    private boolean discardPaddingBefore;
-    private boolean discardPaddingAfter;
-    private MinOptMax effSpaceBefore;
-    private MinOptMax effSpaceAfter;
-
     private int halfBorderSeparationBPD;
     private int halfBorderSeparationIPD;
 
@@ -132,6 +124,13 @@ public class TableLayoutManager extends 
         this.columns = new ColumnSetup(node);
     }
 
+
+    @Override
+    protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() {
+        return getTable().getCommonBorderPaddingBackground();
+    }
+
+
     /** @return the table FO */
     public Table getTable() {
         return (Table)this.fobj;
@@ -522,51 +521,6 @@ public class TableLayoutManager extends 
     }
 
     /** {@inheritDoc} */
-    public void notifySpace(RelSide side, MinOptMax effectiveLength) {
-        if (RelSide.BEFORE == side) {
-            if (log.isDebugEnabled()) {
-                log.debug(this + ": Space " + side + ", "
-                        + this.effSpaceBefore + "-> " + effectiveLength);
-            }
-            this.effSpaceBefore = effectiveLength;
-        } else {
-            if (log.isDebugEnabled()) {
-                log.debug(this + ": Space " + side + ", "
-                        + this.effSpaceAfter + "-> " + effectiveLength);
-            }
-            this.effSpaceAfter = effectiveLength;
-        }
-    }
-
-    /** {@inheritDoc} */
-    public void notifyBorder(RelSide side, MinOptMax effectiveLength) {
-        if (effectiveLength == null) {
-            if (RelSide.BEFORE == side) {
-                this.discardBorderBefore = true;
-            } else {
-                this.discardBorderAfter = true;
-            }
-        }
-        if (log.isDebugEnabled()) {
-            log.debug(this + ": Border " + side + " -> " + effectiveLength);
-        }
-    }
-
-    /** {@inheritDoc} */
-    public void notifyPadding(RelSide side, MinOptMax effectiveLength) {
-        if (effectiveLength == null) {
-            if (RelSide.BEFORE == side) {
-                this.discardPaddingBefore = true;
-            } else {
-                this.discardPaddingAfter = true;
-            }
-        }
-        if (log.isDebugEnabled()) {
-            log.debug(this + ": Padding " + side + " -> " + effectiveLength);
-        }
-    }
-
-    /** {@inheritDoc} */
     public void reset() {
         super.reset();
         curBlockArea = null;

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/pdf/PDFProfile.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/pdf/PDFProfile.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/pdf/PDFProfile.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/pdf/PDFProfile.java Mon Mar 17 09:31:13 2014
@@ -169,15 +169,28 @@ public class PDFProfile {
      * @param context Context information for the user to identify the problem spot
      */
     public void verifyTransparencyAllowed(String context) {
-        final String err = "{0} does not allow the use of transparency. ({1})";
+        Object profile = isTransparencyAllowed();
+        if (profile != null) {
+            throw new PDFConformanceException(profile + " does not allow the use of transparency. ("
+                    + profile + ")");
+        }
+    }
+
+    /**
+     * Returns {@code null} if transparency is allowed, otherwise returns the profile that
+     * prevents it.
+     *
+     * @return {@code null}, or an object whose {@code toString} method returns the name
+     * of the profile that disallows transparency
+     */
+    public Object isTransparencyAllowed() {
         if (pdfAMode.isPart1()) {
-            throw new PDFConformanceException(MessageFormat.format(err,
-                    new Object[] {getPDFAMode(), context}));
+            return getPDFAMode();
         }
         if (isPDFXActive()) {
-            throw new PDFConformanceException(MessageFormat.format(err,
-                    new Object[] {getPDFXMode(), context}));
+            return getPDFXMode();
         }
+        return null;
     }
 
     /** Checks if the right PDF version is set. */

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java Mon Mar 17 09:31:13 2014
@@ -31,6 +31,7 @@ import org.apache.batik.bridge.GVTBuilde
 import org.apache.batik.dom.AbstractDocument;
 import org.apache.batik.dom.svg.SVGDOMImplementation;
 import org.apache.batik.gvt.GraphicsNode;
+import org.apache.batik.gvt.font.DefaultFontFamilyResolver;
 
 import org.apache.xmlgraphics.java2d.Graphics2DImagePainter;
 
@@ -122,7 +123,8 @@ public abstract class AbstractGenericSVG
 
         //Prepare
         FOUserAgent userAgent = rendererContext.getUserAgent();
-        SVGUserAgent svgUserAgent = new SVGUserAgent(userAgent, new AffineTransform());
+        SVGUserAgent svgUserAgent = new SVGUserAgent(userAgent, DefaultFontFamilyResolver.SINGLETON,
+                new AffineTransform());
 
         //Create Batik BridgeContext
         final BridgeContext bridgeContext = new BridgeContext(svgUserAgent);

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/afp/AFPSVGHandler.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/afp/AFPSVGHandler.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/afp/AFPSVGHandler.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/afp/AFPSVGHandler.java Mon Mar 17 09:31:13 2014
@@ -29,6 +29,7 @@ import org.w3c.dom.Document;
 import org.apache.batik.bridge.BridgeContext;
 import org.apache.batik.dom.svg.SVGDOMImplementation;
 import org.apache.batik.gvt.GraphicsNode;
+import org.apache.batik.gvt.font.DefaultFontFamilyResolver;
 
 import org.apache.xmlgraphics.image.loader.ImageManager;
 import org.apache.xmlgraphics.image.loader.ImageSessionContext;
@@ -43,6 +44,7 @@ import org.apache.fop.afp.AFPResourceInf
 import org.apache.fop.afp.AFPResourceManager;
 import org.apache.fop.afp.AFPUnitConverter;
 import org.apache.fop.afp.svg.AFPBridgeContext;
+import org.apache.fop.afp.svg.AFPFontFamilyResolver;
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.fonts.FontInfo;
 import org.apache.fop.image.loader.batik.BatikUtil;
@@ -53,6 +55,7 @@ import org.apache.fop.render.RendererCon
 import org.apache.fop.render.RendererContext.RendererContextWrapper;
 import org.apache.fop.svg.SVGEventProducer;
 import org.apache.fop.svg.SVGUserAgent;
+import org.apache.fop.svg.font.AggregatingFontFamilyResolver;
 
 /**
  * AFP XML handler for SVG. Uses Apache Batik for SVG processing.
@@ -196,15 +199,14 @@ public class AFPSVGHandler extends Abstr
      */
     public static BridgeContext createBridgeContext(FOUserAgent userAgent, AFPGraphics2D g2d) {
         ImageManager imageManager = userAgent.getImageManager();
-
-        SVGUserAgent svgUserAgent
-            = new SVGUserAgent(userAgent, new AffineTransform());
-
-        ImageSessionContext imageSessionContext = userAgent.getImageSessionContext();
-
         FontInfo fontInfo = g2d.getFontInfo();
+        SVGUserAgent svgUserAgent = new SVGUserAgent(userAgent,
+                new AggregatingFontFamilyResolver(new AFPFontFamilyResolver(fontInfo, userAgent.getEventBroadcaster()),
+                        DefaultFontFamilyResolver.SINGLETON),
+                new AffineTransform());
+        ImageSessionContext imageSessionContext = userAgent.getImageSessionContext();
         return new AFPBridgeContext(svgUserAgent, fontInfo, imageManager, imageSessionContext,
-                new AffineTransform(), g2d);
+                new AffineTransform(), g2d, userAgent.getEventBroadcaster());
     }
 
     /** {@inheritDoc} */

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java Mon Mar 17 09:31:13 2014
@@ -21,6 +21,7 @@ package org.apache.fop.render.java2d;
 
 import java.awt.Font;
 import java.awt.FontFormatException;
+import java.awt.Rectangle;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.Map;
@@ -183,11 +184,31 @@ public class CustomFontMetricsMapper ext
         return typeface.getWidths();
     }
 
+    public Rectangle getBoundingBox(int glyphIndex, int size) {
+        return typeface.getBoundingBox(glyphIndex, size);
+    }
+
     /** {@inheritDoc} */
     public final int getXHeight(final int size) {
         return typeface.getXHeight(size);
     }
 
+    public int getUnderlinePosition(int size) {
+        return typeface.getUnderlinePosition(size);
+    }
+
+    public int getUnderlineThickness(int size) {
+        return typeface.getUnderlineThickness(size);
+    }
+
+    public int getStrikeoutPosition(int size) {
+        return typeface.getStrikeoutPosition(size);
+    }
+
+    public int getStrikeoutThickness(int size) {
+        return typeface.getStrikeoutThickness(size);
+    }
+
     /** {@inheritDoc} */
     public final boolean hasKerningInfo() {
         return typeface.hasKerningInfo();

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/java2d/Java2DFontMetrics.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/java2d/Java2DFontMetrics.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/java2d/Java2DFontMetrics.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/java2d/Java2DFontMetrics.java Mon Mar 17 09:31:13 2014
@@ -223,6 +223,26 @@ public class Java2DFontMetrics {
         return xHeight * 1000;
     }
 
+    public int getUnderlinePosition(String family, int style, int size) {
+        setFont(family, style, size);
+        return -Math.round(lineMetrics.getUnderlineOffset());
+    }
+
+    public int getUnderlineThickness(String family, int style, int size) {
+        setFont(family, style, size);
+        return Math.round(lineMetrics.getUnderlineThickness());
+    }
+
+    public int getStrikeoutPosition(String family, int style, int size) {
+        setFont(family, style, size);
+        return -Math.round(lineMetrics.getStrikethroughOffset());
+    }
+
+    public int getStrikeoutThickness(String family, int style, int size) {
+        setFont(family, style, size);
+        return Math.round(lineMetrics.getStrikethroughThickness());
+    }
+
     /**
      * Returns width (in 1/1000ths of point size) of character at
      * code point i

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java Mon Mar 17 09:31:13 2014
@@ -31,6 +31,7 @@ import org.apache.commons.logging.LogFac
 import org.apache.batik.bridge.BridgeContext;
 import org.apache.batik.bridge.GVTBuilder;
 import org.apache.batik.gvt.GraphicsNode;
+import org.apache.batik.gvt.font.DefaultFontFamilyResolver;
 
 import org.apache.fop.image.loader.batik.BatikUtil;
 import org.apache.fop.render.AbstractGenericSVGHandler;
@@ -128,8 +129,8 @@ public class Java2DSVGHandler extends Ab
 
         int x = info.currentXPosition;
         int y = info.currentYPosition;
-
-        SVGUserAgent ua = new SVGUserAgent(context.getUserAgent(), new AffineTransform());
+        SVGUserAgent ua = new SVGUserAgent(context.getUserAgent(), DefaultFontFamilyResolver.SINGLETON,
+                new AffineTransform());
 
         BridgeContext ctx = new BridgeContext(ua);
 

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/java2d/SystemFontMetricsMapper.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/java2d/SystemFontMetricsMapper.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/java2d/SystemFontMetricsMapper.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/render/java2d/SystemFontMetricsMapper.java Mon Mar 17 09:31:13 2014
@@ -20,6 +20,7 @@
 package org.apache.fop.render.java2d;
 
 // Java
+import java.awt.Rectangle;
 import java.util.Map;
 import java.util.Set;
 
@@ -133,6 +134,22 @@ public class SystemFontMetricsMapper ext
         return java2DFontMetrics.getXHeight(family, style, size);
     }
 
+    public int getUnderlinePosition(int size) {
+        return java2DFontMetrics.getUnderlinePosition(family, style, size);
+    }
+
+    public int getUnderlineThickness(int size) {
+        return java2DFontMetrics.getUnderlineThickness(family, style, size);
+    }
+
+    public int getStrikeoutPosition(int size) {
+        return java2DFontMetrics.getStrikeoutPosition(family, style, size);
+    }
+
+    public int getStrikeoutThickness(int size) {
+        return java2DFontMetrics.getStrikeoutThickness(family, style, size);
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -148,6 +165,10 @@ public class SystemFontMetricsMapper ext
         return java2DFontMetrics.getWidths(family, style, Java2DFontMetrics.FONT_SIZE);
     }
 
+    public Rectangle getBoundingBox(int glyphIndex, int size) {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
     /**
      * {@inheritDoc}
      */



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