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/04/28 10:51:31 UTC

svn commit: r397806 [1/2] - in /xmlgraphics/fop/trunk: src/java/META-INF/services/ src/java/org/apache/fop/apps/ src/java/org/apache/fop/area/ src/java/org/apache/fop/fo/ src/java/org/apache/fop/fo/extensions/ src/java/org/apache/fop/layoutmgr/ src/jav...

Author: jeremias
Date: Fri Apr 28 01:51:27 2006
New Revision: 397806

URL: http://svn.apache.org/viewcvs?rev=397806&view=rev
Log:
Introduced "ignored namespaces" list on FopFactory. Attributes from ignored namespaces are not complained about. Not done for elements, yet.
Added support for foreign attributes (attributes in a non-FO namespace) on formatting objects, for example to specify additional (proprietary) hints for rendering i-f-o and e-g. First usage example is PCLRendererContext which the PCLGraphics2DAdapter uses to decide whether to paint natively using HP GL/2 or using a bitmap.

PCL Renderer revived: Basic framework constructed based on the old one. Still incomplete (no border painting, incomplete Graphics2D implementation, problems with reference orientation, no kerning etc.). The PCL Renderer implements PCL5 (monochrome) and HP GL/2. Work in progress!
Added UnitConv helper class which could also be useful elsewhere (Could be a candidate for Commons).

Added:
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/OldExtensionElementMapping.java
      - copied, changed from r396484, xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/util/QName.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/util/UnitConv.java   (with props)
    xmlgraphics/fop/trunk/src/sandbox/META-INF/services/org.apache.fop.render.XMLHandler
    xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/DefaultMonochromeBitmapConverter.java   (with props)
    xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/JAIMonochromeBitmapConverter.java   (with props)
    xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/MonochromeBitmapConverter.java   (with props)
    xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLGenerator.java   (with props)
    xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLGraphics2D.java   (with props)
    xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLGraphics2DAdapter.java   (with props)
    xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLPageDefinition.java   (with props)
    xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLRendererContext.java   (with props)
    xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLSVGHandler.java   (with props)
    xmlgraphics/fop/trunk/test/java/org/apache/fop/util/UnitConvTestCase.java   (with props)
Removed:
    xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLStream.java
Modified:
    xmlgraphics/fop/trunk/src/java/META-INF/services/org.apache.fop.fo.ElementMapping
    xmlgraphics/fop/trunk/src/java/org/apache/fop/apps/FopFactory.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Area.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/area/RegionViewport.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/ElementMappingRegistry.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOTreeBuilder.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FObj.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/PropertyList.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/AbstractGraphicsLayoutManager.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/RendererContextConstants.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/xml/XMLRenderer.java
    xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLRenderer.java
    xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/package.html
    xmlgraphics/fop/trunk/test/java/org/apache/fop/UtilityCodeTestSuite.java

Modified: xmlgraphics/fop/trunk/src/java/META-INF/services/org.apache.fop.fo.ElementMapping
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/META-INF/services/org.apache.fop.fo.ElementMapping?rev=397806&r1=397805&r2=397806&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/META-INF/services/org.apache.fop.fo.ElementMapping (original)
+++ xmlgraphics/fop/trunk/src/java/META-INF/services/org.apache.fop.fo.ElementMapping Fri Apr 28 01:51:27 2006
@@ -2,6 +2,7 @@
 org.apache.fop.fo.extensions.svg.SVGElementMapping
 org.apache.fop.fo.extensions.svg.BatikExtensionElementMapping
 org.apache.fop.fo.extensions.ExtensionElementMapping
+org.apache.fop.fo.extensions.OldExtensionElementMapping
 org.apache.fop.fo.extensions.xmp.XMPElementMapping
 org.apache.fop.fo.extensions.xmp.RDFElementMapping
 org.apache.fop.render.ps.extensions.PSExtensionElementMapping

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/apps/FopFactory.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/apps/FopFactory.java?rev=397806&r1=397805&r2=397806&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/apps/FopFactory.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/apps/FopFactory.java Fri Apr 28 01:51:27 2006
@@ -22,17 +22,23 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.net.MalformedURLException;
-import java.util.List;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
 
 import javax.xml.transform.Source;
 import javax.xml.transform.TransformerException;
 import javax.xml.transform.URIResolver;
 
+import org.xml.sax.SAXException;
+
 import org.apache.avalon.framework.configuration.Configuration;
 import org.apache.avalon.framework.configuration.ConfigurationException;
 import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+
 import org.apache.fop.fo.ElementMapping;
 import org.apache.fop.fo.ElementMappingRegistry;
 import org.apache.fop.hyphenation.HyphenationTreeResolver;
@@ -41,7 +47,6 @@
 import org.apache.fop.render.RendererFactory;
 import org.apache.fop.render.XMLHandlerRegistry;
 import org.apache.fop.util.ContentHandlerFactoryRegistry;
-import org.xml.sax.SAXException;
 
 /**
  * Factory class which instantiates new Fop and FOUserAgent instances. This class also holds
@@ -110,6 +115,8 @@
 
     /** Optional overriding LayoutManagerMaker */
     private LayoutManagerMaker lmMakerOverride = null;
+
+    private Set ignoredNamespaces = new java.util.HashSet();
     
     /**
      * Main constructor.
@@ -429,6 +436,40 @@
      */
     public void setPageWidth(String pageWidth) {
         this.pageWidth = pageWidth;
+    }
+    
+    /**
+     * Adds a namespace to the set of ignored namespaces.
+     * If FOP encounters a namespace which it cannot handle, it issues a warning except if this 
+     * namespace is in the ignored set.
+     * @param namespaceURI the namespace URI
+     */
+    public void ignoreNamespace(String namespaceURI) {
+        this.ignoredNamespaces.add(namespaceURI);
+    }
+    
+    /**
+     * Adds a collection of namespaces to the set of ignored namespaces.
+     * If FOP encounters a namespace which it cannot handle, it issues a warning except if this 
+     * namespace is in the ignored set.
+     * @param namespaceURIs the namespace URIs
+     */
+    public void ignoreNamespaces(Collection namespaceURIs) {
+        this.ignoredNamespaces.addAll(namespaceURIs);
+    }
+    
+    /**
+     * Indicates whether a namespace URI is on the ignored list.
+     * @param namespaceURI the namespace URI
+     * @return true if the namespace is ignored by FOP
+     */
+    public boolean isNamespaceIgnored(String namespaceURI) {
+        return this.ignoredNamespaces.contains(namespaceURI);
+    }
+    
+    /** @return the set of namespaces that are ignored by FOP */
+    public Set getIgnoredNamespace() {
+        return Collections.unmodifiableSet(this.ignoredNamespaces);
     }
     
     //------------------------------------------- Configuration stuff

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Area.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Area.java?rev=397806&r1=397805&r2=397806&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Area.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Area.java Fri Apr 28 01:51:27 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.
@@ -20,13 +20,15 @@
 
 import java.io.Serializable;
 
+import java.util.Collections;
+import java.util.Iterator;
 import java.util.Map;
-import java.util.HashMap;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.fop.datatypes.ColorType;
 import org.apache.fop.traits.BorderProps;
+import org.apache.fop.util.QName;
 
 // If the area appears more than once in the output
 // or if the area has external data it is cached
@@ -129,8 +131,11 @@
     /**
      * Traits for this area stored in a HashMap
      */
-    protected HashMap props = null;
+    protected Map props = null;
 
+    /** Foreign attributes */
+    protected Map foreignAttributes = null;
+    
     /**
      * logging instance
      */
@@ -459,6 +464,57 @@
             throw new IllegalArgumentException("Trait "
                     + oTraitCode.getClass().getName()
                     + " could not be converted to an integer");
+        }
+    }
+    
+    /**
+     * Sets a foreign attribute.
+     * @param name the qualified name of the attribute
+     * @param value the attribute value
+     */
+    public void setForeignAttribute(QName name, String value) {
+        if (this.foreignAttributes == null) {
+            this.foreignAttributes = new java.util.HashMap();
+        }
+        this.foreignAttributes.put(name, value);
+    }
+    
+    /**
+     * Set foreign attributes from a Map.
+     * @param atts a Map with attributes (keys: QName, values: String)
+     */
+    public void setForeignAttributes(Map atts) {
+        if (atts.size() == 0) {
+            return;
+        }
+        Iterator iter = atts.keySet().iterator();
+        while (iter.hasNext()) {
+            QName qName = (QName)iter.next();
+            String value = (String)atts.get(qName);
+            //The casting is only to ensure type safety (too bad we can't use generics, yet) 
+            setForeignAttribute(qName, value);
+        }
+    }
+    
+    /**
+     * Returns the value of a foreign attribute on the area.
+     * @param name the qualified name of the attribute
+     * @return the attribute value or null if it isn't set
+     */
+    public String getForeignAttributeValue(QName name) {
+        if (this.foreignAttributes != null) {
+            return (String)this.foreignAttributes.get(name);
+        } else {
+            return null;
+        }
+    }
+    
+    /** @return the foreign attributes associated with this area */
+    public Map getForeignAttributes() {
+        if (this.foreignAttributes != null) {
+            return Collections.unmodifiableMap(this.foreignAttributes);
+        } else {
+            return Collections.EMPTY_MAP;
         }
     }
     

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/RegionViewport.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/RegionViewport.java?rev=397806&r1=397805&r2=397806&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/RegionViewport.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/RegionViewport.java Fri Apr 28 01:51:27 2006
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2004 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.
@@ -115,7 +115,10 @@
         RegionViewport rv = new RegionViewport((Rectangle2D)viewArea.clone());
         rv.regionReference = (RegionReference)regionReference.clone();
         if (props != null) {
-            rv.props = (HashMap)props.clone();
+            rv.props = new HashMap(props);
+        }
+        if (foreignAttributes != null) {
+            rv.foreignAttributes = new HashMap(foreignAttributes);
         }
         return rv;
     }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/ElementMappingRegistry.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/ElementMappingRegistry.java?rev=397806&r1=397805&r2=397806&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/ElementMappingRegistry.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/ElementMappingRegistry.java Fri Apr 28 01:51:27 2006
@@ -163,4 +163,12 @@
         return mapping.getDOMImplementation();
     }
     
+    /**
+     * Indicates whether a namespace is known to FOP.
+     * @param namespaceURI the namespace URI
+     * @return true if the namespace is known.
+     */
+    public boolean isKnownNamespace(String namespaceURI) {
+        return this.namespaces.containsKey(namespaceURI);
+    }
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOTreeBuilder.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOTreeBuilder.java?rev=397806&r1=397805&r2=397806&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOTreeBuilder.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOTreeBuilder.java Fri Apr 28 01:51:27 2006
@@ -304,6 +304,10 @@
 
             try {
                 foNode = fobjMaker.make(currentFObj);
+                if (rootFObj == null) {
+                    rootFObj = (Root) foNode;
+                    rootFObj.setFOEventHandler(foEventHandler);
+                }
                 propertyList = foNode.createPropertyList(currentPropertyList, foEventHandler);
                 foNode.processNode(localName, getEffectiveLocator(), attlist, propertyList);
                 foNode.startOfNode();
@@ -325,10 +329,7 @@
                 delegate = subHandler;
             }
             
-            if (rootFObj == null) {
-                rootFObj = (Root) foNode;
-                rootFObj.setFOEventHandler(foEventHandler);
-            } else {
+            if (currentFObj != null) {
                 currentFObj.addChildNode(foNode);
             }
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FObj.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FObj.java?rev=397806&r1=397805&r2=397806&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FObj.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FObj.java Fri Apr 28 01:51:27 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.
@@ -19,6 +19,7 @@
 package org.apache.fop.fo;
 
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;
@@ -29,6 +30,7 @@
 import org.apache.fop.fo.extensions.ExtensionAttachment;
 import org.apache.fop.fo.flow.Marker;
 import org.apache.fop.fo.properties.PropertyMaker;
+import org.apache.fop.util.QName;
 import org.xml.sax.Attributes;
 import org.xml.sax.Locator;
 
@@ -46,6 +48,9 @@
     /** The list of extension attachments, null if none */
     private List extensionAttachments = null;
     
+    /** The map of foreign attributes, null if none */
+    private Map foreignAttributes = null;
+    
     /** Used to indicate if this FO is either an Out Of Line FO (see rec)
         or a descendant of one.  Used during validateChildNode() FO 
         validation.
@@ -471,6 +476,40 @@
             return Collections.EMPTY_LIST;
         } else {
             return extensionAttachments;
+        }
+    }
+
+    /**
+     * Adds a foreign attribute to this FObj.
+     * @param uri the namespace URI
+     * @param qName the fully qualified name
+     * @param value the attribute value
+     * @todo Handle this over FOP's property mechanism so we can use inheritance.
+     */
+    public void addForeignAttribute(String uri, 
+            String qName, String value) {
+        if (qName == null) {
+            throw new NullPointerException("Parameter qName must not be null");
+        }
+        if (foreignAttributes == null) {
+            foreignAttributes = new java.util.HashMap();
+        }
+        String localName = qName;
+        String prefix = null;
+        int p = localName.indexOf(':');
+        if (p > 0) {
+            prefix = localName.substring(0, p);
+            localName = localName.substring(p + 1);
+        }
+        foreignAttributes.put(new QName(uri, prefix, localName), value);
+    }
+    
+    /** @return the map of foreign attributes */
+    public Map getForeignAttributes() {
+        if (foreignAttributes == null) {
+            return Collections.EMPTY_MAP;
+        } else {
+            return foreignAttributes;
         }
     }
     

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/PropertyList.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/PropertyList.java?rev=397806&r1=397805&r2=397806&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/PropertyList.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/PropertyList.java Fri Apr 28 01:51:27 2006
@@ -24,7 +24,7 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
-import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FopFactory;
 import org.apache.fop.fo.expr.PropertyException;
 import org.apache.fop.fo.properties.CommonAbsolutePosition;
 import org.apache.fop.fo.properties.CommonAccessibility;
@@ -295,13 +295,20 @@
         }
         
         String attributeNS;
+        FopFactory factory = getFObj().getUserAgent().getFactory(); 
         for (int i = 0; i < attributes.getLength(); i++) {
             /* convert all attributes with the same namespace as the fo element for this fObj */
-            attributeNS = attributes.getURI(i); 
-            if (attributeNS.length() == 0 || attributeNS.equals(fobj.getNamespaceURI())) {
-                attributeName = attributes.getQName(i);
-                attributeValue = attributes.getValue(i);
+            attributeNS = attributes.getURI(i);
+            attributeName = attributes.getQName(i);
+            attributeValue = attributes.getValue(i);
+            if (attributeNS.length() == 0) {
                 convertAttributeToProperty(attributes, attributeName, attributeValue);
+            } else if (!factory.isNamespaceIgnored(attributeNS)) {
+                if (factory.getElementMappingRegistry().isKnownNamespace(attributeNS)) {
+                    getFObj().addForeignAttribute(attributeNS, attributeName, attributeValue);
+                } else {
+                    handleInvalidProperty(attributeName);
+                }
             }
         }
     }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java?rev=397806&r1=397805&r2=397806&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java Fri Apr 28 01:51:27 2006
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2004 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.
@@ -19,16 +19,17 @@
 package org.apache.fop.fo.extensions;
 
 import org.apache.fop.fo.ElementMapping;
+import org.apache.fop.fo.UnknownXMLObj;
 
 import java.util.HashMap;
 
 /**
- * Element mapping for the pdf bookmark extension.
- * This sets up the mapping for the classes that handle the
- * pdf bookmark extension.
+ * Element mapping for FOP's proprietary extension to XSL-FO.
  */
 public class ExtensionElementMapping extends ElementMapping {
-    public static String URI = "http://xml.apache.org/fop/extensions";
+    
+    /** The FOP extension namespace URI */
+    public static final String URI = "http://xmlgraphics.apache.org/fop/extensions";
 
     /**
      * Constructor.
@@ -43,6 +44,8 @@
     protected void initialize() {
         if (foObjs == null) {
             foObjs = new HashMap();
+            foObjs.put("outline", new UnknownXMLObj.Maker(URI));
+            foObjs.put("label", new UnknownXMLObj.Maker(URI));
         }
     }
 }

Copied: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/OldExtensionElementMapping.java (from r396484, xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java)
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/OldExtensionElementMapping.java?p2=xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/OldExtensionElementMapping.java&p1=xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java&r1=396484&r2=397806&rev=397806&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/extensions/OldExtensionElementMapping.java Fri Apr 28 01:51:27 2006
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2004 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.
@@ -18,31 +18,19 @@
 
 package org.apache.fop.fo.extensions;
 
-import org.apache.fop.fo.ElementMapping;
-
-import java.util.HashMap;
-
 /**
- * Element mapping for the pdf bookmark extension.
- * This sets up the mapping for the classes that handle the
- * pdf bookmark extension.
+ * Element mapping for the old FOP extension namespace. It is simply mapped to the new namespace.
  */
-public class ExtensionElementMapping extends ElementMapping {
-    public static String URI = "http://xml.apache.org/fop/extensions";
+public class OldExtensionElementMapping extends ExtensionElementMapping {
+    
+    /** The old FOP extension namespace URI (FOP 0.20.5 and earlier) */
+    public static final String URI = "http://xml.apache.org/fop/extensions";
 
     /**
      * Constructor.
      */
-    public ExtensionElementMapping() {
+    public OldExtensionElementMapping() {
         namespaceURI = URI;
     }
 
-    /**
-     * Initialize the data structures.
-     */
-    protected void initialize() {
-        if (foObjs == null) {
-            foObjs = new HashMap();
-        }
-    }
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java?rev=397806&r1=397805&r2=397806&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java Fri Apr 28 01:51:27 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.
@@ -373,4 +373,12 @@
                 && isFinished());
     }
 
+    /**
+     * Transfers foreign attributes from the formatting object to the area.
+     * @param targetArea the area to set the attributes on
+     */
+    protected void transferForeignAttributes(Area targetArea) {
+        Map atts = getFObj().getForeignAttributes();
+        targetArea.setForeignAttributes(atts);
+    }
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/AbstractGraphicsLayoutManager.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/AbstractGraphicsLayoutManager.java?rev=397806&r1=397805&r2=397806&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/AbstractGraphicsLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/AbstractGraphicsLayoutManager.java Fri Apr 28 01:51:27 2006
@@ -209,6 +209,7 @@
 
         Area viewportArea = getChildArea();
         TraitSetter.setProducerID(viewportArea, fobj.getId());
+        transferForeignAttributes(viewportArea);
 
         Viewport vp = new Viewport(viewportArea);
         TraitSetter.setProducerID(vp, fobj.getId());

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/RendererContextConstants.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/RendererContextConstants.java?rev=397806&r1=397805&r2=397806&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/RendererContextConstants.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/RendererContextConstants.java Fri Apr 28 01:51:27 2006
@@ -44,4 +44,10 @@
     /** The configuration for the XMLHandler. */
     String HANDLER_CONFIGURATION = "cfg";
     
+    /**
+     * An optional Map (keys: QName, values: String) with attributes containing additional hints 
+     * for rendering.
+     */
+    String FOREIGN_ATTRIBUTES = "foreign-attributes";
+    
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/xml/XMLRenderer.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/xml/XMLRenderer.java?rev=397806&r1=397805&r2=397806&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/xml/XMLRenderer.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/xml/XMLRenderer.java Fri Apr 28 01:51:27 2006
@@ -45,6 +45,7 @@
 import org.apache.fop.render.Renderer;
 import org.apache.fop.render.RendererContext;
 import org.apache.fop.render.XMLHandler;
+import org.apache.fop.util.QName;
 import org.apache.fop.util.XMLizable;
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.apps.FOPException;
@@ -279,6 +280,16 @@
      * @param name name of the attribute
      * @param value value of the attribute
      */
+    protected void addAttribute(QName name, String value) {
+        atts.addAttribute(name.getNamespaceURI(), name.getLocalName(), name.getQName(), 
+                CDATA, value);
+    }
+
+    /**
+     * Adds a new attribute to the protected member variable "atts".
+     * @param name name of the attribute
+     * @param value value of the attribute
+     */
     protected void addAttribute(String name, int value) {
         addAttribute(name, Integer.toString(value));
     }
@@ -375,6 +386,13 @@
                     addAttribute(name, value.toString());
                 }
             }
+        }
+        
+        //Transfer foreign attributes
+        Iterator iter = area.getForeignAttributes().entrySet().iterator();
+        while (iter.hasNext()) {
+            Map.Entry entry = (Map.Entry)iter.next();
+            addAttribute((QName)entry.getKey(), (String)entry.getValue());
         }
     }
 

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/util/QName.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/util/QName.java?rev=397806&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/util/QName.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/util/QName.java Fri Apr 28 01:51:27 2006
@@ -0,0 +1,113 @@
+/*
+ * 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.util;
+
+import java.io.Serializable;
+
+/**
+ * Represents a qualified name of an XML element or an XML attribute.
+ * <p>
+ * Note: This class allows to carry a namespace prefix but it is not used in the equals() and 
+ * hashCode() methods.
+ */
+public class QName implements Serializable {
+
+    private static final long serialVersionUID = -5225376740044770690L;
+    
+    private String namespaceURI;
+    private String localName;
+    private String prefix;
+    private int hashCode;
+    
+    /**
+     * Main constructor.
+     * @param namespaceURI the namespace URI
+     * @param prefix the namespace prefix, may be null
+     * @param localName the local name
+     */
+    public QName(String namespaceURI, String prefix, String localName) {
+        if (localName == null) {
+            throw new NullPointerException("Parameter localName must not be null");
+        }
+        if (localName.length() == 0) {
+            throw new IllegalArgumentException("Parameter localName must not be empty");
+        }
+        this.namespaceURI = namespaceURI;
+        this.prefix = prefix;
+        this.localName = localName;
+        this.hashCode = toHashString().hashCode();
+    }
+    
+    /** @return the namespace URI */
+    public String getNamespaceURI() {
+        return this.namespaceURI;
+    }
+    
+    /** @return the namespace prefix */
+    public String getPrefix() {
+        return this.prefix;
+    }
+    
+    /** @return the local name */
+    public String getLocalName() {
+        return this.localName;
+    }
+    
+    /** @return the fully qualified name */
+    public String getQName() {
+        return getPrefix() != null ? getPrefix() + ':' + getLocalName() : getLocalName();
+    }
+
+    /** @see java.lang.Object#hashCode() */
+    public int hashCode() {
+        return this.hashCode;
+    }
+
+    /** @see java.lang.Object#equals(java.lang.Object) */
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        } else if (obj == this) {
+            return true;
+        } else {
+            if (obj instanceof QName) {
+                QName other = (QName)obj;
+                if ((getNamespaceURI() == null && other.getNamespaceURI() == null)
+                        || getNamespaceURI().equals(other.getNamespaceURI())) {
+                    return getLocalName().equals(other.getLocalName());
+                }
+            }
+        }
+        return false;
+    }
+
+    /** @see java.lang.Object#toString() */
+    public String toString() {
+        return prefix != null
+                ? (prefix + ":" + localName)
+                : toHashString();
+    }
+
+    private String toHashString() {
+        return (namespaceURI != null 
+                ? ("{" + namespaceURI + "}" + localName) 
+                : localName);
+    }
+
+}

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/util/UnitConv.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/util/UnitConv.java?rev=397806&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/util/UnitConv.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/util/UnitConv.java Fri Apr 28 01:51:27 2006
@@ -0,0 +1,118 @@
+/*
+ * 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: FixedLength.java 279656 2005-09-08 22:06:48Z pietsch $ */
+
+package org.apache.fop.util;
+
+/**
+ * Utility class for unit conversions.
+ */
+public final class UnitConv {
+
+    /** conversion factory from millimeters to inches. */
+    public static final float IN2MM = 25.4f;
+    
+    /** conversion factory from centimeters to inches. */
+    public static final float IN2CM = 2.54f;
+    
+    /** conversion factory from inches to points. */
+    public static final int IN2PT = 72;
+    
+    /**
+     * Converts millimeters (mm) to points (pt)
+     * @param mm the value in mm
+     * @return the value in pt
+     */
+    public static double mm2pt(double mm) {
+        return mm * IN2PT / IN2MM;
+    }
+
+    /**
+     * Converts millimeters (mm) to millipoints (mpt)
+     * @param mm the value in mm
+     * @return the value in mpt
+     */
+    public static double mm2mpt(double mm) {
+        return mm * 1000 * IN2PT / IN2MM;
+    }
+
+    /**
+     * Converts points (pt) to millimeters (mm)
+     * @param pt the value in pt
+     * @return the value in mm
+     */
+    public static double pt2mm(double pt) {
+        return pt * IN2MM / IN2PT;
+    }
+    
+    /**
+     * Converts millimeters (mm) to inches (in)
+     * @param mm the value in mm
+     * @return the value in inches
+     */
+    public static double mm2in(double mm) {
+        return mm / IN2MM;
+    }
+    
+    /**
+     * Converts inches (in) to millimeters (mm)
+     * @param in the value in inches
+     * @return the value in mm
+     */
+    public static double in2mm(double in) {
+        return in * IN2MM;
+    }
+    
+    /**
+     * Converts inches (in) to millipoints (mpt)
+     * @param in the value in inches
+     * @return the value in mpt
+     */
+    public static double in2mpt(double in) {
+        return in * IN2PT * 1000;
+    }
+    
+    /**
+     * Converts millipoints (mpt) to inches (in) 
+     * @param mpt the value in mpt
+     * @return the value in inches
+     */
+    public static double mpt2in(double mpt) {
+        return mpt / IN2PT / 1000;
+    }
+    
+    /**
+     * Converts millimeters (mm) to pixels (px)
+     * @param mm the value in mm
+     * @param resolution the resolution in dpi (dots per inch)
+     * @return the value in pixels
+     */
+    public static int mm2px(double mm, int resolution) {
+        return (int)Math.round(mm2in(mm) * resolution);
+    }
+
+    /**
+     * Converts millipoints (mpt) to pixels (px)
+     * @param mpt the value in mpt
+     * @param resolution the resolution in dpi (dots per inch)
+     * @return the value in pixels
+     */
+    public static int mpt2px(double mpt, int resolution) {
+        return (int)Math.round(mpt2in(mpt) * resolution);
+    }
+
+}

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

Added: xmlgraphics/fop/trunk/src/sandbox/META-INF/services/org.apache.fop.render.XMLHandler
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/sandbox/META-INF/services/org.apache.fop.render.XMLHandler?rev=397806&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/sandbox/META-INF/services/org.apache.fop.render.XMLHandler (added)
+++ xmlgraphics/fop/trunk/src/sandbox/META-INF/services/org.apache.fop.render.XMLHandler Fri Apr 28 01:51:27 2006
@@ -0,0 +1 @@
+org.apache.fop.render.pcl.PCLSVGHandler

Added: xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/DefaultMonochromeBitmapConverter.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/DefaultMonochromeBitmapConverter.java?rev=397806&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/DefaultMonochromeBitmapConverter.java (added)
+++ xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/DefaultMonochromeBitmapConverter.java Fri Apr 28 01:51:27 2006
@@ -0,0 +1,52 @@
+/*
+ * 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.pcl;
+
+import java.awt.RenderingHints;
+import java.awt.color.ColorSpace;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorConvertOp;
+import java.awt.image.RenderedImage;
+
+/**
+ * Default implementation of the MonochromeBitmapConverter which uses the Java Class Library
+ * to convert grayscale bitmaps to monochrome bitmaps.
+ */
+public class DefaultMonochromeBitmapConverter implements
+        MonochromeBitmapConverter {
+
+    /** @see MonochromeBitmapConverter#setHint(java.lang.String, java.lang.String) */
+    public void setHint(String name, String value) {
+        //ignore, not supported
+    }
+    
+    /** @see MonochromeBitmapConverter#convertToMonochrome(java.awt.image.BufferedImage) */
+    public RenderedImage convertToMonochrome(BufferedImage img) {
+        BufferedImage buf = new BufferedImage(img.getWidth(), img.getHeight(), 
+                BufferedImage.TYPE_BYTE_BINARY);
+        RenderingHints hints = new RenderingHints(null);
+        //This hint doesn't seem to make a difference :-(
+        hints.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
+        ColorConvertOp op = new ColorConvertOp(
+                ColorSpace.getInstance(ColorSpace.CS_GRAY), hints);
+        op.filter(img, buf);
+        return buf;
+    }
+
+}

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

Added: xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/JAIMonochromeBitmapConverter.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/JAIMonochromeBitmapConverter.java?rev=397806&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/JAIMonochromeBitmapConverter.java (added)
+++ xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/JAIMonochromeBitmapConverter.java Fri Apr 28 01:51:27 2006
@@ -0,0 +1,97 @@
+/*
+ * 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.pcl;
+
+import java.awt.RenderingHints;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.IndexColorModel;
+import java.awt.image.RenderedImage;
+import java.awt.image.renderable.ParameterBlock;
+
+import javax.media.jai.ColorCube;
+import javax.media.jai.ImageLayout;
+import javax.media.jai.JAI;
+import javax.media.jai.KernelJAI;
+import javax.media.jai.LookupTableJAI;
+import javax.media.jai.PlanarImage;
+
+/**
+ * Implementation of the MonochromeBitmapConverter which uses Java Advanced Imaging (JAI)
+ * to convert grayscale bitmaps to monochrome bitmaps. JAI provides better dithering options
+ * including error diffusion dithering.
+ * <p>
+ * If you call setHint("quality", "true") on the instance you can enabled error diffusion
+ * dithering which produces a nicer result but is also a lot slower.
+ */
+public class JAIMonochromeBitmapConverter implements
+        MonochromeBitmapConverter {
+
+    private boolean isErrorDiffusion = false;
+    
+    /** @see MonochromeBitmapConverter#setHint(java.lang.String, java.lang.String) */
+    public void setHint(String name, String value) {
+        if ("quality".equalsIgnoreCase(name)) {
+            isErrorDiffusion = "true".equalsIgnoreCase(value);
+        }
+    }
+    
+    /** @see MonochromeBitmapConverter#convertToMonochrome(java.awt.image.BufferedImage) */
+    public RenderedImage convertToMonochrome(BufferedImage img) {
+        if (img.getColorModel().getColorSpace().getNumComponents() != 1) {
+            throw new IllegalArgumentException("Source image must be a grayscale image!");
+        }
+        
+        // Load the ParameterBlock for the dithering operation
+        // and set the operation name.
+        ParameterBlock pb = new ParameterBlock();
+        pb.addSource(img);
+        String opName = null;
+        if (isErrorDiffusion) {
+            opName = "errordiffusion";
+            LookupTableJAI lut = new LookupTableJAI(new byte[] {(byte)0x00, (byte)0xff});
+            pb.add(lut);
+            pb.add(KernelJAI.ERROR_FILTER_FLOYD_STEINBERG);
+        } else {
+            opName = "ordereddither";
+            //Create the color cube.
+            ColorCube colorMap = ColorCube.createColorCube(DataBuffer.TYPE_BYTE,
+                    0, new int[] {2});
+            pb.add(colorMap);
+            pb.add(KernelJAI.DITHER_MASK_441);
+        }
+        
+        //Create an image layout for a monochrome b/w image
+        ImageLayout layout = new ImageLayout();
+        byte[] map = new byte[] {(byte)0x00, (byte)0xff};
+        ColorModel cm = new IndexColorModel(1, 2, map, map, map);
+        layout.setColorModel(cm);
+
+        // Create a hint containing the layout.
+        RenderingHints hints = new RenderingHints(JAI.KEY_IMAGE_LAYOUT, layout);
+
+        // Dither the image.
+        PlanarImage dst = JAI.create(opName, pb, hints);        
+        
+        //Convert it to a BufferedImage
+        return dst.getAsBufferedImage();
+    }
+
+}

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

Added: xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/MonochromeBitmapConverter.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/MonochromeBitmapConverter.java?rev=397806&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/MonochromeBitmapConverter.java (added)
+++ xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/MonochromeBitmapConverter.java Fri Apr 28 01:51:27 2006
@@ -0,0 +1,43 @@
+/*
+ * 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.pcl;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.RenderedImage;
+
+/**
+ * Interface for converters that convert grayscale images to monochrome (1-bit) bitmap images.
+ */
+public interface MonochromeBitmapConverter {
+
+    /**
+     * Sets a hint to the implementation
+     * @param name the name of the hint
+     * @param value the value
+     */
+    void setHint(String name, String value);
+    
+    /**
+     * Converts a grayscale bitmap image to a monochrome (1-bit) b/w bitmap image. 
+     * @param img the grayscale image
+     * @return the converted monochrome image
+     */
+    RenderedImage convertToMonochrome(BufferedImage img);
+    
+}

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

Added: xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLGenerator.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLGenerator.java?rev=397806&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLGenerator.java (added)
+++ xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLGenerator.java Fri Apr 28 01:51:27 2006
@@ -0,0 +1,502 @@
+/*
+ * 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.pcl;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.color.ColorSpace;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorConvertOp;
+import java.awt.image.ColorModel;
+import java.awt.image.IndexColorModel;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.util.Locale;
+
+/**
+ * This class provides methods for generating PCL print files.
+ */
+public class PCLGenerator {
+
+    /** The ESC (escape) character */
+    public static final char ESC = '\033';
+    
+    /** A list of all supported resolutions in PCL (values in dpi) */
+    public static final int[] PCL_RESOLUTIONS = new int[] {75, 100, 150, 200, 300, 600};
+    
+    private final DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.US); 
+    private final DecimalFormat df2 = new DecimalFormat("0.##", symbols);
+    private final DecimalFormat df4 = new DecimalFormat("0.####", symbols);
+    
+    private OutputStream out;
+    
+    /**
+     * Main constructor.
+     * @param out the OutputStream to write the PCL stream to
+     */
+    public PCLGenerator(OutputStream out) {
+        this.out = out;
+    }
+    
+    /** @return the OutputStream that this generator writes to */
+    public OutputStream getOutputStream() {
+        return this.out;
+    }
+    
+    /**
+     * Writes a PCL escape command to the output stream.
+     * @param cmd the command (without the ESCAPE character)
+     * @throws IOException In case of an I/O error
+     */
+    public void writeCommand(String cmd) throws IOException {
+        out.write(27); //ESC
+        out.write(cmd.getBytes("US-ASCII"));
+    }
+    
+    /**
+     * Writes raw text (in ISO-8859-1 encoding) to the output stream.
+     * @param s the text
+     * @throws IOException In case of an I/O error
+     */
+    public void writeText(String s) throws IOException {
+        out.write(s.getBytes("ISO-8859-1"));
+    }
+
+    /**
+     * Formats a double value with two decimal positions for PCL output.
+     * 
+     * @param value value to format
+     * @return the formatted value
+     */
+    public final String formatDouble2(double value) {
+        return df2.format(value);
+    }
+
+    /**
+     * Formats a double value with four decimal positions for PCL output.
+     * 
+     * @param value value to format
+     * @return the formatted value
+     */
+    public final String formatDouble4(double value) {
+        return df4.format(value);
+    }
+
+    /**
+     * Sends the universal end of language command (UEL).
+     * @throws IOException In case of an I/O error
+     */
+    public void universalEndOfLanguage() throws IOException {
+        writeCommand("%-12345X");
+    }
+    
+    /**
+     * Resets the printer and restores the user default environment.
+     * @throws IOException In case of an I/O error
+     */
+    public void resetPrinter() throws IOException {
+        writeCommand("E");
+    }
+    
+    /**
+     * Sends the job separation command.
+     * @throws IOException In case of an I/O error
+     */
+    public void separateJobs() throws IOException {
+        writeCommand("&l1T");
+    }
+    
+    /**
+     * Sends the form feed character.
+     * @throws IOException In case of an I/O error
+     */
+    public void formFeed() throws IOException {
+        out.write(12); //=OC ("FF", Form feed)
+    }
+    
+    /**
+     * Clears the horizontal margins.
+     * @throws IOException In case of an I/O error
+     */
+    public void clearHorizontalMargins() throws IOException {
+        writeCommand("9");
+    }
+    
+    /**
+     * The Top Margin command designates the number of lines between
+     * the top of the logical page and the top of the text area.
+     * @param numberOfLines the number of lines (See PCL specification for details)
+     * @throws IOException In case of an I/O error
+     */
+    public void setTopMargin(int numberOfLines) throws IOException {
+        writeCommand("&l" + numberOfLines + "E");
+    }
+
+    /**
+     * Sets the cursor to a new absolute coordinate.
+     * @param x the X coordinate (in millipoints)
+     * @param y the Y coordinate (in millipoints)
+     * @throws IOException In case of an I/O error
+     */
+    public void setCursorPos(int x, int y) throws IOException {
+        writeCommand("*p" + (x / 100) + "h" + (y / 100) + "V");
+    }
+
+    /**
+     * Generate a filled rectangle
+     *
+     * @param x the x position of left edge in millipoints
+     * @param y the y position of top edge in millipoints
+     * @param w the width in millipoints
+     * @param h the height in millipoints
+     * @param col the fill color
+     * @throws IOException In case of an I/O error
+     */
+    protected void fillRect(int x, int y, int w, int h, Color col) throws IOException {
+        if ((w == 0) || (h == 0)) {
+            return;
+        }
+        if (h < 0) {
+            h *= -1;
+        } else {
+            //y += h;
+        }
+
+        int xpos = (x / 100);
+        if (xpos < 0) {
+            //A negative x coordinate can lead to a displaced rectangle (xpos must be >= 0) 
+            w += x;
+            xpos = 0;
+        }
+        writeCommand("*v1O");
+        writeCommand("&a" + formatDouble4(xpos) + "h" 
+                          + formatDouble4(y / 100) + "V");
+        writeCommand("*c" + formatDouble4(w / 100) + "h" 
+                          + formatDouble4(h / 100) + "V");
+        int lineshade = convertToPCLShade(col);
+        writeCommand("*c" + lineshade + "G");
+        writeCommand("*c2P");
+        // Reset pattern transparency mode.
+        writeCommand("*v0O");
+    }
+
+    /**
+     * Sets the pattern transparency mode.
+     * @param transparent true if transparent, false for opaque
+     * @throws IOException In case of an I/O error
+     */
+    public void setPatternTransparencyMode(boolean transparent) throws IOException {
+        if (transparent) {
+            writeCommand("*v0O");
+        } else {
+            writeCommand("*v1O");
+        }
+    }
+
+    /**
+     * Convert an RGB color value to a grayscale from 0 to 100.
+     * @param r the red component
+     * @param g the green component
+     * @param b the blue component
+     * @return the gray value
+     */
+    public final int convertToGray(int r, int g, int b) {
+        return (r * 30 + g * 59 + b * 11) / 100;
+    }
+    
+    /**
+     * Convert a Color value to a PCL shade value (0-100).
+     * @param col the color
+     * @return the PCL shade value (100=black)
+     */
+    public final int convertToPCLShade(Color col) {
+        float gray = convertToGray(col.getRed(), col.getGreen(), col.getBlue()) / 255f;
+        return (int)(100 - (gray * 100f));
+    }
+    
+    /**
+     * Select the current pattern
+     * @param patternID the pattern ID (<ESC>*c#G command)
+     * @param pattern the pattern type (<ESC>*v#T command)
+     * @throws IOException In case of an I/O error
+     */
+    public void selectCurrentPattern(int patternID, int pattern) throws IOException {
+        writeCommand("*c" + patternID + "G");
+        writeCommand("*v" + pattern + "T");
+    }
+
+    /**
+     * Indicates whether an image is a monochrome (b/w) image.
+     * @param img the image
+     * @return true if it's a monochrome image
+     */
+    public static boolean isMonochromeImage(RenderedImage img) {
+        ColorModel cm = img.getColorModel();
+        if (cm instanceof IndexColorModel) {
+            IndexColorModel icm = (IndexColorModel)cm;
+            return icm.getMapSize() == 2;
+        } else {
+            return false;
+        }
+    }
+    
+    /**
+     * Indicates whether an image is a grayscale image.
+     * @param img the image
+     * @return true if it's a grayscale image
+     */
+    public static boolean isGrayscaleImage(RenderedImage img) {
+        return (img.getColorModel().getColorSpace().getNumComponents() == 1);
+    }
+    
+    private MonochromeBitmapConverter createMonochromeBitmapConverter() {
+        MonochromeBitmapConverter converter = null;
+        try {
+            String clName = "org.apache.fop.render.pcl.JAIMonochromeBitmapConverter";
+            Class clazz = Class.forName(clName);
+            converter = (MonochromeBitmapConverter)clazz.newInstance();
+        } catch (ClassNotFoundException cnfe) {
+            // Class was not compiled so is not available. Simply ignore.
+        } catch (LinkageError le) {
+            // This can happen if fop was build with support for a
+            // particular provider (e.g. a binary fop distribution)
+            // but the required support files (i.e. JAI) are not
+            // available in the current runtime environment.
+            // Simply continue with the backup implementation.
+        } catch (InstantiationException e) {
+            // Problem instantiating the class, simply continue with the backup implementation
+        } catch (IllegalAccessException e) {
+            // Problem instantiating the class, simply continue with the backup implementation
+        }
+        if (converter == null) {
+            converter = new DefaultMonochromeBitmapConverter();
+        }
+        return converter;
+    }
+
+    private int calculatePCLResolution(int resolution) {
+        return calculatePCLResolution(resolution, false);
+    }
+    
+    /**
+     * Calculates the ideal PCL resolution for a given resolution.
+     * @param resolution the input resolution
+     * @param increased true if you want to go to a higher resolution, for example if you
+     *                  convert grayscale or color images to monochrome images so dithering has
+     *                  a chance to generate better quality.
+     * @return the resulting PCL resolution (one of 75, 100, 150, 200, 300, 600)
+     */
+    private int calculatePCLResolution(int resolution, boolean increased) {
+        for (int i = PCL_RESOLUTIONS.length - 2; i >= 0; i--) {
+            if (resolution > PCL_RESOLUTIONS[i]) {
+                int idx = i + 1;
+                if (idx < PCL_RESOLUTIONS.length - 2) {
+                    idx += increased ? 2 : 0;
+                } else if (idx < PCL_RESOLUTIONS.length - 1) {
+                    idx += increased ? 1 : 0;
+                }
+                return PCL_RESOLUTIONS[idx];
+            }
+        }
+        return PCL_RESOLUTIONS[increased ? 2 : 0];
+    }
+    
+    private boolean isValidPCLResolution(int resolution) {
+        return resolution == calculatePCLResolution(resolution);
+    }
+    
+    private Dimension getAdjustedDimension(Dimension orgDim, int orgResolution, 
+            int pclResolution) {
+        if (orgResolution == pclResolution) {
+            return orgDim;
+        } else {
+            Dimension result = new Dimension();
+            result.width = (int)Math.round((double)orgDim.width * pclResolution / orgResolution); 
+            result.height = (int)Math.round((double)orgDim.height * pclResolution / orgResolution); 
+            return result;
+        }
+    }
+    
+    /**
+     * Paint a bitmap at the current cursor position. The bitmap is converted to a monochrome
+     * (1-bit) bitmap image.
+     * @param img the bitmap image
+     * @param resolution the original resolution of the image (in dpi)
+     * @throws IOException In case of an I/O error
+     */
+    public void paintBitmap(RenderedImage img, int resolution) throws IOException {
+        boolean monochrome = isMonochromeImage(img);
+        if (!monochrome) {
+            int effResolution = calculatePCLResolution(resolution, true);
+            Dimension orgDim = new Dimension(img.getWidth(), img.getHeight());
+            Dimension effDim = getAdjustedDimension(orgDim, resolution, effResolution);
+            boolean scaled = !orgDim.equals(effDim);
+            BufferedImage src = null;
+            if (img instanceof BufferedImage && !scaled) {
+                if (!isGrayscaleImage(img)) {
+                    src = new BufferedImage(effDim.width, effDim.height, 
+                            BufferedImage.TYPE_BYTE_GRAY);
+                    ColorConvertOp op = new ColorConvertOp(
+                            ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
+                    op.filter((BufferedImage)img, src);
+                } else {
+                    src = (BufferedImage)img;
+                }
+            }
+            if (src == null) {
+                src = new BufferedImage(effDim.width, effDim.height, 
+                        BufferedImage.TYPE_BYTE_GRAY);
+                Graphics2D g2d = src.createGraphics();
+                try {
+                    AffineTransform at = new AffineTransform();
+                    double sx = effDim.getWidth() / orgDim.getWidth();
+                    double sy = effDim.getHeight() / orgDim.getHeight();
+                    at.scale(sx, sy);
+                    g2d.drawRenderedImage(img, at);
+                } finally {
+                    g2d.dispose();
+                }
+            }
+            MonochromeBitmapConverter converter = createMonochromeBitmapConverter();
+            converter.setHint("quality", "false");
+
+            long start = System.currentTimeMillis();
+            BufferedImage buf = (BufferedImage)converter.convertToMonochrome(src);
+            long duration = System.currentTimeMillis() - start;
+            System.out.println(duration + " ms");
+            
+            RenderedImage red = buf;
+            paintMonochromeBitmap(red, effResolution);
+        } else {
+            int effResolution = calculatePCLResolution(resolution);
+            paintMonochromeBitmap(img, effResolution);
+        }
+    }
+
+    /**
+     * Paint a bitmap at the current cursor position. The bitmap must be a monochrome
+     * (1-bit) bitmap image.
+     * @param img the bitmap image (must be 1-bit b/w)
+     * @param resolution the resolution of the image (must be a PCL resolution)
+     * @throws IOException In case of an I/O error
+     */
+    public void paintMonochromeBitmap(RenderedImage img, int resolution) throws IOException {
+        if (!isValidPCLResolution(resolution)) {
+            throw new IllegalArgumentException("Invalid PCL resolution: " + resolution);
+        }
+        writeCommand("*t" + resolution + "R");
+        writeCommand("*r0f" + img.getHeight() + "t" + img.getWidth() + "s1A");
+        Raster raster = img.getData();
+        boolean monochrome = isMonochromeImage(img);
+        if (!monochrome) {
+            throw new IllegalArgumentException("img must be a monochrome image");
+        }
+        
+        int x = 0;
+        int y = 0;
+        int imgw = img.getWidth();
+        int imgh = img.getHeight();
+        int bytewidth = (imgw / 8);
+        if ((imgw % 8) != 0) {
+            bytewidth++;
+        }
+        byte ib;
+        byte[] rle = new byte[bytewidth * 2]; //compressed (RLE)
+        byte[] uncompressed = new byte[bytewidth]; //uncompressed
+        int lastcount = -1;
+        byte lastbyte = 0;
+        int rlewidth = 0;
+        /*
+        int xres = (iw * 72000) / w;
+        int yres = (ih * 72000) / h;
+        int resolution = xres;
+        if (yres > xres)
+            resolution = yres;
+
+        if (resolution > 300)
+            resolution = 600;
+        else if (resolution > 150)
+            resolution = 300;
+        else if (resolution > 100)
+            resolution = 150;
+        else if (resolution > 75)
+            resolution = 100;
+        else
+            resolution = 75;
+            */
+
+        // Transfer graphics data
+        for (y = 0; y < imgh; y++) {
+            ib = 0;
+            for (x = 0; x < imgw; x++) {
+                int sample = raster.getSample(x, y, 0);
+                //Set image bit for black
+                if ((sample == 0)) {
+                    ib |= (1 << (7 - (x % 8)));
+                }
+                    
+                //RLE encoding
+                if ((x % 8) == 7 || ((x + 1) == imgw)) {
+                    if (rlewidth < bytewidth) {
+                        if (lastcount >= 0) {
+                            if (ib == lastbyte) {
+                                lastcount++;
+                            } else {
+                                rle[rlewidth++] = (byte)(lastcount & 0xFF);
+                                rle[rlewidth++] = lastbyte;
+                                lastbyte = ib;
+                                lastcount = 0;
+                            }
+                        } else {
+                            lastbyte = ib;
+                            lastcount = 0;
+                        }
+                        if (lastcount == 255 || ((x + 1) == imgw)) {
+                            rle[rlewidth++] = (byte)(lastcount & 0xFF);
+                            rle[rlewidth++] = lastbyte;
+                            lastbyte = 0;
+                            lastcount = -1;
+                        }
+                    }
+                    uncompressed[x / 8] = ib;
+                    ib = 0;
+                }
+            }
+            if (rlewidth < bytewidth) {
+                writeCommand("*b1m" + rlewidth + "W");
+                this.out.write(rle, 0, rlewidth);
+            } else {
+                writeCommand("*b0m" + bytewidth + "W");
+                this.out.write(uncompressed);
+            }
+            lastcount = -1;
+            rlewidth = 0;
+        }
+
+        // End raster graphics
+        writeCommand("*rB");
+    }
+    
+}

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

Added: xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLGraphics2D.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLGraphics2D.java?rev=397806&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLGraphics2D.java (added)
+++ xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLGraphics2D.java Fri Apr 28 01:51:27 2006
@@ -0,0 +1,430 @@
+/*
+ * 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.pcl;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.awt.Image;
+import java.awt.Paint;
+import java.awt.Shape;
+import java.awt.Stroke;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.ImageObserver;
+import java.awt.image.RenderedImage;
+import java.awt.image.renderable.RenderableImage;
+import java.io.IOException;
+import java.text.AttributedCharacterIterator;
+
+import org.apache.fop.util.UnitConv;
+import org.apache.xmlgraphics.java2d.AbstractGraphics2D;
+import org.apache.xmlgraphics.java2d.GraphicContext;
+
+/**
+ * Graphics2D implementation implementing PCL and HP GL/2.
+ */
+public class PCLGraphics2D extends AbstractGraphics2D {
+
+    /** The PCL generator */
+    protected PCLGenerator gen;
+    
+    /**
+     * Create a new PCLGraphics2D.
+     * @param gen the PCL Generator to paint with
+     */
+    public PCLGraphics2D(PCLGenerator gen) {
+        super(true);
+        this.gen = gen;
+    }
+
+    /**
+     * Copy constructor
+     * @param g parent PCLGraphics2D
+     */
+    public PCLGraphics2D(PCLGraphics2D g) {
+        super(true);
+        this.gen = g.gen;
+    }
+
+    /** @see java.awt.Graphics#create() */
+    public Graphics create() {
+        return new PCLGraphics2D(this);
+    }
+
+    /** @see java.awt.Graphics#dispose() */
+    public void dispose() {
+        this.gen = null;
+    }
+
+    /**
+     * Sets the GraphicContext
+     * @param c GraphicContext to use
+     */
+    public void setGraphicContext(GraphicContext c) {
+        this.gc = c;
+    }
+
+    /**
+     * Central handler for IOExceptions for this class.
+     * @param ioe IOException to handle
+     */
+    public void handleIOException(IOException ioe) {
+        //TODO Surely, there's a better way to do this.
+        ioe.printStackTrace();
+    }
+
+    /** @see java.awt.Graphics2D#getDeviceConfiguration() */
+    public GraphicsConfiguration getDeviceConfiguration() {
+        return GraphicsEnvironment.getLocalGraphicsEnvironment().
+                getDefaultScreenDevice().getDefaultConfiguration();
+    }
+
+    /**
+     * Applies a new Stroke object.
+     * @param stroke Stroke object to use
+     * @throws IOException In case of an I/O problem
+     */
+    protected void applyStroke(Stroke stroke) throws IOException {
+        if (stroke instanceof BasicStroke) {
+            BasicStroke bs = (BasicStroke)stroke;
+
+            float[] da = bs.getDashArray();
+            if (da != null) {
+                
+                gen.writeText("UL1,");
+                for (int idx = 0, len = Math.min(20, da.length); idx < len; idx++) {
+                    gen.writeText(gen.formatDouble4(da[idx]));
+                    if (idx < da.length - 1) {
+                        gen.writeText(",");
+                    }
+                }
+                gen.writeText(";");
+                /* TODO Dash phase NYI
+                float offset = bs.getDashPhase();
+                gen.writeln(gen.formatDouble4(offset) + " setdash");
+                */
+                gen.writeText("LT1;");
+            } else {
+                gen.writeText("LT;");
+            }
+
+            gen.writeText("LA1"); //line cap
+            int ec = bs.getEndCap();
+            switch (ec) {
+            case BasicStroke.CAP_BUTT:
+                gen.writeText(",1");
+                break;
+            case BasicStroke.CAP_ROUND:
+                gen.writeText(",4");
+                break;
+            case BasicStroke.CAP_SQUARE:
+                gen.writeText(",2");
+                break;
+            default: System.err.println("Unsupported line cap: " + ec);
+            }
+
+            gen.writeText(",2"); //line join
+            int lj = bs.getLineJoin();
+            switch (lj) {
+            case BasicStroke.JOIN_MITER:
+                gen.writeText(",1");
+                break;
+            case BasicStroke.JOIN_ROUND:
+                gen.writeText(",4");
+                break;
+            case BasicStroke.JOIN_BEVEL:
+                gen.writeText(",5");
+                break;
+            default: System.err.println("Unsupported line join: " + lj);
+            }
+
+            float ml = bs.getMiterLimit();
+            gen.writeText(",3"  + gen.formatDouble4(ml));
+            
+            float lw = bs.getLineWidth();
+            Point2D ptSrc = new Point2D.Double(lw, 0);
+            //Pen widths are set as absolute metric values (WU0;)
+            Point2D ptDest = getTransform().transform(ptSrc, null);
+            double transDist = UnitConv.pt2mm(ptDest.distance(0, 0));
+            //System.out.println("--" + ptDest.distance(0, 0) + " " + transDist);
+            gen.writeText(";PW" + gen.formatDouble4(transDist) + ";");
+            
+        } else {
+            System.err.println("Unsupported Stroke: " + stroke.getClass().getName());
+        }
+    }
+
+    /**
+     * Applies a new Paint object.
+     * @param paint Paint object to use
+     * @throws IOException In case of an I/O problem
+     */
+    protected void applyPaint(Paint paint) throws IOException {
+        if (paint instanceof Color) {
+            Color col = (Color)paint;
+            int shade = gen.convertToPCLShade(col);
+            gen.writeText("TR0;FT10," + shade + ";");
+        } else {
+            System.err.println("Unsupported Paint: " + paint.getClass().getName());
+        }
+    }
+
+    /** @see java.awt.Graphics2D#draw(java.awt.Shape) */
+    public void draw(Shape s) {
+        try {
+            AffineTransform trans = getTransform();
+    
+            Shape imclip = getClip();
+            //writeClip(imclip);
+            //establishColor(getColor());
+    
+            applyPaint(getPaint());
+            applyStroke(getStroke());
+    
+            //gen.writeln("newpath");
+            PathIterator iter = s.getPathIterator(trans);
+            processPathIterator(iter);
+            gen.writeText("EP;");
+        } catch (IOException ioe) {
+            handleIOException(ioe);
+        }
+    }
+
+    /** @see java.awt.Graphics2D#fill(java.awt.Shape) */
+    public void fill(Shape s) {
+        try {
+            AffineTransform trans = getTransform();
+            Shape imclip = getClip();
+            //writeClip(imclip);
+            
+            //establishColor(getColor());
+
+            applyPaint(getPaint());
+
+            PathIterator iter = s.getPathIterator(trans);
+            processPathIterator(iter);
+            int fillMethod = (iter.getWindingRule() == PathIterator.WIND_EVEN_ODD ? 0 : 1);
+            gen.writeText("FP" + fillMethod + ";");
+        } catch (IOException ioe) {
+            handleIOException(ioe);
+        }
+    }
+
+    /**
+     * Processes a path iterator generating the nexessary painting operations.
+     * @param iter PathIterator to process
+     * @throws IOException In case of an I/O problem.
+     */
+    public void processPathIterator(PathIterator iter) throws IOException {
+        double[] vals = new double[6];
+        boolean penDown = false;
+        boolean hasFirst = false;
+        double x = 0, firstX = 0;
+        double y = 0, firstY = 0;
+        boolean pendingPM0 = true;
+        penUp();
+        while (!iter.isDone()) {
+            int type = iter.currentSegment(vals);
+            if (type == PathIterator.SEG_CLOSE) {
+                hasFirst = false;
+                /*
+                if (firstX != x && firstY != y) {
+                    plotAbsolute(firstX, firstY);
+                }*/
+                //penUp();
+                gen.writeText("PM1;");
+                iter.next();
+                continue;
+            }
+            if (type == PathIterator.SEG_MOVETO) {
+                if (penDown) {
+                    penUp();
+                    penDown = false;
+                }
+            } else {
+                if (!penDown) {
+                    penDown();
+                    penDown = true;
+                }
+            }
+            switch (type) {
+            case PathIterator.SEG_CUBICTO:
+                x = vals[4];
+                y = vals[5];
+                bezierAbsolute(vals[0], vals[1], vals[2], vals[3], x, y);
+                break;
+            case PathIterator.SEG_LINETO:
+                x = vals[0];
+                y = vals[1];
+                plotAbsolute(x, y);
+                break;
+            case PathIterator.SEG_MOVETO:
+                x = vals[0];
+                y = vals[1];
+                plotAbsolute(x, y);
+                break;
+            case PathIterator.SEG_QUADTO:
+                double originX = x;
+                double originY = y;
+                x = vals[2];
+                y = vals[3];
+                quadraticBezierAbsolute(originX, originY, vals[0], vals[1], x, y);
+                break;
+            case PathIterator.SEG_CLOSE:
+                break;
+            default:
+                break;
+            }
+            if (pendingPM0) {
+                pendingPM0 = false;
+                gen.writeText("PM;");
+            }
+            if (!hasFirst) {
+                firstX = x;
+                firstY = y;
+            }
+            iter.next();
+        }
+        gen.writeText("PM2;");
+    }
+
+    private void plotAbsolute(double x, double y) throws IOException {
+        gen.writeText("PA" + gen.formatDouble4(x) + ","
+                + gen.formatDouble4(y) + ";");
+    }
+
+    private void bezierAbsolute(double x1, double y1, double x2, double y2, double x3, double y3) 
+                throws IOException {
+        gen.writeText("BZ" + gen.formatDouble4(x1) + ","
+                + gen.formatDouble4(y1) + ","
+                + gen.formatDouble4(x2) + ","
+                + gen.formatDouble4(y2) + ","
+                + gen.formatDouble4(x3) + ","
+                + gen.formatDouble4(y3) + ";");
+    }
+
+    private void quadraticBezierAbsolute(double originX, double originY, 
+            double x1, double y1, double x2, double y2) 
+            throws IOException {
+        //Quadratic Bezier curve can be mapped to a normal bezier curve
+        //See http://pfaedit.sourceforge.net/bezier.html
+        double nx1 = originX + (2.0 / 3.0) * (x1 - originX);
+        double ny1 = originY + (2.0 / 3.0) * (y1 - originY);
+        
+        double nx2 = nx1 + (1.0 / 3.0) * (x2 - originX);
+        double ny2 = ny1 + (1.0 / 3.0) * (y2 - originY);
+        
+        bezierAbsolute(nx1, ny1, nx2, ny2, x2, y2);
+    }
+
+    private void penDown() throws IOException {
+        gen.writeText("PD;");
+    }
+
+    private void penUp() throws IOException {
+        gen.writeText("PU;");
+    }
+
+    /** @see java.awt.Graphics2D#drawString(java.lang.String, float, float) */
+    public void drawString(String s, float x, float y) {
+        // TODO Auto-generated method stub
+        System.err.println("drawString NYI");
+    }
+
+    /** @see java.awt.Graphics2D#drawString(java.text.AttributedCharacterIterator, float, float) */
+    public void drawString(AttributedCharacterIterator iterator, float x,
+            float y) {
+        // TODO Auto-generated method stub
+        System.err.println("drawString NYI");
+    }
+
+    /**
+     * @see java.awt.Graphics2D#drawRenderedImage(java.awt.image.RenderedImage, 
+     *          java.awt.geom.AffineTransform)
+     */
+    public void drawRenderedImage(RenderedImage img, AffineTransform xform) {
+        // TODO Auto-generated method stub
+        System.err.println("drawRenderedImage NYI");
+    }
+
+    /**
+     * @see java.awt.Graphics2D#drawRenderableImage(java.awt.image.renderable.RenderableImage, 
+     *          java.awt.geom.AffineTransform)
+     */
+    public void drawRenderableImage(RenderableImage img, AffineTransform xform) {
+        // TODO Auto-generated method stub
+        System.err.println("drawRenderedImage NYI");
+    }
+
+    /**
+     * @see java.awt.Graphics#drawImage(java.awt.Image, int, int, int, int, 
+     *          java.awt.image.ImageObserver)
+     */
+    public boolean drawImage(Image img, int x, int y, int width, int height,
+            ImageObserver observer) {
+        // TODO Auto-generated method stub
+        System.err.println("drawImage NYI");
+        return false;
+    }
+
+    /**
+     * @see java.awt.Graphics#drawImage(java.awt.Image, int, int, java.awt.image.ImageObserver)
+     */
+    public boolean drawImage(Image img, int x, int y, ImageObserver observer) {
+        // TODO Auto-generated method stub
+        System.err.println("drawImage NYI");
+        return false;
+    }
+
+    /** @see java.awt.Graphics#copyArea(int, int, int, int, int, int) */
+    public void copyArea(int x, int y, int width, int height, int dx, int dy) {
+        // TODO Auto-generated method stub
+        System.err.println("copyArea NYI");
+    }
+
+    /** @see java.awt.Graphics#setXORMode(java.awt.Color) */
+    public void setXORMode(Color c1) {
+        // TODO Auto-generated method stub
+        System.err.println("setXORMode NYI");
+    }
+
+    /**
+     * Used to create proper font metrics
+     */
+    private Graphics2D fmg;
+
+    {
+        BufferedImage bi = new BufferedImage(1, 1,
+                                             BufferedImage.TYPE_INT_ARGB);
+
+        fmg = bi.createGraphics();
+    }
+
+    /** @see java.awt.Graphics#getFontMetrics(java.awt.Font) */
+    public java.awt.FontMetrics getFontMetrics(java.awt.Font f) {
+        return fmg.getFontMetrics(f);
+    }
+
+}

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

Added: xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLGraphics2DAdapter.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLGraphics2DAdapter.java?rev=397806&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLGraphics2DAdapter.java (added)
+++ xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLGraphics2DAdapter.java Fri Apr 28 01:51:27 2006
@@ -0,0 +1,137 @@
+/*
+ * 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.pcl;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+
+import org.apache.fop.render.Graphics2DAdapter;
+import org.apache.fop.render.Graphics2DImagePainter;
+import org.apache.fop.render.RendererContext;
+import org.apache.fop.util.UnitConv;
+import org.apache.xmlgraphics.java2d.GraphicContext;
+
+/**
+ * Graphics2DAdapter implementation for PCL and HP GL/2.
+ */
+public class PCLGraphics2DAdapter implements Graphics2DAdapter {
+
+    /**
+     * Main constructor
+     */
+    public PCLGraphics2DAdapter() {
+    }
+    
+    /** @see org.apache.fop.render.Graphics2DAdapter */
+    public void paintImage(Graphics2DImagePainter painter, 
+            RendererContext context,
+            int x, int y, int width, int height) throws IOException {
+        PCLRendererContext pclContext = PCLRendererContext.wrapRendererContext(context);
+        PCLRenderer pcl = (PCLRenderer)context.getRenderer();
+        PCLGenerator gen = pcl.gen;
+        
+        // get the 'width' and 'height' attributes of the SVG document
+        Dimension dim = painter.getImageSize();
+        float imw = (float)dim.getWidth();
+        float imh = (float)dim.getHeight();
+
+        boolean paintAsBitmap = pclContext.paintAsBitmap();
+        if (paintAsBitmap) {
+            int resolution = 300; //TODO not hard-coded, please!
+            int bmw = UnitConv.mpt2px(pclContext.getWidth(), resolution);
+            int bmh = UnitConv.mpt2px(pclContext.getHeight(), resolution);
+            BufferedImage bi = new BufferedImage(
+                    bmw, bmh,
+                    BufferedImage.TYPE_INT_RGB);
+            Graphics2D g2d = bi.createGraphics();
+            try {
+                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
+                        RenderingHints.VALUE_ANTIALIAS_OFF);
+                    g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, 
+                        RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
+                    g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, 
+                        RenderingHints.VALUE_FRACTIONALMETRICS_OFF);
+                    g2d.setRenderingHint(RenderingHints.KEY_RENDERING, 
+                            RenderingHints.VALUE_RENDER_QUALITY);
+                    g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, 
+                            RenderingHints.VALUE_COLOR_RENDER_QUALITY);
+                    g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, 
+                            RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
+                    g2d.setRenderingHint(RenderingHints.KEY_DITHERING,
+                        RenderingHints.VALUE_DITHER_ENABLE);
+                    g2d.setBackground(Color.white);
+                    g2d.setColor(Color.black);
+                    g2d.clearRect(0, 0, bmw, bmh);
+                    double sx = (double)bmw / pclContext.getWidth() * 1000;
+                    double sy = (double)bmh / pclContext.getHeight() * 1000;
+                    g2d.scale(sx, sy);
+
+                    //Paint the SVG on the BufferedImage
+                    Rectangle2D area = new Rectangle2D.Double(
+                            0.0, 0.0, pclContext.getWidth(), pclContext.getHeight());
+                    painter.paint(g2d, area);
+            } finally {
+                g2d.dispose();
+            }
+
+            pcl.moveTo(x, y);
+            gen.paintBitmap(bi, resolution);
+        } else {
+            pcl.saveGraphicsState();
+            GraphicContext ctx = (GraphicContext)pcl.getGraphicContext().clone();
+
+            // Clip to the image area.
+            //gen.writeln("newpath");
+            //gen.defineRect(fx, fy, fwidth, fheight);
+            //gen.writeln("clip");
+            
+            AffineTransform prepareHPGL2 = new AffineTransform();
+            //prepareHPGL2.scale(1, 1);
+            ctx.setTransform(prepareHPGL2);
+
+            pcl.moveTo(x, y);
+            gen.writeCommand("*c" + gen.formatDouble4(width / 100f) + "x" 
+                    + gen.formatDouble4(height / 100f) + "Y");
+            gen.writeCommand("*c0T");
+            gen.writeCommand("%0B");
+            gen.writeText("IN;");
+            gen.writeText("SP1;");
+            //One Plotter unit is 0.025mm!
+            double scale = imw / UnitConv.mm2pt(imw * 0.025);
+            gen.writeText("SC0," + gen.formatDouble4(scale) 
+                    + ",0,-" + gen.formatDouble4(scale) + ",2;");
+            gen.writeText("IR0,100,0,100;");
+            gen.writeText("PU;PA0,0;");
+            PCLGraphics2D graphics = new PCLGraphics2D(gen);
+            graphics.setGraphicContext(ctx);
+            Rectangle2D area = new Rectangle2D.Double(0.0, 0.0, imw, imh);
+            painter.paint(graphics, area);
+
+            gen.writeCommand("%0A");
+            pcl.restoreGraphicsState();
+        }
+    }
+
+}

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



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