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 2009/02/05 17:27:09 UTC

svn commit: r741165 [1/2] - in /xmlgraphics/fop/branches/Temp_AreaTreeNewDesign: src/documentation/intermediate-format-ng/ src/java/org/apache/fop/afp/ src/java/org/apache/fop/afp/fonts/ src/java/org/apache/fop/afp/modca/ src/java/org/apache/fop/afp/ut...

Author: jeremias
Date: Thu Feb  5 16:27:08 2009
New Revision: 741165

URL: http://svn.apache.org/viewvc?rev=741165&view=rev
Log:
Performance improvements and file-size reductions by introducing letter-spacing and word-spacing attributes in new IF (as mentioned on fop-dev).

Allow to control whether kerning information is loaded from fonts.
Started support for AFP font embedding (incomplete and currently disabled)

Added:
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/modca/IncludedResourceObject.java   (with props)
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/util/DefaultFOPResourceAccessor.java   (with props)
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/util/ResourceAccessor.java   (with props)
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/util/SimpleResourceAccessor.java   (with props)
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/ps/FOPProcSet.java   (with props)
Modified:
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/documentation/intermediate-format-ng/fop-intermediate-format-ng-content.xsd
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/AFPResourceManager.java
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/fonts/AFPFont.java
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/fonts/FontLoader.java
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/fonts/LazyFont.java
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/pdf/PDFPaintingState.java
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/afp/AFPPainter.java
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/IFPainter.java
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/IFParser.java
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/IFRenderer.java
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/IFSerializer.java
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/java2d/Java2DPainter.java
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLPainter.java
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFContentGenerator.java
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFPainter.java
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/ps/PSDocumentHandler.java
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/ps/PSPainter.java
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/sandbox/org/apache/fop/render/svg/SVGPainter.java
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/test/layoutengine/standard-testcases/block_letter-spacing.xml
    xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/test/layoutengine/standard-testcases/kerning_1_on.xml

Modified: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/documentation/intermediate-format-ng/fop-intermediate-format-ng-content.xsd
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/documentation/intermediate-format-ng/fop-intermediate-format-ng-content.xsd?rev=741165&r1=741164&r2=741165&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/documentation/intermediate-format-ng/fop-intermediate-format-ng-content.xsd (original)
+++ xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/documentation/intermediate-format-ng/fop-intermediate-format-ng-content.xsd Thu Feb  5 16:27:08 2009
@@ -61,6 +61,8 @@
             <xs:extension base="xs:string">
               <xs:attribute name="x" use="required" type="mf:lengthType"/>
               <xs:attribute name="y" use="required" type="mf:lengthType"/>
+              <xs:attribute name="letter-spacing" type="mf:lengthType"/>
+              <xs:attribute name="word-spacing" type="mf:lengthType"/>
               <xs:attribute name="dx">
                 <xs:simpleType>
                   <xs:list itemType="mf:lengthType"/>

Modified: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/AFPResourceManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/AFPResourceManager.java?rev=741165&r1=741164&r2=741165&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/AFPResourceManager.java (original)
+++ xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/AFPResourceManager.java Thu Feb  5 16:27:08 2009
@@ -21,19 +21,32 @@
 
 import java.io.IOException;
 import java.io.OutputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.util.Map;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
 import org.apache.fop.afp.modca.AbstractNamedAFPObject;
 import org.apache.fop.afp.modca.AbstractPageObject;
 import org.apache.fop.afp.modca.IncludeObject;
+import org.apache.fop.afp.modca.IncludedResourceObject;
 import org.apache.fop.afp.modca.PageSegment;
 import org.apache.fop.afp.modca.Registry;
 import org.apache.fop.afp.modca.ResourceGroup;
+import org.apache.fop.afp.modca.ResourceObject;
+import org.apache.fop.afp.util.ResourceAccessor;
+import org.apache.fop.afp.util.SimpleResourceAccessor;
 
 /**
  * Manages the creation and storage of document resources
  */
 public class AFPResourceManager {
+
+    /** logging instance */
+    private static Log log = LogFactory.getLog(AFPResourceManager.class);
+
     /** The AFP datastream (document tree) */
     private DataStream dataStream;
 
@@ -47,8 +60,8 @@
     /** Maintain a reference count of instream objects for referencing purposes */
     private int instreamObjectCount = 0;
 
-    /** a mapping of resourceInfo --> names of includable objects */
-    private final Map/*<AFPResourceInfo,String>*/ includableObjectsMap
+    /** a mapping of resourceInfo --> include name */
+    private final Map/*<AFPResourceInfo,String>*/ includeNameMap
         = new java.util.HashMap()/*<AFPResourceInfo,String>*/;
 
     private Map pageSegmentMap = new java.util.HashMap();
@@ -120,7 +133,7 @@
         AFPResourceInfo resourceInfo = dataObjectInfo.getResourceInfo();
         updateResourceInfoUri(resourceInfo);
 
-        String objectName = (String)includableObjectsMap.get(resourceInfo);
+        String objectName = (String)includeNameMap.get(resourceInfo);
         if (objectName != null) {
             // an existing data resource so reference it by adding an include to the current page
             includeObject(dataObjectInfo, objectName);
@@ -156,35 +169,35 @@
         useInclude &= resourceGroup != null;
         if (useInclude) {
 
-            boolean usePageSegment = dataObjectInfo.isCreatePageSegment();
-
-            // if it is to reside within a resource group at print-file or external level
-            if (resourceLevel.isPrintFile() || resourceLevel.isExternal()) {
-                if (usePageSegment) {
-                    String pageSegmentName = "S10" + namedObj.getName().substring(3);
-                    namedObj.setName(pageSegmentName);
-                    PageSegment seg = new PageSegment(pageSegmentName);
-                    seg.addObject(namedObj);
-                    namedObj = seg;
-                }
+        boolean usePageSegment = dataObjectInfo.isCreatePageSegment();
 
-                // wrap newly created data object in a resource object
-                namedObj = dataObjectFactory.createResource(namedObj, resourceInfo, objectType);
+        // if it is to reside within a resource group at print-file or external level
+        if (resourceLevel.isPrintFile() || resourceLevel.isExternal()) {
+            if (usePageSegment) {
+                String pageSegmentName = "S10" + namedObj.getName().substring(3);
+                namedObj.setName(pageSegmentName);
+                PageSegment seg = new PageSegment(pageSegmentName);
+                seg.addObject(namedObj);
+                namedObj = seg;
             }
 
-            // add data object into its resource group destination
-            resourceGroup.addObject(namedObj);
+            // wrap newly created data object in a resource object
+            namedObj = dataObjectFactory.createResource(namedObj, resourceInfo, objectType);
+        }
 
-            // create the include object
-            objectName = namedObj.getName();
-            if (usePageSegment) {
-                includePageSegment(dataObjectInfo, objectName);
-                pageSegmentMap.put(resourceInfo, objectName);
-            } else {
-                includeObject(dataObjectInfo, objectName);
-                // record mapping of resource info to data object resource name
-                includableObjectsMap.put(resourceInfo, objectName);
-            }
+        // add data object into its resource group destination
+        resourceGroup.addObject(namedObj);
+
+        // create the include object
+        objectName = namedObj.getName();
+        if (usePageSegment) {
+            includePageSegment(dataObjectInfo, objectName);
+            pageSegmentMap.put(resourceInfo, objectName);
+        } else {
+            includeObject(dataObjectInfo, objectName);
+            // record mapping of resource info to data object resource name
+            includeNameMap.put(resourceInfo, objectName);
+        }
 
         } else {
             // not to be included so inline data object directly into the current page
@@ -206,10 +219,10 @@
 
     private void includeObject(AFPDataObjectInfo dataObjectInfo,
             String objectName) {
-        IncludeObject includeObject
-            = dataObjectFactory.createInclude(objectName, dataObjectInfo);
-        dataStream.getCurrentPage().addObject(includeObject);
-    }
+            IncludeObject includeObject
+                = dataObjectFactory.createInclude(objectName, dataObjectInfo);
+            dataStream.getCurrentPage().addObject(includeObject);
+        }
 
     private void includePageSegment(AFPDataObjectInfo dataObjectInfo,
             String pageSegmentName) {
@@ -221,6 +234,53 @@
     }
 
     /**
+     * Creates an included resource object by loading the contained object from a file.
+     * @param resourceName the name of the resource
+     * @param basePath the base path in which to look for the resource files
+     * @param resourceObjectType the resource object type ({@link ResourceObject}.*)
+     * @throws IOException if an I/O error occurs while loading the resource
+     */
+    public void createIncludedResource(String resourceName, String basePath,
+                byte resourceObjectType) throws IOException {
+        AFPResourceLevel resourceLevel = new AFPResourceLevel(AFPResourceLevel.PRINT_FILE);
+        URI uri;
+        try {
+            uri = new URI(resourceName.trim());
+        } catch (URISyntaxException e) {
+            throw new IOException("Could not create URI from resource name: " + resourceName
+                    + " (" + e.getMessage() + ")");
+        }
+
+        AFPResourceInfo resourceInfo = new AFPResourceInfo();
+        resourceInfo.setLevel(resourceLevel);
+        resourceInfo.setName(resourceName);
+        resourceInfo.setUri(uri.toASCIIString());
+
+        String objectName = (String)includeNameMap.get(resourceInfo);
+        if (objectName == null) {
+            if (log.isDebugEnabled()) {
+                log.debug("Adding included resource: " + resourceName);
+            }
+            //TODO This works with local filenames only. In the long term, this
+            //should work through FOP's URI resolver.
+            ResourceAccessor accessor = new SimpleResourceAccessor(basePath);
+            IncludedResourceObject resourceContent = new IncludedResourceObject(
+                        resourceName, accessor, uri);
+
+            ResourceObject resourceObject = factory.createResource(resourceName);
+            resourceObject.setDataObject(resourceContent);
+            resourceObject.setType(resourceObjectType);
+
+            ResourceGroup resourceGroup = streamer.getResourceGroup(resourceLevel);
+            resourceGroup.addObject(resourceObject);
+            // record mapping of resource info to data object resource name
+            includeNameMap.put(resourceInfo, resourceName);
+        } else {
+            //skip, already created
+        }
+    }
+
+    /**
      * Sets resource level defaults. The existing defaults over merged with the ones passed in
      * as parameter.
      * @param defaults the new defaults
@@ -236,4 +296,5 @@
     public AFPResourceLevelDefaults getResourceLevelDefaults() {
         return this.resourceLevelDefaults;
     }
-}
\ No newline at end of file
+
+}

Modified: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/fonts/AFPFont.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/fonts/AFPFont.java?rev=741165&r1=741164&r2=741165&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/fonts/AFPFont.java (original)
+++ xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/fonts/AFPFont.java Thu Feb  5 16:27:08 2009
@@ -97,6 +97,14 @@
      */
     public abstract CharacterSet getCharacterSet(int size);
 
+    /**
+     * Indicates if this font may be embedded.
+     * @return True, if embedding is possible/permitted
+     */
+    public boolean isEmbeddable() {
+        return false; //TODO Complete AFP font embedding
+    }
+
     /** {@inheritDoc} */
     public String toString() {
         return "name=" + name;

Added: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/modca/IncludedResourceObject.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/modca/IncludedResourceObject.java?rev=741165&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/modca/IncludedResourceObject.java (added)
+++ xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/modca/IncludedResourceObject.java Thu Feb  5 16:27:08 2009
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.afp.modca;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+
+import org.apache.commons.io.IOUtils;
+
+import org.apache.fop.afp.util.ResourceAccessor;
+
+
+/**
+ * Encapsulates an included resource object that is loaded from an external file.
+ */
+public class IncludedResourceObject extends AbstractNamedAFPObject {
+
+    private ResourceAccessor resourceAccessor;
+    private URI uri;
+
+    /**
+     * Main constructor.
+     * @param name the name of the included resource
+     * @param resourceAccessor the resource accessor to load the external file with
+     * @param uri the URI of the external file
+     */
+    public IncludedResourceObject(String name,
+            ResourceAccessor resourceAccessor, URI uri) {
+        super(name);
+        this.resourceAccessor = resourceAccessor;
+        this.uri = uri;
+    }
+
+    /** {@inheritDoc} */
+    public void writeToStream(OutputStream os) throws IOException {
+        InputStream in = resourceAccessor.createInputStream(this.uri);
+        try {
+            IOUtils.copy(in, os);
+        } finally {
+            IOUtils.closeQuietly(in);
+        }
+    }
+
+}

Propchange: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/modca/IncludedResourceObject.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/modca/IncludedResourceObject.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/util/DefaultFOPResourceAccessor.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/util/DefaultFOPResourceAccessor.java?rev=741165&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/util/DefaultFOPResourceAccessor.java (added)
+++ xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/util/DefaultFOPResourceAccessor.java Thu Feb  5 16:27:08 2009
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.afp.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.fop.apps.FOUserAgent;
+
+/**
+ * Default implementation of the {@link ResourceAccessor} interface for use inside FOP.
+ */
+public class DefaultFOPResourceAccessor implements ResourceAccessor {
+
+    private FOUserAgent userAgent;
+
+    /**
+     * Main constructor.
+     * @param userAgent the FO user agent
+     */
+    public DefaultFOPResourceAccessor(FOUserAgent userAgent) {
+        this.userAgent = userAgent;
+    }
+
+    /** {@inheritDoc} */
+    public InputStream createInputStream(URI uri) throws IOException {
+        Source src = userAgent.resolveURI(uri.toASCIIString());
+        if (src == null) {
+            return null;
+        } else if (src instanceof StreamSource) {
+            StreamSource ss = (StreamSource)src;
+            InputStream in = ss.getInputStream();
+            return in;
+        } else {
+            return null;
+        }
+    }
+
+}

Propchange: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/util/DefaultFOPResourceAccessor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/util/DefaultFOPResourceAccessor.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/util/ResourceAccessor.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/util/ResourceAccessor.java?rev=741165&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/util/ResourceAccessor.java (added)
+++ xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/util/ResourceAccessor.java Thu Feb  5 16:27:08 2009
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.afp.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+
+/**
+ * Defines an interface through which external resource objects can be accessed.
+ */
+public interface ResourceAccessor {
+
+    /**
+     * Creates a new {@link InputStream} for the given URI that allows read access to an external
+     * resource.
+     * @param uri the URI of an external resource.
+     * @return the new input stream
+     * @throws IOException if an I/O error occurs while opening the resource
+     */
+    InputStream createInputStream(URI uri) throws IOException;
+
+}

Propchange: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/util/ResourceAccessor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/util/ResourceAccessor.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/util/SimpleResourceAccessor.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/util/SimpleResourceAccessor.java?rev=741165&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/util/SimpleResourceAccessor.java (added)
+++ xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/util/SimpleResourceAccessor.java Thu Feb  5 16:27:08 2009
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.afp.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URL;
+
+/**
+ * Simple implementation of the {@link ResourceAccessor} interface for access via files.
+ */
+public class SimpleResourceAccessor implements ResourceAccessor {
+
+    private URI baseURI;
+
+    /**
+     * Creates a new simple resource accessor.
+     * @param basePath the base path to resolve relative URIs to
+     */
+    public SimpleResourceAccessor(File basePath) {
+        this.baseURI = basePath.toURI();
+    }
+
+    /**
+     * Creates a new simple resource accessor.
+     * @param basePath the base path to resolve relative URIs to
+     */
+    public SimpleResourceAccessor(String basePath) {
+        this(new File(basePath));
+    }
+
+    /** {@inheritDoc} */
+    public InputStream createInputStream(URI uri) throws IOException {
+        URI resolved = this.baseURI.resolve(uri);
+        URL url = resolved.toURL();
+        return url.openStream();
+    }
+
+}

Propchange: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/util/SimpleResourceAccessor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/afp/util/SimpleResourceAccessor.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/fonts/FontLoader.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/fonts/FontLoader.java?rev=741165&r1=741164&r2=741165&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/fonts/FontLoader.java (original)
+++ xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/fonts/FontLoader.java Thu Feb  5 16:27:08 2009
@@ -53,16 +53,21 @@
     protected boolean loaded = false;
     /** true if the font will be embedded, false if it will be referenced only. */
     protected boolean embedded = true;
+    /** true if kerning information shall be loaded if available. */
+    protected boolean useKerning = true;
 
     /**
      * Default constructor.
      * @param fontFileURI the URI to the PFB file of a Type 1 font
      * @param embedded indicates whether the font is embedded or referenced
+     * @param useKerning indicates whether kerning information shall be loaded if available
      * @param resolver the font resolver used to resolve URIs
      */
-    public FontLoader(String fontFileURI, boolean embedded, FontResolver resolver) {
+    public FontLoader(String fontFileURI, boolean embedded, boolean useKerning,
+            FontResolver resolver) {
         this.fontFileURI = fontFileURI;
         this.embedded = embedded;
+        this.useKerning = useKerning;
         this.resolver = resolver;
     }
 
@@ -82,7 +87,8 @@
      */
     public static CustomFont loadFont(File fontFile, String subFontName,
             boolean embedded, EncodingMode encodingMode, FontResolver resolver) throws IOException {
-        return loadFont(fontFile.getAbsolutePath(), subFontName, embedded, encodingMode, resolver);
+        return loadFont(fontFile.getAbsolutePath(), subFontName,
+                embedded, encodingMode, true, resolver);
     }
 
     /**
@@ -96,8 +102,11 @@
      * @throws IOException In case of an I/O error
      */
     public static CustomFont loadFont(URL fontUrl, String subFontName,
-            boolean embedded, EncodingMode encodingMode, FontResolver resolver) throws IOException {
-        return loadFont(fontUrl.toExternalForm(), subFontName, embedded, encodingMode, resolver);
+            boolean embedded, EncodingMode encodingMode,
+            FontResolver resolver) throws IOException {
+        return loadFont(fontUrl.toExternalForm(), subFontName,
+                embedded, encodingMode, true,
+                resolver);
     }
 
     /**
@@ -106,12 +115,14 @@
      * @param subFontName the sub-fontname of a font (for TrueType Collections, null otherwise)
      * @param embedded indicates whether the font is embedded or referenced
      * @param encodingMode the requested encoding mode
+     * @param useKerning indicates whether kerning information should be loaded if available
      * @param resolver the font resolver to use when resolving URIs
      * @return the newly loaded font
      * @throws IOException In case of an I/O error
      */
     public static CustomFont loadFont(String fontFileURI, String subFontName,
-            boolean embedded, EncodingMode encodingMode, FontResolver resolver) throws IOException {
+            boolean embedded, EncodingMode encodingMode, boolean useKerning,
+            FontResolver resolver) throws IOException {
         fontFileURI = fontFileURI.trim();
         boolean type1 = isType1(fontFileURI);
         FontLoader loader;
@@ -120,9 +131,10 @@
                 throw new IllegalArgumentException(
                         "CID encoding mode not supported for Type 1 fonts");
             }
-            loader = new Type1FontLoader(fontFileURI, embedded, resolver);
+            loader = new Type1FontLoader(fontFileURI, embedded, useKerning, resolver);
         } else {
-            loader = new TTFFontLoader(fontFileURI, subFontName, embedded, encodingMode, resolver);
+            loader = new TTFFontLoader(fontFileURI, subFontName,
+                    embedded, encodingMode, useKerning, resolver);
         }
         return loader.getFont();
     }

Modified: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/fonts/LazyFont.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/fonts/LazyFont.java?rev=741165&r1=741164&r2=741165&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/fonts/LazyFont.java (original)
+++ xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/fonts/LazyFont.java Thu Feb  5 16:27:08 2009
@@ -132,7 +132,7 @@
                         throw new RuntimeException("Cannot load font. No font URIs available.");
                     }
                     realFont = FontLoader.loadFont(fontEmbedPath, this.subFontName,
-                            this.embedded, this.encodingMode, resolver);
+                            this.embedded, this.encodingMode, useKerning, resolver);
                 }
                 if (realFont instanceof FontDescriptor) {
                     realFontDescriptor = (FontDescriptor) realFont;

Modified: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java?rev=741165&r1=741164&r2=741165&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java (original)
+++ xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java Thu Feb  5 16:27:08 2009
@@ -225,7 +225,7 @@
                 }
                 try {
                     TTFFontLoader ttfLoader = new TTFFontLoader(
-                            fontFileURI, fontName, true, EncodingMode.AUTO, resolver);
+                            fontFileURI, fontName, true, EncodingMode.AUTO, true, resolver);
                     customFont = ttfLoader.getFont();
                     if (this.eventListener != null) {
                         customFont.setEventListener(this.eventListener);

Modified: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java?rev=741165&r1=741164&r2=741165&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java (original)
+++ xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java Thu Feb  5 16:27:08 2009
@@ -55,7 +55,7 @@
      * @param resolver the FontResolver for font URI resolution
      */
     public TTFFontLoader(String fontFileURI, FontResolver resolver) {
-        this(fontFileURI, null, true, EncodingMode.AUTO, resolver);
+        this(fontFileURI, null, true, EncodingMode.AUTO, true, resolver);
     }
 
     /**
@@ -65,11 +65,13 @@
      *          TrueType fonts)
      * @param embedded indicates whether the font is embedded or referenced
      * @param encodingMode the requested encoding mode
+     * @param useKerning true to enable loading kerning info if available, false to disable
      * @param resolver the FontResolver for font URI resolution
      */
     public TTFFontLoader(String fontFileURI, String subFontName,
-                boolean embedded, EncodingMode encodingMode, FontResolver resolver) {
-        super(fontFileURI, embedded, resolver);
+                boolean embedded, EncodingMode encodingMode, boolean useKerning,
+                FontResolver resolver) {
+        super(fontFileURI, embedded, true, resolver);
         this.subFontName = subFontName;
         this.encodingMode = encodingMode;
         if (this.encodingMode == EncodingMode.AUTO) {
@@ -164,7 +166,9 @@
             copyWidthsSingleByte(ttf);
         }
 
-        copyKerning(ttf, isCid);
+        if (useKerning) {
+            copyKerning(ttf, isCid);
+        }
         if (this.embedded && ttf.isEmbeddable()) {
             returnFont.setEmbedFileName(this.fontFileURI);
         }

Modified: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java?rev=741165&r1=741164&r2=741165&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java (original)
+++ xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java Thu Feb  5 16:27:08 2009
@@ -45,12 +45,13 @@
      * Constructs a new Type 1 font loader.
      * @param fontFileURI the URI to the PFB file of a Type 1 font
      * @param embedded indicates whether the font is embedded or referenced
+     * @param useKerning indicates whether to load kerning information if available
      * @param resolver the font resolver used to resolve URIs
      * @throws IOException In case of an I/O error
      */
-    public Type1FontLoader(String fontFileURI, boolean embedded, FontResolver resolver)
-                throws IOException {
-        super(fontFileURI, embedded, resolver);
+    public Type1FontLoader(String fontFileURI, boolean embedded, boolean useKerning,
+            FontResolver resolver) throws IOException {
+        super(fontFileURI, embedded, useKerning, resolver);
     }
 
     private String getPFMURI(String pfbURI) {
@@ -321,7 +322,9 @@
                     singleFont.setWidth(chm.getCharCode(), (int)Math.round(chm.getWidthX()));
                 }
             }
-            returnFont.replaceKerningMap(afm.createXKerningMapEncoded());
+            if (useKerning) {
+                returnFont.replaceKerningMap(afm.createXKerningMapEncoded());
+            }
         } else {
             returnFont.setFlags(pfm.getFlags());
             returnFont.setFirstChar(pfm.getFirstChar());
@@ -329,7 +332,9 @@
             for (short i = pfm.getFirstChar(); i <= pfm.getLastChar(); i++) {
                 singleFont.setWidth(i, pfm.getCharWidth(i));
             }
-            returnFont.replaceKerningMap(pfm.getKerning());
+            if (useKerning) {
+                returnFont.replaceKerningMap(pfm.getKerning());
+            }
         }
     }
 

Modified: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/pdf/PDFPaintingState.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/pdf/PDFPaintingState.java?rev=741165&r1=741164&r2=741165&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/pdf/PDFPaintingState.java (original)
+++ xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/pdf/PDFPaintingState.java Thu Feb  5 16:27:08 2009
@@ -62,14 +62,15 @@
      * @return true if the new paint changes the current paint
      */
     public boolean setPaint(Paint p) {
-        Paint paint = ((PDFData)getData()).paint;
+        PDFData data = getPDFData();
+        Paint paint = data.paint;
         if (paint == null) {
             if (p != null) {
-                ((PDFData)getData()).paint = p;
+                data.paint = p;
                 return true;
             }
         } else if (!paint.equals(p)) {
-            ((PDFData)getData()).paint = p;
+            data.paint = p;
             return true;
         }
         return false;
@@ -88,7 +89,7 @@
      * @return true if the clip will change the current clip.
      */
     public boolean checkClip(Shape cl) {
-        Shape clip = ((PDFData)getData()).clip;
+        Shape clip = getPDFData().clip;
         if (clip == null) {
             if (cl != null) {
                 return true;
@@ -108,17 +109,40 @@
      * @param cl the new clip in the current state
      */
     public void setClip(Shape cl) {
-        Shape clip = ((PDFData)getData()).clip;
+        PDFData data = getPDFData();
+        Shape clip = data.clip;
         if (clip != null) {
             Area newClip = new Area(clip);
             newClip.intersect(new Area(cl));
-            ((PDFData)getData()).clip = new GeneralPath(newClip);
+            data.clip = new GeneralPath(newClip);
         } else {
-            ((PDFData)getData()).clip = cl;
+            data.clip = cl;
         }
     }
 
     /**
+     * Sets the character spacing (Tc).
+     * @param value the new value
+     * @return true if the value was changed with respect to the previous value
+     */
+    public boolean setCharacterSpacing(float value) {
+        PDFData data = getPDFData();
+        if (value != data.characterSpacing) {
+            data.characterSpacing = value;
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Returns the current character spacing (Tc) value.
+     * @return the Tc value
+     */
+    public float getCharacterSpacing() {
+        return getPDFData().characterSpacing;
+    }
+
+    /**
      * Get the current stack level.
      *
      * @return the current stack level
@@ -149,8 +173,8 @@
                 newState.addValues(state);
             }
         }
-        if (((PDFData)getData()).gstate != null) {
-            newState.addValues(((PDFData)getData()).gstate);
+        if (getPDFData().gstate != null) {
+            newState.addValues(getPDFData().gstate);
         }
         return newState;
     }
@@ -177,32 +201,38 @@
         getStateStack().add(copy);
     }
 
+    private PDFData getPDFData() {
+        return (PDFData)getData();
+    }
+
     private class PDFData extends org.apache.fop.util.AbstractPaintingState.AbstractData {
 
         private static final long serialVersionUID = 3527950647293177764L;
 
         private Paint paint = null;
         private Paint backPaint = null;
-        private int lineCap = 0;
-        private int lineJoin = 0;
-        private float miterLimit = 0;
-        private boolean text = false;
-        private int dashOffset = 0;
+        //private int lineCap = 0; //Disabled the ones that are not used, yet
+        //private int lineJoin = 0;
+        //private float miterLimit = 0;
+        //private int dashOffset = 0;
         private Shape clip = null;
         private PDFGState gstate = null;
 
+        //text state
+        private float characterSpacing = 0f;
+
         /** {@inheritDoc} */
         public Object clone() {
             PDFData obj = (PDFData)super.clone();
             obj.paint = this.paint;
             obj.backPaint = this.paint;
-            obj.lineCap = this.lineCap;
-            obj.lineJoin = this.lineJoin;
-            obj.miterLimit = this.miterLimit;
-            obj.text = this.text;
-            obj.dashOffset = this.dashOffset;
+            //obj.lineCap = this.lineCap;
+            //obj.lineJoin = this.lineJoin;
+            //obj.miterLimit = this.miterLimit;
+            //obj.dashOffset = this.dashOffset;
             obj.clip = this.clip;
             obj.gstate = this.gstate;
+            obj.characterSpacing = this.characterSpacing;
             return obj;
         }
 
@@ -211,10 +241,9 @@
             return super.toString()
                 + ", paint=" + paint
                 + ", backPaint=" + backPaint
-                + ", lineCap=" + lineCap
-                + ", miterLimit=" + miterLimit
-                + ", text=" + text
-                + ", dashOffset=" + dashOffset
+                //+ ", lineCap=" + lineCap
+                //+ ", miterLimit=" + miterLimit
+                //+ ", dashOffset=" + dashOffset
                 + ", clip=" + clip
                 + ", gstate=" + gstate;
         }

Modified: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/afp/AFPPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/afp/AFPPainter.java?rev=741165&r1=741164&r2=741165&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/afp/AFPPainter.java (original)
+++ xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/afp/AFPPainter.java Thu Feb  5 16:27:08 2009
@@ -30,9 +30,6 @@
 
 import org.w3c.dom.Document;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
 import org.apache.xmlgraphics.image.loader.ImageProcessingHints;
 import org.apache.xmlgraphics.image.loader.ImageSessionContext;
 
@@ -49,6 +46,7 @@
 import org.apache.fop.afp.fonts.CharacterSet;
 import org.apache.fop.afp.modca.AbstractPageObject;
 import org.apache.fop.afp.modca.PresentationTextObject;
+import org.apache.fop.afp.modca.ResourceObject;
 import org.apache.fop.afp.ptoca.PtocaBuilder;
 import org.apache.fop.afp.ptoca.PtocaProducer;
 import org.apache.fop.fonts.Font;
@@ -69,8 +67,8 @@
  */
 public class AFPPainter extends AbstractIFPainter {
 
-    /** logging instance */
-    private static Log log = LogFactory.getLog(AFPPainter.class);
+    //** logging instance */
+    //private static Log log = LogFactory.getLog(AFPPainter.class);
 
     private static final int X = 0;
     private static final int Y = 1;
@@ -241,7 +239,7 @@
 
     //TODO Try to resolve the name-clash between the AFPBorderPainter in the afp package
     //and this one. Not done for now to avoid a lot of re-implementation and code duplication.
-    private class AFPBorderPainterAdapter extends BorderPainter {
+    private static class AFPBorderPainterAdapter extends BorderPainter {
 
         private AFPBorderPainter delegate;
 
@@ -312,8 +310,9 @@
     }
 
     /** {@inheritDoc} */
-    public void drawText(int x, int y, final int[] dx, int[] dy, final String text)
-            throws IFException {
+    public void drawText(int x, int y,
+            final int letterSpacing, final int wordSpacing, final int[] dx,
+            final String text) throws IFException {
         final int fontSize = this.state.getFontSize();
         getPaintingState().setFontSize(fontSize);
 
@@ -322,8 +321,8 @@
         //TODO Ignored: state.getFontVariant()
         String fontKey = getFontInfo().getInternalFontKey(triplet);
         if (fontKey == null) {
-            fontKey = getFontInfo().getInternalFontKey(
-                    new FontTriplet("any", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL));
+            triplet = new FontTriplet("any", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
+            fontKey = getFontInfo().getInternalFontKey(triplet);
         }
 
         // register font as necessary
@@ -339,6 +338,23 @@
 
         final CharacterSet charSet = afpFont.getCharacterSet(fontSize);
 
+        if (afpFont.isEmbeddable()) {
+            try {
+                //Embed fonts (char sets and code pages)
+                //TODO This should be moved to a place where it has less performance impact
+                if (charSet.getPath() != null) {
+                    documentHandler.getResourceManager().createIncludedResource(
+                            charSet.getName(), charSet.getPath(),
+                            ResourceObject.TYPE_FONT_CHARACTER_SET);
+                    documentHandler.getResourceManager().createIncludedResource(
+                            charSet.getCodePage(), charSet.getPath(),
+                            ResourceObject.TYPE_CODE_PAGE);
+                }
+            } catch (IOException ioe) {
+                throw new IFException("Error while embedding font resources", ioe);
+            }
+        }
+
         AbstractPageObject page = getDataStream().getCurrentPage();
         PresentationTextObject pto = page.getPresentationTextObject();
         try {
@@ -350,8 +366,6 @@
                     builder.absoluteMoveBaseline(p.y);
                     builder.absoluteMoveInline(p.x);
 
-                    builder.setVariableSpaceCharacterIncrement(0);
-                    builder.setInterCharacterAdjustment(0);
                     builder.setExtendedTextColor(state.getTextColor());
                     builder.setCodedFont((byte)fontReference);
 
@@ -363,33 +377,105 @@
                         int dxu = Math.round(unitConv.mpt2units(dx[0]));
                         builder.relativeMoveInline(-dxu);
                     }
-                    for (int i = 0; i < l; i++) {
-                        char orgChar = text.charAt(i);
-                        float glyphAdjust = 0;
-                        if (CharUtilities.isFixedWidthSpace(orgChar)) {
-                            sb.append(CharUtilities.SPACE);
-                            int spaceWidth = font.getCharWidth(CharUtilities.SPACE);
-                            int charWidth = font.getCharWidth(orgChar);
-                            glyphAdjust += (charWidth - spaceWidth);
-                        } else {
-                            sb.append(orgChar);
+
+                    //Following are two variants for glyph placement.
+                    //SVI does not seem to be implemented in the same way everywhere, so
+                    //a fallback alternative is preserved here.
+                    final boolean usePTOCAWordSpacing = true;
+                    if (usePTOCAWordSpacing) {
+
+                        int interCharacterAdjustment = 0;
+                        if (letterSpacing != 0) {
+                            interCharacterAdjustment = Math.round(unitConv.mpt2units(
+                                    letterSpacing));
                         }
+                        builder.setInterCharacterAdjustment(interCharacterAdjustment);
+
+                        int spaceWidth = font.getCharWidth(CharUtilities.SPACE);
+                        int fixedSpaceCharacterIncrement = Math.round(unitConv.mpt2units(
+                                spaceWidth + letterSpacing));
+                        int varSpaceCharacterIncrement = fixedSpaceCharacterIncrement;
+                        if (wordSpacing != 0) {
+                            varSpaceCharacterIncrement = Math.round(unitConv.mpt2units(
+                                    spaceWidth + wordSpacing + letterSpacing));
+                        }
+                        builder.setVariableSpaceCharacterIncrement(varSpaceCharacterIncrement);
+
+                        boolean fixedSpaceMode = false;
 
-                        if (i < dxl - 1) {
-                            glyphAdjust += dx[i + 1];
+                        for (int i = 0; i < l; i++) {
+                            char orgChar = text.charAt(i);
+                            float glyphAdjust = 0;
+                            if (CharUtilities.isFixedWidthSpace(orgChar)) {
+                                flushText(builder, sb, charSet);
+                                builder.setVariableSpaceCharacterIncrement(
+                                        fixedSpaceCharacterIncrement);
+                                fixedSpaceMode = true;
+                                sb.append(CharUtilities.SPACE);
+                                int charWidth = font.getCharWidth(orgChar);
+                                glyphAdjust += (charWidth - spaceWidth);
+                            } else {
+                                if (fixedSpaceMode) {
+                                    flushText(builder, sb, charSet);
+                                    builder.setVariableSpaceCharacterIncrement(
+                                            varSpaceCharacterIncrement);
+                                    fixedSpaceMode = false;
+                                }
+                                char ch;
+                                if (orgChar == CharUtilities.NBSPACE) {
+                                    ch = ' '; //converted to normal space to allow word spacing
+                                } else {
+                                    ch = orgChar;
+                                }
+                                sb.append(ch);
+                            }
+
+                            if (i < dxl - 1) {
+                                glyphAdjust += dx[i + 1];
+                            }
+
+                            if (glyphAdjust != 0) {
+                                flushText(builder, sb, charSet);
+                                int increment = Math.round(unitConv.mpt2units(glyphAdjust));
+                                builder.relativeMoveInline(increment);
+                            }
                         }
+                    } else {
+                        for (int i = 0; i < l; i++) {
+                            char orgChar = text.charAt(i);
+                            float glyphAdjust = 0;
+                            if (CharUtilities.isFixedWidthSpace(orgChar)) {
+                                sb.append(CharUtilities.SPACE);
+                                int spaceWidth = font.getCharWidth(CharUtilities.SPACE);
+                                int charWidth = font.getCharWidth(orgChar);
+                                glyphAdjust += (charWidth - spaceWidth);
+                            } else {
+                                sb.append(orgChar);
+                            }
 
-                        if (glyphAdjust != 0) {
-                            if (sb.length() > 0) {
-                                builder.addTransparentData(charSet.encodeChars(sb));
-                                sb.setLength(0);
+                            if ((wordSpacing != 0) && CharUtilities.isAdjustableSpace(orgChar)) {
+                                glyphAdjust += wordSpacing;
+                            }
+                            glyphAdjust += letterSpacing;
+                            if (i < dxl - 1) {
+                                glyphAdjust += dx[i + 1];
+                            }
+
+                            if (glyphAdjust != 0) {
+                                flushText(builder, sb, charSet);
+                                int increment = Math.round(unitConv.mpt2units(glyphAdjust));
+                                builder.relativeMoveInline(increment);
                             }
-                            int increment = Math.round(unitConv.mpt2units(glyphAdjust));
-                            builder.relativeMoveInline(increment);
                         }
                     }
+                    flushText(builder, sb, charSet);
+                }
+
+                private void flushText(PtocaBuilder builder, StringBuffer sb,
+                        final CharacterSet charSet) throws IOException {
                     if (sb.length() > 0) {
                         builder.addTransparentData(charSet.encodeChars(sb));
+                        sb.setLength(0);
                     }
                 }
 

Modified: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java?rev=741165&r1=741164&r2=741165&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java (original)
+++ xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java Thu Feb  5 16:27:08 2009
@@ -345,7 +345,8 @@
                 LogUtil.handleException(log, e,
                         userAgent.getFactory().validateUserConfigStrictly());
             }
-
+        } else {
+            fontCollections.add(new AFPFontCollection(userAgent.getEventBroadcaster(), null));
         }
 
         fontManager.setup(fontInfo,

Modified: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java?rev=741165&r1=741164&r2=741165&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java (original)
+++ xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java Thu Feb  5 16:27:08 2009
@@ -411,5 +411,4 @@
         return new AffineTransform(matrix);
     }
 
-
 }

Modified: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/IFPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/IFPainter.java?rev=741165&r1=741164&r2=741165&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/IFPainter.java (original)
+++ xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/IFPainter.java Thu Feb  5 16:27:08 2009
@@ -81,13 +81,53 @@
  */
 public interface IFPainter {
 
-    void startViewport(AffineTransform transform, Dimension size, Rectangle clipRect) throws IFException;
-    void startViewport(AffineTransform[] transforms, Dimension size, Rectangle clipRect) throws IFException;
+    /**
+     * Starts a new viewport, establishing a new coordinate system. A viewport has a size and
+     * can optionally be clipped. Corresponds to SVG's svg element.
+     * @param transform the transformation matrix establishing the new coordinate system
+     * @param size the size of the viewport
+     * @param clipRect the clipping rectangle (may be null)
+     * @throws IFException if an error occurs while handling this element
+     */
+    void startViewport(AffineTransform transform, Dimension size, Rectangle clipRect)
+        throws IFException;
+
+    /**
+     * Starts a new viewport, establishing a new coordinate system. A viewport has a size and
+     * can optionally be clipped. Corresponds to SVG's svg element.
+     * @param transforms a series of transformation matrices establishing the new coordinate system
+     * @param size the size of the viewport
+     * @param clipRect the clipping rectangle (may be null)
+     * @throws IFException if an error occurs while handling this element
+     */
+    void startViewport(AffineTransform[] transforms, Dimension size, Rectangle clipRect)
+        throws IFException;
     //For transform, Batik's org.apache.batik.parser.TransformListHandler/Parser can be used
+
+    /**
+     * Ends the current viewport and restores the previous coordinate system.
+     * @throws IFException if an error occurs while handling this element
+     */
     void endViewport() throws IFException;
 
+    /**
+     * Starts a new group of graphical elements. Corresponds to SVG's g element.
+     * @param transforms a series of transformation matrices establishing the new coordinate system
+     * @throws IFException if an error occurs while handling this element
+     */
     void startGroup(AffineTransform[] transforms) throws IFException;
+
+    /**
+     * Starts a new group of graphical elements. Corresponds to SVG's g element.
+     * @param transform the transformation matrix establishing the new coordinate system
+     * @throws IFException if an error occurs while handling this element
+     */
     void startGroup(AffineTransform transform) throws IFException;
+
+    /**
+     * Ends the current group and restores the previous coordinate system.
+     * @throws IFException if an error occurs while handling this element
+     */
     void endGroup() throws IFException;
 
     /**
@@ -105,16 +145,18 @@
 
     /**
      * Draws text. The initial coordinates (x and y) point to the starting point at the normal
-     * baseline of the font. The arrays (dx and dy) are optional and can be used to achieve
-     * effects like kerning.
+     * baseline of the font. The parameters letterSpacing, wordSpacing and the array dx are
+     * optional and can be used to influence character positioning (for example, for kerning).
      * @param x X-coordinate of the starting point of the text
      * @param y Y-coordinate of the starting point of the text
-     * @param dx an array of adjustment values for each character in X-direction
-     * @param dy an array of adjustment values for each character in Y-direction
+     * @param letterSpacing additional spacing between characters (may be 0)
+     * @param wordSpacing additional spacing between words (may be 0)
+     * @param dx an array of adjustment values for each character in X-direction (may be null)
      * @param text the text
      * @throws IFException if an error occurs while handling this event
      */
-    void drawText(int x, int y, int[] dx, int[] dy, String text) throws IFException;
+    void drawText(int x, int y, int letterSpacing, int wordSpacing,
+            int[] dx, String text) throws IFException;
 
     /**
      * Restricts the current clipping region with the given rectangle.

Modified: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/IFParser.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/IFParser.java?rev=741165&r1=741164&r2=741165&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/IFParser.java (original)
+++ xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/IFParser.java Thu Feb  5 16:27:08 2009
@@ -462,9 +462,12 @@
             public void endElement() throws IFException {
                 int x = Integer.parseInt(lastAttributes.getValue("x"));
                 int y = Integer.parseInt(lastAttributes.getValue("y"));
+                String s = lastAttributes.getValue("letter-spacing");
+                int letterSpacing = (s != null ? Integer.parseInt(s) : 0);
+                s = lastAttributes.getValue("word-spacing");
+                int wordSpacing = (s != null ? Integer.parseInt(s) : 0);
                 int[] dx = XMLUtil.getAttributeAsIntArray(lastAttributes, "dx");
-                int[] dy = XMLUtil.getAttributeAsIntArray(lastAttributes, "dy");
-                painter.drawText(x, y, dx, dy, content.toString());
+                painter.drawText(x, y, letterSpacing, wordSpacing, dx, content.toString());
             }
 
             public boolean ignoreCharacters() {

Modified: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/IFRenderer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/IFRenderer.java?rev=741165&r1=741164&r2=741165&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/IFRenderer.java (original)
+++ xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/IFRenderer.java Thu Feb  5 16:27:08 2009
@@ -984,6 +984,7 @@
         int bl = currentBPPosition + text.getOffset() + text.getBaselineOffset();
         textUtil.flush();
         textUtil.setStartPosition(rx, bl);
+        textUtil.setSpacing(text.getTextLetterSpaceAdjust(), text.getTextWordSpaceAdjust());
         super.renderText(text);
 
         textUtil.flush();
@@ -1009,9 +1010,9 @@
         AbstractTextArea textArea = (AbstractTextArea)space.getParentArea();
         renderText(s, null, font, textArea);
 
-        if (space.isAdjustable()) {
+        if (textUtil.combined && space.isAdjustable()) {
             //Used for justified text, for example
-            int tws = ((TextArea) space.getParentArea()).getTextWordSpaceAdjust()
+            int tws = textArea.getTextWordSpaceAdjust()
                          + 2 * textArea.getTextLetterSpaceAdjust();
             if (tws != 0) {
                 textUtil.adjust(tws);
@@ -1042,7 +1043,7 @@
             char ch = s.charAt(i);
             textUtil.addChar(ch);
             int glyphAdjust = 0;
-            if (font.hasChar(ch)) {
+            if (textUtil.combined && font.hasChar(ch)) {
                 int tls = (i < l - 1 ? parentArea.getTextLetterSpaceAdjust() : 0);
                 glyphAdjust += tls;
             }
@@ -1060,6 +1061,8 @@
         private int lastDXPos = 0;
         private StringBuffer text = new StringBuffer();
         private int startx, starty;
+        private int tls, tws;
+        private boolean combined = false;
 
         void addChar(char ch) {
             text.append(ch);
@@ -1092,6 +1095,11 @@
             this.starty = y;
         }
 
+        void setSpacing(int tls, int tws) {
+            this.tls = tls;
+            this.tws = tws;
+        }
+
         void flush() {
             if (text.length() > 0) {
                 try {
@@ -1101,7 +1109,11 @@
                         effDX = new int[size];
                         System.arraycopy(dx, 0, effDX, 0, size);
                     }
-                    painter.drawText(startx, starty, effDX, null, text.toString());
+                    if (combined) {
+                        painter.drawText(startx, starty, 0, 0, effDX, text.toString());
+                    } else {
+                        painter.drawText(startx, starty, tls, tws, effDX, text.toString());
+                    }
                 } catch (IFException e) {
                     handleIFException(e);
                 }

Modified: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/IFSerializer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/IFSerializer.java?rev=741165&r1=741164&r2=741165&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/IFSerializer.java (original)
+++ xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/IFSerializer.java Thu Feb  5 16:27:08 2009
@@ -508,18 +508,22 @@
     }
 
     /** {@inheritDoc} */
-    public void drawText(int x, int y, int[] dx, int[] dy, String text) throws IFException {
+    public void drawText(int x, int y, int letterSpacing, int wordSpacing,
+            int[] dx, String text) throws IFException {
         try {
             AttributesImpl atts = new AttributesImpl();
             XMLUtil.addAttribute(atts, XMLConstants.XML_SPACE, "preserve");
             addAttribute(atts, "x", Integer.toString(x));
             addAttribute(atts, "y", Integer.toString(y));
+            if (letterSpacing != 0) {
+                addAttribute(atts, "letter-spacing", Integer.toString(letterSpacing));
+            }
+            if (wordSpacing != 0) {
+                addAttribute(atts, "word-spacing", Integer.toString(wordSpacing));
+            }
             if (dx != null) {
                 addAttribute(atts, "dx", IFUtil.toString(dx));
             }
-            if (dy != null) {
-                addAttribute(atts, "dy", IFUtil.toString(dy));
-            }
             handler.startElement(EL_TEXT, atts);
             char[] chars = text.toCharArray();
             handler.characters(chars, 0, chars.length);

Modified: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java?rev=741165&r1=741164&r2=741165&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java (original)
+++ xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java Thu Feb  5 16:27:08 2009
@@ -88,7 +88,8 @@
                     font = new CustomFontMetricsMapper(fontMetrics, fontSource);
                 } else {
                     CustomFont fontMetrics = FontLoader.loadFont(
-                            fontFile, null, true, EncodingMode.AUTO, fontResolver);
+                            fontFile, null, true, EncodingMode.AUTO,
+                            configFontInfo.getKerning(), fontResolver);
                     font = new CustomFontMetricsMapper(fontMetrics);
                 }
 

Modified: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/java2d/Java2DPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/java2d/Java2DPainter.java?rev=741165&r1=741164&r2=741165&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/java2d/Java2DPainter.java (original)
+++ xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/java2d/Java2DPainter.java Thu Feb  5 16:27:08 2009
@@ -46,6 +46,7 @@
 import org.apache.fop.render.intermediate.IFState;
 import org.apache.fop.traits.BorderProps;
 import org.apache.fop.traits.RuleStyle;
+import org.apache.fop.util.CharUtilities;
 
 /**
  * {@code IFPainter} implementation that paints on a Graphics2D instance.
@@ -83,6 +84,7 @@
      * @param g2d the target Graphics2D instance
      * @param context the IF context
      * @param fontInfo the font information
+     * @param state the IF state object
      */
     public Java2DPainter(Graphics2D g2d, IFContext context, FontInfo fontInfo, IFState state) {
         super();
@@ -206,8 +208,8 @@
     }
 
     /** {@inheritDoc} */
-    public void drawText(int x, int y, int[] dx, int[] dy, String text) throws IFException {
-        //Note: dy is currently ignored
+    public void drawText(int x, int y, int letterSpacing, int wordSpacing, int[] dx, String text)
+            throws IFException {
         g2dState.updateColor(state.getTextColor());
         FontTriplet triplet = new FontTriplet(
                 state.getFontFamily(), state.getFontStyle(), state.getFontWeight());
@@ -234,6 +236,10 @@
             float glyphAdjust = 0;
             int cw = font.getCharWidth(orgChar);
 
+            if ((wordSpacing != 0) && CharUtilities.isAdjustableSpace(orgChar)) {
+                glyphAdjust += wordSpacing;
+            }
+            glyphAdjust += letterSpacing;
             if (dx != null && i < dxl - 1) {
                 glyphAdjust += dx[i + 1];
             }

Modified: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLPainter.java?rev=741165&r1=741164&r2=741165&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLPainter.java (original)
+++ xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLPainter.java Thu Feb  5 16:27:08 2009
@@ -312,8 +312,8 @@
     }
 
     /** {@inheritDoc} */
-    public void drawText(int x, int y, int[] dx, int[] dy, String text) throws IFException {
-        //Note: dy is currently ignored
+    public void drawText(int x, int y, int letterSpacing, int wordSpacing, int[] dx, String text)
+                throws IFException {
         try {
             FontTriplet triplet = new FontTriplet(
                     state.getFontFamily(), state.getFontStyle(), state.getFontWeight());
@@ -324,13 +324,13 @@
                         ? false
                         : HardcodedFonts.setFont(gen, fontKey, state.getFontSize(), text);
             if (pclFont) {
-                drawTextNative(x, y, dx, text, triplet);
+                drawTextNative(x, y, letterSpacing, wordSpacing, dx, text, triplet);
             } else {
-                drawTextAsBitmap(x, y, dx, dy, text, triplet);
+                drawTextAsBitmap(x, y, letterSpacing, wordSpacing, dx, text, triplet);
                 if (DEBUG) {
                     state.setTextColor(Color.GRAY);
                     HardcodedFonts.setFont(gen, "F1", state.getFontSize(), text);
-                    drawTextNative(x, y, dx, text, triplet);
+                    drawTextNative(x, y, letterSpacing, wordSpacing, dx, text, triplet);
                 }
             }
         } catch (IOException ioe) {
@@ -338,8 +338,8 @@
         }
     }
 
-    private void drawTextNative(int x, int y, int[] dx, String text, FontTriplet triplet)
-                throws IOException {
+    private void drawTextNative(int x, int y, int letterSpacing, int wordSpacing, int[] dx,
+            String text, FontTriplet triplet) throws IOException {
         Color textColor = state.getTextColor();
         if (textColor != null) {
             gen.setTransparencyMode(true, false);
@@ -376,6 +376,10 @@
             }
             sb.append(ch);
 
+            if ((wordSpacing != 0) && CharUtilities.isAdjustableSpace(orgChar)) {
+                glyphAdjust += wordSpacing;
+            }
+            glyphAdjust += letterSpacing;
             if (dx != null && i < dxl - 1) {
                 glyphAdjust += dx[i + 1];
             }
@@ -391,7 +395,9 @@
 
     private static final double SAFETY_MARGIN_FACTOR = 0.05;
 
-    private Rectangle getTextBoundingBox(int x, int y, int[] dx, int[] dy, String text,
+    private Rectangle getTextBoundingBox(int x, int y,
+            int letterSpacing, int wordSpacing, int[] dx,
+            String text,
             Font font, FontMetricsMapper metrics) {
         int maxAscent = metrics.getMaxAscent(font.getFontSize()) / 1000;
         int descent = metrics.getDescender(font.getFontSize()) / 1000; //is negative
@@ -412,6 +418,10 @@
             float glyphAdjust = 0;
             int cw = font.getCharWidth(orgChar);
 
+            if ((wordSpacing != 0) && CharUtilities.isAdjustableSpace(orgChar)) {
+                glyphAdjust += wordSpacing;
+            }
+            glyphAdjust += letterSpacing;
             if (dx != null && i < dxl - 1) {
                 glyphAdjust += dx[i + 1];
             }
@@ -425,7 +435,8 @@
         return boundingRect;
     }
 
-    private void drawTextAsBitmap(final int x, final int y, final int[] dx, final int[] dy,
+    private void drawTextAsBitmap(final int x, final int y,
+            final int letterSpacing, final int wordSpacing, final int[] dx,
             final String text, FontTriplet triplet) throws IFException {
         //Use Java2D to paint different fonts via bitmap
         final Font font = parent.getFontInfo().getFontInstance(triplet, state.getFontSize());
@@ -439,7 +450,8 @@
         int safetyMargin = (int)(SAFETY_MARGIN_FACTOR * font.getFontSize());
         final int baselineOffset = maxAscent + safetyMargin;
 
-        final Rectangle boundingBox = getTextBoundingBox(x, y, dx, dy, text, font, mapper);
+        final Rectangle boundingBox = getTextBoundingBox(x, y,
+                letterSpacing, wordSpacing, dx, text, font, mapper);
         final Dimension dim = boundingBox.getSize();
 
         Graphics2DImagePainter painter = new Graphics2DImagePainter() {
@@ -462,7 +474,7 @@
                 Java2DPainter painter = new Java2DPainter(g2d,
                         getContext(), parent.getFontInfo(), state);
                 try {
-                    painter.drawText(x, y, dx, dy, text);
+                    painter.drawText(x, y, letterSpacing, wordSpacing, dx, text);
                 } catch (IFException e) {
                     //This should never happen with the Java2DPainter
                     throw new RuntimeException("Unexpected error while painting text", e);

Modified: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFContentGenerator.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFContentGenerator.java?rev=741165&r1=741164&r2=741165&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFContentGenerator.java (original)
+++ xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFContentGenerator.java Thu Feb  5 16:27:08 2009
@@ -238,6 +238,16 @@
     }
 
     /**
+     * Sets the current character spacing (Tc) value.
+     * @param value the Tc value (in unscaled text units)
+     */
+    public void updateCharacterSpacing(float value) {
+        if (getState().setCharacterSpacing(value)) {
+            currentStream.add(format(value) + " Tc\n");
+        }
+    }
+
+    /**
      * Establishes a new foreground or fill color.
      * @param col the color to apply
      * @param fill true to set the fill color, false for the foreground color

Modified: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFPainter.java?rev=741165&r1=741164&r2=741165&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFPainter.java (original)
+++ xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pdf/PDFPainter.java Thu Feb  5 16:27:08 2009
@@ -253,8 +253,8 @@
     }
 
     /** {@inheritDoc} */
-    public void drawText(int x, int y, int[] dx, int[] dy, String text) throws IFException {
-        //Note: dy is currently ignored
+    public void drawText(int x, int y, int letterSpacing, int wordSpacing, int[] dx, String text)
+            throws IFException {
         generator.updateColor(state.getTextColor(), true, null);
         generator.beginTextObject();
         FontTriplet triplet = new FontTriplet(
@@ -277,6 +277,8 @@
         PDFTextUtil textutil = generator.getTextUtil();
         textutil.updateTf(fontKey, fontSize, tf.isMultiByte());
 
+        generator.updateCharacterSpacing((float)letterSpacing / 1000f);
+
         textutil.writeTextMatrix(new AffineTransform(1, 0, 0, -1, x / 1000f, y / 1000f));
         int l = text.length();
         int dxl = (dx != null ? dx.length : 0);
@@ -300,6 +302,9 @@
                         ch = (char)(ch % 256);
                     }
                 }
+                if ((wordSpacing != 0) && CharUtilities.isAdjustableSpace(orgChar)) {
+                    glyphAdjust += wordSpacing;
+                }
             } else {
                 if (CharUtilities.isFixedWidthSpace(orgChar)) {
                     //Fixed width space are rendered as spaces so copy/paste works in a reader
@@ -308,6 +313,9 @@
                     glyphAdjust = -spaceDiff;
                 } else {
                     ch = font.mapChar(orgChar);
+                    if ((wordSpacing != 0) && CharUtilities.isAdjustableSpace(orgChar)) {
+                        glyphAdjust += wordSpacing;
+                    }
                 }
             }
             textutil.writeTJMappedChar(ch);

Added: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/ps/FOPProcSet.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/ps/FOPProcSet.java?rev=741165&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/ps/FOPProcSet.java (added)
+++ xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/ps/FOPProcSet.java Thu Feb  5 16:27:08 2009
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.ps;
+
+import java.io.IOException;
+
+import org.apache.xmlgraphics.ps.DSCConstants;
+import org.apache.xmlgraphics.ps.PSGenerator;
+import org.apache.xmlgraphics.ps.PSProcSet;
+
+/**
+ * Proc Set with FOP-specific procs.
+ */
+public final class FOPProcSet extends PSProcSet {
+
+    /** Singleton instance of the FOP procset */
+    public static final FOPProcSet INSTANCE = new FOPProcSet();
+
+    private FOPProcSet() {
+        super("Apache FOP Std ProcSet", 1.0f, 0);
+    }
+
+    /**
+     * Writes the procset to the PostScript file.
+     * @param gen the PS generator
+     * @throws IOException if an I/O error occurs
+     */
+    public void writeTo(PSGenerator gen) throws IOException {
+        gen.writeDSCComment(DSCConstants.BEGIN_RESOURCE,
+                new Object[] {TYPE_PROCSET, getName(),
+                    Float.toString(getVersion()), Integer.toString(getRevision())});
+        gen.writeDSCComment(DSCConstants.VERSION,
+                new Object[] {Float.toString(getVersion()), Integer.toString(getRevision())});
+        gen.writeDSCComment(DSCConstants.COPYRIGHT, "Copyright 2009 "
+                    + "The Apache Software Foundation. "
+                    + "License terms: http://www.apache.org/licenses/LICENSE-2.0");
+        gen.writeDSCComment(DSCConstants.TITLE,
+                "Basic set of procedures used by Apache FOP");
+
+
+        gen.writeln("/TJ { % Similar but not equal to PDF's TJ operator");
+        gen.writeln("  {");
+        gen.writeln("    dup type /stringtype eq");
+        gen.writeln("    { show }"); //normal text show
+        gen.writeln("    { neg 1000 div 0 rmoveto }"); //negative X movement
+        gen.writeln("    ifelse");
+        gen.writeln("  } forall");
+        gen.writeln("} bd");
+
+        gen.writeln("/ATJ { % As TJ but adds letter-spacing");
+        gen.writeln("  /ATJls exch def");
+        gen.writeln("  {");
+        gen.writeln("    dup type /stringtype eq");
+        gen.writeln("    { ATJls 0 3 2 roll ashow }"); //normal text show
+        gen.writeln("    { neg 1000 div 0 rmoveto }"); //negative X movement
+        gen.writeln("    ifelse");
+        gen.writeln("  } forall");
+        gen.writeln("} bd");
+
+        gen.writeDSCComment(DSCConstants.END_RESOURCE);
+        gen.getResourceTracker().registerSuppliedResource(this);
+    }
+
+}

Propchange: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/ps/FOPProcSet.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/ps/FOPProcSet.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/ps/PSDocumentHandler.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/ps/PSDocumentHandler.java?rev=741165&r1=741164&r2=741165&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/ps/PSDocumentHandler.java (original)
+++ xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/ps/PSDocumentHandler.java Thu Feb  5 16:27:08 2009
@@ -199,6 +199,7 @@
         gen.writeDSCComment(DSCConstants.BEGIN_PROLOG);
         PSProcSets.writeStdProcSet(gen);
         PSProcSets.writeEPSProcSet(gen);
+        FOPProcSet.INSTANCE.writeTo(gen);
         gen.writeDSCComment(DSCConstants.END_PROLOG);
 
         //Setup



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