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 je...@apache.org on 2006/03/16 14:51:17 UTC

svn commit: r386327 [2/3] - in /xmlgraphics/fop/trunk: ./ src/codegen/ src/java/org/apache/fop/apps/ src/java/org/apache/fop/area/ src/java/org/apache/fop/area/inline/ src/java/org/apache/fop/fonts/ src/java/org/apache/fop/layoutmgr/inline/ src/java/or...

Modified: xmlgraphics/fop/trunk/src/codegen/TimesRoman.xml
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/codegen/TimesRoman.xml?rev=386327&r1=386326&r2=386327&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/codegen/TimesRoman.xml (original)
+++ xmlgraphics/fop/trunk/src/codegen/TimesRoman.xml Thu Mar 16 05:51:14 2006
@@ -1,5 +1,5 @@
 <!--
-  Copyright 1999-2004 The Apache Software Foundation
+  Copyright 1999-2004,2006 The Apache Software Foundation
 
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
@@ -258,4 +258,384 @@
       <char name="zcaron" width="444"/>
       <char name="zero" width="500"/>
    </widths>
+  <kerning kpx1="79">
+    <pair kern="-35" kpx2="65"/>
+    <pair kern="-35" kpx2="87"/>
+    <pair kern="-50" kpx2="89"/>
+    <pair kern="-40" kpx2="84"/>
+    <pair kern="0" kpx2="46"/>
+    <pair kern="-50" kpx2="86"/>
+    <pair kern="-40" kpx2="88"/>
+    <pair kern="0" kpx2="44"/>
+  </kerning>
+  <kerning kpx1="107">
+    <pair kern="-10" kpx2="111"/>
+    <pair kern="-15" kpx2="121"/>
+    <pair kern="-10" kpx2="101"/>
+  </kerning>
+  <kerning kpx1="112">
+    <pair kern="-10" kpx2="121"/>
+  </kerning>
+  <kerning kpx1="80">
+    <pair kern="0" kpx2="111"/>
+    <pair kern="-15" kpx2="97"/>
+    <pair kern="-92" kpx2="65"/>
+    <pair kern="-111" kpx2="46"/>
+    <pair kern="0" kpx2="101"/>
+    <pair kern="-111" kpx2="44"/>
+  </kerning>
+  <kerning kpx1="86">
+    <pair kern="-129" kpx2="111"/>
+    <pair kern="-40" kpx2="79"/>
+    <pair kern="-74" kpx2="58"/>
+    <pair kern="-15" kpx2="71"/>
+    <pair kern="-129" kpx2="44"/>
+    <pair kern="-74" kpx2="59"/>
+    <pair kern="-100" kpx2="45"/>
+    <pair kern="-60" kpx2="105"/>
+    <pair kern="-135" kpx2="65"/>
+    <pair kern="-111" kpx2="97"/>
+    <pair kern="-75" kpx2="117"/>
+    <pair kern="-129" kpx2="46"/>
+    <pair kern="-111" kpx2="101"/>
+  </kerning>
+  <kerning kpx1="118">
+    <pair kern="-20" kpx2="111"/>
+    <pair kern="-25" kpx2="97"/>
+    <pair kern="-65" kpx2="46"/>
+    <pair kern="-15" kpx2="101"/>
+    <pair kern="-65" kpx2="44"/>
+  </kerning>
+  <kerning kpx1="32">
+    <pair kern="-55" kpx2="65"/>
+    <pair kern="-30" kpx2="87"/>
+    <pair kern="0" kpx2="147"/>
+    <pair kern="-90" kpx2="89"/>
+    <pair kern="-18" kpx2="84"/>
+    <pair kern="0" kpx2="145"/>
+    <pair kern="-50" kpx2="86"/>
+  </kerning>
+  <kerning kpx1="97">
+    <pair kern="-15" kpx2="119"/>
+    <pair kern="0" kpx2="116"/>
+    <pair kern="0" kpx2="121"/>
+    <pair kern="0" kpx2="112"/>
+    <pair kern="0" kpx2="103"/>
+    <pair kern="0" kpx2="98"/>
+    <pair kern="-20" kpx2="118"/>
+  </kerning>
+  <kerning kpx1="70">
+    <pair kern="-15" kpx2="111"/>
+    <pair kern="0" kpx2="105"/>
+    <pair kern="0" kpx2="114"/>
+    <pair kern="-15" kpx2="97"/>
+    <pair kern="-74" kpx2="65"/>
+    <pair kern="-80" kpx2="46"/>
+    <pair kern="0" kpx2="101"/>
+    <pair kern="-80" kpx2="44"/>
+  </kerning>
+  <kerning kpx1="85">
+    <pair kern="-40" kpx2="65"/>
+    <pair kern="0" kpx2="46"/>
+    <pair kern="0" kpx2="44"/>
+  </kerning>
+  <kerning kpx1="100">
+    <pair kern="0" kpx2="100"/>
+    <pair kern="0" kpx2="119"/>
+    <pair kern="0" kpx2="121"/>
+    <pair kern="0" kpx2="46"/>
+    <pair kern="0" kpx2="118"/>
+    <pair kern="0" kpx2="44"/>
+  </kerning>
+  <kerning kpx1="83">
+    <pair kern="0" kpx2="46"/>
+    <pair kern="0" kpx2="44"/>
+  </kerning>
+  <kerning kpx1="122">
+    <pair kern="0" kpx2="111"/>
+    <pair kern="0" kpx2="101"/>
+  </kerning>
+  <kerning kpx1="68">
+    <pair kern="-40" kpx2="65"/>
+    <pair kern="-30" kpx2="87"/>
+    <pair kern="-55" kpx2="89"/>
+    <pair kern="0" kpx2="46"/>
+    <pair kern="-40" kpx2="86"/>
+    <pair kern="0" kpx2="44"/>
+  </kerning>
+  <kerning kpx1="146">
+    <pair kern="0" kpx2="148"/>
+    <pair kern="-50" kpx2="100"/>
+    <pair kern="-74" kpx2="32"/>
+    <pair kern="-74" kpx2="146"/>
+    <pair kern="-50" kpx2="114"/>
+    <pair kern="-18" kpx2="116"/>
+    <pair kern="-10" kpx2="108"/>
+    <pair kern="-55" kpx2="115"/>
+    <pair kern="-50" kpx2="118"/>
+  </kerning>
+  <kerning kpx1="58">
+    <pair kern="0" kpx2="32"/>
+  </kerning>
+  <kerning kpx1="119">
+    <pair kern="-10" kpx2="111"/>
+    <pair kern="-10" kpx2="97"/>
+    <pair kern="0" kpx2="104"/>
+    <pair kern="-65" kpx2="46"/>
+    <pair kern="0" kpx2="101"/>
+    <pair kern="-65" kpx2="44"/>
+  </kerning>
+  <kerning kpx1="75">
+    <pair kern="-35" kpx2="111"/>
+    <pair kern="-30" kpx2="79"/>
+    <pair kern="-15" kpx2="117"/>
+    <pair kern="-25" kpx2="121"/>
+    <pair kern="-25" kpx2="101"/>
+  </kerning>
+  <kerning kpx1="82">
+    <pair kern="-40" kpx2="79"/>
+    <pair kern="-55" kpx2="87"/>
+    <pair kern="-40" kpx2="85"/>
+    <pair kern="-65" kpx2="89"/>
+    <pair kern="-60" kpx2="84"/>
+    <pair kern="-80" kpx2="86"/>
+  </kerning>
+  <kerning kpx1="145">
+    <pair kern="-80" kpx2="65"/>
+    <pair kern="-74" kpx2="145"/>
+  </kerning>
+  <kerning kpx1="103">
+    <pair kern="0" kpx2="111"/>
+    <pair kern="0" kpx2="105"/>
+    <pair kern="0" kpx2="114"/>
+    <pair kern="-5" kpx2="97"/>
+    <pair kern="0" kpx2="121"/>
+    <pair kern="0" kpx2="46"/>
+    <pair kern="0" kpx2="103"/>
+    <pair kern="0" kpx2="101"/>
+    <pair kern="0" kpx2="44"/>
+  </kerning>
+  <kerning kpx1="66">
+    <pair kern="-35" kpx2="65"/>
+    <pair kern="-10" kpx2="85"/>
+    <pair kern="0" kpx2="46"/>
+    <pair kern="0" kpx2="44"/>
+  </kerning>
+  <kerning kpx1="98">
+    <pair kern="-20" kpx2="117"/>
+    <pair kern="0" kpx2="121"/>
+    <pair kern="-40" kpx2="46"/>
+    <pair kern="0" kpx2="108"/>
+    <pair kern="0" kpx2="98"/>
+    <pair kern="-15" kpx2="118"/>
+    <pair kern="0" kpx2="44"/>
+  </kerning>
+  <kerning kpx1="81">
+    <pair kern="-10" kpx2="85"/>
+    <pair kern="0" kpx2="46"/>
+    <pair kern="0" kpx2="44"/>
+  </kerning>
+  <kerning kpx1="44">
+    <pair kern="-70" kpx2="148"/>
+    <pair kern="0" kpx2="32"/>
+    <pair kern="-70" kpx2="146"/>
+  </kerning>
+  <kerning kpx1="102">
+    <pair kern="0" kpx2="148"/>
+    <pair kern="0" kpx2="111"/>
+    <pair kern="-20" kpx2="105"/>
+    <pair kern="55" kpx2="146"/>
+    <pair kern="-10" kpx2="97"/>
+    <pair kern="-25" kpx2="102"/>
+    <pair kern="0" kpx2="46"/>
+    <pair kern="0" kpx2="108"/>
+    <pair kern="0" kpx2="101"/>
+    <pair kern="0" kpx2="44"/>
+  </kerning>
+  <kerning kpx1="84">
+    <pair kern="-80" kpx2="111"/>
+    <pair kern="-18" kpx2="79"/>
+    <pair kern="-80" kpx2="119"/>
+    <pair kern="-50" kpx2="58"/>
+    <pair kern="-35" kpx2="114"/>
+    <pair kern="0" kpx2="104"/>
+    <pair kern="-74" kpx2="44"/>
+    <pair kern="-55" kpx2="59"/>
+    <pair kern="-92" kpx2="45"/>
+    <pair kern="-35" kpx2="105"/>
+    <pair kern="-93" kpx2="65"/>
+    <pair kern="-80" kpx2="97"/>
+    <pair kern="-45" kpx2="117"/>
+    <pair kern="-80" kpx2="121"/>
+    <pair kern="-74" kpx2="46"/>
+    <pair kern="-70" kpx2="101"/>
+  </kerning>
+  <kerning kpx1="121">
+    <pair kern="0" kpx2="111"/>
+    <pair kern="0" kpx2="97"/>
+    <pair kern="-65" kpx2="46"/>
+    <pair kern="0" kpx2="101"/>
+    <pair kern="-65" kpx2="44"/>
+  </kerning>
+  <kerning kpx1="120">
+    <pair kern="-15" kpx2="101"/>
+  </kerning>
+  <kerning kpx1="101">
+    <pair kern="-25" kpx2="119"/>
+    <pair kern="-15" kpx2="121"/>
+    <pair kern="0" kpx2="112"/>
+    <pair kern="0" kpx2="46"/>
+    <pair kern="-15" kpx2="103"/>
+    <pair kern="0" kpx2="98"/>
+    <pair kern="-15" kpx2="120"/>
+    <pair kern="-25" kpx2="118"/>
+    <pair kern="0" kpx2="44"/>
+  </kerning>
+  <kerning kpx1="99">
+    <pair kern="0" kpx2="107"/>
+    <pair kern="0" kpx2="104"/>
+    <pair kern="-15" kpx2="121"/>
+    <pair kern="0" kpx2="46"/>
+    <pair kern="0" kpx2="108"/>
+    <pair kern="0" kpx2="44"/>
+  </kerning>
+  <kerning kpx1="87">
+    <pair kern="-80" kpx2="111"/>
+    <pair kern="-10" kpx2="79"/>
+    <pair kern="-37" kpx2="58"/>
+    <pair kern="0" kpx2="104"/>
+    <pair kern="-92" kpx2="44"/>
+    <pair kern="-37" kpx2="59"/>
+    <pair kern="-65" kpx2="45"/>
+    <pair kern="-40" kpx2="105"/>
+    <pair kern="-120" kpx2="65"/>
+    <pair kern="-80" kpx2="97"/>
+    <pair kern="-50" kpx2="117"/>
+    <pair kern="-73" kpx2="121"/>
+    <pair kern="-92" kpx2="46"/>
+    <pair kern="-80" kpx2="101"/>
+  </kerning>
+  <kerning kpx1="104">
+    <pair kern="-5" kpx2="121"/>
+  </kerning>
+  <kerning kpx1="71">
+    <pair kern="0" kpx2="46"/>
+    <pair kern="0" kpx2="44"/>
+  </kerning>
+  <kerning kpx1="105">
+    <pair kern="-25" kpx2="118"/>
+  </kerning>
+  <kerning kpx1="65">
+    <pair kern="-55" kpx2="79"/>
+    <pair kern="-111" kpx2="146"/>
+    <pair kern="-92" kpx2="119"/>
+    <pair kern="-90" kpx2="87"/>
+    <pair kern="-40" kpx2="67"/>
+    <pair kern="0" kpx2="112"/>
+    <pair kern="-55" kpx2="81"/>
+    <pair kern="-40" kpx2="71"/>
+    <pair kern="-135" kpx2="86"/>
+    <pair kern="-74" kpx2="118"/>
+    <pair kern="0" kpx2="148"/>
+    <pair kern="-55" kpx2="85"/>
+    <pair kern="0" kpx2="117"/>
+    <pair kern="-105" kpx2="89"/>
+    <pair kern="-92" kpx2="121"/>
+    <pair kern="-111" kpx2="84"/>
+  </kerning>
+  <kerning kpx1="147">
+    <pair kern="-80" kpx2="65"/>
+    <pair kern="0" kpx2="145"/>
+  </kerning>
+  <kerning kpx1="78">
+    <pair kern="-35" kpx2="65"/>
+    <pair kern="0" kpx2="46"/>
+    <pair kern="0" kpx2="44"/>
+  </kerning>
+  <kerning kpx1="115">
+    <pair kern="0" kpx2="119"/>
+  </kerning>
+  <kerning kpx1="111">
+    <pair kern="-25" kpx2="119"/>
+    <pair kern="-10" kpx2="121"/>
+    <pair kern="0" kpx2="103"/>
+    <pair kern="0" kpx2="120"/>
+    <pair kern="-15" kpx2="118"/>
+  </kerning>
+  <kerning kpx1="114">
+    <pair kern="0" kpx2="111"/>
+    <pair kern="0" kpx2="100"/>
+    <pair kern="0" kpx2="107"/>
+    <pair kern="0" kpx2="114"/>
+    <pair kern="0" kpx2="99"/>
+    <pair kern="0" kpx2="112"/>
+    <pair kern="-18" kpx2="103"/>
+    <pair kern="0" kpx2="108"/>
+    <pair kern="0" kpx2="113"/>
+    <pair kern="0" kpx2="118"/>
+    <pair kern="-40" kpx2="44"/>
+    <pair kern="-20" kpx2="45"/>
+    <pair kern="0" kpx2="105"/>
+    <pair kern="0" kpx2="109"/>
+    <pair kern="0" kpx2="97"/>
+    <pair kern="0" kpx2="117"/>
+    <pair kern="0" kpx2="116"/>
+    <pair kern="0" kpx2="121"/>
+    <pair kern="-55" kpx2="46"/>
+    <pair kern="0" kpx2="110"/>
+    <pair kern="0" kpx2="115"/>
+    <pair kern="0" kpx2="101"/>
+  </kerning>
+  <kerning kpx1="108">
+    <pair kern="-10" kpx2="119"/>
+    <pair kern="0" kpx2="121"/>
+  </kerning>
+  <kerning kpx1="76">
+    <pair kern="0" kpx2="148"/>
+    <pair kern="-92" kpx2="146"/>
+    <pair kern="-74" kpx2="87"/>
+    <pair kern="-100" kpx2="89"/>
+    <pair kern="-55" kpx2="121"/>
+    <pair kern="-92" kpx2="84"/>
+    <pair kern="-100" kpx2="86"/>
+  </kerning>
+  <kerning kpx1="148">
+    <pair kern="0" kpx2="32"/>
+  </kerning>
+  <kerning kpx1="109">
+    <pair kern="0" kpx2="117"/>
+    <pair kern="0" kpx2="121"/>
+  </kerning>
+  <kerning kpx1="89">
+    <pair kern="-110" kpx2="111"/>
+    <pair kern="-111" kpx2="45"/>
+    <pair kern="-55" kpx2="105"/>
+    <pair kern="-30" kpx2="79"/>
+    <pair kern="-92" kpx2="58"/>
+    <pair kern="-100" kpx2="97"/>
+    <pair kern="-120" kpx2="65"/>
+    <pair kern="-111" kpx2="117"/>
+    <pair kern="-129" kpx2="46"/>
+    <pair kern="-100" kpx2="101"/>
+    <pair kern="-92" kpx2="59"/>
+    <pair kern="-129" kpx2="44"/>
+  </kerning>
+  <kerning kpx1="74">
+    <pair kern="0" kpx2="111"/>
+    <pair kern="0" kpx2="97"/>
+    <pair kern="-60" kpx2="65"/>
+    <pair kern="0" kpx2="117"/>
+    <pair kern="0" kpx2="46"/>
+    <pair kern="0" kpx2="101"/>
+    <pair kern="0" kpx2="44"/>
+  </kerning>
+  <kerning kpx1="46">
+    <pair kern="-70" kpx2="148"/>
+    <pair kern="-70" kpx2="146"/>
+  </kerning>
+  <kerning kpx1="110">
+    <pair kern="0" kpx2="117"/>
+    <pair kern="-15" kpx2="121"/>
+    <pair kern="-40" kpx2="118"/>
+  </kerning>
 </font-metrics>

Modified: xmlgraphics/fop/trunk/src/codegen/font-file.xsl
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/codegen/font-file.xsl?rev=386327&r1=386326&r2=386327&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/codegen/font-file.xsl (original)
+++ xmlgraphics/fop/trunk/src/codegen/font-file.xsl Thu Mar 16 05:51:14 2006
@@ -1,5 +1,5 @@
 <!--
-  Copyright 1999-2004 The Apache Software Foundation
+  Copyright 1999-2004,2006 The Apache Software Foundation
 
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
@@ -35,6 +35,9 @@
   <xsl:template match="font-metrics">
 package org.apache.fop.fonts.base14;
 
+<xsl:if test="count(kerning) &gt; 0">
+import java.util.Map;
+</xsl:if>
 import org.apache.fop.fonts.FontType;
 import org.apache.fop.fonts.Typeface;
 import org.apache.fop.fonts.CodePointMapping;
@@ -51,10 +54,29 @@
     private final static int[] width;
     private final CodePointMapping mapping =
         CodePointMapping.getMapping("<xsl:value-of select="$encoding"/>");
+<xsl:if test="count(kerning) &gt; 0">
+    private final static Map kerning;
+</xsl:if>
+
+    private boolean enableKerning = false;
 
     static {
         width = new int[256];
         <xsl:apply-templates select="widths"/>
+<xsl:if test="count(kerning) &gt; 0">
+        kerning = new java.util.HashMap();
+        Integer first, second;
+        Map pairs;
+        <xsl:apply-templates select="kerning"/>
+</xsl:if>
+    }
+
+    public <xsl:value-of select="class-name"/>() {
+        this(false);
+    }
+
+    public <xsl:value-of select="class-name"/>(boolean enableKerning) {
+        this.enableKerning = enableKerning;
     }
 
     public String getEncoding() {
@@ -98,19 +120,31 @@
     }
 
     public int[] getWidths() {
-        int[] arr = new int[getLastChar()-getFirstChar()+1];
-        System.arraycopy(width, getFirstChar(), arr, 0, getLastChar()-getFirstChar()+1);
-        //for( int i = 0; i &lt; arr.length; i++) arr[i] *= size;
+        int[] arr = new int[getLastChar() - getFirstChar() + 1];
+        System.arraycopy(width, getFirstChar(), arr, 0, getLastChar() - getFirstChar() + 1);
         return arr;
     }
 
+<xsl:choose>
+  <xsl:when test="count(kerning) &gt; 0">
     public boolean hasKerningInfo() {
-        return false;
+        return enableKerning;
+    }
+
+    public java.util.Map getKerningInfo() {
+        return kerning;
+    }
+  </xsl:when>
+  <xsl:otherwise>
+    public boolean hasKerningInfo() {
+        return false &amp; enableKerning;
     }
 
     public java.util.Map getKerningInfo() {
         return java.util.Collections.EMPTY_MAP;
     }
+  </xsl:otherwise>
+</xsl:choose>
 
     public char mapChar(char c) {
         char d = mapping.mapChar(c);
@@ -129,5 +163,20 @@
   </xsl:template>
 
   <xsl:template match="widths/char"><xsl:variable name="char-name" select="@name"/><xsl:variable name="char-num" select="$glyphs[@name = $char-name]/@codepoint"/><xsl:if test="$char-num!=''">        width[0x<xsl:value-of select="$char-num"/>] = <xsl:value-of select="@width"/>;</xsl:if></xsl:template>
+  
+  <xsl:template match="kerning">
+        first = new Integer(<xsl:value-of select="@kpx1"/>);
+        pairs = (Map)kerning.get(first);
+        if (pairs == null) {
+            pairs = new java.util.HashMap();
+            kerning.put(first, pairs);
+        }
+        <xsl:apply-templates select="pair"/>
+  </xsl:template>
+  
+  <xsl:template match="pair">
+        second = new Integer(<xsl:value-of select="@kpx2"/>);
+        pairs.put(second, new Integer(<xsl:value-of select="@kern"/>));
+  </xsl:template>
 </xsl:stylesheet>
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/apps/FOUserAgent.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/apps/FOUserAgent.java?rev=386327&r1=386326&r2=386327&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/apps/FOUserAgent.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/apps/FOUserAgent.java Thu Mar 16 05:51:14 2006
@@ -120,6 +120,9 @@
     /** @see #setBreakIndentInheritanceOnReferenceAreaBoundary(boolean) */
     private boolean breakIndentInheritanceOnReferenceAreaBoundary = false;
 
+    /** Allows enabling kerning on the base 14 fonts, default is false */
+    private boolean enableBase14Kerning = false;
+    
     /* Additional fo.ElementMapping subclasses set by user */
     private List additionalElementMappings = null;
 
@@ -238,6 +241,19 @@
      */
     public void setBreakIndentInheritanceOnReferenceAreaBoundary(boolean value) {
         this.breakIndentInheritanceOnReferenceAreaBoundary = value;
+    }
+    
+    /** @return true if kerning on base 14 fonts is enabled */
+    public boolean isBase14KerningEnabled() {
+        return this.enableBase14Kerning;
+    }
+    
+    /**
+     * Controls whether kerning is activated on base 14 fonts.
+     * @param value true if kerning should be activated
+     */
+    public void setBase14KerningEnabled(boolean value) {
+        this.enableBase14Kerning = value;
     }
     
     /**

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/AreaTreeParser.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/AreaTreeParser.java?rev=386327&r1=386326&r2=386327&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/AreaTreeParser.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/AreaTreeParser.java Thu Mar 16 05:51:14 2006
@@ -19,6 +19,7 @@
 package org.apache.fop.area;
 
 import java.awt.geom.Rectangle2D;
+import java.util.List;
 import java.util.Map;
 import java.util.Stack;
 import java.util.StringTokenizer;
@@ -674,10 +675,27 @@
 
         private class WordMaker extends AbstractMaker {
 
+            private int[] toIntArray(String s) {
+                if (s == null || s.length() == 0) {
+                    return null;
+                }
+                StringTokenizer tokenizer = new StringTokenizer(s, " ");
+                List values = new java.util.ArrayList();
+                while (tokenizer.hasMoreTokens()) {
+                    values.add(new Integer(tokenizer.nextToken()));
+                }
+                int[] res = new int[values.size()];
+                for (int i = 0, c = res.length; i < c; i++) {
+                    res[i] = ((Integer)values.get(i)).intValue();
+                }
+                return res;
+            }
+            
             public void endElement() {
                 int offset = getAttributeAsInteger(lastAttributes, "offset", 0);
+                int[] letterAdjust = toIntArray(lastAttributes.getValue("letter-adjust"));
                 String txt = content.toString();
-                WordArea word = new WordArea(txt, offset);
+                WordArea word = new WordArea(txt, offset, letterAdjust);
                 AbstractTextArea text = getCurrentText();
                 word.setParentArea(text);
                 text.addChildArea(word);
@@ -691,7 +709,8 @@
                 String txt = content.toString();
                 //TODO the isAdjustable parameter is currently not used/implemented
                 if (txt.length() > 0) {
-                    SpaceArea space = new SpaceArea(txt.charAt(0), offset, false);
+                    boolean adjustable = getAttributeAsBoolean(lastAttributes, "adj", true);
+                    SpaceArea space = new SpaceArea(txt.charAt(0), offset, adjustable);
                     AbstractTextArea text = getCurrentText();
                     space.setParentArea(text);
                     text.addChildArea(space);

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/Character.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/Character.java?rev=386327&r1=386326&r2=386327&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/Character.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/Character.java Thu Mar 16 05:51:14 2006
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 /**
  * Single character inline area.
  * This inline area holds a single character.
+ * @deprecated A TextArea with a single WordArea as its child should be used instead.
  */
 public class Character extends AbstractTextArea {
     // use a String instead of a character because if this character

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/SpaceArea.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/SpaceArea.java?rev=386327&r1=386326&r2=386327&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/SpaceArea.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/SpaceArea.java Thu Mar 16 05:51:14 2006
@@ -28,11 +28,6 @@
     protected String space;
 
     /**
-     * The correction offset for the next area
-     */
-    protected int offset = 0;
-    
-    /**
      * Is this space adjustable?
      */
     protected boolean isAdjustable;
@@ -56,16 +51,8 @@
         return new String(space);
     }
 
-    /**
-     * @return Returns the offset.
-     */
-    public int getOffset() {
-        return offset;
-    }
-    /**
-     * @param o The offset to set.
-     */
-    public void setOffset(int o) {
-        offset = o;
+    /** @return true if the space is adjustable (WRT word-space processing) */
+    public boolean isAdjustable() {
+        return this.isAdjustable;
     }
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/TextArea.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/TextArea.java?rev=386327&r1=386326&r2=386327&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/TextArea.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/TextArea.java Thu Mar 16 05:51:14 2006
@@ -54,7 +54,17 @@
      * @param offset the offset for the next area
      */
     public void addWord(String word, int offset) {
-        WordArea wordArea = new WordArea(word, offset);
+        addWord(word, offset, null);
+    }
+    
+    /**
+     * Create and add a WordArea child to this TextArea.
+     * 
+     * @param word   the word string
+     * @param offset the offset for the next area
+     */
+    public void addWord(String word, int offset, int[] letterAdjust) {
+        WordArea wordArea = new WordArea(word, offset, letterAdjust);
         addChildArea(wordArea);
         wordArea.setParentArea(this);
     }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/WordArea.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/WordArea.java?rev=386327&r1=386326&r2=386327&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/WordArea.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/WordArea.java Thu Mar 16 05:51:14 2006
@@ -22,24 +22,25 @@
  */
 public class WordArea extends InlineArea {
 
-    /**
-     * The text for this word area
-     */
+    /** The text for this word area */
     protected String word;
     
-    /**
-     * The correction offset for the next area
-     */
+    /** The correction offset for the next area */
     protected int offset = 0;
+    
+    /** An array of width for adjusting the individual letters (optional) */
+    protected int[] letterAdjust;
 
     /**
      * Create a word area
      * @param w the word string
      * @param o the offset for the next area
+     * @param la the letter adjust array (may be null)
      */
-    public WordArea(String w, int o) {
+    public WordArea(String w, int o, int[] la) {
         word = w;
         offset = o;
+        this.letterAdjust = la;
     }
 
     /**
@@ -61,4 +62,10 @@
     public void setOffset(int o) {
         offset = o;
     }
+    
+    /** @return the array of letter adjust widths */
+    public int[] getLetterAdjustArray() {
+        return this.letterAdjust;
+    }
+    
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/CustomFont.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/CustomFont.java?rev=386327&r1=386326&r2=386327&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/CustomFont.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/CustomFont.java Thu Mar 16 05:51:14 2006
@@ -21,9 +21,6 @@
 import java.util.Map;
 import javax.xml.transform.Source;
 
-import org.apache.fop.apps.FOUserAgent;
-
-
 /**
  * Abstract base class for custom fonts loaded from files, for example.
  */
@@ -33,7 +30,7 @@
     private String fontName = null;
     private String embedFileName = null;
     private String embedResourceName = null;
-    private FOUserAgent userAgent = null;
+    private FontResolver resolver = null;
     
     private int capHeight = 0;
     private int xHeight = 0;
@@ -48,7 +45,7 @@
     private int firstChar = 0;
     private int lastChar = 255;
 
-    private Map kerning = new java.util.HashMap();
+    private Map kerning;
 
     private boolean useKerning = true;
 
@@ -74,10 +71,11 @@
      * @return Source for an embeddable font file or null if not available.
      */
     public Source getEmbedFileSource() {
-        if (userAgent != null && embedFileName != null) {
-            return userAgent.resolveURI(embedFileName, userAgent.getFontBaseURL());
+        if (resolver != null && embedFileName != null) {
+            return resolver.resolve(embedFileName);
+        } else {
+            return null;
         }
-        return null;
     }
 
     /**
@@ -212,14 +210,14 @@
      * @see org.apache.fop.fonts.FontMetrics#hasKerningInfo()
      */
     public final boolean hasKerningInfo() {
-        return (isKerningEnabled() & kerning.isEmpty());
+        return (isKerningEnabled() && (kerning != null) && !kerning.isEmpty());
     }
 
     /**
      * @see org.apache.fop.fonts.FontMetrics#getKerningInfo()
      */
     public final Map getKerningInfo() {
-        if (isKerningEnabled()) {
+        if (hasKerningInfo()) {
             return kerning;
         } else {
             return java.util.Collections.EMPTY_MAP;
@@ -343,17 +341,20 @@
     }
 
     /**
-     * Sets the user agent environment. Needed for URI resolution
-     * @param userAgent the user agent
+     * Sets the font resolver. Needed for URI resolution.
+     * @param resolver the font resolver
      */
-    public void setUserAgent(FOUserAgent userAgent) {
-        this.userAgent = userAgent;
+    public void setResolver(FontResolver resolver) {
+        this.resolver = resolver;
     }
 
     /**
      * @see org.apache.fop.fonts.MutableFont#putKerningEntry(Integer, Map)
      */
     public void putKerningEntry(Integer key, Map value) {
+        if (kerning == null) {
+            kerning = new java.util.HashMap();
+        }
         this.kerning.put(key, value);
     }
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/Font.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/Font.java?rev=386327&r1=386326&r2=386327&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/Font.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/Font.java Thu Mar 16 05:51:14 2006
@@ -111,18 +111,39 @@
         return metric.getXHeight(fontSize) / 1000;
     }
 
+    /** @return true if the font has kerning info */
+    public boolean hasKerning() {
+        return metric.hasKerningInfo();
+    }
+    
     /**
      * Returns the font's kerning table
      * @return the kerning table
      */
     public Map getKerning() {
-        Map ret = metric.getKerningInfo();
-        if (ret != null) {
-            return ret;
+        if (metric.hasKerningInfo()) {
+            return metric.getKerningInfo();
         } else {
             return java.util.Collections.EMPTY_MAP;
         }
     }
+    
+    /**
+     * Returns the amount of kerning between two characters.
+     * @param ch1 first character
+     * @param ch2 second character
+     * @return the distance to adjust for kerning, 0 if there's no kerning
+     */
+    public int getKernValue(char ch1, char ch2) {
+        Map kernPair = (Map)getKerning().get(new Integer(ch1));
+        if (kernPair != null) {
+            Integer width = (Integer)kernPair.get(new Integer(ch2));
+            if (width != null) {
+                return width.intValue();
+            }
+        }
+        return 0;
+    }
 
     /**
      * Returns the width of a character
@@ -206,63 +227,50 @@
         if ((c == '\n') || (c == '\r') || (c == '\t') || (c == '\u00A0')) {
             width = getCharWidth(' ');
         } else {
-            width = getWidth(mapChar(c));
+            if (hasChar(c)) {
+                width = getWidth(mapChar(c));
+            } else {
+                width = -1;
+            }
             if (width <= 0) {
                 // Estimate the width of spaces not represented in
                 // the font
-                int em = getWidth(mapChar('m'));
-                int en = getWidth(mapChar('n'));
-                if (em <= 0) {
-                    em = 500 * getFontSize();
-                }
-                if (en <= 0) {
-                    en = em - 10;
-                }
+                int em = getFontSize(); //http://en.wikipedia.org/wiki/Em_(typography)
+                int en = em / 2; //http://en.wikipedia.org/wiki/En_(typography)
 
                 if (c == ' ') {
                     width = em;
-                }
-                if (c == '\u2000') {
+                } else if (c == '\u2000') {
                     width = en;
-                }
-                if (c == '\u2001') {
+                } else if (c == '\u2001') {
                     width = em;
-                }
-                if (c == '\u2002') {
+                } else if (c == '\u2002') {
                     width = em / 2;
-                }
-                if (c == '\u2003') {
+                } else if (c == '\u2003') {
                     width = getFontSize();
-                }
-                if (c == '\u2004') {
+                } else if (c == '\u2004') {
                     width = em / 3;
-                }
-                if (c == '\u2005') {
+                } else if (c == '\u2005') {
                     width = em / 4;
-                }
-                if (c == '\u2006') {
+                } else if (c == '\u2006') {
                     width = em / 6;
-                }
-                if (c == '\u2007') {
-                    width = getCharWidth(' ');
-                }
-                if (c == '\u2008') {
+                } else if (c == '\u2007') {
+                    width = getCharWidth('0');
+                } else if (c == '\u2008') {
                     width = getCharWidth('.');
-                }
-                if (c == '\u2009') {
+                } else if (c == '\u2009') {
                     width = em / 5;
-                }
-                if (c == '\u200A') {
-                    width = 5;
-                }
-                if (c == '\u200B') {
-                    width = 100;
-                }
-                if (c == '\u202F') {
+                } else if (c == '\u200A') {
+                    width = em / 10;
+                } else if (c == '\u200B') {
+                    width = 0;
+                } else if (c == '\u202F') {
                     width = getCharWidth(' ') / 2;
-                }
-                if (c == '\u3000') {
+                } else if (c == '\u3000') {
                     width = getCharWidth(' ') * 2;
+                } else {
+                    //Will be internally replaced by "#" if not found
+                    width = getWidth(mapChar(c));
                 }
             }
         }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontReader.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontReader.java?rev=386327&r1=386326&r2=386327&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontReader.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontReader.java Thu Mar 16 05:51:14 2006
@@ -34,7 +34,6 @@
 
 //FOP
 import org.apache.fop.apps.FOPException;
-import org.apache.fop.apps.FOUserAgent;
 import org.xml.sax.InputSource;
 
 /**
@@ -114,11 +113,11 @@
     }
 
     /**
-     * Sets the user agent environment. Needed for URI resolution
-     * @param userAgent the user agent
+     * Sets the font resolver. Needed for URI resolution.
+     * @param resolver the font resolver
      */
-    public void setUserAgent(FOUserAgent userAgent) {
-        returnFont.setUserAgent(userAgent);
+    public void setResolver(FontResolver resolver) {
+        returnFont.setResolver(resolver);
     }
 
 

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontResolver.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontResolver.java?rev=386327&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontResolver.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontResolver.java Thu Mar 16 05:51:14 2006
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fonts;
+
+import javax.xml.transform.Source;
+
+/**
+ * This interface is used to resolve absolute and relative font URIs.
+ */
+public interface FontResolver {
+
+    /**
+     * Called to resolve an URI to a Source instance. The base URI needed by the URIResolver's
+     * resolve() method is defined to be implicitely available in this case. If the URI cannot
+     * be resolved, null is returned and it is assumed that the FontResolver implementation
+     * already warned the user about the problem.
+     * @param href An href attribute, which may be relative or absolute.
+     * @return A Source object, or null if the href could not resolved.
+     */
+    Source resolve(String href);
+    
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontResolver.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontSetup.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontSetup.java?rev=386327&r1=386326&r2=386327&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontSetup.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontSetup.java Thu Mar 16 05:51:14 2006
@@ -18,8 +18,6 @@
 
 package org.apache.fop.fonts;
 
-import org.apache.fop.apps.FOUserAgent;
-
 // FOP (base 14 fonts)
 import org.apache.fop.fonts.base14.Helvetica;
 import org.apache.fop.fonts.base14.HelveticaBold;
@@ -68,22 +66,39 @@
      * triplets for lookup.
      *
      * @param fontInfo the font info object to set up
-     * @param embedList ???
+     * @param embedList a list of EmbedFontInfo objects
+     * @param resolver the font resolver
+     */
+    public static void setup(FontInfo fontInfo, List embedList, FontResolver resolver) {
+        setup(fontInfo, embedList, resolver, false);
+    }
+
+    /**
+     * Sets up the font info object.
+     *
+     * Adds metrics for basic fonts and useful family-style-weight
+     * triplets for lookup.
+     *
+     * @param fontInfo the font info object to set up
+     * @param embedList a list of EmbedFontInfo objects
+     * @param resolver the font resolver
+     * @param enableBase14Kerning true if kerning should be enabled for base 14 fonts
      */
-    public static void setup(FontInfo fontInfo, List embedList, FOUserAgent ua) {
+    public static void setup(FontInfo fontInfo, List embedList, FontResolver resolver, 
+            boolean enableBase14Kerning) {
 
-        fontInfo.addMetrics("F1", new Helvetica());
-        fontInfo.addMetrics("F2", new HelveticaOblique());
-        fontInfo.addMetrics("F3", new HelveticaBold());
-        fontInfo.addMetrics("F4", new HelveticaBoldOblique());
-        fontInfo.addMetrics("F5", new TimesRoman());
-        fontInfo.addMetrics("F6", new TimesItalic());
-        fontInfo.addMetrics("F7", new TimesBold());
-        fontInfo.addMetrics("F8", new TimesBoldItalic());
-        fontInfo.addMetrics("F9", new Courier());
-        fontInfo.addMetrics("F10", new CourierOblique());
-        fontInfo.addMetrics("F11", new CourierBold());
-        fontInfo.addMetrics("F12", new CourierBoldOblique());
+        fontInfo.addMetrics("F1", new Helvetica(enableBase14Kerning));
+        fontInfo.addMetrics("F2", new HelveticaOblique(enableBase14Kerning));
+        fontInfo.addMetrics("F3", new HelveticaBold(enableBase14Kerning));
+        fontInfo.addMetrics("F4", new HelveticaBoldOblique(enableBase14Kerning));
+        fontInfo.addMetrics("F5", new TimesRoman(enableBase14Kerning));
+        fontInfo.addMetrics("F6", new TimesItalic(enableBase14Kerning));
+        fontInfo.addMetrics("F7", new TimesBold(enableBase14Kerning));
+        fontInfo.addMetrics("F8", new TimesBoldItalic(enableBase14Kerning));
+        fontInfo.addMetrics("F9", new Courier(enableBase14Kerning));
+        fontInfo.addMetrics("F10", new CourierOblique(enableBase14Kerning));
+        fontInfo.addMetrics("F11", new CourierBold(enableBase14Kerning));
+        fontInfo.addMetrics("F12", new CourierBoldOblique(enableBase14Kerning));
         fontInfo.addMetrics("F13", new Symbol());
         fontInfo.addMetrics("F14", new ZapfDingbats());
 
@@ -162,17 +177,18 @@
                                    "normal", Font.NORMAL);
 
         /* Add configured fonts */
-        addConfiguredFonts(fontInfo, embedList, 15, ua);
+        addConfiguredFonts(fontInfo, embedList, 15, resolver);
     }
 
     /**
      * Add fonts from configuration file starting with internal name F<num>.
      * @param fontInfo the font info object to set up
-     * @param fontInfoList
+     * @param fontInfoList a list of EmbedFontInfo objects
      * @param num starting index for internal font numbering
+     * @param resolver the font resolver
      */
     public static void addConfiguredFonts(FontInfo fontInfo, List fontInfoList
-                                        , int num, FOUserAgent userAgent) {
+                                        , int num, FontResolver resolver) {
         if (fontInfoList == null) {
             return; //No fonts to process
         }
@@ -196,7 +212,7 @@
                 LazyFont font = new LazyFont(configFontInfo.getEmbedFile(),
                                              metricsFile,
                                              configFontInfo.getKerning(), 
-                                             userAgent);
+                                             resolver);
                 fontInfo.addMetrics(internalName, font);
 
                 List triplets = configFontInfo.getFontTriplets();

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/LazyFont.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/LazyFont.java?rev=386327&r1=386326&r2=386327&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/LazyFont.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/LazyFont.java Thu Mar 16 05:51:14 2006
@@ -17,10 +17,8 @@
 /* $Id$ */
 
 package org.apache.fop.fonts;
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
-import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.Map;
 import javax.xml.transform.Source;
@@ -29,7 +27,6 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.fop.apps.FOPException;
-import org.apache.fop.apps.FOUserAgent;
 import org.xml.sax.InputSource;
 
 /**
@@ -47,21 +44,21 @@
     private Typeface realFont = null;
     private FontDescriptor realFontDescriptor = null;
 
-    private FOUserAgent userAgent = null;
+    private FontResolver resolver = null;
     
     /**
      * Main constructor
      * @param fontEmbedPath path to embeddable file (may be null)
      * @param metricsFileName path to the metrics XML file
      * @param useKerning True, if kerning should be enabled
-     * @param userAgent the environment for uri resoltuion
+     * @param resolver the font resolver to handle font URIs
      */
     public LazyFont(String fontEmbedPath, String metricsFileName
-                    , boolean useKerning, FOUserAgent userAgent) {
+                    , boolean useKerning, FontResolver resolver) {
         this.metricsFileName = metricsFileName;
         this.fontEmbedPath = fontEmbedPath;
         this.useKerning = useKerning;
-        this.userAgent = userAgent;
+        this.resolver = resolver;
     }
 
     private void load(boolean fail) {
@@ -69,9 +66,8 @@
             try {
                 /**@todo Possible thread problem here */
                 FontReader reader = null;
-                if (userAgent != null) {
-                    Source source = userAgent.resolveURI(metricsFileName
-                                                        , userAgent.getFontBaseURL());
+                if (resolver != null) {
+                    Source source = resolver.resolve(metricsFileName);
                     if (source == null) {
                         String err = "Cannot load font: failed to create Source from metrics file " 
                             + metricsFileName; 
@@ -106,7 +102,7 @@
                 }
                 reader.setKerningEnabled(useKerning);
                 reader.setFontEmbedPath(fontEmbedPath);
-                reader.setUserAgent(userAgent);
+                reader.setResolver(resolver);
                 realFont = reader.getFont();
                 if (realFont instanceof FontDescriptor) {
                     realFontDescriptor = (FontDescriptor) realFont;

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java?rev=386327&r1=386326&r2=386327&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java Thu Mar 16 05:51:14 2006
@@ -68,14 +68,15 @@
         hyphIPD = font.getCharWidth(fobj.getCommonHyphenation().hyphenationCharacter);
         borderProps = fobj.getCommonBorderPaddingBackground();
         setCommonBorderPaddingBackground(borderProps);
-        org.apache.fop.area.inline.Character chArea = getCharacterInlineArea(fobj);
+        org.apache.fop.area.inline.TextArea chArea = getCharacterInlineArea(fobj);
         chArea.setBaselineOffset(font.getAscender());
         setCurrentArea(chArea);
     }
 
-    private org.apache.fop.area.inline.Character getCharacterInlineArea(Character node) {
-        org.apache.fop.area.inline.Character ch 
-            = new org.apache.fop.area.inline.Character(node.getCharacter());
+    private org.apache.fop.area.inline.TextArea getCharacterInlineArea(Character node) {
+        org.apache.fop.area.inline.TextArea ch 
+            = new org.apache.fop.area.inline.TextArea();
+        ch.addWord(String.valueOf(node.getCharacter()), 0);
         TraitSetter.setProducerID(ch, node.getId());
         TraitSetter.addTextDecoration(ch, fobj.getTextDecoration());
         return ch;

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java?rev=386327&r1=386326&r2=386327&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java Thu Mar 16 05:51:14 2006
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -62,14 +62,16 @@
         private short iLScount;
         private MinOptMax ipdArea;
         private boolean bHyphenated;
+        private boolean isSpace;
         public AreaInfo(short iSIndex, short iBIndex, short iWS, short iLS,
-                        MinOptMax ipd, boolean bHyph) {
+                        MinOptMax ipd, boolean bHyph, boolean isSpace) {
             iStartIndex = iSIndex;
             iBreakIndex = iBIndex;
             iWScount = iWS;
             iLScount = iLS;
             ipdArea = ipd;
             bHyphenated = bHyph;
+            this.isSpace = isSpace;
         }
         
         public String toString() {
@@ -79,6 +81,7 @@
                 + ", sidx=" + iStartIndex
                 + ", bidx=" + iBreakIndex
                 + ", hyph=" + bHyphenated
+                + ", space=" + isSpace
                 + "]";
         }
 
@@ -104,14 +107,12 @@
 
     private FOText foText;
     private char[] textArray;
+    /** Contains an array of widths to adjust for kerning and letter spacing */
+    private MinOptMax[] letterAdjustArray; //size = textArray.length + 1
+    /** The sum of all entries in the letterAdjustArray */
+    private MinOptMax totalLetterAdjust = new MinOptMax(0);
 
     private static final char NEWLINE = '\n';
-    private static final char SPACE = '\u0020'; // Normal space
-    private static final char NBSPACE = '\u00A0'; // Non-breaking space
-    private static final char LINEBREAK = '\u2028';
-    private static final char ZERO_WIDTH_SPACE = '\u200B';
-    // byte order mark
-    private static final char ZERO_WIDTH_NOBREAK_SPACE = '\uFEFF';
 
     private Font font = null;
     /** Start index of first character in this parent Area */
@@ -128,8 +129,12 @@
     private MinOptMax letterSpaceIPD;
     /** size of the hyphen character glyph in current font */
     private int hyphIPD;
+    /** 1/1 of word-spacing value */
+    private SpaceVal ws;
     /** 1/2 of word-spacing value */
     private SpaceVal halfWS;
+    /** 1/2 of letter-spacing value */
+    private SpaceVal halfLS; 
     /** Number of space characters after previous possible break position. */
     private int iNbSpacesPending;
 
@@ -156,6 +161,7 @@
         textArray = new char[node.endIndex - node.startIndex];
         System.arraycopy(node.ca, node.startIndex, textArray, 0,
             node.endIndex - node.startIndex);
+        letterAdjustArray = new MinOptMax[textArray.length + 1];
 
         vecAreaInfo = new java.util.ArrayList();
     }
@@ -168,9 +174,13 @@
         spaceCharIPD = font.getCharWidth(' ');
         // Use hyphenationChar property
         hyphIPD = font.getCharWidth(foText.getCommonHyphenation().hyphenationCharacter);
-        // Make half-space: <space> on either side of a word-space)
+        
         SpaceVal ls = SpaceVal.makeLetterSpacing(foText.getLetterSpacing());
-        SpaceVal ws = SpaceVal.makeWordSpacing(foText.getWordSpacing(), ls, font);
+        halfLS = new SpaceVal(MinOptMax.multiply(ls.getSpace(), 0.5),
+                ls.isConditional(), ls.isForcing(), ls.getPrecedence());
+        
+        ws = SpaceVal.makeWordSpacing(foText.getWordSpacing(), ls, font);
+        // Make half-space: <space> on either side of a word-space)
         halfWS = new SpaceVal(MinOptMax.multiply(ws.getSpace(), 0.5),
                 ws.isConditional(), ws.isForcing(), ws.getPrecedence());
 
@@ -180,6 +190,7 @@
         //      A<<ws>>S<ls>I<ls>M<ls>P<ls>L<ls>E<<ws>>T<ls>E<ls>S<ls>T
         // there is no letter space after the last character of a word,
         // nor after a space character
+        // NOTE: The above is not quite correct. Read on in XSL 1.0, 7.16.2, letter-spacing
 
         // set letter space and word space dimension;
         // the default value "normal" was converted into a MinOptMax value
@@ -288,13 +299,22 @@
         }
         if (ai == null) {
             return;
-        } else if (ai.iLScount == ai.iBreakIndex - ai.iStartIndex
+        }
+        int textLength = ai.iBreakIndex - ai.iStartIndex;
+        if (ai.iLScount == textLength
                    && context.isLastArea()) {
             // the line ends at a character like "/" or "-";
             // remove the letter space after the last character
             realWidth.add(MinOptMax.multiply(letterSpaceIPD, -1));
             iLScount--;
         }
+        
+        for (int i = ai.iStartIndex + 1; i < ai.iBreakIndex + 1; i++) {
+            MinOptMax ladj = letterAdjustArray[i]; 
+            if (ladj != null && ladj.isElastic()) {
+                iLScount++;
+            }
+        }
 
         // add hyphenation character if the last word is hyphenated
         if (context.isLastArea() && ai.bHyphenated) {
@@ -415,9 +435,9 @@
         // set the text of the TextArea, split into words and spaces
         int wordStartIndex = -1;
         AreaInfo areaInfo;
-        for (int i = firstIndex; i <= lastIndex; i ++) {
+        for (int i = firstIndex; i <= lastIndex; i++) {
             areaInfo = (AreaInfo) vecAreaInfo.get(i);
-            if (areaInfo.iWScount > 0) {
+            if (areaInfo.isSpace) {
                 // areaInfo stores information about a space
                 // add a space to the TextArea
                 char spaceChar = textArray[areaInfo.iStartIndex];
@@ -429,17 +449,28 @@
                     // here starts a new word
                     wordStartIndex = areaInfo.iStartIndex;
                 }
-                if (i == lastIndex || ((AreaInfo) vecAreaInfo.get(i + 1)).iWScount > 0) {
+                if (i == lastIndex || ((AreaInfo) vecAreaInfo.get(i + 1)).isSpace) {
                     // here ends a new word
                     // add a word to the TextArea
-                    String wordChars = new String(textArray, wordStartIndex, areaInfo.iBreakIndex - wordStartIndex);
+                    int len = areaInfo.iBreakIndex - wordStartIndex;
+                    String wordChars = new String(textArray, wordStartIndex, len);
                     if (isLastArea
                         && i == lastIndex 
                         && areaInfo.bHyphenated) {
                         // add the hyphenation character
                         wordChars += foText.getCommonHyphenation().hyphenationCharacter;
                     }
-                    textArea.addWord(wordChars, 0);
+                    int[] letterAdjust = new int[wordChars.length()];
+                    int lsCount = areaInfo.iLScount;
+                    for (int letter = 0; letter < len; letter++) {
+                        MinOptMax adj = letterAdjustArray[letter + wordStartIndex + 1];
+                        letterAdjust[letter] = (adj != null ? adj.opt : 0);
+                        if (lsCount > 0) {
+                            letterAdjust[letter] += textArea.getTextLetterSpaceAdjust();
+                            lsCount--;
+                        }
+                    }
+                    textArea.addWord(wordChars, 0, letterAdjust);
                     wordStartIndex = -1;
                 }
             }
@@ -451,7 +482,40 @@
         
         return textArea;
     }
+    
+    private void addToLetterAdjust(int index, int width) {
+        if (letterAdjustArray[index] == null) {
+            letterAdjustArray[index] = new MinOptMax(width);
+        } else {
+            letterAdjustArray[index].add(width);
+        }
+        totalLetterAdjust.add(width);
+    }
 
+    private void addToLetterAdjust(int index, MinOptMax width) {
+        if (letterAdjustArray[index] == null) {
+            letterAdjustArray[index] = new MinOptMax(width);
+        } else {
+            letterAdjustArray[index].add(width);
+        }
+        totalLetterAdjust.add(width);
+    }
+
+    /**
+     * Indicates whether a character is a space in terms of this layout manager.
+     * @param ch the character
+     * @return true if it's a space
+     */
+    private static boolean isSpace(final char ch) {
+        return ch == CharUtilities.SPACE
+            || ch == CharUtilities.NBSPACE
+            || CharUtilities.isFixedWidthSpace(ch);
+    }
+    
+    private static boolean isBreakChar(final char ch) {
+        return (BREAK_CHARS.indexOf(ch) >= 0);
+    }
+    
     /** @see org.apache.fop.layoutmgr.LayoutManager#getNextKnuthElements(LayoutContext, int) */
     public LinkedList getNextKnuthElements(LayoutContext context, int alignment) {
         lineStartBAP = context.getLineStartBorderAndPaddingWidth();
@@ -464,13 +528,14 @@
         returnList.add(sequence);
 
         while (iNextStart < textArray.length) {
-            if (textArray[iNextStart] == SPACE
-                || textArray[iNextStart] == NBSPACE) {
+            char ch = textArray[iNextStart]; 
+            if (ch == CharUtilities.SPACE
+                || ch == CharUtilities.NBSPACE) {
                 // normal space or non-breaking space:
                 // create the AreaInfo object
                 ai = new AreaInfo(iNextStart, (short) (iNextStart + 1),
                         (short) 1, (short) 0,
-                        wordSpaceIPD, false); 
+                        wordSpaceIPD, false, true); 
                 vecAreaInfo.add(ai);
 
                 // create the elements
@@ -479,7 +544,21 @@
 
                 // advance to the next character
                 iNextStart++;
-            } else if (textArray[iNextStart] == NEWLINE) {
+            } else if (CharUtilities.isFixedWidthSpace(ch)) {
+                // create the AreaInfo object
+                MinOptMax ipd = new MinOptMax(font.getCharWidth(ch));
+                ai = new AreaInfo(iNextStart, (short) (iNextStart + 1),
+                        (short) 0, (short) 0,
+                        ipd, false, true); 
+                vecAreaInfo.add(ai);
+
+                // create the elements
+                sequence.addAll
+                    (createElementsForASpace(alignment, ai, vecAreaInfo.size() - 1));
+
+                // advance to the next character
+                iNextStart++;
+            } else if (ch == NEWLINE) {
                 // linefeed; this can happen when linefeed-treatment="preserve"
                 // add a penalty item to the list and start a new sequence
                 if (lineEndBAP != 0) {
@@ -497,24 +576,45 @@
                 // the beginning of a word
                 iThisStart = iNextStart;
                 iTempStart = iNextStart;
-                MinOptMax wordIPD = new MinOptMax(0);
                 for (; iTempStart < textArray.length
-                        && textArray[iTempStart] != SPACE
-                        && textArray[iTempStart] != NBSPACE
+                        && !isSpace(textArray[iTempStart])
                         && textArray[iTempStart] != NEWLINE
                         && !(iTempStart > iNextStart
-                             && BREAK_CHARS.indexOf(textArray[iTempStart - 1]) >= 0);
+                             && isBreakChar(textArray[iTempStart - 1]));
                         iTempStart++) {
-                    wordIPD.add(font.getCharWidth(textArray[iTempStart]));
+                    //nop, just find the word boundary
                 }
-                int iLetterSpaces = iTempStart - iThisStart - 1;
+                
+                //Word boundary found, process widths and kerning
+                int wordLength = iTempStart - iThisStart;
+                boolean kerning = font.hasKerning();
+                MinOptMax wordIPD = new MinOptMax(0);
+                for (int i = iThisStart; i < iTempStart; i++) {
+                    char c = textArray[i];
+                    
+                    //character width
+                    int charWidth = font.getCharWidth(c);
+                    wordIPD.add(charWidth);
+                    
+                    //kerning
+                    int kern = 0;
+                    if (kerning && (i > iThisStart)) {
+                        char previous = textArray[i - 1];
+                        kern = font.getKernValue(previous, c) * font.getFontSize() / 1000;
+                        if (kern != 0) {
+                            addToLetterAdjust(i + 1, kern);
+                        }
+                        wordIPD.add(kern);
+                    }
+                }
+                
+                int iLetterSpaces = wordLength - 1;
                 // if the last character is '-' or '/' and the next one
                 // is not a space, it could be used as a line end;
                 // add one more letter space, in case other text follows
-                if (BREAK_CHARS.indexOf(textArray[iTempStart - 1]) >= 0
-                    && iTempStart < textArray.length
-                    && textArray[iTempStart] != SPACE
-                    && textArray[iTempStart] != NBSPACE) {
+                if (isBreakChar(textArray[iTempStart - 1])
+                        && iTempStart < textArray.length
+                        && !isSpace(textArray[iTempStart])) {
                     iLetterSpaces++;
                 }
                 wordIPD.add(MinOptMax.multiply(letterSpaceIPD, iLetterSpaces));
@@ -522,12 +622,11 @@
                 // create the AreaInfo object
                 ai = new AreaInfo(iThisStart, iTempStart, (short) 0,
                         (short) iLetterSpaces,
-                        wordIPD, false);
+                        wordIPD, false, false);
                 vecAreaInfo.add(ai);
 
                 // create the elements
-                sequence.addAll
-                (createElementsForAWordFragment(alignment, ai,
+                sequence.addAll(createElementsForAWordFragment(alignment, ai,
                         vecAreaInfo.size() - 1, letterSpaceIPD));
 
                 // advance to the next character
@@ -666,7 +765,7 @@
                                    (short) (bIsWordEnd
                                             ? (iStopIndex - iStartIndex - 1)
                                             : (iStopIndex - iStartIndex)),
-                                   newIPD, bHyphenFollows),
+                                   newIPD, bHyphenFollows, false),
                       ((LeafPosition) pos).getLeafPos()));
                 bNothingChanged = false;
             }
@@ -752,7 +851,7 @@
         LinkedList spaceElements = new LinkedList();
         LeafPosition mainPosition = new LeafPosition(this, leafValue);
         
-        if (textArray[ai.iStartIndex] == NBSPACE) {
+        if (textArray[ai.iStartIndex] == CharUtilities.NBSPACE) {
             // a non-breaking space
             //TODO: other kinds of non-breaking spaces
             if (alignment == EN_JUSTIFY) {
@@ -784,7 +883,8 @@
                 spaceElements
                         .add(new KnuthPenalty(
                                 0,
-                                (textArray[ai.iStartIndex] == NBSPACE ? KnuthElement.INFINITE
+                                (textArray[ai.iStartIndex] == CharUtilities.NBSPACE 
+                                        ? KnuthElement.INFINITE
                                         : 0), false,
                                 new LeafPosition(this, -1), false));
                 spaceElements.add(new KnuthGlue(ai.ipdArea.opt
@@ -899,8 +999,8 @@
         // the fragment could end a line; in this case, it loses one
         // of its letter spaces;
         boolean bSuppressibleLetterSpace 
-            = ai.iLScount == (ai.iBreakIndex - ai.iStartIndex)
-                && BREAK_CHARS.indexOf(textArray[ai.iBreakIndex - 1]) >= 0;
+            = /*ai.iLScount == (ai.iBreakIndex - ai.iStartIndex)
+                &&*/ isBreakChar(textArray[ai.iBreakIndex - 1]);
 
         if (letterSpaceWidth.min == letterSpaceWidth.max) {
             // constant letter spacing
@@ -941,7 +1041,7 @@
             // otherwise nothing happens
             wordElements.addAll(createElementsForAHyphen(alignment, hyphIPD, new MinOptMax(0)));
         } else if (bSuppressibleLetterSpace) {
-            // the word framgent ends with a character that acts as a hyphen
+            // the word fragment ends with a character that acts as a hyphen
             // if a break occurs the width does not increase,
             // otherwise there is one more letter space
             wordElements.addAll(createElementsForAHyphen(alignment, 0, letterSpaceWidth));

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/AbstractRenderer.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/AbstractRenderer.java?rev=386327&r1=386326&r2=386327&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/AbstractRenderer.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/AbstractRenderer.java Thu Mar 16 05:51:14 2006
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -49,6 +49,7 @@
 import org.apache.fop.area.RegionReference;
 import org.apache.fop.area.Trait;
 import org.apache.fop.area.OffDocumentItem;
+import org.apache.fop.area.inline.Character;
 import org.apache.fop.area.inline.Container;
 import org.apache.fop.area.inline.ForeignObject;
 import org.apache.fop.area.inline.Image;
@@ -59,7 +60,6 @@
 import org.apache.fop.area.inline.Space;
 import org.apache.fop.area.inline.Viewport;
 import org.apache.fop.area.inline.TextArea;
-import org.apache.fop.area.inline.Character;
 import org.apache.fop.area.inline.WordArea;
 import org.apache.fop.area.inline.SpaceArea;
 import org.apache.fop.apps.FOUserAgent;
@@ -204,9 +204,9 @@
         StringBuffer sb = new StringBuffer();
         for (int count = 0; count < children.size(); count++) {
             InlineArea inline = (InlineArea) children.get(count);
-            if (inline instanceof Character) {
-                sb.append(((Character) inline).getChar());
-            } else if (inline instanceof TextArea) {
+            //if (inline instanceof Character) {
+            //    sb.append(((Character) inline).getChar());
+            /*} else*/ if (inline instanceof TextArea) {
                 sb.append(((TextArea) inline).getText());
             } else if (inline instanceof InlineParent) {
                 sb.append(convertToString(
@@ -618,8 +618,8 @@
     protected void renderInlineArea(InlineArea inlineArea) {
         if (inlineArea instanceof TextArea) {
             renderText((TextArea) inlineArea);
-        } else if (inlineArea instanceof Character) {
-            renderCharacter((Character) inlineArea);
+        //} else if (inlineArea instanceof Character) {
+            //renderCharacter((Character) inlineArea);
         } else if (inlineArea instanceof WordArea) {
             renderWord((WordArea) inlineArea);
         } else if (inlineArea instanceof SpaceArea) {
@@ -640,6 +640,7 @@
     /**
      * Render the given Character.
      * @param ch the character to render
+     * @deprecated Only TextArea should be used. This method will be removed eventually.
      */
     protected void renderCharacter(Character ch) {
         currentIPPosition += ch.getAllocIPD();

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/DefaultFontResolver.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/DefaultFontResolver.java?rev=386327&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/DefaultFontResolver.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/DefaultFontResolver.java Thu Mar 16 05:51:14 2006
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render;
+
+import javax.xml.transform.Source;
+
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.fonts.FontResolver;
+
+/**
+ * Default FontResolver implementation which uses the FOUserAgent to resolve font URIs.
+ */
+public class DefaultFontResolver implements FontResolver {
+
+    private FOUserAgent userAgent;
+    
+    /**
+     * Main constructor.
+     * @param userAgent the user agent
+     */
+    public DefaultFontResolver(FOUserAgent userAgent) {
+        this.userAgent = userAgent;
+    }
+    
+    /** @see org.apache.fop.fonts.FontResolver#resolve(java.lang.String) */
+    public Source resolve(String href) {
+        return userAgent.resolveURI(href, userAgent.getFontBaseURL());
+    }
+    
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/DefaultFontResolver.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/PrintRenderer.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/PrintRenderer.java?rev=386327&r1=386326&r2=386327&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/PrintRenderer.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/PrintRenderer.java Thu Mar 16 05:51:14 2006
@@ -23,6 +23,7 @@
 import org.apache.fop.area.Trait;
 import org.apache.fop.fonts.Font;
 import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontResolver;
 import org.apache.fop.fonts.FontSetup;
 import org.apache.fop.fonts.FontTriplet;
 
@@ -46,7 +47,8 @@
      */
     public void setupFontInfo(FontInfo inFontInfo) {
         this.fontInfo = inFontInfo;
-        FontSetup.setup(fontInfo, fontList, userAgent);
+        FontResolver resolver = new DefaultFontResolver(userAgent);
+        FontSetup.setup(fontInfo, fontList, resolver, userAgent.isBase14KerningEnabled());
     }
 
     /**

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/java2d/Java2DRenderer.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/java2d/Java2DRenderer.java?rev=386327&r1=386326&r2=386327&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/java2d/Java2DRenderer.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/java2d/Java2DRenderer.java Thu Mar 16 05:51:14 2006
@@ -55,7 +55,6 @@
 import org.apache.fop.area.PageViewport;
 import org.apache.fop.area.RegionViewport;
 import org.apache.fop.area.Trait;
-import org.apache.fop.area.inline.Character;
 import org.apache.fop.area.inline.ForeignObject;
 import org.apache.fop.area.inline.Image;
 import org.apache.fop.area.inline.InlineArea;
@@ -863,33 +862,6 @@
         super.renderText(text);
 
         renderTextDecoration(font, text, y, x);
-    }
-
-    /**
-     * @see org.apache.fop.render.AbstractRenderer#renderCharacter(Character)
-     */
-    public void renderCharacter(Character ch) {
-        renderInlineAreaBackAndBorders(ch);
-
-        float x = currentIPPosition + ch.getBorderAndPaddingWidthStart();
-        float y = currentBPPosition + ch.getOffset() + ch.getBaselineOffset(); // baseline
-
-        Font font = getFontFromArea(ch);
-        state.updateFont(font.getFontName(), font.getFontSize(), null);
-
-        ColorType ct = (ColorType) ch.getTrait(Trait.COLOR);
-        state.updateColor(ct, false, null);
-
-        String s = ch.getChar();
-        state.getGraph().drawString(s, x / 1000f, y / 1000f);
-
-        // getLogger().debug( "renderCharacter(): \"" + s + "\", x: "
-        // + x + ", y: " + y + state);
-
-        // rendering text decorations
-        renderTextDecoration(font, ch, y, x);
-
-        super.renderCharacter(ch);
     }
 
     /**

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderer.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderer.java?rev=386327&r1=386326&r2=386327&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderer.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderer.java Thu Mar 16 05:51:14 2006
@@ -47,7 +47,7 @@
 import org.apache.fop.area.Trait;
 import org.apache.fop.area.OffDocumentItem;
 import org.apache.fop.area.BookmarkData;
-import org.apache.fop.area.inline.Character;
+import org.apache.fop.area.inline.AbstractTextArea;
 import org.apache.fop.area.inline.TextArea;
 import org.apache.fop.area.inline.ForeignObject;
 import org.apache.fop.area.inline.Image;
@@ -83,6 +83,7 @@
 import org.apache.fop.render.AbstractPathOrientedRenderer;
 import org.apache.fop.render.Graphics2DAdapter;
 import org.apache.fop.render.RendererContext;
+import org.apache.fop.util.CharUtilities;
 import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.extensions.ExtensionAttachment;
 import org.apache.fop.fo.extensions.xmp.XMPMetadata;
@@ -185,7 +186,7 @@
     /**
      * true if a TJ command is left to be written
      */
-    protected boolean textOpen = false;
+    //protected boolean textOpen = false;
 
     /**
      * true if a BT command has been written. 
@@ -196,18 +197,18 @@
      * the previous Y coordinate of the last word written.
      * Used to decide if we can draw the next word on the same line.
      */
-    protected int prevWordY = 0;
+    //protected int prevWordY = 0;
 
     /**
      * the previous X coordinate of the last word written.
      * used to calculate how much space between two words
      */
-    protected int prevWordX = 0;
+    //protected int prevWordX = 0;
 
     /**
      * The width of the previous word. Used to calculate space between
      */
-    protected int prevWordWidth = 0;
+    //protected int prevWordWidth = 0;
 
     /**
      * reusable word area string buffer to reduce memory usage
@@ -402,6 +403,7 @@
     protected void beginTextObject() {
         if (!inTextMode) {
             currentStream.add("BT\n");
+            currentFontName = "";
             inTextMode = true;
         }
     }
@@ -931,79 +933,6 @@
     }
 
     /**
-     * @see org.apache.fop.render.AbstractRenderer#renderCharacter(Character)
-     */
-    public void renderCharacter(Character ch) {
-        renderInlineAreaBackAndBorders(ch);
-
-        beginTextObject();
-        StringBuffer pdf = new StringBuffer();
-
-        Font font = getFontFromArea(ch);
-
-        // This assumes that *all* CIDFonts use a /ToUnicode mapping
-        Typeface tf = (Typeface) fontInfo.getFonts().get(font.getFontName());
-        boolean useMultiByte = tf.isMultiByte();
-
-        // String startText = useMultiByte ? "<FEFF" : "(";
-        String startText = useMultiByte ? "<" : "(";
-        String endText = useMultiByte ? "> " : ") ";
-
-        updateFont(font.getFontName(), font.getFontSize(), pdf);
-        ColorType ct = (ColorType) ch.getTrait(Trait.COLOR);
-        if (ct != null) {
-            updateColor(ct, true, pdf);
-        }
-
-        // word.getOffset() = only height of text itself
-        // currentBlockIPPosition: 0 for beginning of line; nonzero
-        //  where previous line area failed to take up entire allocated space
-        int rx = currentIPPosition + ch.getBorderAndPaddingWidthStart();
-        int bl = currentBPPosition + ch.getOffset() + ch.getBaselineOffset();
-
-/*        log.debug("Text = " + ch.getTextArea() +
-            "; text width: " + ch.getWidth() +
-            "; BlockIP Position: " + currentBlockIPPosition +
-            "; currentBPPosition: " + currentBPPosition +
-            "; offset: " + ch.getOffset());
-*/
-        // Set letterSpacing
-        //float ls = fs.getLetterSpacing() / this.currentFontSize;
-        //pdf.append(ls).append(" Tc\n");
-
-        if (!textOpen || bl != prevWordY) {
-            closeText();
-
-            pdf.append("1 0 0 -1 " + format(rx / 1000f) + " " + format(bl / 1000f) + " Tm "
-                       + format(ch.getTextLetterSpaceAdjust() / 1000f) + " Tc "
-                       + format(ch.getTextWordSpaceAdjust() / 1000f) + " Tw [" + startText);
-            prevWordY = bl;
-            textOpen = true;
-        } else {
-            closeText();
-
-            pdf.append("1 0 0 -1 " + format(rx / 1000f) + " " + format(bl / 1000f) + " Tm "
-                           + format(ch.getTextLetterSpaceAdjust() / 1000f) + " Tc "
-                           + format(ch.getTextWordSpaceAdjust() / 1000f) + " Tw [" + startText);
-            textOpen = true;
-        }
-        prevWordWidth = ch.getIPD();
-        prevWordX = rx;
-
-        String s = ch.getChar();
-
-
-        escapeText(s, font, useMultiByte, pdf);
-        pdf.append(endText);
-
-        currentStream.add(pdf.toString());
-
-        renderTextDecoration(tf, font.getFontSize(), ch, bl, rx);
-        
-        super.renderCharacter(ch);
-    }
-
-    /**
      * @see org.apache.fop.render.AbstractRenderer#renderText(TextArea)
      */
     public void renderText(TextArea text) {
@@ -1028,39 +957,17 @@
         int rx = currentIPPosition + text.getBorderAndPaddingWidthStart();
         int bl = currentBPPosition + text.getOffset() + text.getBaselineOffset();
 
-/*        log.debug("Text = " + text.getTextArea() +
-            "; text width: " + text.getWidth() +
-            "; BlockIP Position: " + currentBlockIPPosition +
-            "; currentBPPosition: " + currentBPPosition +
-            "; offset: " + text.getOffset());
-*/
-        // Set letterSpacing
-        //float ls = fs.getLetterSpacing() / this.currentFontSize;
-        //pdf.append(ls).append(" Tc\n");
-
-        if (!textOpen || bl != prevWordY) {
-            closeText();
-
-            pdf.append("1 0 0 -1 " + format(rx / 1000f) + " " + format(bl / 1000f) + " Tm "
-                       + format(text.getTextLetterSpaceAdjust() / 1000f) + " Tc "
-                       + format(text.getTextWordSpaceAdjust() / 1000f) + " Tw [");
-            prevWordY = bl;
-            textOpen = true;
-        } else {
-            closeText();
-
-            pdf.append("1 0 0 -1 " + format(rx / 1000f) + " " + format(bl / 1000f) + " Tm "
-                       + format(text.getTextLetterSpaceAdjust() / 1000f) + " Tc "
-                       + format(text.getTextWordSpaceAdjust() / 1000f) + " Tw [");
-            textOpen = true;
-        }
-        prevWordWidth = text.getIPD();
-        prevWordX = rx;
+        pdf.append("1 0 0 -1 " + format(rx / 1000f) + " " + format(bl / 1000f) + " Tm "
+                   /*+ format(text.getTextLetterSpaceAdjust() / 1000f) + " Tc\n"*/
+                   /*+ format(text.getTextWordSpaceAdjust() / 1000f) + " Tw ["*/);
 
+        pdf.append("[");
         currentStream.add(pdf.toString());
 
         super.renderText(text);
 
+        currentStream.add("] TJ\n");
+        
         renderTextDecoration(tf, size, text, bl, rx);
     }
     
@@ -1072,17 +979,11 @@
         Typeface tf = (Typeface) fontInfo.getFonts().get(font.getFontName());
         boolean useMultiByte = tf.isMultiByte();
 
-        String startText = useMultiByte ? "<" : "(";
-        String endText = useMultiByte ? "> " : ") ";
-        
         StringBuffer pdf = new StringBuffer();
         
-        pdf.append(startText);
-
         String s = word.getWord();
-        
-        escapeText(s, font, useMultiByte, pdf);
-        pdf.append(endText);
+        escapeText(s, word.getLetterAdjustArray(), 
+                font, (AbstractTextArea)word.getParentArea(), useMultiByte, pdf);
         
         currentStream.add(pdf.toString());
 
@@ -1097,22 +998,21 @@
         Typeface tf = (Typeface) fontInfo.getFonts().get(font.getFontName());
         boolean useMultiByte = tf.isMultiByte();
 
-        String startText = useMultiByte ? "<" : "(";
-        String endText = useMultiByte ? "> " : ") ";
+        String s = space.getSpace();
         
         StringBuffer pdf = new StringBuffer();
-        
-        pdf.append(startText);
 
-        String s = space.getSpace();
-        
-        escapeText(s, font, useMultiByte, pdf);
-        pdf.append(endText);
-        
-        if (useMultiByte) {
-            float tws = -(((TextArea) space.getParentArea()).getTextWordSpaceAdjust() 
-                    / (font.getFontSize() / 1000f));
-            pdf.append(format(tws) + " ");
+        AbstractTextArea textArea = (AbstractTextArea)space.getParentArea();
+        escapeText(s, null, font, textArea, useMultiByte, pdf);
+
+        if (space.isAdjustable()) {
+            int tws = -((TextArea) space.getParentArea()).getTextWordSpaceAdjust()
+                         - 2 * textArea.getTextLetterSpaceAdjust();
+                    
+            if (tws != 0) {
+                pdf.append(format(tws / (font.getFontSize() / 1000f)));
+                pdf.append(" ");
+            }
         }
         
         currentStream.add(pdf.toString());
@@ -1123,15 +1023,19 @@
     /**
      * Escapes text according to PDF rules.
      * @param s Text to escape
+     * @param letterAdjust an array of widths for letter adjustment (may be null)
      * @param fs Font state
+     * @param parentArea the parent text area to retrieve certain traits from
      * @param useMultiByte Indicates the use of multi byte convention
      * @param pdf target buffer for the escaped text
      */
-    public void escapeText(String s, Font fs,
+    public void escapeText(String s, int[] letterAdjust,
+                           Font fs, AbstractTextArea parentArea,
                            boolean useMultiByte, StringBuffer pdf) {
         String startText = useMultiByte ? "<" : "(";
         String endText = useMultiByte ? "> " : ") ";
 
+        /*
         boolean kerningAvailable = false;
         Map kerning = fs.getKerning();
         if (kerning != null && !kerning.isEmpty()) {
@@ -1139,12 +1043,37 @@
             //TODO Reenable me when the layout engine supports kerning, too
             log.warn("Kerning support is disabled until it is supported by the layout engine!");
         }
+        */
 
         int l = s.length();
 
+        float fontSize = fs.getFontSize() / 1000f;
+        boolean startPending = true;
         for (int i = 0; i < l; i++) {
-            char ch = fs.mapChar(s.charAt(i));
-
+            char orgChar = s.charAt(i);
+            char ch;
+            float glyphAdjust = 0;
+            if (fs.hasChar(orgChar)) {
+                ch = fs.mapChar(orgChar);
+                int tls = (i < l - 1 ? parentArea.getTextLetterSpaceAdjust() : 0);
+                glyphAdjust -= tls;
+            } else {
+                if (CharUtilities.isFixedWidthSpace(orgChar)) {
+                    //Fixed width space are rendered as spaces so copy/paste works in a reader
+                    ch = fs.mapChar(CharUtilities.SPACE);
+                    glyphAdjust = fs.getCharWidth(ch) - fs.getCharWidth(orgChar);
+                } else {
+                    ch = fs.mapChar(orgChar);
+                }
+            }
+            if (letterAdjust != null && i < l - 1) {
+                glyphAdjust -= letterAdjust[i + 1]; 
+            }
+            
+            if (startPending) {
+                pdf.append(startText);
+                startPending = false;
+            }
             if (!useMultiByte) {
                 if (ch > 127) {
                     pdf.append("\\");
@@ -1156,6 +1085,7 @@
                         case '\\':
                             pdf.append("\\");
                             break;
+                        default:
                     }
                     pdf.append(ch);
                 }
@@ -1163,24 +1093,16 @@
                 pdf.append(PDFText.toUnicodeHex(ch));
             }
 
-            if (kerningAvailable && (i + 1) < l) {
-                addKerning(pdf, (new Integer((int) ch)),
-                           (new Integer((int) fs.mapChar(s.charAt(i + 1)))
-                           ), kerning, startText, endText);
+            float adjust = glyphAdjust / fontSize;
+            
+            if (adjust != 0) {
+                pdf.append(endText).append(format(adjust)).append(' ');
+                startPending = true;
             }
+            
         }
-    }
-
-    private void addKerning(StringBuffer buf, Integer ch1, Integer ch2,
-                            Map kerning, String startText, String endText) {
-        Map kernPair = (Map) kerning.get(ch1);
-
-        if (kernPair != null) {
-            Integer width = (Integer) kernPair.get(ch2);
-            if (width != null) {
-                buf.append(endText).append(-width.intValue());
-                buf.append(' ').append(startText);
-            }
+        if (!startPending) {
+            pdf.append(endText);
         }
     }
 
@@ -1189,13 +1111,14 @@
      * still and writes out the TJ command to the stream if we do
      */
     protected void closeText() {
+        /*
         if (textOpen) {
             currentStream.add("] TJ\n");
             textOpen = false;
             prevWordX = 0;
             prevWordY = 0;
             currentFontName = "";
-        }
+        }*/
     }
 
     /**
@@ -1319,6 +1242,11 @@
             FopPDFImage pdfimage = new FopPDFImage(fopimage, url);
             int xobj = pdfDoc.addImage(currentContext, pdfimage).getXNumber();
             fact.releaseImage(url, userAgent);
+            
+            float w = (float)pos.getWidth() / 1000f;
+            float h = (float)pos.getHeight() / 1000f;
+            placeImage((float) pos.getX() / 1000,
+                       (float) pos.getY() / 1000, w, h, xobj);
         } else if ("image/jpeg".equals(mime) || "image/tiff".equals(mime)) {
             FopPDFImage pdfimage = new FopPDFImage(fopimage, url);
             int xobj = pdfDoc.addImage(currentContext, pdfimage).getXNumber();

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSDocumentGraphics2D.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSDocumentGraphics2D.java?rev=386327&r1=386326&r2=386327&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSDocumentGraphics2D.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSDocumentGraphics2D.java Thu Mar 16 05:51:14 2006
@@ -53,11 +53,6 @@
      */
     PSDocumentGraphics2D(boolean textAsShapes) {
         super(textAsShapes);
-
-        if (!textAsShapes) {
-            fontInfo = new FontInfo();
-            FontSetup.setup(fontInfo, null, null);
-        }
     }
 
     /**



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