You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by vh...@apache.org on 2012/04/05 18:20:17 UTC

svn commit: r1309921 [38/42] - in /xmlgraphics/fop/branches/Temp_TrueTypeInPostScript: ./ examples/embedding/ examples/embedding/java/embedding/ examples/embedding/java/embedding/atxml/ examples/embedding/java/embedding/tools/ examples/plan/src/org/apa...

Modified: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/CharUtilities.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/CharUtilities.java?rev=1309921&r1=1309920&r2=1309921&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/CharUtilities.java (original)
+++ xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/CharUtilities.java Thu Apr  5 16:19:19 2012
@@ -74,6 +74,20 @@ public class CharUtilities {
     public static final char WORD_JOINER = '\u2060';
     /** zero-width joiner */
     public static final char ZERO_WIDTH_JOINER = '\u200D';
+    /** left-to-right mark */
+    public static final char LRM = '\u200E';
+    /** right-to-left mark */
+    public static final char RLM = '\u202F';
+    /** left-to-right embedding */
+    public static final char LRE = '\u202A';
+    /** right-to-left embedding */
+    public static final char RLE = '\u202B';
+    /** pop directional formatting */
+    public static final char PDF = '\u202C';
+    /** left-to-right override */
+    public static final char LRO = '\u202D';
+    /** right-to-left override */
+    public static final char RLO = '\u202E';
     /** zero-width no-break space (= byte order mark) */
     public static final char ZERO_WIDTH_NOBREAK_SPACE = '\uFEFF';
     /** soft hyphen */
@@ -86,10 +100,11 @@ public class CharUtilities {
     public static final char MISSING_IDEOGRAPH = '\u25A1';
     /** Ideogreaphic space */
     public static final char IDEOGRAPHIC_SPACE = '\u3000';
+    /** Object replacement character */
+    public static final char OBJECT_REPLACEMENT_CHARACTER = '\uFFFC';
     /** Unicode value indicating the the character is "not a character". */
     public static final char NOT_A_CHARACTER = '\uFFFF';
 
-
     /**
      * Utility class: Constructor prevents instantiating when subclassed.
      */
@@ -103,7 +118,7 @@ public class CharUtilities {
      * @param c character to inspect
      * @return the determined character class
      */
-    public static int classOf(char c) {
+    public static int classOf ( int c ) {
         switch (c) {
             case CODE_EOT:
                 return EOT;
@@ -126,7 +141,7 @@ public class CharUtilities {
      * @param c character to inspect
      * @return True if the character is a normal space
      */
-    public static boolean isBreakableSpace(char c) {
+    public static boolean isBreakableSpace ( int c ) {
         return (c == SPACE || isFixedWidthSpace(c));
     }
 
@@ -135,7 +150,7 @@ public class CharUtilities {
      * @param c the character to check
      * @return true if the character is a zero-width space
      */
-    public static boolean isZeroWidthSpace(char c) {
+    public static boolean isZeroWidthSpace ( int c ) {
         return c == ZERO_WIDTH_SPACE           // 200Bh
             || c == WORD_JOINER                // 2060h
             || c == ZERO_WIDTH_NOBREAK_SPACE;  // FEFFh (also used as BOM)
@@ -146,7 +161,7 @@ public class CharUtilities {
      * @param c the character to check
      * @return true if the character has a fixed-width
      */
-    public static boolean isFixedWidthSpace(char c) {
+    public static boolean isFixedWidthSpace ( int c ) {
         return (c >= '\u2000' && c <= '\u200B')
                 || c == '\u3000';
 //      c == '\u2000'                   // en quad
@@ -170,7 +185,7 @@ public class CharUtilities {
      * @param c character to check
      * @return True if the character is a nbsp
      */
-    public static boolean isNonBreakableSpace(char c) {
+    public static boolean isNonBreakableSpace ( int c ) {
         return
             (c == NBSPACE       // no-break space
             || c == '\u202F'    // narrow no-break space
@@ -185,7 +200,7 @@ public class CharUtilities {
      * @param c character to check
      * @return True if the character is adjustable
      */
-    public static boolean isAdjustableSpace(char c) {
+    public static boolean isAdjustableSpace ( int c ) {
         //TODO: are there other kinds of adjustable spaces?
         return
             (c == '\u0020'    // normal space
@@ -197,19 +212,19 @@ public class CharUtilities {
      * @param c character to check
      * @return True if the character represents any kind of space
      */
-    public static boolean isAnySpace(char c) {
+    public static boolean isAnySpace ( int c ) {
         return (isBreakableSpace(c) || isNonBreakableSpace(c));
     }
 
     /**
      * Indicates whether a character is classified as "Alphabetic" by the Unicode standard.
-     * @param ch the character
+     * @param c the character
      * @return true if the character is "Alphabetic"
      */
-    public static boolean isAlphabetic(char ch) {
+    public static boolean isAlphabetic ( int c ) {
         //http://www.unicode.org/Public/UNIDATA/UCD.html#Alphabetic
         //Generated from: Other_Alphabetic + Lu + Ll + Lt + Lm + Lo + Nl
-        int generalCategory = Character.getType(ch);
+        int generalCategory = Character.getType((char)c);
         switch (generalCategory) {
             case Character.UPPERCASE_LETTER: //Lu
             case Character.LOWERCASE_LETTER: //Ll
@@ -227,15 +242,116 @@ public class CharUtilities {
 
     /**
      * Indicates whether the given character is an explicit break-character
-     * @param ch    the character to check
+     * @param c    the character to check
      * @return  true if the character represents an explicit break
      */
-    public static boolean isExplicitBreak(char ch) {
-        return (ch == LINEFEED_CHAR
-            || ch == CARRIAGE_RETURN
-            || ch == NEXT_LINE
-            || ch == LINE_SEPARATOR
-            || ch == PARAGRAPH_SEPARATOR);
+    public static boolean isExplicitBreak ( int c ) {
+        return (c == LINEFEED_CHAR
+            || c == CARRIAGE_RETURN
+            || c == NEXT_LINE
+            || c == LINE_SEPARATOR
+            || c == PARAGRAPH_SEPARATOR);
+    }
+
+    /**
+     * Convert a single unicode scalar value to an XML numeric character
+     * reference. If in the BMP, four digits are used, otherwise 6 digits are used.
+     * @param c a unicode scalar value
+     * @return a string representing a numeric character reference
+     */
+    public static String charToNCRef ( int c ) {
+        StringBuffer sb = new StringBuffer();
+        for ( int i = 0, nDigits = ( c > 0xFFFF ) ? 6 : 4; i < nDigits; i++, c >>= 4 ) {
+            int d = c & 0xF;
+            char hd;
+            if ( d < 10 ) {
+                hd = (char) ( (int) '0' + d );
+            } else {
+                hd = (char) ( (int) 'A' + ( d - 10 ) );
+            }
+            sb.append ( hd );
+        }
+        return "&#x" + sb.reverse() + ";";
+    }
+
+    /**
+     * Convert a string to a sequence of ASCII or XML numeric character references.
+     * @param s a java string (encoded in UTF-16)
+     * @return a string representing a sequence of numeric character reference or
+     * ASCII characters
+     */
+    public static String toNCRefs ( String s ) {
+        StringBuffer sb = new StringBuffer();
+        if ( s != null ) {
+            for ( int i = 0; i < s.length(); i++ ) {
+                char c = s.charAt(i);
+                if ( ( c >= 32 ) && ( c < 127 ) ) {
+                    if ( c == '<' ) {
+                        sb.append ( "&lt;" );
+                    } else if ( c == '>' ) {
+                        sb.append ( "&gt;" );
+                    } else if ( c == '&' ) {
+                        sb.append ( "&amp;" );
+                    } else {
+                        sb.append ( c );
+                    }
+                } else {
+                    sb.append ( charToNCRef ( c ) );
+                }
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Pad a string S on left out to width W using padding character PAD.
+     * @param s string to pad
+     * @param width width of field to add padding
+     * @param pad character to use for padding
+     * @return padded string
+     */
+    public static String padLeft ( String s, int width, char pad ) {
+        StringBuffer sb = new StringBuffer();
+        for ( int i = s.length(); i < width; i++ ) {
+            sb.append(pad);
+        }
+        sb.append ( s );
+        return sb.toString();
+    }
+
+    /**
+     * Format character for debugging output, which it is prefixed with "0x", padded left with '0'
+     * and either 4 or 6 hex characters in width according to whether it is in the BMP or not.
+     * @param c character code
+     * @return formatted character string
+     */
+    public static String format ( int c ) {
+        if ( c < 1114112 ) {
+            return "0x" + padLeft ( Integer.toString ( c, 16 ), ( c < 65536 ) ? 4 : 6, '0' );
+        } else {
+            return "!NOT A CHARACTER!";
+        }
     }
-}
 
+    /**
+     * Determine if two character sequences contain the same characters.
+     * @param cs1 first character sequence
+     * @param cs2 second character sequence
+     * @return true if both sequences have same length and same character sequence
+     */
+    public static boolean isSameSequence ( CharSequence cs1, CharSequence cs2 ) {
+        assert cs1 != null;
+        assert cs2 != null;
+        if ( cs1.length() != cs2.length() ) {
+            return false;
+        } else {
+            for ( int i = 0, n = cs1.length(); i < n; i++ ) {
+                if ( cs1.charAt(i) != cs2.charAt(i) ) {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
+}

Modified: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/ColorExt.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/ColorExt.java?rev=1309921&r1=1309920&r2=1309921&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/ColorExt.java (original)
+++ xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/ColorExt.java Thu Apr  5 16:19:19 2012
@@ -28,7 +28,9 @@ import java.util.Arrays;
  * <p>
  * This class extends java.awt.Color class keeping track of the original color
  * property values specified by the fo user in a rgb-icc call.
+ * @deprecated Replaced by {@link ColorWithAlternatives}
  */
+@Deprecated
 public final class ColorExt extends Color {
     //
     private static final long serialVersionUID = 1L;
@@ -136,12 +138,14 @@ public final class ColorExt extends Colo
     }
 
     /** {@inheritDoc} */
+    @Override
     public int hashCode() {
         //implementation from the superclass should be good enough for our purposes
         return super.hashCode();
     }
 
     /** {@inheritDoc} */
+    @Override
     public boolean equals(Object obj) {
         if (this == obj) {
             return true;

Propchange: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/ColorExt.java
------------------------------------------------------------------------------
  Merged /xmlgraphics/fop/branches/Temp_Color/src/java/org/apache/fop/util/ColorExt.java:r956535-1069429
  Merged /xmlgraphics/fop/branches/Temp_PDF_ObjectStreams/src/java/org/apache/fop/util/ColorExt.java:r1303414-1305418
  Merged /xmlgraphics/fop/trunk/src/java/org/apache/fop/util/ColorExt.java:r1040963-1307575
  Merged /xmlgraphics/fop/branches/Temp_ImproveAccessibility/src/java/org/apache/fop/util/ColorExt.java:r1187234-1242827

Modified: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/ColorProfileUtil.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/ColorProfileUtil.java?rev=1309921&r1=1309920&r2=1309921&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/ColorProfileUtil.java (original)
+++ xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/ColorProfileUtil.java Thu Apr  5 16:19:19 2012
@@ -19,13 +19,11 @@
 
 package org.apache.fop.util;
 
-import java.awt.color.ColorSpace;
-import java.awt.color.ICC_ColorSpace;
 import java.awt.color.ICC_Profile;
-import java.io.UnsupportedEncodingException;
 
 /**
  * Helper methods for handling color profiles.
+ * @deprecated use org.apache.xmlgraphics.java2d.color.profile.ColorProfileUtil directly
  */
 public final class ColorProfileUtil {
 
@@ -36,21 +34,11 @@ public final class ColorProfileUtil {
      * Returns the profile description of an ICC profile
      * @param profile the profile
      * @return the description
+     * @deprecated use org.apache.xmlgraphics.java2d.color.profile.ColorProfileUtil directly
      */
     public static String getICCProfileDescription(ICC_Profile profile) {
-        byte[] data = profile.getData(ICC_Profile.icSigProfileDescriptionTag);
-        if (data == null) {
-            return null;
-        } else {
-            //Info on the data format: http://www.color.org/ICC-1_1998-09.PDF
-            int length = (data[8] << 3 * 8) | (data[9] << 2 * 8) | (data[10] << 8) | data[11];
-            length--; //Remove trailing NUL character
-            try {
-                return new String(data, 12, length, "US-ASCII");
-            } catch (UnsupportedEncodingException e) {
-                throw new UnsupportedOperationException("Incompatible VM");
-            }
-        }
+        return org.apache.xmlgraphics.java2d.color.profile.ColorProfileUtil
+                .getICCProfileDescription(profile);
     }
 
     /**
@@ -58,14 +46,10 @@ public final class ColorProfileUtil {
      * provided by the Java class library.
      * @param profile the color profile to check
      * @return true if it is the default sRGB profile
+     * @deprecated use org.apache.xmlgraphics.java2d.color.profile.ColorProfileUtil directly
      */
     public static boolean isDefaultsRGB(ICC_Profile profile) {
-        ColorSpace sRGB = ColorSpace.getInstance(ColorSpace.CS_sRGB);
-        ICC_Profile sRGBProfile = null;
-        if (sRGB instanceof ICC_ColorSpace) {
-            sRGBProfile = ((ICC_ColorSpace)sRGB).getProfile();
-        }
-        return profile == sRGBProfile;
+        return org.apache.xmlgraphics.java2d.color.profile.ColorProfileUtil
+                .isDefaultsRGB(profile);
     }
-
 }

Modified: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/ColorSpaceCache.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/ColorSpaceCache.java?rev=1309921&r1=1309920&r2=1309921&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/ColorSpaceCache.java (original)
+++ xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/ColorSpaceCache.java Thu Apr  5 16:19:19 2012
@@ -20,7 +20,6 @@
 package org.apache.fop.util;
 
 import java.awt.color.ColorSpace;
-import java.awt.color.ICC_ColorSpace;
 import java.awt.color.ICC_Profile;
 import java.util.Collections;
 import java.util.Map;
@@ -32,6 +31,10 @@ import javax.xml.transform.stream.Stream
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
+import org.apache.xmlgraphics.java2d.color.ICCColorSpaceWithIntent;
+import org.apache.xmlgraphics.java2d.color.RenderingIntent;
+import org.apache.xmlgraphics.java2d.color.profile.ColorProfileUtil;
+
 /**
  * Map with cached ICC based ColorSpace objects.
  */
@@ -40,7 +43,8 @@ public class ColorSpaceCache {
     private static Log log = LogFactory.getLog(ColorSpaceCache.class);
 
     private URIResolver resolver;
-    private Map colorSpaceMap = Collections.synchronizedMap(new java.util.HashMap());
+    private Map<String, ColorSpace> colorSpaceMap
+            = Collections.synchronizedMap(new java.util.HashMap<String, ColorSpace>());
 
     /**
      * Default constructor
@@ -59,13 +63,17 @@ public class ColorSpaceCache {
      * The FOP URI resolver is used to try and locate the ICC file.
      * If that fails null is returned.
      *
+     * @param profileName the profile name
      * @param base a base URI to resolve relative URIs
      * @param iccProfileSrc ICC Profile source to return a ColorSpace for
+     * @param renderingIntent overriding rendering intent
      * @return ICC ColorSpace object or null if ColorSpace could not be created
      */
-    public ColorSpace get(String base, String iccProfileSrc) {
+    public ColorSpace get(String profileName, String base, String iccProfileSrc,
+            RenderingIntent renderingIntent) {
+        String key = profileName + ":" + base + iccProfileSrc;
         ColorSpace colorSpace = null;
-        if (!colorSpaceMap.containsKey(base + iccProfileSrc)) {
+        if (!colorSpaceMap.containsKey(key)) {
             try {
                 ICC_Profile iccProfile = null;
                 // First attempt to use the FOP URI resolver to locate the ICC
@@ -74,7 +82,7 @@ public class ColorSpaceCache {
                 if (src != null && src instanceof StreamSource) {
                     // FOP URI resolver found ICC profile - create ICC profile
                     // from the Source
-                    iccProfile = ICC_Profile.getInstance(((StreamSource) src)
+                    iccProfile = ColorProfileUtil.getICC_Profile(((StreamSource) src)
                             .getInputStream());
                 } else {
                     // TODO - Would it make sense to fall back on VM ICC
@@ -86,7 +94,8 @@ public class ColorSpaceCache {
                     // iccProfile = ICC_Profile.getInstance(iccProfileSrc);
                 }
                 if (iccProfile != null) {
-                    colorSpace = new ICC_ColorSpace(iccProfile);
+                    colorSpace = new ICCColorSpaceWithIntent(iccProfile, renderingIntent,
+                            profileName, iccProfileSrc);
                 }
             } catch (Exception e) {
                 // Ignore exception - will be logged a bit further down
@@ -95,15 +104,14 @@ public class ColorSpaceCache {
 
             if (colorSpace != null) {
                 // Put in cache (not when VM resolved it as we can't control
-                colorSpaceMap.put(base + iccProfileSrc, colorSpace);
+                colorSpaceMap.put(key, colorSpace);
             } else {
                 // TODO To avoid an excessive amount of warnings perhaps
                 // register a null ColorMap in the colorSpaceMap
                 log.warn("Color profile '" + iccProfileSrc + "' not found.");
             }
         } else {
-            colorSpace = (ColorSpace)colorSpaceMap.get(base
-                    + iccProfileSrc);
+            colorSpace = colorSpaceMap.get(key);
         }
         return colorSpace;
     }

Modified: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/ColorUtil.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/ColorUtil.java?rev=1309921&r1=1309920&r2=1309921&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/ColorUtil.java (original)
+++ xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/ColorUtil.java Thu Apr  5 16:19:19 2012
@@ -21,13 +21,24 @@ package org.apache.fop.util;
 
 import java.awt.Color;
 import java.awt.color.ColorSpace;
+import java.awt.color.ICC_ColorSpace;
+import java.awt.color.ICC_Profile;
+import java.io.IOException;
 import java.util.Collections;
 import java.util.Map;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
+import org.apache.xmlgraphics.java2d.color.CIELabColorSpace;
+import org.apache.xmlgraphics.java2d.color.ColorSpaceOrigin;
+import org.apache.xmlgraphics.java2d.color.ColorSpaces;
+import org.apache.xmlgraphics.java2d.color.ColorWithAlternatives;
 import org.apache.xmlgraphics.java2d.color.DeviceCMYKColorSpace;
+import org.apache.xmlgraphics.java2d.color.NamedColorSpace;
+import org.apache.xmlgraphics.java2d.color.RenderingIntent;
+import org.apache.xmlgraphics.java2d.color.profile.NamedColorProfile;
+import org.apache.xmlgraphics.java2d.color.profile.NamedColorProfileParser;
 
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.fo.expr.PropertyException;
@@ -40,17 +51,24 @@ import org.apache.fop.fo.expr.PropertyEx
  */
 public final class ColorUtil {
 
+    //ColorWithFallback is used to preserve the sRGB fallback exclusively for the purpose
+    //of regenerating textual color functions as specified in XSL-FO.
+
     /** The name for the uncalibrated CMYK pseudo-profile */
     public static final String CMYK_PSEUDO_PROFILE = "#CMYK";
 
+    /** The name for the Separation pseudo-profile used for spot colors */
+    public static final String SEPARATION_PSEUDO_PROFILE = "#Separation";
+
     /**
-     *
-     * keeps all the predefined and parsed colors.
+     * Keeps all the predefined and parsed colors.
      * <p>
      * This map is used to predefine given colors, as well as speeding up
      * parsing of already parsed colors.
+     * <p>
+     * Important: The use of this color map assumes that all Color instances are immutable!
      */
-    private static Map colorMap = null;
+    private static Map<String, Color> colorMap = null;
 
     /** Logger instance */
     protected static final Log log = LogFactory.getLog(ColorUtil.class);
@@ -97,7 +115,7 @@ public final class ColorUtil {
             return null;
         }
 
-        Color parsedColor = (Color) colorMap.get(value.toLowerCase());
+        Color parsedColor = colorMap.get(value.toLowerCase());
 
         if (parsedColor == null) {
             if (value.startsWith("#")) {
@@ -113,6 +131,10 @@ public final class ColorUtil {
                 parsedColor = parseAsSystemColor(value);
             } else if (value.startsWith("fop-rgb-icc")) {
                 parsedColor = parseAsFopRgbIcc(foUserAgent, value);
+            } else if (value.startsWith("fop-rgb-named-color")) {
+                parsedColor = parseAsFopRgbNamedColor(foUserAgent, value);
+            } else if (value.startsWith("cie-lab-color")) {
+                parsedColor = parseAsCIELabColor(foUserAgent, value);
             } else if (value.startsWith("cmyk")) {
                 parsedColor = parseAsCMYK(value);
             }
@@ -124,9 +146,6 @@ public final class ColorUtil {
             colorMap.put(value, parsedColor);
         }
 
-        // TODO - Returned Color object can be one from the static colorMap cache.
-        //        That means it should be treated as read only for the rest of its lifetime.
-        //        Not sure that is the case though.
         return parsedColor;
     }
 
@@ -149,7 +168,7 @@ public final class ColorUtil {
             throw new PropertyException("Unknown color format: " + value
                     + ". Must be system-color(x)");
         }
-        return (Color) colorMap.get(value);
+        return colorMap.get(value);
     }
 
     /**
@@ -164,7 +183,9 @@ public final class ColorUtil {
      */
     private static Color parseAsJavaAWTColor(String value)
             throws PropertyException {
-        float red = 0.0f, green = 0.0f, blue = 0.0f;
+        float red = 0.0f;
+        float green = 0.0f;
+        float blue = 0.0f;
         int poss = value.indexOf("[");
         int pose = value.indexOf("]");
         try {
@@ -188,10 +209,8 @@ public final class ColorUtil {
                 throw new IllegalArgumentException(
                             "Invalid format for a java.awt.Color: " + value);
             }
-        } catch (PropertyException pe) {
-            throw pe;
-        } catch (Exception e) {
-            throw new PropertyException(e);
+        } catch (RuntimeException re) {
+            throw new PropertyException(re);
         }
         return new Color(red, green, blue);
     }
@@ -217,40 +236,17 @@ public final class ColorUtil {
                     throw new PropertyException(
                             "Invalid number of arguments: rgb(" + value + ")");
                 }
-                float red = 0.0f, green = 0.0f, blue = 0.0f;
-                String str = args[0].trim();
-                if (str.endsWith("%")) {
-                    red = Float.parseFloat(str.substring(0,
-                            str.length() - 1)) / 100f;
-                } else {
-                    red = Float.parseFloat(str) / 255f;
-                }
-                str = args[1].trim();
-                if (str.endsWith("%")) {
-                    green = Float.parseFloat(str.substring(0,
-                            str.length() - 1)) / 100f;
-                } else {
-                    green = Float.parseFloat(str) / 255f;
-                }
-                str = args[2].trim();
-                if (str.endsWith("%")) {
-                    blue = Float.parseFloat(str.substring(0,
-                            str.length() - 1)) / 100f;
-                } else {
-                    blue = Float.parseFloat(str) / 255f;
-                }
-                if ((red < 0.0 || red > 1.0)
-                        || (green < 0.0 || green > 1.0)
-                        || (blue < 0.0 || blue > 1.0)) {
-                    throw new PropertyException("Color values out of range");
-                }
-                parsedColor = new Color(red, green, blue);
-            } catch (PropertyException pe) {
-                //simply re-throw
-                throw pe;
-            } catch (Exception e) {
+                float red = parseComponent255(args[0], value);
+                float green = parseComponent255(args[1], value);
+                float blue = parseComponent255(args[2], value);
+                //Convert to ints to synchronize the behaviour with toRGBFunctionCall()
+                int r = (int)(red * 255 + 0.5);
+                int g = (int)(green * 255 + 0.5);
+                int b = (int)(blue * 255 + 0.5);
+                parsedColor = new Color(r, g, b);
+            } catch (RuntimeException re) {
                 //wrap in a PropertyException
-                throw new PropertyException(e);
+                throw new PropertyException(re);
             }
         } else {
             throw new PropertyException("Unknown color format: " + value
@@ -259,8 +255,50 @@ public final class ColorUtil {
         return parsedColor;
     }
 
+    private static float parseComponent255(String str, String function)
+            throws PropertyException {
+        float component;
+        str = str.trim();
+        if (str.endsWith("%")) {
+            component = Float.parseFloat(str.substring(0,
+                    str.length() - 1)) / 100f;
+        } else {
+            component = Float.parseFloat(str) / 255f;
+        }
+        if ((component < 0.0 || component > 1.0)) {
+            throw new PropertyException("Color value out of range for " + function + ": "
+                    + str + ". Valid range: [0..255] or [0%..100%]");
+        }
+        return component;
+    }
+
+    private static float parseComponent1(String argument, String function)
+            throws PropertyException {
+        return parseComponent(argument, 0f, 1f, function);
+    }
+
+    private static float parseComponent(String argument, float min, float max, String function)
+            throws PropertyException {
+        float component = Float.parseFloat(argument.trim());
+        if ((component < min || component > max)) {
+            throw new PropertyException("Color value out of range for " + function + ": "
+                    + argument + ". Valid range: [" + min + ".." + max + "]");
+        }
+        return component;
+    }
+
+    private static Color parseFallback(String[] args, String value) throws PropertyException {
+        float red = parseComponent1(args[0], value);
+        float green = parseComponent1(args[1], value);
+        float blue = parseComponent1(args[2], value);
+        //Sun's classlib rounds differently with this constructor than when converting to sRGB
+        //via CIE XYZ.
+        Color sRGB = new Color(red, green, blue);
+        return sRGB;
+    }
+
     /**
-     * parse a color given in the #.... format.
+     * Parse a color given in the #.... format.
      *
      * @param value
      *            the complete line
@@ -269,7 +307,7 @@ public final class ColorUtil {
      *             if the format is wrong.
      */
     private static Color parseWithHash(String value) throws PropertyException {
-        Color parsedColor = null;
+        Color parsedColor;
         try {
             int len = value.length();
             int alpha;
@@ -279,7 +317,9 @@ public final class ColorUtil {
             } else {
                 alpha = 0xFF;
             }
-            int red = 0, green = 0, blue = 0;
+            int red = 0;
+            int green = 0;
+            int blue = 0;
             if ((len == 4) || (len == 5)) {
                 //multiply by 0x11 = 17 = 255/15
                 red = Integer.parseInt(value.substring(1, 2), 16) * 0x11;
@@ -293,7 +333,7 @@ public final class ColorUtil {
                 throw new NumberFormatException();
             }
             parsedColor = new Color(red, green, blue, alpha);
-        } catch (Exception e) {
+        } catch (RuntimeException re) {
             throw new PropertyException("Unknown color format: " + value
                     + ". Must be #RGB. #RGBA, #RRGGBB, or #RRGGBBAA");
         }
@@ -319,6 +359,10 @@ public final class ColorUtil {
                 if (args.length < 5) {
                     throw new PropertyException("Too few arguments for rgb-icc() function");
                 }
+
+                //Set up fallback sRGB value
+                Color sRGB = parseFallback(args, value);
+
                 /* Get and verify ICC profile name */
                 String iccProfileName = args[3].trim();
                 if (iccProfileName == null || "".equals(iccProfileName)) {
@@ -328,7 +372,10 @@ public final class ColorUtil {
                 String iccProfileSrc = null;
                 if (isPseudoProfile(iccProfileName)) {
                     if (CMYK_PSEUDO_PROFILE.equalsIgnoreCase(iccProfileName)) {
-                        colorSpace = DeviceCMYKColorSpace.getInstance();
+                        colorSpace = ColorSpaces.getDeviceCMYKColorSpace();
+                    } else if (SEPARATION_PSEUDO_PROFILE.equalsIgnoreCase(iccProfileName)) {
+                        colorSpace = new NamedColorSpace(args[5], sRGB,
+                                SEPARATION_PSEUDO_PROFILE, null);
                     } else {
                         assert false : "Incomplete implementation";
                     }
@@ -338,62 +385,209 @@ public final class ColorUtil {
                     if (iccProfileSrc == null || "".equals(iccProfileSrc)) {
                         throw new PropertyException("ICC profile source missing");
                     }
-                    if (iccProfileSrc.startsWith("\"") || iccProfileSrc.startsWith("'")) {
-                        iccProfileSrc = iccProfileSrc.substring(1);
-                    }
-                    if (iccProfileSrc.endsWith("\"") || iccProfileSrc.endsWith("'")) {
-                        iccProfileSrc = iccProfileSrc.substring(0, iccProfileSrc.length() - 1);
-                    }
+                    iccProfileSrc = unescapeString(iccProfileSrc);
                 }
                 /* ICC profile arguments */
-                float[] iccComponents = new float[args.length - 5];
-                for (int ix = 4; ++ix < args.length;) {
-                    iccComponents[ix - 5] = Float.parseFloat(args[ix].trim());
+                int componentStart = 4;
+                if (colorSpace instanceof NamedColorSpace) {
+                    componentStart++;
+                }
+                float[] iccComponents = new float[args.length - componentStart - 1];
+                for (int ix = componentStart; ++ix < args.length;) {
+                    iccComponents[ix - componentStart - 1] = Float.parseFloat(args[ix].trim());
+                }
+                if (colorSpace instanceof NamedColorSpace && iccComponents.length == 0) {
+                    iccComponents = new float[] {1.0f}; //full tint if not specified
                 }
 
-                float red = 0, green = 0, blue = 0;
-                red = Float.parseFloat(args[0].trim());
-                green = Float.parseFloat(args[1].trim());
-                blue = Float.parseFloat(args[2].trim());
-                /* Verify rgb replacement arguments */
-                if ((red < 0 || red > 1)
-                        || (green < 0 || green > 1)
-                        || (blue < 0 || blue > 1)) {
-                    throw new PropertyException("Color values out of range. "
-                            + "Fallback RGB arguments to fop-rgb-icc() must be [0..1]");
+                /* Ask FOP factory to get ColorSpace for the specified ICC profile source */
+                if (foUserAgent != null && iccProfileSrc != null) {
+                    RenderingIntent renderingIntent = RenderingIntent.AUTO;
+                    //TODO connect to fo:color-profile/@rendering-intent
+                    colorSpace = foUserAgent.getFactory().getColorSpaceCache().get(
+                            iccProfileName,
+                            foUserAgent.getBaseURL(), iccProfileSrc,
+                            renderingIntent);
+                }
+                if (colorSpace != null) {
+                    // ColorSpace is available
+                    if (ColorSpaces.isDeviceColorSpace(colorSpace)) {
+                        //Device-specific colors are handled differently:
+                        //sRGB is the primary color with the CMYK as the alternative
+                        Color deviceColor = new Color(colorSpace, iccComponents, 1.0f);
+                        float[] rgbComps = sRGB.getRGBColorComponents(null);
+                        parsedColor = new ColorWithAlternatives(
+                                rgbComps[0], rgbComps[1], rgbComps[2],
+                                new Color[] {deviceColor});
+                    } else {
+                        parsedColor = new ColorWithFallback(
+                                colorSpace, iccComponents, 1.0f, null, sRGB);
+                    }
+                } else {
+                    // ICC profile could not be loaded - use rgb replacement values */
+                    log.warn("Color profile '" + iccProfileSrc
+                            + "' not found. Using sRGB replacement values.");
+                    parsedColor = sRGB;
+                }
+            } catch (RuntimeException re) {
+                throw new PropertyException(re);
+            }
+        } else {
+            throw new PropertyException("Unknown color format: " + value
+                    + ". Must be fop-rgb-icc(r,g,b,NCNAME,src,....)");
+        }
+        return parsedColor;
+    }
+
+    /**
+     * Parse a color specified using the fop-rgb-named-color() function.
+     *
+     * @param value the function call
+     * @return a color if possible
+     * @throws PropertyException if the format is wrong.
+     */
+    private static Color parseAsFopRgbNamedColor(FOUserAgent foUserAgent, String value)
+            throws PropertyException {
+        Color parsedColor;
+        int poss = value.indexOf("(");
+        int pose = value.indexOf(")");
+        if (poss != -1 && pose != -1) {
+            String[] args = value.substring(poss + 1, pose).split(",");
+
+            try {
+                if (args.length != 6) {
+                    throw new PropertyException("rgb-named-color() function must have 6 arguments");
+                }
+
+                //Set up fallback sRGB value
+                Color sRGB = parseFallback(args, value);
+
+                /* Get and verify ICC profile name */
+                String iccProfileName = args[3].trim();
+                if (iccProfileName == null || "".equals(iccProfileName)) {
+                    throw new PropertyException("ICC profile name missing");
+                }
+                ICC_ColorSpace colorSpace = null;
+                String iccProfileSrc;
+                if (isPseudoProfile(iccProfileName)) {
+                    throw new IllegalArgumentException(
+                            "Pseudo-profiles are not allowed with fop-rgb-named-color()");
+                } else {
+                    /* Get and verify ICC profile source */
+                    iccProfileSrc = args[4].trim();
+                    if (iccProfileSrc == null || "".equals(iccProfileSrc)) {
+                        throw new PropertyException("ICC profile source missing");
+                    }
+                    iccProfileSrc = unescapeString(iccProfileSrc);
                 }
 
+                // color name
+                String colorName = unescapeString(args[5].trim());
+
                 /* Ask FOP factory to get ColorSpace for the specified ICC profile source */
                 if (foUserAgent != null && iccProfileSrc != null) {
-                    colorSpace = foUserAgent.getFactory().getColorSpace(
-                            foUserAgent.getBaseURL(), iccProfileSrc);
+                    RenderingIntent renderingIntent = RenderingIntent.AUTO;
+                    //TODO connect to fo:color-profile/@rendering-intent
+                    colorSpace = (ICC_ColorSpace)foUserAgent.getFactory().getColorSpaceCache().get(
+                            iccProfileName,
+                            foUserAgent.getBaseURL(), iccProfileSrc,
+                            renderingIntent);
                 }
                 if (colorSpace != null) {
-                    // ColorSpace available - create ColorExt (keeps track of replacement rgb
-                    // values for possible later colorTOsRGBString call
-                    parsedColor = ColorExt.createFromFoRgbIcc(red, green, blue,
-                            iccProfileName, iccProfileSrc, colorSpace, iccComponents);
+                    ICC_Profile profile = colorSpace.getProfile();
+                    if (NamedColorProfileParser.isNamedColorProfile(profile)) {
+                        NamedColorProfileParser parser = new NamedColorProfileParser();
+                        NamedColorProfile ncp = parser.parseProfile(profile,
+                                    iccProfileName, iccProfileSrc);
+                        NamedColorSpace ncs = ncp.getNamedColor(colorName);
+                        if (ncs != null) {
+                            parsedColor = new ColorWithFallback(ncs,
+                                    new float[] {1.0f}, 1.0f, null, sRGB);
+                        } else {
+                            log.warn("Color '" + colorName
+                                    + "' does not exist in named color profile: " + iccProfileSrc);
+                            parsedColor = sRGB;
+                        }
+                    } else {
+                        log.warn("ICC profile is no named color profile: " + iccProfileSrc);
+                        parsedColor = sRGB;
+                    }
                 } else {
                     // ICC profile could not be loaded - use rgb replacement values */
                     log.warn("Color profile '" + iccProfileSrc
-                            + "' not found. Using rgb replacement values.");
-                    parsedColor = new Color(Math.round(red * 255),
-                            Math.round(green * 255), Math.round(blue * 255));
-                }
-            } catch (PropertyException pe) {
-                //simply re-throw
-                throw pe;
-            } catch (Exception e) {
+                            + "' not found. Using sRGB replacement values.");
+                    parsedColor = sRGB;
+                }
+            } catch (IOException ioe) {
+                //wrap in a PropertyException
+                throw new PropertyException(ioe);
+            } catch (RuntimeException re) {
+                throw new PropertyException(re);
                 //wrap in a PropertyException
-                throw new PropertyException(e);
             }
         } else {
             throw new PropertyException("Unknown color format: " + value
-                    + ". Must be fop-rgb-icc(r,g,b,NCNAME,src,....)");
+                    + ". Must be fop-rgb-named-color(r,g,b,NCNAME,src,color-name)");
+        }
+        return parsedColor;
+    }
+
+    /**
+     * Parse a color specified using the cie-lab-color() function.
+     *
+     * @param value the function call
+     * @return a color if possible
+     * @throws PropertyException if the format is wrong.
+     */
+    private static Color parseAsCIELabColor(FOUserAgent foUserAgent, String value)
+            throws PropertyException {
+        Color parsedColor;
+        int poss = value.indexOf("(");
+        int pose = value.indexOf(")");
+        if (poss != -1 && pose != -1) {
+            try {
+                String[] args = value.substring(poss + 1, pose).split(",");
+
+                if (args.length != 6) {
+                    throw new PropertyException("cie-lab-color() function must have 6 arguments");
+                }
+
+                //Set up fallback sRGB value
+                float red = parseComponent255(args[0], value);
+                float green = parseComponent255(args[1], value);
+                float blue = parseComponent255(args[2], value);
+                Color sRGB = new Color(red, green, blue);
+
+                float l = parseComponent(args[3], 0f, 100f, value);
+                float a = parseComponent(args[4], -127f, 127f, value);
+                float b = parseComponent(args[5], -127f, 127f, value);
+
+                //Assuming the XSL-FO spec uses the D50 white point
+                CIELabColorSpace cs = ColorSpaces.getCIELabColorSpaceD50();
+                //use toColor() to have components normalized
+                Color labColor = cs.toColor(l, a, b, 1.0f);
+                //Convert to ColorWithFallback
+                parsedColor = new ColorWithFallback(labColor, sRGB);
+            } catch (RuntimeException re) {
+                throw new PropertyException(re);
+            }
+        } else {
+            throw new PropertyException("Unknown color format: " + value
+                    + ". Must be cie-lab-color(r,g,b,Lightness,a-value,b-value)");
         }
         return parsedColor;
     }
 
+    private static String unescapeString(String iccProfileSrc) {
+        if (iccProfileSrc.startsWith("\"") || iccProfileSrc.startsWith("'")) {
+            iccProfileSrc = iccProfileSrc.substring(1);
+        }
+        if (iccProfileSrc.endsWith("\"") || iccProfileSrc.endsWith("'")) {
+            iccProfileSrc = iccProfileSrc.substring(0, iccProfileSrc.length() - 1);
+        }
+        return iccProfileSrc;
+    }
+
     /**
      * Parse a color given with the cmyk() function.
      *
@@ -415,52 +609,17 @@ public final class ColorUtil {
                     throw new PropertyException(
                             "Invalid number of arguments: cmyk(" + value + ")");
                 }
-                float cyan = 0.0f, magenta = 0.0f, yellow = 0.0f, black = 0.0f;
-                String str = args[0].trim();
-                if (str.endsWith("%")) {
-                  cyan  = Float.parseFloat(str.substring(0,
-                            str.length() - 1)) / 100.0f;
-                } else {
-                  cyan  = Float.parseFloat(str);
-                }
-                str = args[1].trim();
-                if (str.endsWith("%")) {
-                  magenta = Float.parseFloat(str.substring(0,
-                            str.length() - 1)) / 100.0f;
-                } else {
-                  magenta = Float.parseFloat(str);
-                }
-                str = args[2].trim();
-                if (str.endsWith("%")) {
-                  yellow = Float.parseFloat(str.substring(0,
-                            str.length() - 1)) / 100.0f;
-                } else {
-                  yellow = Float.parseFloat(str);
-                }
-                str = args[3].trim();
-                if (str.endsWith("%")) {
-                  black = Float.parseFloat(str.substring(0,
-                            str.length() - 1)) / 100.0f;
-                } else {
-                  black = Float.parseFloat(str);
-                }
-
-                if ((cyan < 0.0 || cyan > 1.0)
-                        || (magenta < 0.0 || magenta > 1.0)
-                        || (yellow < 0.0 || yellow > 1.0)
-                        || (black < 0.0 || black > 1.0)) {
-                    throw new PropertyException("Color values out of range"
-                            + "Arguments to cmyk() must be in the range [0%-100%] or [0.0-1.0]");
-                }
-                float[] cmyk = new float[] {cyan, magenta, yellow, black};
-                DeviceCMYKColorSpace cmykCs = DeviceCMYKColorSpace.getInstance();
-                float[] rgb = cmykCs.toRGB(cmyk);
-                parsedColor = ColorExt.createFromFoRgbIcc(rgb[0], rgb[1], rgb[2],
-                        CMYK_PSEUDO_PROFILE, null, cmykCs, cmyk);
-            } catch (PropertyException pe) {
-                throw pe;
-            } catch (Exception e) {
-                throw new PropertyException(e);
+                float cyan = parseComponent1(args[0], value);
+                float magenta = parseComponent1(args[1], value);
+                float yellow = parseComponent1(args[2], value);
+                float black = parseComponent1(args[3], value);
+                float[] comps = new float[] {cyan, magenta, yellow, black};
+                Color cmykColor = DeviceCMYKColorSpace.createCMYKColor(comps);
+                float[] rgbComps = cmykColor.getRGBColorComponents(null);
+                parsedColor = new ColorWithAlternatives(rgbComps[0], rgbComps[1], rgbComps[2],
+                        new Color[] {cmykColor});
+            } catch (RuntimeException re) {
+                throw new PropertyException(re);
             }
         } else {
             throw new PropertyException("Unknown color format: " + value
@@ -481,197 +640,306 @@ public final class ColorUtil {
      */
     public static String colorToString(Color color) {
         ColorSpace cs = color.getColorSpace();
-        if (color instanceof ColorExt) {
-            return ((ColorExt)color).toFunctionCall();
+        if (color instanceof ColorWithAlternatives) {
+            return toFunctionCall((ColorWithAlternatives)color);
         } else if (cs != null && cs.getType() == ColorSpace.TYPE_CMYK) {
             StringBuffer sbuf = new StringBuffer(24);
             float[] cmyk = color.getColorComponents(null);
-            sbuf.append("cmyk(" + cmyk[0] + "," + cmyk[1] + "," + cmyk[2] + "," +  cmyk[3] + ")");
+            sbuf.append("cmyk(").append(cmyk[0])
+                    .append(",").append(cmyk[1])
+                    .append(",").append(cmyk[2])
+                    .append(",").append(cmyk[3]).append(")");
             return sbuf.toString();
         } else {
-            StringBuffer sbuf = new StringBuffer();
-            sbuf.append('#');
-            String s = Integer.toHexString(color.getRed());
+            return toRGBFunctionCall(color);
+        }
+    }
+
+    private static String toRGBFunctionCall(Color color) {
+        StringBuffer sbuf = new StringBuffer();
+        sbuf.append('#');
+        String s = Integer.toHexString(color.getRed());
+        if (s.length() == 1) {
+            sbuf.append('0');
+        }
+        sbuf.append(s);
+        s = Integer.toHexString(color.getGreen());
+        if (s.length() == 1) {
+            sbuf.append('0');
+        }
+        sbuf.append(s);
+        s = Integer.toHexString(color.getBlue());
+        if (s.length() == 1) {
+            sbuf.append('0');
+        }
+        sbuf.append(s);
+        if (color.getAlpha() != 255) {
+            s = Integer.toHexString(color.getAlpha());
             if (s.length() == 1) {
                 sbuf.append('0');
             }
             sbuf.append(s);
-            s = Integer.toHexString(color.getGreen());
-            if (s.length() == 1) {
-                sbuf.append('0');
+        }
+        return sbuf.toString();
+    }
+
+    private static Color getsRGBFallback(ColorWithAlternatives color) {
+        Color fallbackColor;
+        if (color instanceof ColorWithFallback) {
+            fallbackColor = ((ColorWithFallback)color).getFallbackColor();
+            if (!fallbackColor.getColorSpace().isCS_sRGB()) {
+                fallbackColor = toSRGBColor(fallbackColor);
             }
-            sbuf.append(s);
-            s = Integer.toHexString(color.getBlue());
-            if (s.length() == 1) {
-                sbuf.append('0');
+        } else {
+            fallbackColor = toSRGBColor(color);
+        }
+        return fallbackColor;
+    }
+
+    private static Color toSRGBColor(Color color) {
+        float[] comps;
+        ColorSpace sRGB = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+        comps = color.getRGBColorComponents(null);
+        float[] allComps = color.getComponents(null);
+        float alpha = allComps[allComps.length - 1]; //Alpha is on last component
+        return new Color(sRGB, comps, alpha);
+    }
+
+    /**
+     * Create string representation of a fop-rgb-icc (or fop-rgb-named-color) function call from
+     * the given color.
+     * @param color the color to turn into a function call
+     * @return the string representing the internal fop-rgb-icc() or fop-rgb-named-color()
+     *           function call
+     */
+    private static String toFunctionCall(ColorWithAlternatives color) {
+        ColorSpace cs = color.getColorSpace();
+        if (cs.isCS_sRGB() && !color.hasAlternativeColors()) {
+            return toRGBFunctionCall(color);
+        }
+        if (cs instanceof CIELabColorSpace) {
+            return toCIELabFunctionCall(color);
+        }
+
+        Color specColor = color;
+        if (color.hasAlternativeColors()) {
+            Color alt = color.getAlternativeColors()[0];
+            if (ColorSpaces.isDeviceColorSpace(alt.getColorSpace())) {
+                cs = alt.getColorSpace();
+                specColor = alt;
             }
-            sbuf.append(s);
-            if (color.getAlpha() != 255) {
-                s = Integer.toHexString(color.getAlpha());
-                if (s.length() == 1) {
-                    sbuf.append('0');
-                }
-                sbuf.append(s);
+        }
+        ColorSpaceOrigin origin = ColorSpaces.getColorSpaceOrigin(cs);
+        String functionName;
+
+        Color fallbackColor = getsRGBFallback(color);
+        float[] rgb = fallbackColor.getColorComponents(null);
+        assert rgb.length == 3;
+        StringBuffer sb = new StringBuffer(40);
+        sb.append("(");
+        sb.append(rgb[0]).append(",");
+        sb.append(rgb[1]).append(",");
+        sb.append(rgb[2]).append(",");
+        String profileName = origin.getProfileName();
+        sb.append(profileName).append(",");
+        if (origin.getProfileURI() != null) {
+            sb.append("\"").append(origin.getProfileURI()).append("\"");
+        }
+
+        if (cs instanceof NamedColorSpace) {
+            NamedColorSpace ncs = (NamedColorSpace)cs;
+            if (SEPARATION_PSEUDO_PROFILE.equalsIgnoreCase(profileName)) {
+                functionName = "fop-rgb-icc";
+            } else {
+                functionName = "fop-rgb-named-color";
             }
-            return sbuf.toString();
+            sb.append(",").append(ncs.getColorName());
+        } else {
+            functionName = "fop-rgb-icc";
+            float[] colorComponents = specColor.getColorComponents(null);
+            for (float colorComponent : colorComponents) {
+                sb.append(",");
+                sb.append(colorComponent);
+            }
+        }
+        sb.append(")");
+        return functionName + sb.toString();
+    }
+
+    private static String toCIELabFunctionCall(ColorWithAlternatives color) {
+        Color fallbackColor = getsRGBFallback(color);
+        StringBuffer sb = new StringBuffer("cie-lab-color(");
+        sb.append(fallbackColor.getRed()).append(',');
+        sb.append(fallbackColor.getGreen()).append(',');
+        sb.append(fallbackColor.getBlue());
+        CIELabColorSpace cs = (CIELabColorSpace)color.getColorSpace();
+        float[] lab = cs.toNativeComponents(color.getColorComponents(null));
+        for (int i = 0; i < 3; i++) {
+            sb.append(',').append(lab[i]);
         }
+        sb.append(')');
+        return sb.toString();
+    }
+
+    private static Color createColor(int r, int g, int b) {
+        return new Color(r, g, b);
     }
 
     /**
      * Initializes the colorMap with some predefined values.
      */
     private static void initializeColorMap() {                  // CSOK: MethodLength
-        colorMap = Collections.synchronizedMap(new java.util.HashMap());
+        colorMap = Collections.synchronizedMap(new java.util.HashMap<String, Color>());
 
-        colorMap.put("aliceblue", new Color(240, 248, 255));
-        colorMap.put("antiquewhite", new Color(250, 235, 215));
-        colorMap.put("aqua", new Color(0, 255, 255));
-        colorMap.put("aquamarine", new Color(127, 255, 212));
-        colorMap.put("azure", new Color(240, 255, 255));
-        colorMap.put("beige", new Color(245, 245, 220));
-        colorMap.put("bisque", new Color(255, 228, 196));
-        colorMap.put("black", new Color(0, 0, 0));
-        colorMap.put("blanchedalmond", new Color(255, 235, 205));
-        colorMap.put("blue", new Color(0, 0, 255));
-        colorMap.put("blueviolet", new Color(138, 43, 226));
-        colorMap.put("brown", new Color(165, 42, 42));
-        colorMap.put("burlywood", new Color(222, 184, 135));
-        colorMap.put("cadetblue", new Color(95, 158, 160));
-        colorMap.put("chartreuse", new Color(127, 255, 0));
-        colorMap.put("chocolate", new Color(210, 105, 30));
-        colorMap.put("coral", new Color(255, 127, 80));
-        colorMap.put("cornflowerblue", new Color(100, 149, 237));
-        colorMap.put("cornsilk", new Color(255, 248, 220));
-        colorMap.put("crimson", new Color(220, 20, 60));
-        colorMap.put("cyan", new Color(0, 255, 255));
-        colorMap.put("darkblue", new Color(0, 0, 139));
-        colorMap.put("darkcyan", new Color(0, 139, 139));
-        colorMap.put("darkgoldenrod", new Color(184, 134, 11));
-        colorMap.put("darkgray", new Color(169, 169, 169));
-        colorMap.put("darkgreen", new Color(0, 100, 0));
-        colorMap.put("darkgrey", new Color(169, 169, 169));
-        colorMap.put("darkkhaki", new Color(189, 183, 107));
-        colorMap.put("darkmagenta", new Color(139, 0, 139));
-        colorMap.put("darkolivegreen", new Color(85, 107, 47));
-        colorMap.put("darkorange", new Color(255, 140, 0));
-        colorMap.put("darkorchid", new Color(153, 50, 204));
-        colorMap.put("darkred", new Color(139, 0, 0));
-        colorMap.put("darksalmon", new Color(233, 150, 122));
-        colorMap.put("darkseagreen", new Color(143, 188, 143));
-        colorMap.put("darkslateblue", new Color(72, 61, 139));
-        colorMap.put("darkslategray", new Color(47, 79, 79));
-        colorMap.put("darkslategrey", new Color(47, 79, 79));
-        colorMap.put("darkturquoise", new Color(0, 206, 209));
-        colorMap.put("darkviolet", new Color(148, 0, 211));
-        colorMap.put("deeppink", new Color(255, 20, 147));
-        colorMap.put("deepskyblue", new Color(0, 191, 255));
-        colorMap.put("dimgray", new Color(105, 105, 105));
-        colorMap.put("dimgrey", new Color(105, 105, 105));
-        colorMap.put("dodgerblue", new Color(30, 144, 255));
-        colorMap.put("firebrick", new Color(178, 34, 34));
-        colorMap.put("floralwhite", new Color(255, 250, 240));
-        colorMap.put("forestgreen", new Color(34, 139, 34));
-        colorMap.put("fuchsia", new Color(255, 0, 255));
-        colorMap.put("gainsboro", new Color(220, 220, 220));
-        colorMap.put("ghostwhite", new Color(248, 248, 255));
-        colorMap.put("gold", new Color(255, 215, 0));
-        colorMap.put("goldenrod", new Color(218, 165, 32));
-        colorMap.put("gray", new Color(128, 128, 128));
-        colorMap.put("green", new Color(0, 128, 0));
-        colorMap.put("greenyellow", new Color(173, 255, 47));
-        colorMap.put("grey", new Color(128, 128, 128));
-        colorMap.put("honeydew", new Color(240, 255, 240));
-        colorMap.put("hotpink", new Color(255, 105, 180));
-        colorMap.put("indianred", new Color(205, 92, 92));
-        colorMap.put("indigo", new Color(75, 0, 130));
-        colorMap.put("ivory", new Color(255, 255, 240));
-        colorMap.put("khaki", new Color(240, 230, 140));
-        colorMap.put("lavender", new Color(230, 230, 250));
-        colorMap.put("lavenderblush", new Color(255, 240, 245));
-        colorMap.put("lawngreen", new Color(124, 252, 0));
-        colorMap.put("lemonchiffon", new Color(255, 250, 205));
-        colorMap.put("lightblue", new Color(173, 216, 230));
-        colorMap.put("lightcoral", new Color(240, 128, 128));
-        colorMap.put("lightcyan", new Color(224, 255, 255));
-        colorMap.put("lightgoldenrodyellow", new Color(250, 250, 210));
-        colorMap.put("lightgray", new Color(211, 211, 211));
-        colorMap.put("lightgreen", new Color(144, 238, 144));
-        colorMap.put("lightgrey", new Color(211, 211, 211));
-        colorMap.put("lightpink", new Color(255, 182, 193));
-        colorMap.put("lightsalmon", new Color(255, 160, 122));
-        colorMap.put("lightseagreen", new Color(32, 178, 170));
-        colorMap.put("lightskyblue", new Color(135, 206, 250));
-        colorMap.put("lightslategray", new Color(119, 136, 153));
-        colorMap.put("lightslategrey", new Color(119, 136, 153));
-        colorMap.put("lightsteelblue", new Color(176, 196, 222));
-        colorMap.put("lightyellow", new Color(255, 255, 224));
-        colorMap.put("lime", new Color(0, 255, 0));
-        colorMap.put("limegreen", new Color(50, 205, 50));
-        colorMap.put("linen", new Color(250, 240, 230));
-        colorMap.put("magenta", new Color(255, 0, 255));
-        colorMap.put("maroon", new Color(128, 0, 0));
-        colorMap.put("mediumaquamarine", new Color(102, 205, 170));
-        colorMap.put("mediumblue", new Color(0, 0, 205));
-        colorMap.put("mediumorchid", new Color(186, 85, 211));
-        colorMap.put("mediumpurple", new Color(147, 112, 219));
-        colorMap.put("mediumseagreen", new Color(60, 179, 113));
-        colorMap.put("mediumslateblue", new Color(123, 104, 238));
-        colorMap.put("mediumspringgreen", new Color(0, 250, 154));
-        colorMap.put("mediumturquoise", new Color(72, 209, 204));
-        colorMap.put("mediumvioletred", new Color(199, 21, 133));
-        colorMap.put("midnightblue", new Color(25, 25, 112));
-        colorMap.put("mintcream", new Color(245, 255, 250));
-        colorMap.put("mistyrose", new Color(255, 228, 225));
-        colorMap.put("moccasin", new Color(255, 228, 181));
-        colorMap.put("navajowhite", new Color(255, 222, 173));
-        colorMap.put("navy", new Color(0, 0, 128));
-        colorMap.put("oldlace", new Color(253, 245, 230));
-        colorMap.put("olive", new Color(128, 128, 0));
-        colorMap.put("olivedrab", new Color(107, 142, 35));
-        colorMap.put("orange", new Color(255, 165, 0));
-        colorMap.put("orangered", new Color(255, 69, 0));
-        colorMap.put("orchid", new Color(218, 112, 214));
-        colorMap.put("palegoldenrod", new Color(238, 232, 170));
-        colorMap.put("palegreen", new Color(152, 251, 152));
-        colorMap.put("paleturquoise", new Color(175, 238, 238));
-        colorMap.put("palevioletred", new Color(219, 112, 147));
-        colorMap.put("papayawhip", new Color(255, 239, 213));
-        colorMap.put("peachpuff", new Color(255, 218, 185));
-        colorMap.put("peru", new Color(205, 133, 63));
-        colorMap.put("pink", new Color(255, 192, 203));
-        colorMap.put("plum ", new Color(221, 160, 221));
-        colorMap.put("plum", new Color(221, 160, 221));
-        colorMap.put("powderblue", new Color(176, 224, 230));
-        colorMap.put("purple", new Color(128, 0, 128));
-        colorMap.put("red", new Color(255, 0, 0));
-        colorMap.put("rosybrown", new Color(188, 143, 143));
-        colorMap.put("royalblue", new Color(65, 105, 225));
-        colorMap.put("saddlebrown", new Color(139, 69, 19));
-        colorMap.put("salmon", new Color(250, 128, 114));
-        colorMap.put("sandybrown", new Color(244, 164, 96));
-        colorMap.put("seagreen", new Color(46, 139, 87));
-        colorMap.put("seashell", new Color(255, 245, 238));
-        colorMap.put("sienna", new Color(160, 82, 45));
-        colorMap.put("silver", new Color(192, 192, 192));
-        colorMap.put("skyblue", new Color(135, 206, 235));
-        colorMap.put("slateblue", new Color(106, 90, 205));
-        colorMap.put("slategray", new Color(112, 128, 144));
-        colorMap.put("slategrey", new Color(112, 128, 144));
-        colorMap.put("snow", new Color(255, 250, 250));
-        colorMap.put("springgreen", new Color(0, 255, 127));
-        colorMap.put("steelblue", new Color(70, 130, 180));
-        colorMap.put("tan", new Color(210, 180, 140));
-        colorMap.put("teal", new Color(0, 128, 128));
-        colorMap.put("thistle", new Color(216, 191, 216));
-        colorMap.put("tomato", new Color(255, 99, 71));
-        colorMap.put("turquoise", new Color(64, 224, 208));
-        colorMap.put("violet", new Color(238, 130, 238));
-        colorMap.put("wheat", new Color(245, 222, 179));
-        colorMap.put("white", new Color(255, 255, 255));
-        colorMap.put("whitesmoke", new Color(245, 245, 245));
-        colorMap.put("yellow", new Color(255, 255, 0));
-        colorMap.put("yellowgreen", new Color(154, 205, 50));
-        colorMap.put("transparent", new Color(0, 0, 0, 0));
+        colorMap.put("aliceblue", createColor(240, 248, 255));
+        colorMap.put("antiquewhite", createColor(250, 235, 215));
+        colorMap.put("aqua", createColor(0, 255, 255));
+        colorMap.put("aquamarine", createColor(127, 255, 212));
+        colorMap.put("azure", createColor(240, 255, 255));
+        colorMap.put("beige", createColor(245, 245, 220));
+        colorMap.put("bisque", createColor(255, 228, 196));
+        colorMap.put("black", createColor(0, 0, 0));
+        colorMap.put("blanchedalmond", createColor(255, 235, 205));
+        colorMap.put("blue", createColor(0, 0, 255));
+        colorMap.put("blueviolet", createColor(138, 43, 226));
+        colorMap.put("brown", createColor(165, 42, 42));
+        colorMap.put("burlywood", createColor(222, 184, 135));
+        colorMap.put("cadetblue", createColor(95, 158, 160));
+        colorMap.put("chartreuse", createColor(127, 255, 0));
+        colorMap.put("chocolate", createColor(210, 105, 30));
+        colorMap.put("coral", createColor(255, 127, 80));
+        colorMap.put("cornflowerblue", createColor(100, 149, 237));
+        colorMap.put("cornsilk", createColor(255, 248, 220));
+        colorMap.put("crimson", createColor(220, 20, 60));
+        colorMap.put("cyan", createColor(0, 255, 255));
+        colorMap.put("darkblue", createColor(0, 0, 139));
+        colorMap.put("darkcyan", createColor(0, 139, 139));
+        colorMap.put("darkgoldenrod", createColor(184, 134, 11));
+        colorMap.put("darkgray", createColor(169, 169, 169));
+        colorMap.put("darkgreen", createColor(0, 100, 0));
+        colorMap.put("darkgrey", createColor(169, 169, 169));
+        colorMap.put("darkkhaki", createColor(189, 183, 107));
+        colorMap.put("darkmagenta", createColor(139, 0, 139));
+        colorMap.put("darkolivegreen", createColor(85, 107, 47));
+        colorMap.put("darkorange", createColor(255, 140, 0));
+        colorMap.put("darkorchid", createColor(153, 50, 204));
+        colorMap.put("darkred", createColor(139, 0, 0));
+        colorMap.put("darksalmon", createColor(233, 150, 122));
+        colorMap.put("darkseagreen", createColor(143, 188, 143));
+        colorMap.put("darkslateblue", createColor(72, 61, 139));
+        colorMap.put("darkslategray", createColor(47, 79, 79));
+        colorMap.put("darkslategrey", createColor(47, 79, 79));
+        colorMap.put("darkturquoise", createColor(0, 206, 209));
+        colorMap.put("darkviolet", createColor(148, 0, 211));
+        colorMap.put("deeppink", createColor(255, 20, 147));
+        colorMap.put("deepskyblue", createColor(0, 191, 255));
+        colorMap.put("dimgray", createColor(105, 105, 105));
+        colorMap.put("dimgrey", createColor(105, 105, 105));
+        colorMap.put("dodgerblue", createColor(30, 144, 255));
+        colorMap.put("firebrick", createColor(178, 34, 34));
+        colorMap.put("floralwhite", createColor(255, 250, 240));
+        colorMap.put("forestgreen", createColor(34, 139, 34));
+        colorMap.put("fuchsia", createColor(255, 0, 255));
+        colorMap.put("gainsboro", createColor(220, 220, 220));
+        colorMap.put("ghostwhite", createColor(248, 248, 255));
+        colorMap.put("gold", createColor(255, 215, 0));
+        colorMap.put("goldenrod", createColor(218, 165, 32));
+        colorMap.put("gray", createColor(128, 128, 128));
+        colorMap.put("green", createColor(0, 128, 0));
+        colorMap.put("greenyellow", createColor(173, 255, 47));
+        colorMap.put("grey", createColor(128, 128, 128));
+        colorMap.put("honeydew", createColor(240, 255, 240));
+        colorMap.put("hotpink", createColor(255, 105, 180));
+        colorMap.put("indianred", createColor(205, 92, 92));
+        colorMap.put("indigo", createColor(75, 0, 130));
+        colorMap.put("ivory", createColor(255, 255, 240));
+        colorMap.put("khaki", createColor(240, 230, 140));
+        colorMap.put("lavender", createColor(230, 230, 250));
+        colorMap.put("lavenderblush", createColor(255, 240, 245));
+        colorMap.put("lawngreen", createColor(124, 252, 0));
+        colorMap.put("lemonchiffon", createColor(255, 250, 205));
+        colorMap.put("lightblue", createColor(173, 216, 230));
+        colorMap.put("lightcoral", createColor(240, 128, 128));
+        colorMap.put("lightcyan", createColor(224, 255, 255));
+        colorMap.put("lightgoldenrodyellow", createColor(250, 250, 210));
+        colorMap.put("lightgray", createColor(211, 211, 211));
+        colorMap.put("lightgreen", createColor(144, 238, 144));
+        colorMap.put("lightgrey", createColor(211, 211, 211));
+        colorMap.put("lightpink", createColor(255, 182, 193));
+        colorMap.put("lightsalmon", createColor(255, 160, 122));
+        colorMap.put("lightseagreen", createColor(32, 178, 170));
+        colorMap.put("lightskyblue", createColor(135, 206, 250));
+        colorMap.put("lightslategray", createColor(119, 136, 153));
+        colorMap.put("lightslategrey", createColor(119, 136, 153));
+        colorMap.put("lightsteelblue", createColor(176, 196, 222));
+        colorMap.put("lightyellow", createColor(255, 255, 224));
+        colorMap.put("lime", createColor(0, 255, 0));
+        colorMap.put("limegreen", createColor(50, 205, 50));
+        colorMap.put("linen", createColor(250, 240, 230));
+        colorMap.put("magenta", createColor(255, 0, 255));
+        colorMap.put("maroon", createColor(128, 0, 0));
+        colorMap.put("mediumaquamarine", createColor(102, 205, 170));
+        colorMap.put("mediumblue", createColor(0, 0, 205));
+        colorMap.put("mediumorchid", createColor(186, 85, 211));
+        colorMap.put("mediumpurple", createColor(147, 112, 219));
+        colorMap.put("mediumseagreen", createColor(60, 179, 113));
+        colorMap.put("mediumslateblue", createColor(123, 104, 238));
+        colorMap.put("mediumspringgreen", createColor(0, 250, 154));
+        colorMap.put("mediumturquoise", createColor(72, 209, 204));
+        colorMap.put("mediumvioletred", createColor(199, 21, 133));
+        colorMap.put("midnightblue", createColor(25, 25, 112));
+        colorMap.put("mintcream", createColor(245, 255, 250));
+        colorMap.put("mistyrose", createColor(255, 228, 225));
+        colorMap.put("moccasin", createColor(255, 228, 181));
+        colorMap.put("navajowhite", createColor(255, 222, 173));
+        colorMap.put("navy", createColor(0, 0, 128));
+        colorMap.put("oldlace", createColor(253, 245, 230));
+        colorMap.put("olive", createColor(128, 128, 0));
+        colorMap.put("olivedrab", createColor(107, 142, 35));
+        colorMap.put("orange", createColor(255, 165, 0));
+        colorMap.put("orangered", createColor(255, 69, 0));
+        colorMap.put("orchid", createColor(218, 112, 214));
+        colorMap.put("palegoldenrod", createColor(238, 232, 170));
+        colorMap.put("palegreen", createColor(152, 251, 152));
+        colorMap.put("paleturquoise", createColor(175, 238, 238));
+        colorMap.put("palevioletred", createColor(219, 112, 147));
+        colorMap.put("papayawhip", createColor(255, 239, 213));
+        colorMap.put("peachpuff", createColor(255, 218, 185));
+        colorMap.put("peru", createColor(205, 133, 63));
+        colorMap.put("pink", createColor(255, 192, 203));
+        colorMap.put("plum ", createColor(221, 160, 221));
+        colorMap.put("plum", createColor(221, 160, 221));
+        colorMap.put("powderblue", createColor(176, 224, 230));
+        colorMap.put("purple", createColor(128, 0, 128));
+        colorMap.put("red", createColor(255, 0, 0));
+        colorMap.put("rosybrown", createColor(188, 143, 143));
+        colorMap.put("royalblue", createColor(65, 105, 225));
+        colorMap.put("saddlebrown", createColor(139, 69, 19));
+        colorMap.put("salmon", createColor(250, 128, 114));
+        colorMap.put("sandybrown", createColor(244, 164, 96));
+        colorMap.put("seagreen", createColor(46, 139, 87));
+        colorMap.put("seashell", createColor(255, 245, 238));
+        colorMap.put("sienna", createColor(160, 82, 45));
+        colorMap.put("silver", createColor(192, 192, 192));
+        colorMap.put("skyblue", createColor(135, 206, 235));
+        colorMap.put("slateblue", createColor(106, 90, 205));
+        colorMap.put("slategray", createColor(112, 128, 144));
+        colorMap.put("slategrey", createColor(112, 128, 144));
+        colorMap.put("snow", createColor(255, 250, 250));
+        colorMap.put("springgreen", createColor(0, 255, 127));
+        colorMap.put("steelblue", createColor(70, 130, 180));
+        colorMap.put("tan", createColor(210, 180, 140));
+        colorMap.put("teal", createColor(0, 128, 128));
+        colorMap.put("thistle", createColor(216, 191, 216));
+        colorMap.put("tomato", createColor(255, 99, 71));
+        colorMap.put("turquoise", createColor(64, 224, 208));
+        colorMap.put("violet", createColor(238, 130, 238));
+        colorMap.put("wheat", createColor(245, 222, 179));
+        colorMap.put("white", createColor(255, 255, 255));
+        colorMap.put("whitesmoke", createColor(245, 245, 245));
+        colorMap.put("yellow", createColor(255, 255, 0));
+        colorMap.put("yellowgreen", createColor(154, 205, 50));
+        colorMap.put("transparent", new ColorWithAlternatives(0, 0, 0, 0, null));
     }
 
     /**
@@ -691,7 +959,8 @@ public final class ColorUtil {
      * @return true if the color profile name is of a built-in pseudo-profile
      */
     public static boolean isPseudoProfile(String colorProfileName) {
-        return CMYK_PSEUDO_PROFILE.equalsIgnoreCase(colorProfileName);
+        return CMYK_PSEUDO_PROFILE.equalsIgnoreCase(colorProfileName)
+                || SEPARATION_PSEUDO_PROFILE.equalsIgnoreCase(colorProfileName);
     }
 
     /**
@@ -709,11 +978,6 @@ public final class ColorUtil {
      * @return the CMYK color
      */
     public static Color toCMYKGrayColor(float black) {
-        float[] cmyk = new float[] {0f, 0f, 0f, 1.0f - black};
-        DeviceCMYKColorSpace cmykCs = DeviceCMYKColorSpace.getInstance();
-        float[] rgb = cmykCs.toRGB(cmyk);
-        return ColorExt.createFromFoRgbIcc(rgb[0], rgb[1], rgb[2],
-                CMYK_PSEUDO_PROFILE, null, cmykCs, cmyk);
+        return org.apache.xmlgraphics.java2d.color.ColorUtil.toCMYKGrayColor(black);
     }
-
 }

Modified: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/DefaultErrorListener.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/DefaultErrorListener.java?rev=1309921&r1=1309920&r2=1309921&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/DefaultErrorListener.java (original)
+++ xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/DefaultErrorListener.java Thu Apr  5 16:19:19 2012
@@ -62,4 +62,4 @@ public class DefaultErrorListener implem
         throw exc;
     }
 
-}
\ No newline at end of file
+}

Modified: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/ListUtil.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/ListUtil.java?rev=1309921&r1=1309920&r2=1309921&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/ListUtil.java (original)
+++ xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/ListUtil.java Thu Apr  5 16:19:19 2012
@@ -34,22 +34,22 @@ public final class ListUtil {
     /**
      * Retrieve the last element from a list.
      *
-     * @param list
-     *            The list to work on
+     * @param <T> the type of objects stored in the list
+     * @param list  the list to work on
      * @return last element
      */
-    public static Object getLast(List list) {
+    public static <T> T getLast(List<T> list) {
         return list.get(list.size() - 1);
     }
 
     /**
      * Retrieve and remove the last element from a list.
      *
-     * @param list
-     *            The list to work on
+     * @param <T> the type of objects stored in the list
+     * @param list  the list to work on
      * @return previous last element
      */
-    public static Object removeLast(List list) {
+    public static <T> T removeLast(List<T> list) {
         return list.remove(list.size() - 1);
     }
 }

Modified: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/LogUtil.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/LogUtil.java?rev=1309921&r1=1309920&r2=1309921&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/LogUtil.java (original)
+++ xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/LogUtil.java Thu Apr  5 16:19:19 2012
@@ -20,6 +20,7 @@
 package org.apache.fop.util;
 
 import org.apache.commons.logging.Log;
+
 import org.apache.fop.apps.FOPException;
 
 /**

Modified: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/XMLResourceBundle.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/XMLResourceBundle.java?rev=1309921&r1=1309920&r2=1309921&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/XMLResourceBundle.java (original)
+++ xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/XMLResourceBundle.java Thu Apr  5 16:19:19 2012
@@ -227,7 +227,9 @@ public class XMLResourceBundle extends R
     }
 
     private void setLocale(String name) {
-        String language = "", country = "", variant = "";
+        String language = "";
+        String country = "";
+        String variant = "";
         if (name.length() > 1) {
             int nextIndex = name.indexOf('_', 1);
             if (nextIndex == -1) {

Modified: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/XMLUtil.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/XMLUtil.java?rev=1309921&r1=1309920&r2=1309921&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/XMLUtil.java (original)
+++ xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/XMLUtil.java Thu Apr  5 16:19:19 2012
@@ -21,7 +21,6 @@ package org.apache.fop.util;
 
 import java.awt.Rectangle;
 import java.awt.geom.Rectangle2D;
-import java.util.Locale;
 
 import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
@@ -175,37 +174,125 @@ public final class XMLUtil implements XM
     }
 
     /**
-     * Converts a {@link Locale} instance to an RFC 3066 compliant language identifier.
-     * @param language the language
-     * @return the formatted language identifier
+     * Encode a glyph position adjustments array as a string, where the string value
+     * adheres to the following syntax:
+     *
+     * count ( 'Z' repeat | number )
+     *
+     * where each token is separated by whitespace, except that 'Z' followed by repeat
+     * are considered to be a single token with no intervening whitespace, and where
+     * 'Z' repeat encodes repeated zeroes.
+     * @param dp the adjustments array
+     * @param paCount the number of entries to encode from adjustments array
+     * @return the encoded value
      */
-    public static String toRFC3066(Locale language) {
-        if (language == null || language.getLanguage().length() == 0) {
-            return null;
-        }
+    public static String encodePositionAdjustments ( int[][] dp, int paCount ) {
+        assert dp != null;
         StringBuffer sb = new StringBuffer();
-        sb.append(language.getLanguage());
-        if (language.getCountry().length() > 0) {
-            sb.append('-');
-            sb.append(language.getCountry());
+        int na = paCount;
+        int nz = 0;
+        sb.append ( na );
+        for ( int i = 0; i < na; i++ ) {
+            int[] pa = dp [ i ];
+            for ( int k = 0; k < 4; k++ ) {
+                int a = pa [ k ];
+                if ( a != 0 ) {
+                    encodeNextAdjustment ( sb, nz, a );
+                    nz = 0;
+                } else {
+                    nz++;
+                }
+            }
         }
+        encodeNextAdjustment ( sb, nz, 0 );
         return sb.toString();
     }
 
     /**
-     * Converts an RFC 3066 compliant language identifier to a {@link Locale} instance.
-     * @param lang the language string
-     * @return the converted locale instance
+     * Encode a glyph position adjustments array as a string, where the string value
+     * adheres to the following syntax:
+     *
+     * count ( 'Z' repeat | number )
+     *
+     * where each token is separated by whitespace, except that 'Z' followed by repeat
+     * are considered to be a single token with no intervening whitespace.
+     * @param dp the adjustments array
+     * @return the encoded value
+     */
+    public static String encodePositionAdjustments ( int[][] dp ) {
+        assert dp != null;
+        return encodePositionAdjustments ( dp, dp.length );
+    }
+
+    private static void encodeNextAdjustment ( StringBuffer sb, int nz, int a ) {
+        encodeZeroes ( sb, nz );
+        encodeAdjustment ( sb, a );
+    }
+
+    private static void encodeZeroes ( StringBuffer sb, int nz ) {
+        if ( nz > 0 ) {
+            sb.append ( ' ' );
+            if ( nz == 1 ) {
+                sb.append ( '0' );
+            } else {
+                sb.append ( 'Z' );
+                sb.append ( nz );
+            }
+        }
+    }
+
+    private static void encodeAdjustment ( StringBuffer sb, int a ) {
+        if ( a != 0 ) {
+            sb.append ( ' ' );
+            sb.append ( a );
+        }
+    }
+
+    /**
+     * Decode a string as a glyph position adjustments array, where the string
+     * shall adhere to the syntax specified by {@link #encodePositionAdjustments}.
+     * @param value the encoded value
+     * @return the position adjustments array
+     */
+    public static int[][] decodePositionAdjustments ( String value ) {
+        int[][] dp = null;
+        if ( value != null ) {
+            String[] sa = value.split ( "\\s" );
+            if ( sa != null ) {
+                if ( sa.length > 0 ) {
+                    int na = Integer.parseInt ( sa[0] );
+                    dp = new int [ na ] [ 4 ];
+                    for ( int i = 1, n = sa.length, k = 0; i < n; i++ ) {
+                        String s = sa [ i ];
+                        if ( s.charAt(0) == 'Z' ) {
+                            int nz = Integer.parseInt ( s.substring ( 1 ) );
+                            k += nz;
+                        } else {
+                            dp [ k / 4 ] [ k % 4 ] = Integer.parseInt ( s );
+                            k += 1;
+                        }
+                    }
+                }
+            }
+        }
+        return dp;
+    }
+
+    /**
+     * Returns an attribute value as a glyph position adjustments array. The string value
+     * is expected to be a non-empty sequence of either Z<repeat> or <number>, where the
+     * former encodes a repeat count (of zeroes) and the latter encodes a integer number,
+     * and where each item is separated by whitespace.
+     * @param attributes the Attributes object
+     * @param name the name of the attribute
+     * @return the position adjustments array
      */
-    public static Locale convertRFC3066ToLocale(String lang) {
-        if (lang == null || lang.length() == 0) {
+    public static int[][] getAttributeAsPositionAdjustments(Attributes attributes, String name) {
+        String s = attributes.getValue(name);
+        if (s == null) {
             return null;
-        }
-        String[] parts = lang.split("-");
-        if (parts.length == 1) {
-            return new Locale(parts[0]);
         } else {
-            return new Locale(parts[0], parts[1]);
+            return decodePositionAdjustments(s.trim());
         }
     }
 

Modified: xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/bitmap/BitmapImageUtil.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/bitmap/BitmapImageUtil.java?rev=1309921&r1=1309920&r2=1309921&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/bitmap/BitmapImageUtil.java (original)
+++ xmlgraphics/fop/branches/Temp_TrueTypeInPostScript/src/java/org/apache/fop/util/bitmap/BitmapImageUtil.java Thu Apr  5 16:19:19 2012
@@ -213,7 +213,9 @@ public final class BitmapImageUtil {
             WritableRaster wr = img.getColorModel().createCompatibleWritableRaster(
                     img.getWidth(), img.getHeight());
             boolean premult = img.getColorModel().isAlphaPremultiplied();
-            return new BufferedImage(img.getColorModel(), wr, premult, null);
+            BufferedImage buf = new BufferedImage(img.getColorModel(), wr, premult, null);
+            transferImage(img, buf);
+            return buf;
         }
     }
 



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