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 [7/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/afp/fonts/AFPFont.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/AFPFont.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/AFPFont.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/AFPFont.java Mon Mar 17 09:31:13 2014
@@ -19,6 +19,7 @@
 
 package org.apache.fop.afp.fonts;
 
+import java.awt.Rectangle;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
@@ -34,6 +35,8 @@ import org.apache.fop.fonts.Typeface;
  */
 public abstract class AFPFont extends Typeface {
 
+    private static final double STRIKEOUT_POSITION_FACTOR = 0.45;
+
     /** The font name */
     protected final String name;
 
@@ -117,7 +120,34 @@ public abstract class AFPFont extends Ty
      */
     protected static final char toUnicodeCodepoint(int character) {
         //AFP fonts use Unicode directly as their mapped code points, so we can simply cast to char
-        return (char)character;
+        return (char) character;
+    }
+
+    /** {@inheritDoc} */
+    public int getUnderlineThickness(int size) {
+        // This is the FOCA recommendation in the absence of the Underline Thickness parameter
+        return getBoundingBox('-', size).height;
+    }
+
+    /** {@inheritDoc} */
+    public int getStrikeoutPosition(int size) {
+        //TODO This conflicts with the FOCA recommendation of 0 in the absence of the Throughscore Position
+        // parameter
+        return (int) (STRIKEOUT_POSITION_FACTOR * getCapHeight(size));
+    }
+
+    /** {@inheritDoc} */
+    public int getStrikeoutThickness(int size) {
+        // This is the FOCA recommendation in the absence of the Throughscore Thickness parameter
+        return getBoundingBox('-', size).height;
+    }
+
+    /** {@inheritDoc} */
+    public abstract Rectangle getBoundingBox(int glyphIndex, int size);
+
+    /** {@inheritDoc} */
+    public int[] getWidths() {
+        throw new UnsupportedOperationException();
     }
 
     /** {@inheritDoc} */

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java Mon Mar 17 09:31:13 2014
@@ -71,22 +71,6 @@ public abstract class AbstractOutlineFon
     }
 
     /**
-     * Get the first character in this font.
-     * @return the first character in this font
-     */
-    public int getFirstChar() {
-        return charSet.getFirstChar();
-    }
-
-    /**
-     * Get the last character in this font.
-     * @return the last character in this font
-     */
-    public int getLastChar() {
-        return charSet.getLastChar();
-    }
-
-    /**
      * The ascender is the part of a lowercase letter that extends above the
      * "x-height" (the height of the letter "x"), such as "d", "t", or "h". Also
      * used to denote the part of the letter extending above the x-height.
@@ -98,6 +82,17 @@ public abstract class AbstractOutlineFon
         return charSet.getAscender() * size;
     }
 
+    /** {@inheritDoc} */
+    public int getUnderlinePosition(int size) {
+        return charSet.getUnderscorePosition() * size;
+    }
+
+    @Override
+    public int getUnderlineThickness(int size) {
+        int underscoreWidth = charSet.getUnderscoreWidth();
+        return underscoreWidth == 0 ? super.getUnderlineThickness(size) : underscoreWidth * size;
+    }
+
     /**
      * Obtains the height of capital letters for the specified point size.
      *
@@ -130,40 +125,7 @@ public abstract class AbstractOutlineFon
         return charSet.getXHeight() * size;
     }
 
-    /**
-     * Obtain the width of the character for the specified point size.
-     * @param character the character
-     * @param size the font size (in mpt)
-     * @return the width of the character for the specified point size
-     */
-    public int getWidth(int character, int size) {
-        return charSet.getWidth(toUnicodeCodepoint(character)) * size;
-    }
 
-    /**
-     * Get the getWidth (in 1/1000ths of a point size) of all characters in this
-     * character set.
-     *
-     * @param size the font size (in mpt)
-     * @return the widths of all characters
-     */
-    public int[] getWidths(int size) {
-        int[] widths =  charSet.getWidths();
-        for (int i = 0; i < widths.length; i++) {
-            widths[i] = widths[i] * size;
-        }
-        return widths;
-    }
-
-    /**
-     * Get the getWidth (in 1/1000ths of a point size) of all characters in this
-     * character set.
-     *
-     * @return the widths of all characters
-     */
-    public int[] getWidths() {
-        return getWidths(1000);
-    }
 
     /** {@inheritDoc} */
     public boolean hasChar(char c) {

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/CharacterSet.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/CharacterSet.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/CharacterSet.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/CharacterSet.java Mon Mar 17 09:31:13 2014
@@ -19,10 +19,9 @@
 
 package org.apache.fop.afp.fonts;
 
+import java.awt.Rectangle;
 import java.io.UnsupportedEncodingException;
 import java.nio.charset.CharacterCodingException;
-import java.util.HashMap;
-import java.util.Map;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -63,6 +62,8 @@ public class CharacterSet {
 
     private static final int MAX_NAME_LEN = 8;
 
+    /** The current orientation (currently only 0 is supported by FOP) */
+    public static final int SUPPORTED_ORIENTATION = 0;
 
     /** The code page to which the character set relates */
     protected final String codePage;
@@ -79,11 +80,8 @@ public class CharacterSet {
     /** The path to the installed fonts */
     private final AFPResourceAccessor accessor;
 
-    /** The current orientation (currently only 0 is supported by FOP) */
-    private final String currentOrientation = "0";
-
     /** The collection of objects for each orientation */
-    private final Map<String, CharacterSetOrientation> characterSetOrientations;
+    private CharacterSetOrientation characterSetOrientation;
 
     /** The nominal vertical size (in millipoints) for bitmap fonts. 0 for outline fonts. */
     private int nominalVerticalSize;
@@ -116,8 +114,6 @@ public class CharacterSet {
         this.encoding = encoding;
         this.encoder = charsetType.getEncoder(encoding);
         this.accessor = accessor;
-
-        this.characterSetOrientations = new HashMap<String, CharacterSetOrientation>(4);
     }
 
      // right pad short names with space
@@ -131,7 +127,9 @@ public class CharacterSet {
      * @param cso the metrics for the orientation
      */
     public void addCharacterSetOrientation(CharacterSetOrientation cso) {
-        characterSetOrientations.put(String.valueOf(cso.getOrientation()), cso);
+        if (cso.getOrientation() == SUPPORTED_ORIENTATION) {
+            characterSetOrientation = cso;
+        }
     }
 
     /**
@@ -165,11 +163,24 @@ public class CharacterSet {
      * @return the ascender value in millipoints
      */
     public int getAscender() {
-
         return getCharacterSetOrientation().getAscender();
     }
 
     /**
+     * TODO
+     */
+    public int getUnderscoreWidth() {
+        return getCharacterSetOrientation().getUnderscoreWidth();
+    }
+
+    /**
+     * TODO
+     */
+    public int getUnderscorePosition() {
+        return getCharacterSetOrientation().getUnderscorePosition();
+    }
+
+    /**
      * Cap height is the average height of the uppercase characters in
      * a font. This value is specified by the designer of a font and is
      * usually the height of the uppercase M.
@@ -177,7 +188,6 @@ public class CharacterSet {
      * @return the cap height value in millipoints
      */
     public int getCapHeight() {
-
         return getCharacterSetOrientation().getCapHeight();
     }
 
@@ -194,24 +204,6 @@ public class CharacterSet {
     }
 
     /**
-     * Returns the first character in the character set
-     *
-     * @return the first character in the character set (Unicode codepoint)
-     */
-    public char getFirstChar() {
-        return getCharacterSetOrientation().getFirstChar();
-    }
-
-    /**
-     * Returns the last character in the character set
-     *
-     * @return the last character in the character set (Unicode codepoint)
-     */
-    public char getLastChar() {
-        return getCharacterSetOrientation().getLastChar();
-    }
-
-    /**
      * Returns the resource accessor to load the font resources with.
      * @return the resource accessor to load the font resources with
      */
@@ -220,16 +212,6 @@ public class CharacterSet {
     }
 
     /**
-     * Get the width (in 1/1000ths of a point size) of all characters
-     *
-     * @return the widths of all characters
-     */
-    public int[] getWidths() {
-
-        return getCharacterSetOrientation().getWidths();
-    }
-
-    /**
      * XHeight refers to the height of the lower case letters above the baseline.
      *
      * @return the typical height of characters
@@ -246,11 +228,13 @@ public class CharacterSet {
      * @param character the Unicode character from which the width will be calculated
      * @return the width of the character
      */
-    public int getWidth(char character) {
-        return getCharacterSetOrientation().getWidth(character);
+    public int getWidth(char character, int size) {
+        return getCharacterSetOrientation().getWidth(character, size);
     }
 
-
+    public Rectangle getCharacterBox(char character, int size) {
+        return getCharacterSetOrientation().getCharacterBox(character, size);
+    }
 
     /**
      * Returns the AFP character set identifier
@@ -309,9 +293,7 @@ public class CharacterSet {
      * @return characterSetOrentation The current orientation metrics.
      */
     private CharacterSetOrientation getCharacterSetOrientation() {
-        CharacterSetOrientation c
-            = characterSetOrientations.get(currentOrientation);
-        return c;
+        return characterSetOrientation;
     }
 
     /**

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java Mon Mar 17 09:31:13 2014
@@ -19,6 +19,7 @@
 
 package org.apache.fop.afp.fonts;
 
+import java.awt.Rectangle;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.MalformedURLException;
@@ -292,16 +293,14 @@ public abstract class CharacterSetBuilde
                     metricNormalizationFactor = 1000.0d * 72000.0d
                         / fontDescriptor.getNominalFontSizeInMillipoints() / dpi;
                 }
-
+                ValueNormalizer normalizer = new ValueNormalizer(metricNormalizationFactor);
                 //process D3AC89 Font Position
-                processFontPosition(structuredFieldReader, characterSetOrientations,
-                        metricNormalizationFactor);
-
+                processFontPosition(structuredFieldReader, characterSetOrientations, normalizer);
                 //process D38C89 Font Index (per orientation)
                 for (int i = 0; i < characterSetOrientations.length; i++) {
-                    processFontIndex(structuredFieldReader,
-                            characterSetOrientations[i], codePage, metricNormalizationFactor);
-                    characterSet.addCharacterSetOrientation(characterSetOrientations[i]);
+                    CharacterSetOrientation characterSetOrientation = characterSetOrientations[i];
+                    processFontIndex(structuredFieldReader, characterSetOrientation, codePage, normalizer);
+                    characterSet.addCharacterSetOrientation(characterSetOrientation);
                 }
             } else {
                 throw new IOException("Missing D3AE89 Font Control structured field.");
@@ -314,6 +313,19 @@ public abstract class CharacterSetBuilde
         return characterSet;
     }
 
+    private static class ValueNormalizer {
+
+        private final double factor;
+
+        public ValueNormalizer(double factor) {
+            this.factor = factor;
+        }
+
+        public int normalize(int value) {
+            return (int) Math.round(value *  factor);
+        }
+    }
+
     /**
      * Load the code page information from the appropriate file. The file name
      * to load is determined by the code page name and the file extension 'CDP'.
@@ -475,7 +487,7 @@ public abstract class CharacterSetBuilde
      * @throws IOException if an I/O exception of some sort has occurred.
      */
     private void processFontPosition(StructuredFieldReader structuredFieldReader,
-        CharacterSetOrientation[] characterSetOrientations, double metricNormalizationFactor)
+        CharacterSetOrientation[] characterSetOrientations, ValueNormalizer normalizer)
             throws IOException {
 
         byte[] data = structuredFieldReader.getNext(FONT_POSITION_SF);
@@ -493,48 +505,34 @@ public abstract class CharacterSetBuilde
                 if (position == 9) {
                     CharacterSetOrientation characterSetOrientation
                             = characterSetOrientations[characterSetOrientationIndex];
-
                     int xHeight = getSBIN(fpData, 2);
                     int capHeight = getSBIN(fpData, 4);
                     int ascHeight = getSBIN(fpData, 6);
                     int dscHeight = getSBIN(fpData, 8);
-
                     dscHeight = dscHeight * -1;
-
-                    characterSetOrientation.setXHeight(
-                            (int)Math.round(xHeight * metricNormalizationFactor));
-                    characterSetOrientation.setCapHeight(
-                            (int)Math.round(capHeight * metricNormalizationFactor));
-                    characterSetOrientation.setAscender(
-                            (int)Math.round(ascHeight * metricNormalizationFactor));
-                    characterSetOrientation.setDescender(
-                            (int)Math.round(dscHeight * metricNormalizationFactor));
+                    int underscoreWidth = getUBIN(fpData, 17);
+                    int underscorePosition = getSBIN(fpData, 20);
+                    characterSetOrientation.setXHeight(normalizer.normalize(xHeight));
+                    characterSetOrientation.setCapHeight(normalizer.normalize(capHeight));
+                    characterSetOrientation.setAscender(normalizer.normalize(ascHeight));
+                    characterSetOrientation.setDescender(normalizer.normalize(dscHeight));
+                    characterSetOrientation.setUnderscoreWidth(normalizer.normalize(underscoreWidth));
+                    characterSetOrientation.setUnderscorePosition(normalizer.normalize(underscorePosition));
                 }
             } else if (position == 22) {
                 position = 0;
                 characterSetOrientationIndex++;
                 fpData[position] = data[index];
             }
-
             position++;
         }
 
     }
 
-    /**
-     * Process the font index details for the character set orientation.
-     *
-     * @param structuredFieldReader the structured field reader
-     * @param cso the CharacterSetOrientation object to populate
-     * @param codepage the map of code pages
-     * @param metricNormalizationFactor factor to apply to the metrics to get normalized
-     *                  font metric values
-     * @throws IOException if an I/O exception of some sort has occurred.
-     */
-    private void processFontIndex(StructuredFieldReader structuredFieldReader,
-            CharacterSetOrientation cso, Map<String, String> codepage,
-            double metricNormalizationFactor)
-        throws IOException {
+
+    private void processFontIndex(StructuredFieldReader structuredFieldReader, CharacterSetOrientation cso,
+            Map<String, String> codepage, ValueNormalizer normalizer)
+            throws IOException {
 
         byte[] data = structuredFieldReader.getNext(FONT_INDEX_SF);
 
@@ -543,8 +541,6 @@ public abstract class CharacterSetBuilde
         byte[] gcgid = new byte[8];
         byte[] fiData = new byte[20];
 
-        char lowest = 255;
-        char highest = 0;
         String firstABCMismatch = null;
 
         // Read data, ignoring bytes 0 - 2
@@ -569,13 +565,15 @@ public abstract class CharacterSetBuilde
 
                     char cidx = idx.charAt(0);
                     int width = getUBIN(fiData, 0);
+                    int ascendHt = getSBIN(fiData, 2);
+                    int descendDp = getSBIN(fiData, 4);
                     int a = getSBIN(fiData, 10);
                     int b = getUBIN(fiData, 12);
                     int c = getSBIN(fiData, 14);
                     int abc = a + b + c;
                     int diff = Math.abs(abc - width);
                     if (diff != 0 && width != 0) {
-                        double diffPercent = 100 * diff / (double)width;
+                        double diffPercent = 100 * diff / (double) width;
                         if (diffPercent > 2) {
                             if (LOG.isTraceEnabled()) {
                                 LOG.trace(gcgiString + ": "
@@ -587,27 +585,16 @@ public abstract class CharacterSetBuilde
                             }
                         }
                     }
-
-                    if (cidx < lowest) {
-                        lowest = cidx;
-                    }
-
-                    if (cidx > highest) {
-                        highest = cidx;
-                    }
-
-                    int normalizedWidth = (int)Math.round(width * metricNormalizationFactor);
-
-                    cso.setWidth(cidx, normalizedWidth);
-
+                    int normalizedWidth = normalizer.normalize(width);
+                    int x0 = normalizer.normalize(a);
+                    int y0 = normalizer.normalize(-descendDp);
+                    int dx = normalizer.normalize(b);
+                    int dy = normalizer.normalize(ascendHt + descendDp);
+                    cso.setCharacterMetrics(cidx, normalizedWidth, new Rectangle(x0, y0, dx, dy));
                 }
-
             }
         }
 
-        cso.setFirstChar(lowest);
-        cso.setLastChar(highest);
-
         if (LOG.isDebugEnabled() && firstABCMismatch != null) {
             //Debug level because it usually is no problem.
             LOG.debug("Font has metrics inconsitencies where A+B+C doesn't equal the"

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/CharacterSetOrientation.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/CharacterSetOrientation.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/CharacterSetOrientation.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/CharacterSetOrientation.java Mon Mar 17 09:31:13 2014
@@ -19,7 +19,7 @@
 
 package org.apache.fop.afp.fonts;
 
-import java.util.Arrays;
+import java.awt.Rectangle;
 
 /**
  * The IBM Font Object Content Architecture (FOCA) supports presentation
@@ -60,23 +60,13 @@ public class CharacterSetOrientation {
     /**
      * The character widths in the character set (indexed using Unicode codepoints)
      */
-    private int[] charsWidths;
+    private IntegerKeyStore<CharacterMetrics> characterMetrics;
 
     /**
      * The height of lowercase letters
      */
     private int xHeight;
 
-    /**
-     * The first character (Unicode codepoint)
-     */
-    private char firstChar;
-
-    /**
-     * The last character (Unicode codepoint)
-     */
-    private char lastChar;
-
     /** The character set orientation */
     private final int orientation;
     /** space increment */
@@ -86,6 +76,10 @@ public class CharacterSetOrientation {
     /** Nominal Character Increment */
     private final int nomCharIncrement;
 
+    private int underscoreWidth;
+
+    private int underscorePosition;
+
     /**
      * Constructor for the CharacterSetOrientation, the orientation is
      * expressed as the degrees rotation (i.e 0, 90, 180, 270)
@@ -97,8 +91,7 @@ public class CharacterSetOrientation {
         this.spaceIncrement = spaceIncrement;
         this.emSpaceIncrement = emSpaceIncrement;
         this.nomCharIncrement = nomCharIncrement;
-        charsWidths = new int[256];
-        Arrays.fill(charsWidths, -1);
+        this.characterMetrics = new IntegerKeyStore<CharacterMetrics>();
     }
 
     /**
@@ -138,19 +131,17 @@ public class CharacterSetOrientation {
     }
 
     /**
-     * The first character in the character set
-     * @return the first character (Unicode codepoint)
+     * TODO
      */
-    public char getFirstChar() {
-        return firstChar;
+    public int getUnderscoreWidth() {
+        return underscoreWidth;
     }
 
     /**
-     * The last character in the character set
-     * @return the last character (Unicode codepoint)
+     * TODO
      */
-    public char getLastChar() {
-        return lastChar;
+    public int getUnderscorePosition() {
+        return underscorePosition;
     }
 
     /**
@@ -162,17 +153,6 @@ public class CharacterSetOrientation {
     }
 
     /**
-     * Get the width (in 1/1000ths of a point size) of all characters
-     * in this character set.
-     * @return the widths of all characters
-     */
-    public int[] getWidths() {
-        int[] arr = new int[(getLastChar() - getFirstChar()) + 1];
-        System.arraycopy(charsWidths, getFirstChar(), arr, 0, (getLastChar() - getFirstChar()) + 1);
-        return arr;
-    }
-
-    /**
      * XHeight refers to the height of the lower case letters above
      * the baseline.
      * @return heightX the typical height of characters
@@ -187,13 +167,38 @@ public class CharacterSetOrientation {
      * @param character the Unicode character to evaluate
      * @return the widths of the character
      */
-    public int getWidth(char character) {
-        if (character >= charsWidths.length) {
-            throw new IllegalArgumentException("Invalid character: "
-                    + character + " (" + Integer.toString(character)
-                    + "), maximum is " + (charsWidths.length - 1));
+    public int getWidth(char character, int size) {
+        CharacterMetrics cm = getCharacterMetrics(character);
+        return cm == null ? -1 : size * cm.width;
+    }
+
+    private CharacterMetrics getCharacterMetrics(char character) {
+        return characterMetrics.get((int) character);
+    }
+
+    /**
+     * Get the character box (rectangle with dimensions in 1/1000ths of a point size) of the character
+     * identified by the parameter passed.
+     * @param character the Unicode character to evaluate
+     * @return the character box
+     */
+    public Rectangle getCharacterBox(char character, int size) {
+        CharacterMetrics cm = getCharacterMetrics(character);
+        return scale(cm == null ? getFallbackCharacterBox() : cm.characterBox, size);
+    }
+
+    private static Rectangle scale(Rectangle rectangle, int size) {
+        if (rectangle == null) {
+            return null;
+        } else {
+        return new Rectangle((int) (size * rectangle.getX()), (int) (size * rectangle.getY()),
+                (int) (size * rectangle.getWidth()), (int) (size * rectangle.getHeight()));
         }
-        return charsWidths[character];
+    }
+
+    private Rectangle getFallbackCharacterBox() {
+        // TODO replace with something sensible
+        return new Rectangle(0, 0, 0, 0);
     }
 
     /**
@@ -233,19 +238,19 @@ public class CharacterSetOrientation {
     }
 
     /**
-     * The first character in the character set
-     * @param firstChar the first character
+     * TODO
+     * @param underscoreWidth the underscore width value in millipoints
      */
-    public void setFirstChar(char firstChar) {
-        this.firstChar = firstChar;
+    public void setUnderscoreWidth(int underscoreWidth) {
+        this.underscoreWidth = underscoreWidth;
     }
 
     /**
-     * The last character in the character set
-     * @param lastChar the last character
+     * TODO
+     * @param underscorePosition the underscore position value in millipoints
      */
-    public void setLastChar(char lastChar) {
-        this.lastChar = lastChar;
+    public void setUnderscorePosition(int underscorePosition) {
+        this.underscorePosition = underscorePosition;
     }
 
     /**
@@ -254,17 +259,8 @@ public class CharacterSetOrientation {
      * @param character the Unicode character for which the width is being set
      * @param width the widths of the character
      */
-    public void setWidth(char character, int width) {
-        if (character >= charsWidths.length) {
-            // Increase the size of the array if necessary
-            //  TODO Can we remove firstChar? surely firstChar==0 at this stage?
-            int[] arr = new int[(character - firstChar) + 1];
-            System.arraycopy(charsWidths, 0, arr, 0, charsWidths.length);
-            Arrays.fill(arr, charsWidths.length, character - firstChar, -1);
-            charsWidths = arr;
-        }
-        charsWidths[character] = width;
-
+    public void setCharacterMetrics(char character, int width, Rectangle characterBox) {
+        characterMetrics.put((int) character, new CharacterMetrics(width, characterBox));
     }
 
     /**
@@ -299,4 +295,16 @@ public class CharacterSetOrientation {
     public int getNominalCharIncrement() {
         return this.nomCharIncrement;
     }
+
+    private static class CharacterMetrics {
+
+        public final int width;
+
+        public final Rectangle characterBox;
+
+        public CharacterMetrics(int width, Rectangle characterBox) {
+            this.width = width;
+            this.characterBox = characterBox;
+        }
+    }
 }

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/DoubleByteFont.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/DoubleByteFont.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/DoubleByteFont.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/DoubleByteFont.java Mon Mar 17 09:31:13 2014
@@ -19,6 +19,7 @@
 
 package org.apache.fop.afp.fonts;
 
+import java.awt.Rectangle;
 import java.lang.Character.UnicodeBlock;
 import java.util.HashSet;
 import java.util.Set;
@@ -68,7 +69,7 @@ public class DoubleByteFont extends Abst
     public int getWidth(int character, int size) {
         int charWidth;
         try {
-            charWidth = charSet.getWidth(toUnicodeCodepoint(character));
+            charWidth = charSet.getWidth(toUnicodeCodepoint(character), size);
         } catch (IllegalArgumentException e) {
             if (!charsProcessed.contains(character)) {
                 charsProcessed.add(character);
@@ -80,9 +81,9 @@ public class DoubleByteFont extends Abst
         }
 
         if (charWidth == -1) {
-            charWidth = getDefaultCharacterWidth(character);
+            charWidth = getDefaultCharacterWidth(character) * size;
         }
-        return charWidth * size;
+        return charWidth;
     }
 
     private int getDefaultCharacterWidth(int character) {
@@ -94,6 +95,33 @@ public class DoubleByteFont extends Abst
         }
     }
 
+    @Override
+    public Rectangle getBoundingBox(int character, int size) {
+        Rectangle characterBox = getBoundingBoxOrNull(character, size);
+        if (characterBox == null) {
+            characterBox = getDefaultCharacterBox(character, size);
+        }
+        return characterBox;
+    }
+
+    private Rectangle getBoundingBoxOrNull(int character, int size) {
+        Rectangle characterBox = null;
+        try {
+            characterBox = charSet.getCharacterBox(toUnicodeCodepoint(character), size);
+        } catch (IllegalArgumentException e) {
+            if (!charsProcessed.contains(character)) {
+                charsProcessed.add(character);
+                getAFPEventProducer().charactersetMissingMetrics(this, (char) character,
+                        charSet.getName().trim());
+            }
+        }
+        return characterBox;
+    }
+
+    private Rectangle getDefaultCharacterBox(int character, int size) {
+        return getBoundingBoxOrNull('-', size);
+    }
+
     private int inferCharWidth(int character) {
 
         //Is this character an ideograph?

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java Mon Mar 17 09:31:13 2014
@@ -19,6 +19,8 @@
 
 package org.apache.fop.afp.fonts;
 
+import java.awt.Rectangle;
+
 import org.apache.fop.afp.AFPEventProducer;
 import org.apache.fop.afp.util.AFPResourceAccessor;
 import org.apache.fop.fonts.Typeface;
@@ -84,45 +86,31 @@ public class FopCharacterSet extends Cha
     }
 
     /**
-     * The first character in the character set
-     * @return the first character
+     * XHeight refers to the height of the lower case letters above the baseline.
+     * @return the typical height of characters
      */
-    public char getFirstChar() {
-        return 0;
+    public int getXHeight() {
+        return charSet.getXHeight(1);
     }
 
-    /**
-     * The last character in the character set
-     * @return the last character
-     */
-    public char getLastChar() {
-        return 0;
+    @Override
+    public int getWidth(char character, int size) {
+        return charSet.getWidth(character, size);
     }
 
-    /**
-     * Get the width (in 1/1000ths of a point size) of all characters
-     * @return the widths of all characters
-     */
-    public int[] getWidths() {
-        return charSet.getWidths();
-    }
+    @Override
+    public Rectangle getCharacterBox(char character, int size) {
+        return charSet.getBoundingBox(character, size);
+    };
 
-    /**
-     * XHeight refers to the height of the lower case letters above the baseline.
-     * @return the typical height of characters
-     */
-    public int getXHeight() {
-        return charSet.getXHeight(1);
+    @Override
+    public int getUnderscoreWidth() {
+        return charSet.getUnderlineThickness(1);
     }
 
-    /**
-     * Get the width (in 1/1000ths of a point size) of the character
-     * identified by the parameter passed.
-     * @param character the character from which the width will be calculated
-     * @return the width of the character
-     */
-    public int getWidth(char character) {
-        return charSet.getWidth(character, 1);
+    @Override
+    public int getUnderscorePosition() {
+        return charSet.getUnderlinePosition(1);
     }
 
     /**

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/OutlineFont.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/OutlineFont.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/OutlineFont.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/OutlineFont.java Mon Mar 17 09:31:13 2014
@@ -19,6 +19,8 @@
 
 package org.apache.fop.afp.fonts;
 
+import java.awt.Rectangle;
+
 import org.apache.fop.afp.AFPEventProducer;
 
 /**
@@ -38,4 +40,18 @@ public class OutlineFont extends Abstrac
         super(name, embeddable, charSet, eventProducer);
     }
 
+    /**
+     * Obtain the width of the character for the specified point size.
+     * @param character the character
+     * @param size the font size (in mpt)
+     * @return the width of the character for the specified point size
+     */
+    public int getWidth(int character, int size) {
+        return charSet.getWidth(toUnicodeCodepoint(character), size);
+    }
+
+    @Override
+    public Rectangle getBoundingBox(int character, int size) {
+        return charSet.getCharacterBox(toUnicodeCodepoint(character), size);
+    }
 }

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/RasterFont.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/RasterFont.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/RasterFont.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/fonts/RasterFont.java Mon Mar 17 09:31:13 2014
@@ -19,8 +19,8 @@
 
 package org.apache.fop.afp.fonts;
 
+import java.awt.Rectangle;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.Map;
 import java.util.SortedMap;
 import java.util.TreeMap;
@@ -135,46 +135,21 @@ public class RasterFont extends AFPFont 
 
     }
 
-    /**
-     * Get the first character in this font.
-     * @return the first character in this font.
-     */
-    public int getFirstChar() {
-        Iterator<CharacterSet> it = charSets.values().iterator();
-        if (it.hasNext()) {
-            CharacterSet csm = it.next();
-            return csm.getFirstChar();
-        } else {
-            String msg = "getFirstChar() - No character set found for font:" + getFontName();
-            LOG.error(msg);
-            throw new FontRuntimeException(msg);
-        }
-    }
-
-    /**
-     * Get the last character in this font.
-     * @return the last character in this font.
-     */
-    public int getLastChar() {
-
-        Iterator<CharacterSet> it = charSets.values().iterator();
-        if (it.hasNext()) {
-            CharacterSet csm = it.next();
-            return csm.getLastChar();
+    private int metricsToAbsoluteSize(CharacterSet cs, int value, int givenSize) {
+        int nominalVerticalSize = cs.getNominalVerticalSize();
+        if (nominalVerticalSize != 0) {
+            return value * nominalVerticalSize;
         } else {
-            String msg = "getLastChar() - No character set found for font:" + getFontName();
-            LOG.error(msg);
-            throw new FontRuntimeException(msg);
+            return value * givenSize;
         }
-
     }
 
-    private int metricsToAbsoluteSize(CharacterSet cs, int value, int givenSize) {
+    private int metricsToAbsoluteSize(CharacterSet cs, double value, int givenSize) {
         int nominalVerticalSize = cs.getNominalVerticalSize();
         if (nominalVerticalSize != 0) {
-            return value * nominalVerticalSize;
+            return (int) (value * nominalVerticalSize);
         } else {
-            return value * givenSize;
+            return (int) (value * givenSize);
         }
     }
 
@@ -191,6 +166,20 @@ public class RasterFont extends AFPFont 
         return metricsToAbsoluteSize(cs, cs.getAscender(), size);
     }
 
+    /** {@inheritDoc} */
+    public int getUnderlinePosition(int size) {
+        CharacterSet cs = getCharacterSet(size);
+        return metricsToAbsoluteSize(cs, cs.getUnderscorePosition(), size);
+    }
+
+    @Override
+    public int getUnderlineThickness(int size) {
+        CharacterSet cs = getCharacterSet(size);
+        int underscoreWidth = cs.getUnderscoreWidth();
+        return underscoreWidth == 0 ? super.getUnderlineThickness(size)
+                : metricsToAbsoluteSize(cs, underscoreWidth, size);
+    }
+
     /**
      * Obtains the height of capital letters for the specified point size.
      *
@@ -234,33 +223,20 @@ public class RasterFont extends AFPFont 
      */
     public int getWidth(int character, int size) {
         CharacterSet cs = getCharacterSet(size);
-        return metricsToAbsoluteSize(cs, cs.getWidth(toUnicodeCodepoint(character)), size);
+        return metricsToAbsoluteSize(cs, cs.getWidth(toUnicodeCodepoint(character), 1), size);
     }
 
     /**
-     * Get the getWidth (in 1/1000ths of a point size) of all characters in this
-     * character set.
-     *
-     * @param size the font size (in mpt)
-     * @return the widths of all characters
+     * TODO
      */
-    public int[] getWidths(int size) {
+    public Rectangle getBoundingBox(int character, int size) {
         CharacterSet cs = getCharacterSet(size);
-        int[] widths = cs.getWidths();
-        for (int i = 0, c = widths.length; i < c; i++) {
-            widths[i] = metricsToAbsoluteSize(cs, widths[i], size);
-        }
-        return widths;
-    }
-
-    /**
-     * Get the getWidth (in 1/1000ths of a point size) of all characters in this
-     * character set.
-     *
-     * @return the widths of all characters
-     */
-    public int[] getWidths() {
-        return getWidths(1000);
+        Rectangle characterBox = cs.getCharacterBox(toUnicodeCodepoint(character), 1);
+        int x = metricsToAbsoluteSize(cs, characterBox.getX(), size);
+        int y = metricsToAbsoluteSize(cs, characterBox.getY(), size);
+        int w = metricsToAbsoluteSize(cs, characterBox.getWidth(), size);
+        int h = metricsToAbsoluteSize(cs, characterBox.getHeight(), size);
+        return new Rectangle(x, y, w, h);
     }
 
     /** {@inheritDoc} */

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java Mon Mar 17 09:31:13 2014
@@ -67,7 +67,11 @@ public class GraphicsCharacterString ext
 
     /** {@inheritDoc} */
     public int getDataLength() {
-        return super.getDataLength() + str.length();
+        try {
+            return super.getDataLength() + getStringAsBytes().length;
+        } catch (IOException ioe) {
+            throw new RuntimeException(ioe);
+        }
     }
 
     /** {@inheritDoc} */

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/svg/AFPBridgeContext.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/svg/AFPBridgeContext.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/svg/AFPBridgeContext.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/svg/AFPBridgeContext.java Mon Mar 17 09:31:13 2014
@@ -25,13 +25,17 @@ import org.apache.batik.bridge.BridgeCon
 import org.apache.batik.bridge.DocumentLoader;
 import org.apache.batik.bridge.UserAgent;
 import org.apache.batik.gvt.TextPainter;
+import org.apache.batik.gvt.font.DefaultFontFamilyResolver;
+import org.apache.batik.gvt.font.FontFamilyResolver;
 
 import org.apache.xmlgraphics.image.loader.ImageManager;
 import org.apache.xmlgraphics.image.loader.ImageSessionContext;
 
 import org.apache.fop.afp.AFPGraphics2D;
+import org.apache.fop.events.EventBroadcaster;
 import org.apache.fop.fonts.FontInfo;
 import org.apache.fop.svg.AbstractFOPBridgeContext;
+import org.apache.fop.svg.font.AggregatingFontFamilyResolver;
 
 /**
  * An AFP specific implementation of a Batik BridgeContext
@@ -40,6 +44,8 @@ public class AFPBridgeContext extends Ab
 
     private final AFPGraphics2D g2d;
 
+    private final EventBroadcaster eventBroadCaster;
+
     /**
      * Constructs a new bridge context.
      *
@@ -54,47 +60,35 @@ public class AFPBridgeContext extends Ab
      */
     public AFPBridgeContext(UserAgent userAgent, FontInfo fontInfo,
             ImageManager imageManager, ImageSessionContext imageSessionContext,
-            AffineTransform linkTransform, AFPGraphics2D g2d) {
+            AffineTransform linkTransform, AFPGraphics2D g2d, EventBroadcaster eventBroadCaster) {
         super(userAgent, fontInfo, imageManager, imageSessionContext, linkTransform);
         this.g2d = g2d;
+        this.eventBroadCaster = eventBroadCaster;
     }
 
-    /**
-     * Constructs a new bridge context.
-     * @param userAgent the user agent
-     * @param documentLoader the Document Loader to use for referenced documents.
-     * @param fontInfo the font list for the text painter, may be null
-     *                 in which case text is painted as shapes
-     * @param imageManager an image manager
-     * @param imageSessionContext an image session context
-     * @param linkTransform AffineTransform to properly place links,
-     *                      may be null
-     * @param g2d an AFPGraphics 2D implementation
-     */
-    public AFPBridgeContext(UserAgent userAgent, DocumentLoader documentLoader,
+    private AFPBridgeContext(UserAgent userAgent, DocumentLoader documentLoader,
             FontInfo fontInfo, ImageManager imageManager,
             ImageSessionContext imageSessionContext,
-            AffineTransform linkTransform, AFPGraphics2D g2d) {
-        super(userAgent, documentLoader, fontInfo, imageManager,
-              imageSessionContext, linkTransform);
+            AffineTransform linkTransform, AFPGraphics2D g2d, EventBroadcaster eventBroadCaster) {
+        super(userAgent, documentLoader, fontInfo, imageManager, imageSessionContext, linkTransform);
         this.g2d = g2d;
+        this.eventBroadCaster = eventBroadCaster;
     }
 
     /** {@inheritDoc} */
     @Override
     public void registerSVGBridges() {
         super.registerSVGBridges();
-
         if (fontInfo != null) {
             AFPTextHandler textHandler = new AFPTextHandler(fontInfo, g2d.getResourceManager());
             g2d.setCustomTextHandler(textHandler);
-
-            TextPainter textPainter = new AFPTextPainter(textHandler);
-            setTextPainter(textPainter);
-
+            //TODO
+            FontFamilyResolver fontFamilyResolver = new AggregatingFontFamilyResolver(
+                    new AFPFontFamilyResolver(fontInfo, eventBroadCaster), DefaultFontFamilyResolver.SINGLETON);
+            TextPainter textPainter = new AFPTextPainter(textHandler, fontFamilyResolver);
+            setTextPainter(new AFPTextPainter(textHandler, fontFamilyResolver));
             putBridge(new AFPTextElementBridge(textPainter));
         }
-
         putBridge(new AFPImageElementBridge());
     }
 
@@ -105,7 +99,7 @@ public class AFPBridgeContext extends Ab
                 fontInfo,
                 getImageManager(),
                 getImageSessionContext(),
-                linkTransform, g2d);
+                linkTransform, g2d, eventBroadCaster);
     }
 
 }

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/svg/AFPTextHandler.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/svg/AFPTextHandler.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/svg/AFPTextHandler.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/svg/AFPTextHandler.java Mon Mar 17 09:31:13 2014
@@ -120,9 +120,8 @@ public class AFPTextHandler extends FOPT
 
             // set the color
             AFPPaintingState paintingState = g2d.getPaintingState();
-            if (paintingState.setColor(color)) {
-                graphicsObj.setColor(color);
-            }
+            paintingState.setColor(color);
+            graphicsObj.setColor(color);
 
             // set the character set
             int fontReference = 0;
@@ -135,27 +134,18 @@ public class AFPTextHandler extends FOPT
                 if (log.isDebugEnabled()) {
                     log.debug("  with overriding font: " + internalFontName + ", " + fontSize);
                 }
-            } else {
-                java.awt.Font awtFont = g2d.getFont();
-                Font fopFont = fontInfo.getFontInstanceForAWTFont(awtFont);
-                if (log.isDebugEnabled()) {
-                    log.debug("  with font: " + fopFont);
-                }
-                internalFontName = fopFont.getFontName();
-                fontSize = fopFont.getFontSize();
+                fontSize = (int) Math.round(g2d.convertToAbsoluteLength(fontSize));
+                fontReference = registerPageFont(pageFonts, internalFontName, fontSize);
+                // TODO: re-think above registerPageFont code...
+                AFPFont afpFont = (AFPFont) fontInfo.getFonts().get(internalFontName);
+                final CharacterSet charSet = afpFont.getCharacterSet(fontSize);
+                // Work-around for InfoPrint's AFP which loses character set state
+                // over Graphics Data
+                // boundaries.
+                graphicsObj.setCharacterSet(fontReference);
+                // add the character string
+                graphicsObj.addString(str, Math.round(x), Math.round(y), charSet);
             }
-            fontSize = (int)Math.round(
-                    g2d.convertToAbsoluteLength(fontSize));
-            fontReference = registerPageFont(pageFonts, internalFontName, fontSize);
-            // TODO: re-think above registerPageFont code...
-            AFPFont afpFont = (AFPFont) fontInfo.getFonts().get(internalFontName);
-            final CharacterSet charSet = afpFont.getCharacterSet(fontSize);
-            // Work-around for InfoPrint's AFP which loses character set state
-            // over Graphics Data
-            // boundaries.
-            graphicsObj.setCharacterSet(fontReference);
-            // add the character string
-            graphicsObj.addString(str, Math.round(x), Math.round(y), charSet);
         } else {
             //Inside Batik's SVG filter operations, you won't get an AFPGraphics2D
             g.drawString(str, x, y);

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/svg/AFPTextPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/svg/AFPTextPainter.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/svg/AFPTextPainter.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/afp/svg/AFPTextPainter.java Mon Mar 17 09:31:13 2014
@@ -21,6 +21,9 @@ package org.apache.fop.afp.svg;
 
 import java.awt.Graphics2D;
 
+import org.apache.batik.gvt.font.FontFamilyResolver;
+import org.apache.batik.gvt.renderer.StrokingTextPainter;
+
 import org.apache.fop.afp.AFPGraphics2D;
 import org.apache.fop.svg.AbstractFOPTextPainter;
 import org.apache.fop.svg.FOPTextHandler;
@@ -39,8 +42,8 @@ public class AFPTextPainter extends Abst
      * Create a new text painter with the given font information.
      * @param nativeTextHandler the NativeTextHandler instance used for text painting
      */
-    public AFPTextPainter(FOPTextHandler nativeTextHandler) {
-        super(nativeTextHandler);
+    public AFPTextPainter(FOPTextHandler nativeTextHandler, FontFamilyResolver fopFontFamilyResolver) {
+        super(nativeTextHandler, new FOPStrokingTextPainter(fopFontFamilyResolver));
     }
 
     /** {@inheritDoc} */
@@ -48,4 +51,18 @@ public class AFPTextPainter extends Abst
         return g2d instanceof AFPGraphics2D;
     }
 
+    private static class FOPStrokingTextPainter extends StrokingTextPainter {
+
+        private final FontFamilyResolver fopFontFontFamily;
+
+        FOPStrokingTextPainter(FontFamilyResolver fopFontFontFamily) {
+            this.fopFontFontFamily = fopFontFontFamily;
+        }
+
+        @Override
+        protected FontFamilyResolver getFontFamilyResolver() {
+            return fopFontFontFamily;
+        }
+    }
+
 }

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/area/AreaTreeParser.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/area/AreaTreeParser.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/area/AreaTreeParser.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/area/AreaTreeParser.java Mon Mar 17 09:31:13 2014
@@ -62,6 +62,7 @@ import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.area.Trait.Background;
 import org.apache.fop.area.Trait.InternalLink;
 import org.apache.fop.area.inline.AbstractTextArea;
+import org.apache.fop.area.inline.Container;
 import org.apache.fop.area.inline.ForeignObject;
 import org.apache.fop.area.inline.Image;
 import org.apache.fop.area.inline.InlineArea;
@@ -195,6 +196,7 @@ public class AreaTreeParser {
             makers.put("space", new SpaceMaker());
             makers.put("leader", new LeaderMaker());
             makers.put("viewport", new InlineViewportMaker());
+            makers.put("container", new ContainerMaker());
             makers.put("image", new ImageMaker());
             makers.put("foreignObject", new ForeignObjectMaker());
             makers.put("bookmarkTree", new BookmarkTreeMaker());
@@ -863,6 +865,21 @@ public class AreaTreeParser {
             }
         }
 
+        private class ContainerMaker extends AbstractMaker {
+
+            public void startElement(Attributes attributes) {
+                Container container = new Container();
+                transferForeignObjects(attributes, container);
+                InlineViewport parent = (InlineViewport) areaStack.peek();
+                parent.setContent(container);
+                areaStack.push(container);
+            }
+
+            public void endElement() {
+                assertObjectOfClass(areaStack.pop(), Container.class);
+            }
+        }
+
         private class InlineViewportMaker extends AbstractMaker {
 
             public void startElement(Attributes attributes) {

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/area/inline/Container.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/area/inline/Container.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/area/inline/Container.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/area/inline/Container.java Mon Mar 17 09:31:13 2014
@@ -51,13 +51,12 @@ public class Container extends Area {
     public Container() {
     }
 
-    /**
-     * Add the block to this area.
-     *
-     * @param block the block area to add
-     */
-    public void addBlock(Block block) {
-        blocks.add(block);
+    @Override
+    public void addChildArea(Area child) {
+        if (!(child instanceof Block)) {
+            throw new IllegalArgumentException("Container only accepts block areas");
+        }
+        blocks.add((Block) child);
     }
 
     /**
@@ -65,7 +64,7 @@ public class Container extends Area {
      *
      * @return the list of block areas
      */
-    public List getBlocks() {
+    public List<Block> getBlocks() {
         return blocks;
     }
 

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/cli/CommandLineOptions.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/cli/CommandLineOptions.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/cli/CommandLineOptions.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/cli/CommandLineOptions.java Mon Mar 17 09:31:13 2014
@@ -124,6 +124,8 @@ public class CommandLineOptions {
     private boolean conserveMemoryPolicy = false;
     /* true if a complex script features are enabled */
     private boolean useComplexScriptFeatures = true;
+    /* set to true if -dpi used in command line */
+    private boolean overrideTargetResolution = false;
 
     private FopFactory factory;
     private FOUserAgent foUserAgent;
@@ -440,6 +442,7 @@ public class CommandLineOptions {
                     "if you use '-dpi', you must specify a resolution (dots per inch)");
         } else {
             this.targetResolution = Integer.parseInt(args[i + 1]);
+            this.overrideTargetResolution = true;
             return 1;
         }
     }
@@ -1017,6 +1020,9 @@ public class CommandLineOptions {
             try {
                 FopConfParser fopConfParser = new FopConfParser(userConfigFile, baseURI);
                 fopFactoryBuilder = fopConfParser.getFopFactoryBuilder();
+                if (this.overrideTargetResolution) {
+                    fopFactoryBuilder.setTargetResolution(targetResolution);
+                }
             } catch (SAXException e) {
                 throw new FOPException(e);
             }

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/FOText.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/FOText.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/FOText.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/FOText.java Mon Mar 17 09:31:13 2014
@@ -21,7 +21,6 @@ package org.apache.fop.fo;
 
 import java.awt.Color;
 import java.nio.CharBuffer;
-import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Stack;
 
@@ -38,12 +37,13 @@ import org.apache.fop.fo.properties.Comm
 import org.apache.fop.fo.properties.KeepProperty;
 import org.apache.fop.fo.properties.Property;
 import org.apache.fop.fo.properties.SpaceProperty;
+import org.apache.fop.fonts.TextFragment;
 import org.apache.fop.util.CharUtilities;
 
 /**
  * A text node (PCDATA) in the formatting object tree.
  */
-public class FOText extends FONode implements CharSequence {
+public class FOText extends FONode implements CharSequence, TextFragment {
 
     /** the <code>CharBuffer</code> containing the text */
     private CharBuffer charBuffer;
@@ -93,9 +93,6 @@ public class FOText extends FONode imple
     /* bidi levels */
     private int[] bidiLevels;
 
-    /* advanced script processing state */
-    private Map/*<MapRange,String>*/ mappings;
-
     private static final int IS_WORD_CHAR_FALSE = 0;
     private static final int IS_WORD_CHAR_TRUE = 1;
     private static final int IS_WORD_CHAR_MAYBE = 2;
@@ -804,93 +801,6 @@ public class FOText extends FONode imple
         }
     }
 
-    /**
-     * Add characters mapped by script substitution processing.
-     * @param start index in character buffer
-     * @param end index in character buffer
-     * @param mappedChars sequence of character codes denoting substituted characters
-     */
-    public void addMapping(int start, int end, CharSequence mappedChars) {
-        if (mappings == null) {
-            mappings = new java.util.HashMap();
-        }
-        mappings.put(new MapRange(start, end), mappedChars.toString());
-    }
-
-    /**
-     * Determine if characters over specific interval  have a mapping.
-     * @param start index in character buffer
-     * @param end index in character buffer
-     * @return true if a mapping exist such that the mapping's interval is coincident to
-     * [start,end)
-     */
-    public boolean hasMapping(int start, int end) {
-        return (mappings != null) && (mappings.containsKey(new MapRange(start, end)));
-    }
-
-    /**
-     * Obtain mapping of characters over specific interval.
-     * @param start index in character buffer
-     * @param end index in character buffer
-     * @return a string of characters representing the mapping over the interval
-     * [start,end)
-     */
-    public String getMapping(int start, int end) {
-        if (mappings != null) {
-            return (String) mappings.get(new MapRange(start, end));
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Obtain length of mapping of characters over specific interval.
-     * @param start index in character buffer
-     * @param end index in character buffer
-     * @return the length of the mapping (if present) or zero
-     */
-    public int getMappingLength(int start, int end) {
-        if (mappings != null) {
-            return ((String) mappings.get(new MapRange(start, end))) .length();
-        } else {
-            return 0;
-        }
-    }
-
-    /**
-     * 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
-     */
-    public int[] getMappingBidiLevels(int start, int end) {
-        if (hasMapping(start, end)) {
-            int   nc = end - start;
-            int   nm = getMappingLength(start, end);
-            int[] la = getBidiLevels(start, end);
-            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 getBidiLevels(start, end);
-        }
-    }
-
     @Override
     protected Stack collectDelimitedTextRanges(Stack ranges, DelimitedTextRange currentRange) {
         if (currentRange != null) {

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/flow/InlineContainer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/flow/InlineContainer.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/flow/InlineContainer.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/flow/InlineContainer.java Mon Mar 17 09:31:13 2014
@@ -37,49 +37,38 @@ import org.apache.fop.traits.Direction;
 import org.apache.fop.traits.WritingMode;
 import org.apache.fop.traits.WritingModeTraits;
 
-/**
- * Class modelling the <a href="http://www.w3.org/TR/xsl/#fo_inline-container">
- * <code>fo:inline-container</code></a> object.
- */
 public class InlineContainer extends FObj {
 
-    // The value of FO traits (refined properties) that apply to fo:inline-container.
-    private Length alignmentAdjust;
-    private int alignmentBaseline;
-    private Length baselineShift;
+    private LengthRangeProperty inlineProgressionDimension;
     private LengthRangeProperty blockProgressionDimension;
+    private int overflow;
     private CommonBorderPaddingBackground commonBorderPaddingBackground;
     private CommonMarginInline commonMarginInline;
-    private int clip;
-    private int dominantBaseline;
-    private LengthRangeProperty inlineProgressionDimension;
+    private Numeric referenceOrientation;
+    private int displayAlign;
     private KeepProperty keepTogether;
+    private KeepProperty keepWithNext;
+    private KeepProperty keepWithPrevious;
     private SpaceProperty lineHeight;
-    private int overflow;
-    private Numeric referenceOrientation;
+    private Length alignmentAdjust;
+    private int alignmentBaseline;
+    private Length baselineShift;
+    private int dominantBaseline;
     private WritingModeTraits writingModeTraits;
-    // Unused but valid items, commented out for performance:
-    //     private CommonRelativePosition commonRelativePosition;
-    //     private int displayAlign;
-    //     private Length height;
-    //     private KeepProperty keepWithNext;
-    //     private KeepProperty keepWithPrevious;
-    //     private Length width;
-    // End of FO trait values
 
     /** used for FO validation */
-    private boolean blockItemFound = false;
+    private boolean blockItemFound;
 
     /**
-     * Base constructor
+     * Creates a new instance.
      *
-     * @param parent {@link FONode} that is the parent of this object
+     * @param parent the parent of this inline-container
      */
     public InlineContainer(FONode parent) {
         super(parent);
     }
 
-    /** {@inheritDoc} */
+    @Override
     public void bind(PropertyList pList) throws FOPException {
         super.bind(pList);
         alignmentAdjust = pList.get(PR_ALIGNMENT_ADJUST).getLength();
@@ -88,28 +77,31 @@ public class InlineContainer extends FOb
         blockProgressionDimension = pList.get(PR_BLOCK_PROGRESSION_DIMENSION).getLengthRange();
         commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
         commonMarginInline = pList.getMarginInlineProps();
-        clip = pList.get(PR_CLIP).getEnum();
+        displayAlign = pList.get(PR_DISPLAY_ALIGN).getEnum();
         dominantBaseline = pList.get(PR_DOMINANT_BASELINE).getEnum();
         inlineProgressionDimension = pList.get(PR_INLINE_PROGRESSION_DIMENSION).getLengthRange();
         keepTogether = pList.get(PR_KEEP_TOGETHER).getKeep();
+        keepWithNext = pList.get(PR_KEEP_WITH_NEXT).getKeep();
+        keepWithPrevious = pList.get(PR_KEEP_WITH_PREVIOUS).getKeep();
         lineHeight = pList.get(PR_LINE_HEIGHT).getSpace();
         overflow = pList.get(PR_OVERFLOW).getEnum();
         referenceOrientation = pList.get(PR_REFERENCE_ORIENTATION).getNumeric();
         writingModeTraits = new WritingModeTraits(
-            WritingMode.valueOf(pList.get(PR_WRITING_MODE).getEnum()),
-            pList.getExplicit(PR_WRITING_MODE) != null);
+                WritingMode.valueOf(pList.get(PR_WRITING_MODE).getEnum()),
+                pList.getExplicit(PR_WRITING_MODE) != null);
     }
 
     /**
      * {@inheritDoc}
      * <br>XSL Content Model: marker* (%block;)+
      */
+    @Override
     protected void validateChildNode(Locator loc, String nsURI, String localName)
                 throws ValidationException {
         if (FO_URI.equals(nsURI)) {
             if (localName.equals("marker")) {
                 if (blockItemFound) {
-                   nodesOutOfOrderError(loc, "fo:marker", "(%block;)");
+                   nodesOutOfOrderError(loc, "fo:marker", "(%block;)+");
                 }
             } else if (!isBlockItem(nsURI, localName)) {
                 invalidChildError(loc, nsURI, localName);
@@ -119,153 +111,129 @@ public class InlineContainer extends FOb
         }
     }
 
-    /** {@inheritDoc} */
+    @Override
     public void endOfNode() throws FOPException {
         if (!blockItemFound) {
             missingChildElementError("marker* (%block;)+");
         }
     }
 
-    /** @return the "alignment-adjust" FO trait */
-    public Length getAlignmentAdjust() {
-        return alignmentAdjust;
+    /** {@inheritDoc} */
+    public String getLocalName() {
+        return "inline-container";
     }
 
-    /** @return the "alignment-baseline" FO trait */
-    public int getAlignmentBaseline() {
-        return alignmentBaseline;
+    /**
+     * {@inheritDoc}
+     * @return {@link org.apache.fop.fo.Constants#FO_INLINE_CONTAINER}
+     */
+    public int getNameId() {
+        return FO_INLINE_CONTAINER;
     }
 
-    /** @return the "baseline-shift" FO trait */
-    public Length getBaselineShift() {
-        return baselineShift;
+    public LengthRangeProperty getInlineProgressionDimension() {
+        return inlineProgressionDimension;
     }
 
-    /** @return the "block-progression-dimension" FO trait */
     public LengthRangeProperty getBlockProgressionDimension() {
         return blockProgressionDimension;
     }
 
-    /** @return the "clip" FO trait */
-    public int getClip() {
-        return clip;
+    public int getOverflow() {
+        return overflow;
     }
 
-    /**@return Returns the {@link CommonBorderPaddingBackground} */
     public CommonBorderPaddingBackground getCommonBorderPaddingBackground() {
         return this.commonBorderPaddingBackground;
     }
 
-    /** @return Returns the {@link CommonMarginInline} */
     public CommonMarginInline getCommonMarginInline() {
         return this.commonMarginInline;
     }
 
-    /** @return the "dominant-baseline" FO trait */
-    public int getDominantBaseline() {
-        return dominantBaseline;
+    public int getReferenceOrientation() {
+        return referenceOrientation.getValue();
+    }
+
+    public int getDisplayAlign() {
+        return this.displayAlign;
+    }
+
+    public KeepProperty getKeepWithPrevious() {
+        return keepWithPrevious;
     }
 
-    /** @return the "keep-together" FO trait */
     public KeepProperty getKeepTogether() {
         return keepTogether;
     }
 
-    /** @return the "inline-progression-dimension" FO trait */
-    public LengthRangeProperty getInlineProgressionDimension() {
-        return inlineProgressionDimension;
+    public KeepProperty getKeepWithNext() {
+        return keepWithNext;
     }
 
-    /** @return the "line-height" FO trait */
     public SpaceProperty getLineHeight() {
         return lineHeight;
     }
 
-    /** @return the "overflow" FO trait */
-    public int getOverflow() {
-        return overflow;
+    public Length getAlignmentAdjust() {
+        return alignmentAdjust;
     }
 
-    /** @return the "reference-orientation" FO trait */
-    public int getReferenceOrientation() {
-        return referenceOrientation.getValue();
+    public int getAlignmentBaseline() {
+        return alignmentBaseline;
+    }
+
+    public Length getBaselineShift() {
+        return baselineShift;
+    }
+
+    public int getDominantBaseline() {
+        return dominantBaseline;
+    }
+
+    public WritingMode getWritingMode() {
+        return writingModeTraits.getWritingMode();
     }
 
     /**
-     * Obtain inline progression direction.
-     * @return the inline progression direction
+     * Obtain writing mode explicit indicator.
+     * @return the writing mode explicit indicator
      */
+    public boolean getExplicitWritingMode() {
+        return writingModeTraits.getExplicitWritingMode();
+    }
+
     public Direction getInlineProgressionDirection() {
         return writingModeTraits.getInlineProgressionDirection();
     }
 
-    /**
-     * Obtain block progression direction.
-     * @return the block progression direction
-     */
     public Direction getBlockProgressionDirection() {
         return writingModeTraits.getBlockProgressionDirection();
     }
 
-    /**
-     * Obtain column progression direction.
-     * @return the column progression direction
-     */
     public Direction getColumnProgressionDirection() {
         return writingModeTraits.getColumnProgressionDirection();
     }
 
-    /**
-     * Obtain row progression direction.
-     * @return the row progression direction
-     */
     public Direction getRowProgressionDirection() {
         return writingModeTraits.getRowProgressionDirection();
     }
 
-    /**
-     * Obtain (baseline) shift direction.
-     * @return the (baseline) shift direction
-     */
     public Direction getShiftDirection() {
         return writingModeTraits.getShiftDirection();
     }
 
-    /**
-     * Obtain writing mode.
-     * @return the writing mode
-     */
-    public WritingMode getWritingMode() {
-        return writingModeTraits.getWritingMode();
-    }
-
-    /**
-     * Obtain writing mode explicit indicator.
-     * @return the writing mode explicit indicator
-     */
-    public boolean getExplicitWritingMode() {
-        return writingModeTraits.getExplicitWritingMode();
-    }
-
-    /** {@inheritDoc} */
-    public String getLocalName() {
-        return "inline-container";
-    }
-
-    /**
-     * {@inheritDoc}
-     * @return {@link org.apache.fop.fo.Constants#FO_INLINE_CONTAINER}
-     */
-    public int getNameId() {
-        return FO_INLINE_CONTAINER;
-    }
-
     @Override
     public boolean isDelimitedTextRangeBoundary(int boundary) {
         return false;
     }
 
     @Override
+    public boolean generatesReferenceAreas() {
+        return true;
+    }
+
+    @Override
     protected boolean isBidiBoundary(boolean propagate) {
         return getExplicitWritingMode();
     }

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/properties/FontSizePropertyMaker.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/properties/FontSizePropertyMaker.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/properties/FontSizePropertyMaker.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fo/properties/FontSizePropertyMaker.java Mon Mar 17 09:31:13 2014
@@ -105,6 +105,9 @@ public class FontSizePropertyMaker
             // than the last caculated step
             lastStepFontSize = nextStepFontSize;
             nextStepFontSize = (int)Math.round(lastStepFontSize * scale);
+            if (nextStepFontSize == lastStepFontSize) {
+                break;
+            }
         }
         // baseFontSize is between last and next step font size
         // Return the step value closer to the baseFontSize

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fonts/Base14Font.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fonts/Base14Font.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fonts/Base14Font.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fonts/Base14Font.java Mon Mar 17 09:31:13 2014
@@ -25,4 +25,15 @@ package org.apache.fop.fonts;
  */
 public abstract class Base14Font extends Typeface {
 
+    /** Thickness for underline and strikeout. */
+    private static final int LINE_THICKNESS = 50;
+
+    public int getStrikeoutPosition(int size) {
+        return getXHeight(size) / 2;
+    }
+
+    public int getStrikeoutThickness(int size) {
+        return size * LINE_THICKNESS;
+    }
+
 }

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fonts/CustomFont.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fonts/CustomFont.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fonts/CustomFont.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fonts/CustomFont.java Mon Mar 17 09:31:13 2014
@@ -37,6 +37,9 @@ import org.apache.fop.apps.io.InternalRe
 public abstract class CustomFont extends Typeface
             implements FontDescriptor, MutableFont {
 
+    /** Fallback thickness for underline and strikeout when not provided by the font. */
+    private static final int DEFAULT_LINE_THICKNESS = 50;
+
     private String fontName;
     private String fullName;
     private Set<String> familyNames;
@@ -60,6 +63,14 @@ public abstract class CustomFont extends
     private int firstChar;
     private int lastChar = 255;
 
+    private int underlinePosition;
+
+    private int underlineThickness;
+
+    private int strikeoutPosition;
+
+    private int strikeoutThickness;
+
     private Map<Integer, Map<Integer, Integer>> kerning;
 
     private boolean useKerning = true;
@@ -507,4 +518,40 @@ public abstract class CustomFont extends
         return copy;
     }
 
+    public int getUnderlinePosition(int size) {
+        return (underlinePosition == 0)
+                ? getDescender(size) / 2
+                : size * underlinePosition;
+    }
+
+    public void setUnderlinePosition(int underlinePosition) {
+        this.underlinePosition = underlinePosition;
+    }
+
+    public int getUnderlineThickness(int size) {
+        return size * ((underlineThickness == 0) ? DEFAULT_LINE_THICKNESS : underlineThickness);
+    }
+
+    public void setUnderlineThickness(int underlineThickness) {
+        this.underlineThickness = underlineThickness;
+    }
+
+    public int getStrikeoutPosition(int size) {
+        return (strikeoutPosition == 0)
+                ? getXHeight(size) / 2
+                : size * strikeoutPosition;
+    }
+
+    public void setStrikeoutPosition(int strikeoutPosition) {
+        this.strikeoutPosition = strikeoutPosition;
+    }
+
+    public int getStrikeoutThickness(int size) {
+        return (strikeoutThickness == 0) ? getUnderlineThickness(size) : size * strikeoutThickness;
+    }
+
+    public void setStrikeoutThickness(int strikeoutThickness) {
+        this.strikeoutThickness = strikeoutThickness;
+    }
+
 }

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fonts/FontInfo.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fonts/FontInfo.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fonts/FontInfo.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fonts/FontInfo.java Mon Mar 17 09:31:13 2014
@@ -30,6 +30,7 @@ import java.util.TreeSet;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
+
 /**
  * The FontInfo holds font information for the layout and rendering of a fo document.
  * This stores the list of available fonts that are setup by
@@ -135,12 +136,10 @@ public class FontInfo {
         if (oldName != null) {
             int oldPriority = tripletPriorities.get(triplet).intValue();
             if (oldPriority < newPriority) {
-                logDuplicateFont(triplet, false, oldName, oldPriority,
-                            internalFontKey, newPriority);
+                logDuplicateFont(triplet, false, oldName, oldPriority, internalFontKey, newPriority);
                 return;
             } else {
-                logDuplicateFont(triplet, true, oldName, oldPriority,
-                            internalFontKey, newPriority);
+                logDuplicateFont(triplet, true, oldName, oldPriority, internalFontKey, newPriority);
             }
         }
         this.triplets.put(triplet, internalFontKey);
@@ -157,9 +156,8 @@ public class FontInfo {
      * @param newKey the new internal font name
      * @param newPriority the priority of the duplicate font mapping
      */
-    private void logDuplicateFont(FontTriplet triplet, boolean replacing,
-                                  String oldKey, int oldPriority,
-                                  String newKey, int newPriority) {
+    private void logDuplicateFont(FontTriplet triplet, boolean replacing, String oldKey, int oldPriority,
+            String newKey, int newPriority) {
         if (log.isDebugEnabled()) {
             log.debug(triplet
                     + (replacing ? ": Replacing " : ": Not replacing ")
@@ -198,8 +196,7 @@ public class FontInfo {
      *                  default font if not found
      * @return internal font triplet key
      */
-    private FontTriplet fontLookup(String family, String style,
-                             int weight, boolean substitutable) {
+    private FontTriplet fontLookup(String family, String style, int weight, boolean substitutable) {
         if (log.isTraceEnabled()) {
             log.trace("Font lookup: " + family + " " + style + " " + weight
                     + (substitutable ? " substitutable" : ""));
@@ -302,8 +299,7 @@ public class FontInfo {
      * @return the requested Font instance
      */
     public Font getFontInstance(FontTriplet triplet, int fontSize) {
-        Map<Integer, Font> sizes
-            = getFontInstanceCache().get(triplet);
+        Map<Integer, Font> sizes = getFontInstanceCache().get(triplet);
         if (sizes == null) {
             sizes = new HashMap<Integer, Font>();
             getFontInstanceCache().put(triplet, sizes);
@@ -379,13 +375,11 @@ public class FontInfo {
      * @param weight font weight
      * @return the font triplet of the font chosen
      */
-    public FontTriplet fontLookup(String family, String style,
-                             int weight) {
+    public FontTriplet fontLookup(String family, String style, int weight) {
         return fontLookup(family, style, weight, true);
     }
 
-    private List<FontTriplet> fontLookup(String[] families, String style,
-            int weight, boolean substitutable) {
+    private List<FontTriplet> fontLookup(String[] families, String style, int weight, boolean substitutable) {
         List<FontTriplet> matchingTriplets = new ArrayList<FontTriplet>();
         FontTriplet triplet = null;
         for (int i = 0; i < families.length; i++) {
@@ -410,8 +404,7 @@ public class FontInfo {
      * @return the set of font triplets of all supported and chosen font-families
      *          in the specified style and weight.
      */
-    public FontTriplet[] fontLookup(String[] families, String style,
-                             int weight) {
+    public FontTriplet[] fontLookup(String[] families, String style, int weight) {
         if (families.length == 0) {
             throw new IllegalArgumentException("Specify at least one font family");
         }
@@ -434,8 +427,8 @@ public class FontInfo {
                 sb.append(families[i]);
             }
             throw new IllegalStateException(
-                        "fontLookup must return an array with at least one "
-                        + "FontTriplet on the last call. Lookup: " + sb.toString());
+                    "fontLookup must return an array with at least one "
+                            + "FontTriplet on the last call. Lookup: " + sb.toString());
 
         }
         FontTriplet[] fontTriplets = new FontTriplet[matchedTriplets.size()];
@@ -469,8 +462,7 @@ public class FontInfo {
      * @param weight font weight
      * @return internal key
      */
-    public FontTriplet findAdjustWeight(String family, String style,
-                             int weight) {
+    public FontTriplet findAdjustWeight(String family, String style, int weight) {
         FontTriplet key = null;
         String f = null;
         int newWeight = weight;
@@ -542,8 +534,7 @@ public class FontInfo {
      * @param weight font weight
      * @return internal key
      */
-    public static FontTriplet createFontKey(String family, String style,
-                                       int weight) {
+    public static FontTriplet createFontKey(String family, String style, int weight) {
         return new FontTriplet(family, style, weight);
     }
 

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fonts/FontMetrics.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fonts/FontMetrics.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fonts/FontMetrics.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fonts/FontMetrics.java Mon Mar 17 09:31:13 2014
@@ -19,6 +19,7 @@
 
 package org.apache.fop.fonts;
 
+import java.awt.Rectangle;
 import java.util.Map;
 import java.util.Set;
 
@@ -120,6 +121,15 @@ public interface FontMetrics {
     int[] getWidths();
 
     /**
+     * Returns the bounding box of the glyph at the given index, for the given font size.
+     *
+     * @param glyphIndex glyph index
+     * @param size font size
+     * @return the scaled bounding box scaled in 1/1000ths of the given size
+     */
+    Rectangle getBoundingBox(int glyphIndex, int size);
+
+    /**
      * Indicates if the font has kering information.
      * @return True, if kerning is available.
      */
@@ -131,4 +141,38 @@ public interface FontMetrics {
      */
     Map<Integer, Map<Integer, Integer>> getKerningInfo();
 
+    /**
+     * Returns the distance from the baseline to the center of the underline (negative
+     * value indicates below baseline).
+     *
+     * @param size font size
+     * @return the position in 1/1000ths of the font size
+     */
+    int getUnderlinePosition(int size);
+
+    /**
+     * Returns the thickness of the underline.
+     *
+     * @param size font size
+     * @return the thickness in 1/1000ths of the font size
+     */
+    int getUnderlineThickness(int size);
+
+    /**
+     * Returns the distance from the baseline to the center of the strikeout line
+     * (negative value indicates below baseline).
+     *
+     * @param size font size
+     * @return the position in 1/1000ths of the font size
+     */
+    int getStrikeoutPosition(int size);
+
+    /**
+     * Returns the thickness of the strikeout line.
+     *
+     * @param size font size
+     * @return the thickness in 1/1000ths of the font size
+     */
+    int getStrikeoutThickness(int size);
+
 }

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fonts/LazyFont.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fonts/LazyFont.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fonts/LazyFont.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fonts/LazyFont.java Mon Mar 17 09:31:13 2014
@@ -18,6 +18,7 @@
 /* $Id$ */
 
 package org.apache.fop.fonts;
+import java.awt.Rectangle;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URI;
@@ -250,6 +251,26 @@ public class LazyFont extends Typeface i
         return realFont.getXHeight(size);
     }
 
+    public int getUnderlinePosition(int size) {
+        load(true);
+        return realFont.getUnderlinePosition(size);
+    }
+
+    public int getUnderlineThickness(int size) {
+        load(true);
+        return realFont.getUnderlineThickness(size);
+    }
+
+    public int getStrikeoutPosition(int size) {
+        load(true);
+        return realFont.getStrikeoutPosition(size);
+    }
+
+    public int getStrikeoutThickness(int size) {
+        load(true);
+        return realFont.getStrikeoutThickness(size);
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -268,6 +289,11 @@ public class LazyFont extends Typeface i
         return realFont.getWidths();
     }
 
+    public Rectangle getBoundingBox(int glyphIndex, int size) {
+        load(true);
+        return realFont.getBoundingBox(glyphIndex, size);
+    }
+
     /**
      * {@inheritDoc}
      */

Modified: xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fonts/MultiByteFont.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fonts/MultiByteFont.java?rev=1578276&r1=1578275&r2=1578276&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fonts/MultiByteFont.java (original)
+++ xmlgraphics/fop/branches/Temp_WhitespaceManagement/src/java/org/apache/fop/fonts/MultiByteFont.java Mon Mar 17 09:31:13 2014
@@ -19,6 +19,7 @@
 
 package org.apache.fop.fonts;
 
+import java.awt.Rectangle;
 import java.nio.CharBuffer;
 import java.nio.IntBuffer;
 import java.util.BitSet;
@@ -68,6 +69,9 @@ public class MultiByteFont extends CIDFo
     private int firstUnmapped;
     private int lastUnmapped;
 
+    /** Contains the character bounding boxes for all characters in the font */
+    protected Rectangle[] boundingBoxes;
+
     private boolean isOTFFile = false;
 
     // since for most users the most likely glyphs are in the first cmap segments we store their mapping.
@@ -196,6 +200,12 @@ public class MultiByteFont extends CIDFo
         return arr;
     }
 
+    public Rectangle getBoundingBox(int glyphIndex, int size) {
+        int index = isEmbeddable() ? cidSet.getOriginalGlyphIndex(glyphIndex) : glyphIndex;
+        Rectangle bbox = boundingBoxes[index];
+        return new Rectangle(bbox.x * size, bbox.y * size, bbox.width * size, bbox.height * size);
+    }
+
     /**
      * Returns the glyph index for a Unicode character. The method returns 0 if there's no
      * such glyph in the character map.
@@ -401,6 +411,14 @@ public class MultiByteFont extends CIDFo
     }
 
     /**
+     * Sets the bounding boxes array.
+     * @param boundingBoxes array of bounding boxes.
+     */
+    public void setBBoxArray(Rectangle[] boundingBoxes) {
+        this.boundingBoxes = boundingBoxes;
+    }
+
+    /**
      * Returns a Map of used Glyphs.
      * @return Map Map of used Glyphs
      */



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