Author: cbowditch
Date: Tue Jul  7 10:21:07 2009
New Revision: 791781

URL: http://svn.apache.org/viewvc?rev=791781&view=rev
Log:
bug fix: fractional points sizes in AFP not working correctly together with 
fo:inline

Modified:
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/AFPBase12FontCollection.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/AFPFontReader.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/CharacterSet.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/OutlineFont.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/RasterFont.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/MapCodedFont.java

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/AFPBase12FontCollection.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/AFPBase12FontCollection.java?rev=791781&r1=791780&r2=791781&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/AFPBase12FontCollection.java
 (original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/AFPBase12FontCollection.java
 Tue Jul  7 10:21:07 2009
@@ -49,7 +49,7 @@
 
     private void addCharacterSet(RasterFont font, String charsetName, 
Base14Font base14) {
         for (int i = 0; i < RASTER_SIZES.length; i++) {
-            int size = RASTER_SIZES[i];
+            int size = RASTER_SIZES[i] * 1000;
             FopCharacterSet characterSet = new FopCharacterSet(
                     CharacterSet.DEFAULT_CODEPAGE, 
CharacterSet.DEFAULT_ENCODING,
                     charsetName + CHARSET_REF[i], base14);

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/AFPFontReader.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/AFPFontReader.java?rev=791781&r1=791780&r2=791781&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/AFPFontReader.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/AFPFontReader.java 
Tue Jul  7 10:21:07 2009
@@ -177,7 +177,8 @@
             StructuredFieldReader structuredFieldReader = new 
StructuredFieldReader(inputStream);
 
             // Process D3A689 Font Descriptor
-            int pointSize = processFontDescriptor(structuredFieldReader);
+            FontDescriptor fontDescriptor = 
processFontDescriptor(structuredFieldReader);
+            
characterSet.setNominalVerticalSize(fontDescriptor.getNominalFontSizeInMillipoints());
 
             // Process D3A789 Font Control
             FontControl fontControl = 
processFontControl(structuredFieldReader);
@@ -187,12 +188,13 @@
                 CharacterSetOrientation[] characterSetOrientations
                     = processFontOrientation(structuredFieldReader);
 
-                int dpi = fontControl.getDpi();
-                int metricNormalizationFactor = 0;
+                int metricNormalizationFactor;
                 if (fontControl.isRelative()) {
                     metricNormalizationFactor = 1;
                 } else {
-                    metricNormalizationFactor = 72000 / dpi / pointSize;
+                    int dpi = fontControl.getDpi();
+                    metricNormalizationFactor = 1000 * 72000
+                        / fontDescriptor.getNominalFontSizeInMillipoints() / 
dpi;
                 }
 
                 //process D3AC89 Font Position
@@ -274,15 +276,13 @@
      * Process the font descriptor details using the structured field reader.
      *
      * @param structuredFieldReader the structured field reader
-     * @return the nominal size of the font (in points)
+     * @return a class representing the font descriptor
      */
-    private static int processFontDescriptor(StructuredFieldReader 
structuredFieldReader)
+    private static FontDescriptor processFontDescriptor(StructuredFieldReader 
structuredFieldReader)
     throws IOException {
 
         byte[] fndData = structuredFieldReader.getNext(FONT_DESCRIPTOR_SF);
-
-        int nominalPointSize = (((fndData[39] & 0xFF) << 8) + (fndData[40] & 
0xFF)) / 10;
-        return nominalPointSize;
+        return new FontDescriptor(fndData);
     }
 
     /**
@@ -303,8 +303,13 @@
             if (fncData[7] == (byte) 0x02) {
                 fontControl.setRelative(true);
             }
-            int metricResolution = (((fncData[9] & 0xFF) << 8) + (fncData[10] 
& 0xFF)) / 10;
-            fontControl.setDpi(metricResolution);
+            int metricResolution = getUBIN(fncData, 9);
+            if (metricResolution == 1000) {
+                //Special case: 1000 units per em (rather than dpi)
+                fontControl.setUnitsPerEm(1000);
+            } else {
+                fontControl.setDpi(metricResolution / 10);
+            }
         }
         return fontControl;
     }
@@ -378,7 +383,7 @@
      *                  font metric values
      */
     private void processFontPosition(StructuredFieldReader 
structuredFieldReader,
-        CharacterSetOrientation[] characterSetOrientations, int 
metricNormalizationFactor)
+        CharacterSetOrientation[] characterSetOrientations, double 
metricNormalizationFactor)
             throws IOException {
 
         byte[] data = structuredFieldReader.getNext(FONT_POSITION_SF);
@@ -397,17 +402,21 @@
                     CharacterSetOrientation characterSetOrientation
                             = 
characterSetOrientations[characterSetOrientationIndex];
 
-                    int xHeight = ((fpData[2] & 0xFF) << 8) + (fpData[3] & 
0xFF);
-                    int capHeight = ((fpData[4] & 0xFF) << 8) + (fpData[5] & 
0xFF);
-                    int ascHeight = ((fpData[6] & 0xFF) << 8) + (fpData[7] & 
0xFF);
-                    int dscHeight = ((fpData[8] & 0xFF) << 8) + (fpData[9] & 
0xFF);
+                    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(xHeight * 
metricNormalizationFactor);
-                    characterSetOrientation.setCapHeight(capHeight * 
metricNormalizationFactor);
-                    characterSetOrientation.setAscender(ascHeight * 
metricNormalizationFactor);
-                    characterSetOrientation.setDescender(dscHeight * 
metricNormalizationFactor);
+                    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));
                 }
             } else if (position == 22) {
                 position = 0;
@@ -430,7 +439,8 @@
      *                  font metric values
      */
     private void processFontIndex(StructuredFieldReader structuredFieldReader,
-        CharacterSetOrientation cso, Map/*<String,String>*/ codepage, int 
metricNormalizationFactor)
+        CharacterSetOrientation cso, Map/*<String,String>*/ codepage,
+        double metricNormalizationFactor)
         throws IOException {
 
         byte[] data = structuredFieldReader.getNext(FONT_INDEX_SF);
@@ -442,6 +452,7 @@
 
         int lowest = 255;
         int highest = 0;
+        String firstABCMismatch = null;
 
         // Read data, ignoring bytes 0 - 2
         for (int index = 3; index < data.length; index++) {
@@ -464,7 +475,26 @@
                 if (idx != null) {
 
                     int cidx = idx.charAt(0);
-                    int width = ((fiData[0] & 0xFF) << 8) + (fiData[1] & 0xFF);
+                    int width = getUBIN(fiData, 0);
+                    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;
+                        //if difference > 2%
+                        if (diffPercent > 2) {
+                            if (log.isTraceEnabled()) {
+                                log.trace(gcgiString + ": "
+                                        + a + " + " + b + " + " + c + " = " + 
(a + b + c)
+                                        + " but found: " + width);
+                            }
+                            if (firstABCMismatch == null) {
+                                firstABCMismatch = gcgiString;
+                            }
+                        }
+                    }
 
                     if (cidx < lowest) {
                         lowest = cidx;
@@ -474,9 +504,9 @@
                         highest = cidx;
                     }
 
-                    int a = (width * metricNormalizationFactor);
+                    int normalizedWidth = (int)Math.round(width * 
metricNormalizationFactor);
 
-                    cso.setWidth(cidx, a);
+                    cso.setWidth(cidx, normalizedWidth);
 
                 }
 
@@ -486,11 +516,32 @@
         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"
+                    + " character increment. The first such character found: "
+                    + firstABCMismatch);
+        }
+    }
+
+    private static int getUBIN(byte[] data, int start) {
+        return ((data[start] & 0xFF) << 8) + (data[start + 1] & 0xFF);
+    }
+
+    private static int getSBIN(byte[] data, int start) {
+        int ubin = ((data[start] & 0xFF) << 8) + (data[start + 1] & 0xFF);
+        if ((ubin & 0x8000) != 0) {
+            //extend sign
+            return ubin | 0xFFFF0000;
+        } else {
+            return ubin;
+        }
     }
 
     private class FontControl {
 
         private int dpi;
+        private int unitsPerEm;
 
         private boolean isRelative = false;
 
@@ -502,6 +553,14 @@
             dpi = i;
         }
 
+        public int getUnitsPerEm() {
+            return this.unitsPerEm;
+        }
+
+        public void setUnitsPerEm(int value) {
+            this.unitsPerEm = value;
+        }
+
         public boolean isRelative() {
             return isRelative;
         }
@@ -511,4 +570,18 @@
         }
     }
 
+    private static class FontDescriptor {
+
+        private byte[] data;
+
+        public FontDescriptor(byte[] data) {
+            this.data = data;
+        }
+
+        public int getNominalFontSizeInMillipoints() {
+            int nominalFontSize = 100 * getUBIN(data, 39);
+            return nominalFontSize;
+        }
+    }
+
 }

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/CharacterSet.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/CharacterSet.java?rev=791781&r1=791780&r2=791781&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/CharacterSet.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/CharacterSet.java 
Tue Jul  7 10:21:07 2009
@@ -95,6 +95,9 @@
     /** The collection of objects for each orientation */
     private Map characterSetOrientations = null;
 
+    /** The nominal vertical size (in millipoints) for bitmap fonts. 0 for 
outline fonts. */
+    private int nominalVerticalSize = 0;
+
     /**
      * Constructor for the CharacterSetMetric object, the character set is used
      * to load the font information from the actual AFP font.
@@ -159,6 +162,23 @@
     }
 
     /**
+     * Sets the nominal vertical size of the font in the case of bitmap fonts.
+     * @param nominalVerticalSize the nominal vertical size (in millipoints)
+     */
+    public void setNominalVerticalSize(int nominalVerticalSize) {
+        this.nominalVerticalSize = nominalVerticalSize;
+    }
+
+    /**
+     * Returns the nominal vertical size of the font in the case of bitmap 
fonts. For outline fonts,
+     * zero is returned, because these are scalable fonts.
+     * @return the nominal vertical size (in millipoints) for bitmap fonts, or 
0 for outline fonts.
+     */
+    public int getNominalVerticalSize() {
+        return this.nominalVerticalSize;
+    }
+
+    /**
      * Ascender height is the distance from the character baseline to the
      * top of the character box. A negative ascender height signifies that
      * all of the graphic character is below the character baseline. For

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/OutlineFont.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/OutlineFont.java?rev=791781&r1=791780&r2=791781&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/OutlineFont.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/OutlineFont.java 
Tue Jul  7 10:21:07 2009
@@ -87,8 +87,7 @@
      * "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.
      *
-     * @param size
-     *            the point size
+     * @param size the font size (in mpt)
      * @return the ascender for the given size
      */
     public int getAscender(int size) {
@@ -98,8 +97,7 @@
     /**
      * Obtains the height of capital letters for the specified point size.
      *
-     * @param size
-     *            the point size
+     * @param size the font size (in mpt)
      * @return the cap height for the given size
      */
     public int getCapHeight(int size) {
@@ -111,8 +109,7 @@
      * base line, such as "g", "j", or "p". Also used to denote the part of the
      * letter extending below the base line.
      *
-     * @param size
-     *            the point size
+     * @param size the font size (in mpt)
      * @return the descender for the given size
      */
     public int getDescender(int size) {
@@ -122,8 +119,7 @@
     /**
      * The "x-height" (the height of the letter "x").
      *
-     * @param size
-     *            the point size
+     * @param size the font size (in mpt)
      * @return the x height for the given size
      */
     public int getXHeight(int size) {
@@ -133,7 +129,7 @@
     /**
      * Obtain the width of the character for the specified point size.
      * @param character the character
-     * @param size point size
+     * @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) {
@@ -144,8 +140,7 @@
      * Get the getWidth (in 1/1000ths of a point size) of all characters in 
this
      * character set.
      *
-     * @param size
-     *            the point size
+     * @param size the font size (in mpt)
      * @return the widths of all characters
      */
     public int[] getWidths(int size) {

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/RasterFont.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/RasterFont.java?rev=791781&r1=791780&r2=791781&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/RasterFont.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/RasterFont.java Tue 
Jul  7 10:21:07 2009
@@ -19,10 +19,10 @@
 
 package org.apache.fop.afp.fonts;
 
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.SortedMap;
-import java.util.HashMap;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -163,26 +163,37 @@
 
     }
 
+    private int metricsToAbsoluteSize(CharacterSet cs, int value, int 
givenSize) {
+        int nominalVerticalSize = cs.getNominalVerticalSize();
+        if (nominalVerticalSize != 0) {
+            return value * nominalVerticalSize;
+        } else {
+            return value * givenSize;
+        }
+    }
+
     /**
      * 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.
      *
-     * @param size the point size (in mpt)
+     * @param size the font size (in mpt)
      * @return the ascender for the given point size
      */
     public int getAscender(int size) {
-        return getCharacterSet(size).getAscender() * size;
+        CharacterSet cs = getCharacterSet(size);
+        return metricsToAbsoluteSize(cs, cs.getAscender(), size);
     }
 
     /**
      * Obtains the height of capital letters for the specified point size.
      *
-     * @param size the point size (in mpt)
+     * @param size the font size (in mpt)
      * @return the cap height for the specified point size
      */
     public int getCapHeight(int size) {
-        return getCharacterSet(size).getCapHeight() * size;
+        CharacterSet cs = getCharacterSet(size);
+        return metricsToAbsoluteSize(cs, cs.getCapHeight(), size);
     }
 
     /**
@@ -190,42 +201,50 @@
      * base line, such as "g", "j", or "p". Also used to denote the part of the
      * letter extending below the base line.
      *
-     * @param size the point size (in mpt)
+     * @param size the font size (in mpt)
      * @return the descender for the specified point size
      */
     public int getDescender(int size) {
-        return getCharacterSet(size).getDescender() * size;
+        CharacterSet cs = getCharacterSet(size);
+        return metricsToAbsoluteSize(cs, cs.getDescender(), size);
     }
 
     /**
      * The "x-height" (the height of the letter "x").
      *
-     * @param size the point size (in mpt)
+     * @param size the font size (in mpt)
      * @return the x height for the given point size
      */
     public int getXHeight(int size) {
-        return getCharacterSet(size).getXHeight() * size;
+        CharacterSet cs = getCharacterSet(size);
+        return metricsToAbsoluteSize(cs, cs.getXHeight(), size);
     }
 
     /**
      * Obtain the width of the character for the specified point size.
      * @param character the character
-     * @param size the point size (in mpt)
+     * @param size the font size (in mpt)
      * @return the width for the given point size
      */
     public int getWidth(int character, int size) {
-        return getCharacterSet(size).getWidth(character) * size;
+        CharacterSet cs = getCharacterSet(size);
+        return metricsToAbsoluteSize(cs, cs.getWidth(character), size);
     }
 
     /**
      * Get the getWidth (in 1/1000ths of a point size) of all characters in 
this
      * character set.
      *
-     * @param size  the point size (in mpt)
+     * @param size the font size (in mpt)
      * @return the widths of all characters
      */
     public int[] getWidths(int size) {
-        return getCharacterSet(size).getWidths();
+        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;
     }
 
     /**

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/MapCodedFont.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/MapCodedFont.java?rev=791781&r1=791780&r2=791781&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/MapCodedFont.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/MapCodedFont.java 
Tue Jul  7 10:21:07 2009
@@ -206,7 +206,7 @@
 
                 // There are approximately 72 points to 1 inch or 20 1440ths 
per point.
 
-                fontDefinition.scale = ((size / 1000) * 20);
+                fontDefinition.scale = 20 * size / 1000;
 
                 fontDefinition.codePage = cs.getCodePage().getBytes(
                     AFPConstants.EBCIDIC_ENCODING);



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to