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 ad...@apache.org on 2007/09/22 00:51:25 UTC

svn commit: r578311 - in /xmlgraphics/fop/trunk: ./ src/java/org/apache/fop/fo/ src/java/org/apache/fop/fo/expr/ src/java/org/apache/fop/fo/properties/ src/java/org/apache/fop/fonts/ src/java/org/apache/fop/layoutmgr/ src/java/org/apache/fop/layoutmgr/...

Author: adelmelle
Date: Fri Sep 21 15:51:22 2007
New Revision: 578311

URL: http://svn.apache.org/viewvc?rev=578311&view=rev
Log:
PropertyCache phase 2:
        * improvement of the PropertyCache itself should guarantee acceptable
          performance of the static caches in multi-session environments, which is 
          a possible problem with synchronizedMap
        * changed CommonFont to use the cache: 
          added CachedCommonFont to contain the properties that are always cacheable
          CommonFont itself is only cached if the remaining properties are absolutes
        * changed CommonHyphenation, KeepProperty, ColorProperty and FontFamilyProperty
          to use the cache

Facilitate the implementation for font-selection-strategy:
        * Changed FontInfo.fontLookup to always return an array of FontTriplet
        * Changed CommonFont.getFontState to return an array of FontTriplet
        * Initial modifications to the related LMs: initialized with
          the font corresponding to the first of the triplets

This line, and those below, will be ignored--

M    src/java/org/apache/fop/render/rtf/TextAttributesConverter.java
M    src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
M    src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java
M    src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLayoutManager.java
M    src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
M    src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java
M    src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
M    src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java
M    src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java
M    src/java/org/apache/fop/fonts/FontInfo.java
M    src/java/org/apache/fop/fo/properties/CommonHyphenation.java
M    src/java/org/apache/fop/fo/properties/CommonAccessibility.java
M    src/java/org/apache/fop/fo/properties/CompoundPropertyMaker.java
M    src/java/org/apache/fop/fo/properties/FontFamilyProperty.java
M    src/java/org/apache/fop/fo/properties/FixedLength.java
M    src/java/org/apache/fop/fo/properties/PropertyCache.java
M    src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java
M    src/java/org/apache/fop/fo/properties/CommonFont.java
M    src/java/org/apache/fop/fo/properties/ColorProperty.java
M    src/java/org/apache/fop/fo/properties/KeepProperty.java
M    src/java/org/apache/fop/fo/PropertyList.java
M    src/java/org/apache/fop/fo/FOPropertyMapping.java
M    src/java/org/apache/fop/fo/expr/PropertyParser.java
M    src/java/org/apache/fop/fo/expr/ICCColorFunction.java
M    src/java/org/apache/fop/fo/expr/CMYKcolorFunction.java
M    src/java/org/apache/fop/fo/expr/RGBColorFunction.java
M    src/java/org/apache/fop/fo/expr/SystemColorFunction.java
M    status.xml

Modified:
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOPropertyMapping.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/PropertyList.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/CMYKcolorFunction.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/ICCColorFunction.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/PropertyParser.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/RGBColorFunction.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/SystemColorFunction.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/ColorProperty.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonAccessibility.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonFont.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonHyphenation.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CompoundPropertyMaker.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/FixedLength.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/FontFamilyProperty.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/KeepProperty.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/PropertyCache.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontInfo.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLayoutManager.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/TextAttributesConverter.java
    xmlgraphics/fop/trunk/status.xml

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOPropertyMapping.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOPropertyMapping.java?rev=578311&r1=578310&r2=578311&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOPropertyMapping.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOPropertyMapping.java Fri Sep 21 15:51:22 2007
@@ -568,7 +568,7 @@
                 if (nameval != null) {
                     FObj fobj = (fo == null ? propertyList.getFObj() : fo);
                     FOUserAgent ua = (fobj == null ? null : fobj.getUserAgent());
-                    return new ColorProperty(ua, nameval);
+                    return ColorProperty.getInstance(ua, nameval);
                 }
                 return super.convertPropertyDatatype(p, propertyList, fo);
             }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/PropertyList.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/PropertyList.java?rev=578311&r1=578310&r2=578311&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 Sep 21 15:51:22 2007
@@ -577,7 +577,7 @@
      */
     public CommonBorderPaddingBackground getBorderPaddingBackgroundProps() 
                 throws PropertyException {
-        return new CommonBorderPaddingBackground(this, fobj);
+        return new CommonBorderPaddingBackground(this);
     }
     
     /**
@@ -586,7 +586,7 @@
      * @throws PropertyException if there's a problem while processing the properties
      */
     public CommonHyphenation getHyphenationProps() throws PropertyException {
-        return new CommonHyphenation(this);
+        return CommonHyphenation.getInstance(this);
     }
     
     /**
@@ -652,7 +652,7 @@
      * @throws PropertyException if there's a problem while processing the properties
      */
     public CommonFont getFontProps() throws PropertyException {
-        return CommonFont(this);
+        return CommonFont.getInstance(this);
     }
     
     /**

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/CMYKcolorFunction.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/CMYKcolorFunction.java?rev=578311&r1=578310&r2=578311&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/CMYKcolorFunction.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/CMYKcolorFunction.java Fri Sep 21 15:51:22 2007
@@ -43,7 +43,7 @@
         FOUserAgent ua = (pInfo == null) 
                 ? null 
                 : (pInfo.getFO() == null ? null : pInfo.getFO().getUserAgent());
-        return new ColorProperty(ua, sb.toString());
+        return ColorProperty.getInstance(ua, sb.toString());
     }
 
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/ICCColorFunction.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/ICCColorFunction.java?rev=578311&r1=578310&r2=578311&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/ICCColorFunction.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/ICCColorFunction.java Fri Sep 21 15:51:22 2007
@@ -70,7 +70,7 @@
         FOUserAgent ua = (pInfo == null
                 ? null
                 : (pInfo.getFO() == null ? null : pInfo.getFO().getUserAgent()));
-        return new ColorProperty(ua, sb.toString());
+        return ColorProperty.getInstance(ua, sb.toString());
     }
 
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/PropertyParser.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/PropertyParser.java?rev=578311&r1=578310&r2=578311&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/PropertyParser.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/PropertyParser.java Fri Sep 21 15:51:22 2007
@@ -302,7 +302,7 @@
             FOUserAgent ua = (propInfo == null) 
                 ? null
                 : (propInfo.getFO() == null ? null : propInfo.getFO().getUserAgent());
-            prop = new ColorProperty(ua, currentTokenValue);
+            prop = ColorProperty.getInstance(ua, currentTokenValue);
             break;
 
         case TOK_FUNCTION_LPAR:

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/RGBColorFunction.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/RGBColorFunction.java?rev=578311&r1=578310&r2=578311&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/RGBColorFunction.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/RGBColorFunction.java Fri Sep 21 15:51:22 2007
@@ -50,7 +50,7 @@
       FOUserAgent ua = (pInfo == null) 
               ? null 
               : (pInfo.getFO() == null ? null : pInfo.getFO().getUserAgent());
-      return new ColorProperty(ua, "rgb(" + args[0] + "," + args[1] + "," + args[2] + ")");
+      return ColorProperty.getInstance(ua, "rgb(" + args[0] + "," + args[1] + "," + args[2] + ")");
 
     }
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/SystemColorFunction.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/SystemColorFunction.java?rev=578311&r1=578310&r2=578311&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/SystemColorFunction.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/expr/SystemColorFunction.java Fri Sep 21 15:51:22 2007
@@ -39,7 +39,7 @@
         FOUserAgent ua = (pInfo == null) 
                 ? null 
                 : (pInfo.getFO() == null ? null : pInfo.getFO().getUserAgent());
-        return new ColorProperty(ua, "system-color(" + args[0] + ")");
+        return ColorProperty.getInstance(ua, "system-color(" + args[0] + ")");
 
     }
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/ColorProperty.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/ColorProperty.java?rev=578311&r1=578310&r2=578311&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/ColorProperty.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/ColorProperty.java Fri Sep 21 15:51:22 2007
@@ -28,9 +28,12 @@
 import org.apache.fop.util.ColorUtil;
 
 /**
- * Superclass for properties that wrap Color values
+ * Class for properties that wrap Color values
  */
-public class ColorProperty extends Property  {
+public final class ColorProperty extends Property  {
+    
+    /** cache holding canonical ColorProperty instances */
+    private static final PropertyCache cache = new PropertyCache();
     
     /**
      * The color represented by this property.
@@ -92,16 +95,28 @@
      * @throws PropertyException if the value can't be parsed
      * @see ColorUtil#parseColorString(FOUserAgent, String)
      */
-    public ColorProperty(FOUserAgent foUserAgent, String value) throws PropertyException {
-        this.color = ColorUtil.parseColorString(foUserAgent, value);
+    public static ColorProperty getInstance(FOUserAgent foUserAgent, String value) throws PropertyException {
+        ColorProperty instance = new ColorProperty(
+                                       ColorUtil.parseColorString(
+                                               foUserAgent, value));
+        return (ColorProperty) cache.fetch(instance);
     }
 
     /**
+     * 
+     * @param value
+     * @return
+     */
+    public static ColorProperty getInstance(Color value) {
+        return (ColorProperty) cache.fetch(new ColorProperty(value));
+    }
+    
+    /**
      * Create a new ColorProperty with a given color.
      * 
      * @param value the color to use.
      */
-    public ColorProperty(Color value) {
+    private ColorProperty(Color value) {
         this.color = value;
     }
     
@@ -114,9 +129,7 @@
         return color;
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public String toString() {
         return ColorUtil.colorToString(color);
     }
@@ -134,6 +147,23 @@
      */
     public Object getObject() {
         return this;
+    }
+    
+    /** {@inheritDoc} */
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        
+        if (o instanceof ColorProperty) {
+            return ((ColorProperty) o).color.equals(this.color);
+        }
+        return false;
+    }
+    
+    /** {@inheritDoc} */
+    public int hashCode() {
+        return this.color.hashCode();
     }
 }
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonAccessibility.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonAccessibility.java?rev=578311&r1=578310&r2=578311&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonAccessibility.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonAccessibility.java Fri Sep 21 15:51:22 2007
@@ -40,7 +40,7 @@
     public String role = null;
 
     /**
-     * Create a CommonAbsolutePosition object.
+     * Create a <code>CommonAccessibility</code> object.
      * @param pList The PropertyList with propery values.
      */
     public CommonAccessibility(PropertyList pList) throws PropertyException {

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java?rev=578311&r1=578310&r2=578311&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java Fri Sep 21 15:51:22 2007
@@ -137,15 +137,16 @@
     
     /**
      * Construct a CommonBorderPaddingBackground object.
+     * 
      * @param pList The PropertyList to get properties from.
      * @param fobj The FO to create this instance for.
      * @throws PropertyException if there's an error while binding the properties
      */
-    public CommonBorderPaddingBackground(PropertyList pList, FObj fobj) throws PropertyException {
+    public CommonBorderPaddingBackground(PropertyList pList) throws PropertyException {
         
         backgroundAttachment = pList.get(Constants.PR_BACKGROUND_ATTACHMENT).getEnum();
         backgroundColor = pList.get(Constants.PR_BACKGROUND_COLOR).getColor(
-                fobj == null ? null : fobj.getUserAgent());
+                                        pList.getFObj().getUserAgent());
         if (backgroundColor.getAlpha() == 0) {
             backgroundColor = null;
         }
@@ -162,7 +163,7 @@
             
             //Additional processing: preload image
             String url = ImageFactory.getURL(backgroundImage);
-            FOUserAgent userAgent = fobj.getUserAgent();
+            FOUserAgent userAgent = pList.getFObj().getUserAgent();
             ImageFactory fact = userAgent.getFactory().getImageFactory();
             fopimage = fact.getImage(url, userAgent);
             if (fopimage == null) {
@@ -207,9 +208,7 @@
         // If style = none, force width to 0, don't get Color (spec 7.7.20)
         int style = pList.get(styleProp).getEnum();
         if (style != Constants.EN_NONE) {
-            FOUserAgent ua = (pList == null) 
-                    ? null 
-                    : (pList.getFObj() == null ? null : pList.getFObj().getUserAgent());
+            FOUserAgent ua = pList.getFObj().getUserAgent();
             setBorderInfo(new BorderInfo(style,
                 pList.get(widthProp).getCondLength(),
                 pList.get(colorProp).getColor(ua)), side);

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonFont.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonFont.java?rev=578311&r1=578310&r2=578311&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonFont.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonFont.java Fri Sep 21 15:51:22 2007
@@ -24,140 +24,329 @@
 
 import org.apache.fop.datatypes.Length;
 import org.apache.fop.datatypes.Numeric;
-import org.apache.fop.datatypes.PercentBaseContext;
 import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.PropertyList;
 import org.apache.fop.fo.expr.PropertyException;
-import org.apache.fop.fonts.Font;
 import org.apache.fop.fonts.FontInfo;
 import org.apache.fop.fonts.FontTriplet;
 
 /**
- * Collection of properties used in
+ * Collection of CommonFont properties
  */
-public class CommonFont {
+public final class CommonFont {
 
+    /** cache holding canonical CommonFont instances (only those with
+     *  absolute font-size and font-size-adjust) */
+    private static final PropertyCache cache = new PropertyCache();
+    
     /**
-     * The "font-family" property.
+     * Class holding canonical instances of bundles of the
+     * cacheable (non-relative) CommonFont properties
+     *
      */
-    private String[] fontFamily;
+    protected static final class CachedCommonFont {
+        
+        /** cache holding all canonical instances */
+        private static final PropertyCache cache = new PropertyCache();
+        
+        private int hash = 0;
+        
+        /**
+         * The "font-family" property.
+         */
+        private final FontFamilyProperty fontFamily;
+    
+        /**
+         * The "font-selection-strategy" property.
+         */
+        private final EnumProperty fontSelectionStrategy;
+    
+        /**
+         * The "font-stretch" property.
+         */
+        private final EnumProperty fontStretch;
+
+        /**
+         * The "font-style" property.
+         */
+        private final EnumProperty fontStyle;
+
+        /**
+         * The "font-variant" property.
+         */
+        private final EnumProperty fontVariant;
+
+        /**
+         * The "font-weight" property.
+         */
+        private final EnumProperty fontWeight;
+        
+        /**
+         * Constructor
+         * 
+         * @param fontFamily    the font-family property
+         * @param fontSelectionStrategy the font-selection-strategy property
+         * @param fontStretch   the font-stretch property
+         * @param fontStyle     the font-style property
+         * @param fontVariant   the font-variant property
+         * @param fontWeight    the font-weight property
+         */
+        private CachedCommonFont(FontFamilyProperty fontFamily,
+                         EnumProperty fontSelectionStrategy,
+                         EnumProperty fontStretch,
+                         EnumProperty fontStyle,
+                         EnumProperty fontVariant,
+                         EnumProperty fontWeight) {
+            this.fontFamily = fontFamily;
+            this.fontSelectionStrategy = fontSelectionStrategy;
+            this.fontStretch = fontStretch;
+            this.fontStyle = fontStyle;
+            this.fontVariant = fontVariant;
+            this.fontWeight = fontWeight;
+        }
+        
+        /**
+         * Returns the canonical instance corresponding to the given
+         * properties
+         * 
+         * @param fontFamily    the font-family property
+         * @param fontSelectionStrategy the font-selection-strategy property
+         * @param fontStretch   the font-stretch property
+         * @param fontStyle     the font-style property
+         * @param fontVariant   the font-variant property
+         * @param fontWeight    the font-weight property
+         * @return  the canonical instance
+         */
+        private static final CachedCommonFont getInstance(FontFamilyProperty fontFamily,
+                           EnumProperty fontSelectionStrategy,
+                           EnumProperty fontStretch,
+                           EnumProperty fontStyle,
+                           EnumProperty fontVariant,
+                           EnumProperty fontWeight) {
+            return cache.fetch(new CachedCommonFont(
+                                    fontFamily,
+                                    fontSelectionStrategy,
+                                    fontStretch,
+                                    fontStyle,
+                                    fontVariant,
+                                    fontWeight));
+        }
+        
+        /** @return the first font-family name in the list */
+        private String getFirstFontFamily() {
+            return ((Property) fontFamily.list.get(0)).getString();
+        }
+        
+        /** @return an array with the font-family names */
+        private String[] getFontFamily() {
+            List lst = fontFamily.getList();
+            String[] fontFamily = new String[lst.size()];
+            for (int i = 0, c = lst.size(); i < c; i++) {
+                fontFamily[i] = ((Property)lst.get(i)).getString();
+            }
+            return fontFamily;
+        }
+        
+        /** {@inheritDoc} */
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            
+            if (o instanceof CachedCommonFont) {
+                CachedCommonFont ccf = (CachedCommonFont) o;
+                return (ccf.fontFamily == this.fontFamily)
+                    && (ccf.fontSelectionStrategy == this.fontSelectionStrategy)
+                    && (ccf.fontStretch == this.fontStretch)
+                    && (ccf.fontStyle == this.fontStyle)
+                    && (ccf.fontVariant == this.fontVariant)
+                    && (ccf.fontWeight == this.fontWeight);
+            }
+            return false;
+        }
+        
+        /** {@inheritDoc} */
+        public int hashCode() {
+            if (this.hash == 0) {
+                int hash = 17;
+                hash = 37 * hash + (fontFamily == null ? 0 : fontFamily.hashCode());
+                hash = 37 * hash + (fontSelectionStrategy == null ? 0 : fontSelectionStrategy.hashCode());
+                hash = 37 * hash + (fontStretch == null ? 0 : fontStretch.hashCode());
+                hash = 37 * hash + (fontStyle == null ? 0 : fontStyle.hashCode());
+                hash = 37 * hash + (fontVariant == null ? 0 : fontVariant.hashCode());
+                hash = 37 * hash + (fontStretch == null ? 0 : fontStretch.hashCode());
+                this.hash = hash;
+            }
+            return this.hash;
+        }
+        
+    }
 
     /**
-     * The "font-selection-strategy" property.
+     * The cached CommonFont properties (access these through the getters)
+     * The remaining properties, font-size and font-size-adjust,
+     * will only be cached values if they are absolute.
      */
-    public int fontSelectionStrategy;
-
+    private final CachedCommonFont cachedCommonFont;
+    
     /**
      * The "font-size" property.
      */
-    public Length fontSize;
-
-    /**
-     * The "font-stretch" property.
-     */
-    public int fontStretch;
+    public final Length fontSize;
 
     /**
      * The "font-size-adjust" property.
      */
-    public Numeric fontSizeAdjust;
-
-    /**
-     * The "font-style" property.
-     */
-    public int fontStyle;
-
-    /**
-     * The "font-variant" property.
-     */
-    public int fontVariant;
+    public final Numeric fontSizeAdjust;
 
     /**
-     * The "font-weight" property.
+     * Construct a CommonFont instance
+     * 
+     * @param ccf       the cached CommonFont properties
+     * @param fontSize  the font-size (possibly non-cached)
+     * @param fontSizeAdjust    the font-size-adjust (possibly non-cached)
      */
-    public int fontWeight;
-
-    private Font fontState;
+    private CommonFont(CachedCommonFont ccf, 
+                       Length fontSize, 
+                       Numeric fontSizeAdjust) {
+        this.cachedCommonFont = ccf;
+        this.fontSize = fontSize;
+        this.fontSizeAdjust = fontSizeAdjust;
+    }
 
     /**
-     * Create a CommonFont object.
-     * @param pList The PropertyList to get properties from.
+     * Returns a CommonFont instance for the given PropertyList
+     * If the font-size and font-size-adjust properties are absolute
+     * the entire instance will be cached.
+     * If not, then a distinct instance will be returned, with
+     * as much cached information as possible.
+     * 
+     * @param pList the PropertyList to get the properties from
+     * @return  a CommonFont instance corresponding to the properties
+     * @throws PropertyException    if there was a problem getting the properties
      */
-    public CommonFont(PropertyList pList) throws PropertyException {
-        List lst = pList.get(Constants.PR_FONT_FAMILY).getList();
-        fontFamily = new String[lst.size()];
-        for (int i = 0, c = lst.size(); i < c; i++) {
-            fontFamily[i] = ((Property)lst.get(i)).getString();
-        }
-        if (fontFamily.length == 0) {
-            //Shouldn't happen, but we never know.
-            fontFamily = new String[] {"any"};
+    public static CommonFont getInstance(PropertyList pList) throws PropertyException {
+        FontFamilyProperty fontFamily = (FontFamilyProperty) pList.get(Constants.PR_FONT_FAMILY);
+        EnumProperty fontSelectionStrategy = (EnumProperty) pList.get(Constants.PR_FONT_SELECTION_STRATEGY);
+        EnumProperty fontStretch = (EnumProperty) pList.get(Constants.PR_FONT_STRETCH);
+        EnumProperty fontStyle = (EnumProperty) pList.get(Constants.PR_FONT_STYLE);
+        EnumProperty fontVariant = (EnumProperty) pList.get(Constants.PR_FONT_VARIANT);
+        EnumProperty fontWeight = (EnumProperty) pList.get(Constants.PR_FONT_WEIGHT);
+        CachedCommonFont cachedCommonFont = CachedCommonFont.getInstance(
+                                                fontFamily, 
+                                                fontSelectionStrategy, 
+                                                fontStretch, 
+                                                fontStyle, 
+                                                fontVariant, 
+                                                fontWeight);
+        
+        Numeric fontSizeAdjust = pList.get(Constants.PR_FONT_SIZE_ADJUST).getNumeric();
+        Length fontSize = pList.get(Constants.PR_FONT_SIZE).getLength();
+        CommonFont cf = new CommonFont(cachedCommonFont, fontSize, fontSizeAdjust);
+        if (fontSize.isAbsolute() && fontSizeAdjust.isAbsolute()) {
+            return cache.fetch(cf);
+        } else {
+            return cf;
         }
-        fontSelectionStrategy = pList.get(Constants.PR_FONT_SELECTION_STRATEGY).getEnum();
-        fontSize = pList.get(Constants.PR_FONT_SIZE).getLength();
-        fontStretch = pList.get(Constants.PR_FONT_STRETCH).getEnum();
-        fontSizeAdjust = pList.get(Constants.PR_FONT_SIZE_ADJUST).getNumeric();
-        fontStyle = pList.get(Constants.PR_FONT_STYLE).getEnum();
-        fontVariant = pList.get(Constants.PR_FONT_VARIANT).getEnum();
-        fontWeight = pList.get(Constants.PR_FONT_WEIGHT).getEnum();
+        
     }
-
+    
     /** @return the first font-family name in the list */
     public String getFirstFontFamily() {
-        return this.fontFamily[0];
+        return cachedCommonFont.getFirstFontFamily();
+    }
+    
+    /** @return the "font-selection-strategy" property */
+    public int getFontSelectionStrategy() {
+        return cachedCommonFont.fontSelectionStrategy.getEnum();
+    }
+
+    /** @return the "font-stretch" property */
+    public int getFontStretch() {
+        return cachedCommonFont.fontStretch.getEnum();
     }
     
-    /** @return the font-family names */
-    public String[] getFontFamily() {
-        return this.fontFamily;
+    /** @return the "font-style" property */
+    public int getFontStyle() {
+        return cachedCommonFont.fontStyle.getEnum();
+    }
+    
+    /** @return the "font-variant" property */
+    public int getFontVariant() {
+        return cachedCommonFont.fontVariant.getEnum();
+    }
+
+    /** @return the "font-weight" property */
+    public int getFontWeight() {
+        return cachedCommonFont.fontWeight.getEnum();
     }
     
     /**
-     * Create and return a Font object based on the properties. 
+     * Create and return an array of <code>FontTriplets</code> based on 
+     * the properties stored in the instance variables.
      * 
      * @param fontInfo
      * @return a Font object.
      */
-    public Font getFontState(FontInfo fontInfo, PercentBaseContext context) {
-        if (fontState == null) {
-            /**@todo this is ugly. need to improve. */
-
-            int font_weight;
-            switch (fontWeight) {
-            case Constants.EN_100: font_weight = 100; break;
-            case Constants.EN_200: font_weight = 200; break;
-            case Constants.EN_300: font_weight = 300; break;
-            case Constants.EN_400: font_weight = 400; break;
-            case Constants.EN_500: font_weight = 500; break;
-            case Constants.EN_600: font_weight = 600; break;
-            case Constants.EN_700: font_weight = 700; break;
-            case Constants.EN_800: font_weight = 800; break;
-            case Constants.EN_900: font_weight = 900; break;
-            default: font_weight = 400;
-            }
+    public FontTriplet[] getFontState(FontInfo fontInfo) {
+        int font_weight;
+        switch (cachedCommonFont.fontWeight.getEnum()) {
+        case Constants.EN_100: font_weight = 100; break;
+        case Constants.EN_200: font_weight = 200; break;
+        case Constants.EN_300: font_weight = 300; break;
+        case Constants.EN_400: font_weight = 400; break;
+        case Constants.EN_500: font_weight = 500; break;
+        case Constants.EN_600: font_weight = 600; break;
+        case Constants.EN_700: font_weight = 700; break;
+        case Constants.EN_800: font_weight = 800; break;
+        case Constants.EN_900: font_weight = 900; break;
+        default: font_weight = 400;
+        }
 
-            String style;
-            switch (fontStyle) {
-            case Constants.EN_ITALIC: 
-                style = "italic";
-                break;
-            case Constants.EN_OBLIQUE: 
-                style = "oblique";
-                break;
-            case Constants.EN_BACKSLANT: 
-                style = "backslant";
-                break;
-            default:
-                style = "normal";
-            }
-            // NOTE: this is incomplete. font-size may be specified with
-            // various kinds of keywords too
-            //int fontVariant = propertyList.get("font-variant").getEnum();
-            FontTriplet triplet = fontInfo.fontLookup(getFontFamily(), style,
-                                               font_weight);
-            fontState = fontInfo.getFontInstance(triplet, fontSize.getValue(context));
+        String style;
+        switch (cachedCommonFont.fontStyle.getEnum()) {
+        case Constants.EN_ITALIC: 
+            style = "italic";
+            break;
+        case Constants.EN_OBLIQUE: 
+            style = "oblique";
+            break;
+        case Constants.EN_BACKSLANT: 
+            style = "backslant";
+            break;
+        default:
+            style = "normal";
         }
-        return fontState;
+        // NOTE: this is incomplete. font-size may be specified with
+        // various kinds of keywords too
+        //int fontVariant = propertyList.get("font-variant").getEnum();
+        FontTriplet[] triplets = fontInfo.fontLookup(
+                                    cachedCommonFont.getFontFamily(), 
+                                    style, font_weight);
+        return triplets;
     }
 
+    /** {@inheritDoc} */
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        
+        if (o instanceof CommonFont) {
+            CommonFont cf = (CommonFont) o;
+            return (cf.cachedCommonFont == this.cachedCommonFont
+                    && cf.fontSize == this.fontSize
+                    && cf.fontSizeAdjust == this.fontSizeAdjust);
+        }
+        return false;
+    }
+    
+    /** {@inheritDoc} */
+    public int hashCode() {
+        int hash = 17;
+        hash = 37 * hash + cachedCommonFont.hashCode();
+        hash = 37 * hash + fontSize.hashCode();
+        hash = 37 * hash + fontSizeAdjust.hashCode();
+        return hash;
+    }
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonHyphenation.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonHyphenation.java?rev=578311&r1=578310&r2=578311&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonHyphenation.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CommonHyphenation.java Fri Sep 21 15:51:22 2007
@@ -28,57 +28,123 @@
  * See Sec. 7.9 of the XSL-FO Standard.
  * Public "structure" allows direct member access.
  */
-public class CommonHyphenation {
-    /**
-     * The "language" property.
-     */
-    public String language;
-
-    /**
-     * The "country" property.
-     */
-    public String country;
-
-    /**
-     * The "script" property.
-     */
-    public String script;
-
-    /**
-     * The "hyphenate" property.
-     */
-    public int hyphenate;
-
-    /**
-     * The "hyphenation-character" property.
-     */
-    public char hyphenationCharacter;
-
-    /**
-     * The "hyphenation-push-character" property.
-     */
-    public int hyphenationPushCharacterCount;
-
-    /**
-     * The "hyphenation-remain-character-count" property.
-     */
-    public int hyphenationRemainCharacterCount;
-
+public final class CommonHyphenation {
+    
+    private static final PropertyCache cache = new PropertyCache();
+    
+    private int hash = 0;
+    
+    /** The "language" property */
+    public final StringProperty language;
+
+    /** The "country" property */
+    public final StringProperty country;
+
+    /** The "script" property */
+    public final StringProperty script;
+
+    /** The "hyphenate" property */
+    public final EnumProperty hyphenate;
+
+    /** The "hyphenation-character" property */
+    public final CharacterProperty hyphenationCharacter;
+
+    /** The "hyphenation-push-character-count" property */
+    public final NumberProperty hyphenationPushCharacterCount;
+
+    /** The "hyphenation-remain-character-count" property*/
+    public final NumberProperty hyphenationRemainCharacterCount;
+
+    /**
+     * Construct a CommonHyphenation object holding the given properties
+     * 
+     */
+    private CommonHyphenation(StringProperty language,
+                              StringProperty country,
+                              StringProperty script,
+                              EnumProperty hyphenate,
+                              CharacterProperty hyphenationCharacter,
+                              NumberProperty hyphenationPushCharacterCount,
+                              NumberProperty hyphenationRemainCharacterCount) {
+        this.language = language;
+        this.country = country;
+        this.script = script;
+        this.hyphenate = hyphenate;
+        this.hyphenationCharacter = hyphenationCharacter;
+        this.hyphenationPushCharacterCount = hyphenationPushCharacterCount;
+        this.hyphenationRemainCharacterCount = hyphenationRemainCharacterCount;
+    }
+    
     /**
-     * Create a CommonHyphenation object.
-     * @param pList The PropertyList with propery values.
-     */
-    public CommonHyphenation(PropertyList pList) throws PropertyException {
-        language = pList.get(Constants.PR_LANGUAGE).getString();
-        country = pList.get(Constants.PR_COUNTRY).getString();
-        script = pList.get(Constants.PR_SCRIPT).getString();
-        hyphenate = pList.get(Constants.PR_HYPHENATE).getEnum();
-        hyphenationCharacter = pList.get(Constants.PR_HYPHENATION_CHARACTER).getCharacter();
-        hyphenationPushCharacterCount = 
-            pList.get(Constants.PR_HYPHENATION_PUSH_CHARACTER_COUNT).getNumber().intValue();
-        hyphenationRemainCharacterCount = 
-            pList.get(Constants.PR_HYPHENATION_REMAIN_CHARACTER_COUNT).getNumber().intValue();
-
+     * Gets the canonical <code>CommonHyphenation</code> instance corresponding
+     * to the values of the related properties present on the given 
+     * <code>PropertyList</code>
+     * 
+     * @param propertyList  the <code>PropertyList</code>
+     */
+    public static CommonHyphenation getInstance(PropertyList propertyList) throws PropertyException {
+        StringProperty language = 
+            (StringProperty) propertyList.get(Constants.PR_LANGUAGE);
+        StringProperty country = 
+            (StringProperty) propertyList.get(Constants.PR_COUNTRY);
+        StringProperty script = 
+            (StringProperty) propertyList.get(Constants.PR_SCRIPT);
+        EnumProperty hyphenate = 
+            (EnumProperty) propertyList.get(Constants.PR_HYPHENATE);
+        CharacterProperty hyphenationCharacter = 
+            (CharacterProperty) propertyList.get(Constants.PR_HYPHENATION_CHARACTER);
+        NumberProperty hyphenationPushCharacterCount = 
+            (NumberProperty) propertyList.get(Constants.PR_HYPHENATION_PUSH_CHARACTER_COUNT);
+        NumberProperty hyphenationRemainCharacterCount = 
+            (NumberProperty) propertyList.get(Constants.PR_HYPHENATION_REMAIN_CHARACTER_COUNT);
+        
+        CommonHyphenation instance = new CommonHyphenation(
+                                language, 
+                                country, 
+                                script, 
+                                hyphenate, 
+                                hyphenationCharacter, 
+                                hyphenationPushCharacterCount, 
+                                hyphenationRemainCharacterCount);
+        
+        return cache.fetch(instance);
+        
     }
-
+    
+    /** {@inheritDoc */
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof CommonHyphenation) {
+            CommonHyphenation ch = (CommonHyphenation) obj;
+            return (ch.language == this.language
+                    && ch.country == this.country
+                    && ch.script == this.script
+                    && ch.hyphenate == this.hyphenate
+                    && ch.hyphenationCharacter == this.hyphenationCharacter
+                    && ch.hyphenationPushCharacterCount == this.hyphenationPushCharacterCount
+                    && ch.hyphenationRemainCharacterCount == this.hyphenationRemainCharacterCount);
+        }
+        return false;
+    }
+    
+    /** {@inheritDoc} */
+    public int hashCode() {
+        if (hash == 0) {
+            int hash = 17;
+            hash = 37 * hash + (language == null ? 0 : language.hashCode());
+            hash = 37 * hash + (script == null ? 0 : script.hashCode());
+            hash = 37 * hash + (country == null ? 0 : country.hashCode());
+            hash = 37 * hash + (hyphenate == null ? 0 : hyphenate.hashCode());
+            hash = 37 * hash + 
+                (hyphenationCharacter == null ? 0 : hyphenationCharacter.hashCode());
+            hash = 37 * hash + 
+                (hyphenationPushCharacterCount == null ? 0 : hyphenationPushCharacterCount.hashCode());
+            hash = 37 * hash + 
+                (hyphenationRemainCharacterCount == null ? 0 : hyphenationRemainCharacterCount.hashCode());
+        }
+        return hash;
+    }
+    
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CompoundPropertyMaker.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CompoundPropertyMaker.java?rev=578311&r1=578310&r2=578311&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CompoundPropertyMaker.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/CompoundPropertyMaker.java Fri Sep 21 15:51:22 2007
@@ -26,12 +26,6 @@
 import org.apache.fop.fo.expr.PropertyException;
 
 /**
- * @author me
- *
- * To change the template for this generated type comment go to
- * Window - Preferences - Java - Code Generation - Code and Comments
- */
-/**
  * This class extends Property.Maker with support for sub-properties.  
  */
 public class CompoundPropertyMaker extends PropertyMaker {

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/FixedLength.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/FixedLength.java?rev=578311&r1=578310&r2=578311&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/FixedLength.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/FixedLength.java Fri Sep 21 15:51:22 2007
@@ -24,7 +24,7 @@
 /**
  * An absolute length quantity in XSL
  */
-public class FixedLength extends LengthProperty {
+public final class FixedLength extends LengthProperty {
     
     /** cache holding all canonical FixedLength instances */
     private static final PropertyCache cache = new PropertyCache();
@@ -33,6 +33,7 @@
 
     /**
      * Set the length given a number of units and a unit name.
+     * 
      * @param numUnits quantity of input units
      * @param units input unit specifier (in, cm, etc.)
      */
@@ -41,16 +42,17 @@
     }
     
     /**
-     * Return the canonical FixedLength instance corresponding
+     * Return the cached FixedLength instance corresponding
      * to the computed value
+     * 
      * @param numUnits  input units
      * @param units     unit specifier
      * @return  the canonical FixedLength instance corresponding
      *          to the given number of units and unit specifier
      */
-    public static FixedLength getInstance(double numUnits, String units) {
-        return (FixedLength) cache.fetch(
-                    new FixedLength(numUnits, units));
+    public static FixedLength getInstance(double numUnits, 
+                                          String units) {
+        return (FixedLength) cache.fetch(new FixedLength(numUnits, units));
         
     }
     

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/FontFamilyProperty.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/FontFamilyProperty.java?rev=578311&r1=578310&r2=578311&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/FontFamilyProperty.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/FontFamilyProperty.java Fri Sep 21 15:51:22 2007
@@ -19,6 +19,8 @@
 
 package org.apache.fop.fo.properties;
 
+import java.util.Iterator;
+
 import org.apache.fop.fo.FObj;
 import org.apache.fop.fo.PropertyList;
 import org.apache.fop.fo.expr.PropertyException;
@@ -26,8 +28,13 @@
 /**
  * Property class for the font-family property.
  */
-public class FontFamilyProperty extends ListProperty {
+public final class FontFamilyProperty extends ListProperty {
 
+    /** cache holding all canonical FontFamilyProperty instances */
+    private static final PropertyCache cache = new PropertyCache();
+    
+    private int hash = 0;
+    
     /**
      * Inner class for creating instances of ListProperty
      */
@@ -42,15 +49,12 @@
 
         /**
          * {@inheritDoc}
-         *         org.apache.fop.fo.PropertyList, 
-         *         java.lang.String, 
-         *         org.apache.fop.fo.FObj)
          */
         public Property make(PropertyList propertyList, String value, FObj fo) throws PropertyException {
             if ("inherit".equals(value)) {
                 return super.make(propertyList, value, fo);
             } else {
-                ListProperty prop = new ListProperty();
+                FontFamilyProperty prop = new FontFamilyProperty();
                 String tmpVal;
                 int startIndex = 0;
                 int commaIndex = value.indexOf(',');
@@ -89,7 +93,7 @@
                         prop.addProperty(StringProperty.getInstance(tmpVal));
                     }
                 }
-                return prop;
+                return cache.fetch(prop);
             }
         }
 
@@ -110,12 +114,20 @@
     /**
      * @param prop the first Property to be added to the list
      */
-    public FontFamilyProperty(Property prop) {
+    private FontFamilyProperty(Property prop) {
         super();
         addProperty(prop);
     }
 
     /**
+     * Default constructor.
+     *
+     */
+    private FontFamilyProperty() {
+        super();
+    }
+    
+    /**
      * Add a new property to the list
      * @param prop Property to be added to the list
      */
@@ -137,4 +149,30 @@
         }
     }
 
+    /** {@inheritDoc} */
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        
+        if (o instanceof FontFamilyProperty) {
+            FontFamilyProperty ffp = (FontFamilyProperty) o;
+            return (this.list != null
+                    && this.list.equals(ffp.list));
+        }
+        return false;
+    }
+    
+    /** {@inheritDoc} */
+    public int hashCode() {
+        if (this.hash == 0) {
+            int hash = 17;
+            for (Iterator i = list.iterator(); i.hasNext();) {
+                Property p = (Property) i.next();
+                hash = 37 * hash + (p == null ? 0 : p.hashCode());
+            }
+            this.hash = hash;
+        }
+        return this.hash;
+    }
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/KeepProperty.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/KeepProperty.java?rev=578311&r1=578310&r2=578311&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/KeepProperty.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/KeepProperty.java Fri Sep 21 15:51:22 2007
@@ -25,9 +25,14 @@
 import org.apache.fop.fo.expr.PropertyException;
 
 /**
- * Superclass for properties that wrap Keep values
+ * Class for properties that wrap Keep values
  */
-public class KeepProperty extends Property implements CompoundDatatype {
+public final class KeepProperty extends Property implements CompoundDatatype {
+    
+    /** class holding all canonical KeepProperty instances*/
+    private static final PropertyCache cache = new PropertyCache();
+    
+    private boolean isCachedValue = false;
     private Property withinLine;
     private Property withinColumn;
     private Property withinPage;
@@ -70,6 +75,10 @@
      */
     public void setComponent(int cmpId, Property cmpnValue,
                              boolean bIsDefault) {
+        if (isCachedValue) {
+            log.warn("KeepProperty.setComponent() called on cached value. Ignoring...");
+            return;
+        }
         if (cmpId == CP_WITHIN_LINE) {
             setWithinLine(cmpnValue, bIsDefault);
         } else if (cmpId == CP_WITHIN_COLUMN) {
@@ -152,10 +161,14 @@
     }
 
     /**
-     * @return this.keep
+     * @return the canonical KeepProperty instance corresponding to
+     *          this property
      */
     public KeepProperty getKeep() {
-        return this;
+        KeepProperty keep = (KeepProperty) cache.fetch(this);
+        /* make sure setComponent() can never alter cached values */
+        keep.isCachedValue = true;
+        return keep;
     }
 
     /**
@@ -165,4 +178,27 @@
         return this;
     }
 
+    /** {@inheritDoc} */
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        
+        if (o instanceof KeepProperty) {
+            KeepProperty keep = (KeepProperty) o;
+            return (keep.withinColumn == this.withinColumn)
+                && (keep.withinLine == this.withinLine)
+                && (keep.withinPage == this.withinPage);
+        }
+        return false;
+    }
+    
+    /** {@inheritDoc} */
+    public int hashCode() {
+        int hash = 17;
+        hash = 37 * hash + (withinColumn == null ? 0 : withinColumn.hashCode());
+        hash = 37 * hash + (withinLine == null ? 0 : withinLine.hashCode());
+        hash = 37 * hash + (withinPage == null ? 0 : withinPage.hashCode());
+        return hash;
+    }
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/PropertyCache.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/PropertyCache.java?rev=578311&r1=578310&r2=578311&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/PropertyCache.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/properties/PropertyCache.java Fri Sep 21 15:51:22 2007
@@ -20,39 +20,353 @@
 package org.apache.fop.fo.properties;
 
 import java.lang.ref.WeakReference;
-import java.util.Collections;
-import java.util.Map;
-import java.util.WeakHashMap;
 
 /**
- *  Thin wrapper around a HashMap to implement the property caching idiom
- *  in which a new Property instance is created then tested against cached
- *  instances created previously. If an existing property is found, this is
- *  retained and the newly created one is instantly eligible for garbage
- *  collection.
+ *  Dedicated cache, meant for storing canonical instances
+ *  of property-related classes.
+ *  The public access points are overloaded <code>fetch()</code> methods
+ *  that each correspond to a cached type.
+ *  It is designed especially to be used concurrently by multiple threads,
+ *  drawing heavily upon the principles behind Java 1.5's 
+ *  <code>ConcurrentHashMap</code>. 
  */
-public class PropertyCache {
+public final class PropertyCache {
 
-    private Map propCache = Collections.synchronizedMap(new WeakHashMap());
+    /** bitmask to apply to the hash to get to the 
+     *  corresponding cache segment */
+    private static final int SEGMENT_MASK = 0x1F;
     
+    /** the segments array (length = 32) */
+    private CacheSegment[] segments = new CacheSegment[SEGMENT_MASK + 1];
+    /** the table of hash-buckets */
+    private CacheEntry[] table = new CacheEntry[8];
+    
+    /* same hash function as used by java.util.HashMap */
+    private static int hash(Object x) {
+        int h = x.hashCode();
+
+        h += ~(h << 9);
+        h ^= (h >>> 14);
+        h += (h << 4);
+        h ^= (h >>> 10);
+        return h;
+    }
+    
+    /* shortcut function */
+    private static boolean eq(Object p, Object q) {
+        return (p == q || (p != null && p.equals(q)));
+    }
+    
+    /* Class modeling a cached entry */
+    private final class CacheEntry {
+        final CacheEntry next;
+        volatile WeakReference ref;
+        final int hash;
+        
+        /* main constructor */
+        CacheEntry(Object p, CacheEntry next) {
+            this.next = next;
+            this.ref = new WeakReference(p);
+            this.hash = p.hashCode();
+        }
+        
+        /* clone constructor */
+        CacheEntry(CacheEntry old, CacheEntry next) {
+            this.next = next;
+            this.ref = old.ref;
+            this.hash = old.hash;
+        }
+        
+    }
+    
+    /* Wrapper objects to synchronize on */
+    private final class CacheSegment {
+        private int count = 0;
+    }
+    
+    /*
+     * Class modeling a cleanup thread.
+     * 
+     * Once run() is called, the segment is locked and the hash-bucket
+     * will be traversed, removing any obsolete entries.
+     * If the cleanup has no effect, rehash() is called.
+     */
+    private final class CacheCleaner implements Runnable {
+        
+        private int hash;
+        
+        CacheCleaner(int hash) {
+            this.hash = hash;
+        }
+        
+        public void run() {
+            //System.out.println("Cleaning segment " + this.segment);
+            CacheSegment segment = segments[this.hash & SEGMENT_MASK];
+            int oldCount;
+            int newCount;
+            synchronized (segment) {
+                oldCount = segment.count;
+                /* check first to see if another cleaner thread already
+                 * pushed the number of entries back below the threshold
+                 * if so, return immediately
+                 */
+                if (segment.count < (2 * table.length)) {
+                    return;
+                }
+                
+                int index = this.hash & (table.length - 1);
+                CacheEntry first = table[index];
+                WeakReference ref;
+                for (CacheEntry e = first; e != null; e = e.next) {
+                    ref = e.ref;
+                    if (ref != null && ref.get() == null) {
+                        /* remove obsolete entry
+                        /* 1. clear value, cause interference for non-blocking get() */
+                        e.ref = null;
+                        
+                        /* 2. clone the segment, without the obsolete entry */
+                        CacheEntry head = e.next;
+                        for (CacheEntry c = first; c != e; c = c.next) {
+                            head = new CacheEntry(c, head);
+                        }
+                        table[index] = head;
+                        segment.count--;
+                    }
+                }
+                newCount = segment.count;
+            }
+            if (oldCount == newCount) {
+                /* cleanup had no effect, try rehashing */
+                rehash(SEGMENT_MASK);
+            }
+        }
+    }
+    
+    /*
+     * Puts a new instance in the cache.
+     * If the total number of entries for the corresponding
+     * segment exceeds twice the amount of hash-buckets, a
+     * cleanup thread will be launched to remove obsolete
+     * entries.
+     */
+    private final void put(Object o) {
+        
+        int hash = hash(o);
+        CacheSegment segment = segments[hash & SEGMENT_MASK];
+        
+        synchronized (segment) {
+            int index = hash & (table.length - 1);
+            CacheEntry entry = table[index];
+            
+            if (entry == null) {
+                entry = new CacheEntry(o, null);
+                table[index] = entry;
+                segment.count++;
+            } else {
+                WeakReference ref = entry.ref;
+                if (ref != null && eq(ref.get(), o)) {
+                    return;
+                } else {
+                    CacheEntry newEntry = new CacheEntry(o, entry);
+                    table[index] = newEntry;
+                    segment.count++;
+                }
+            }
+            
+            if (segment.count > (2 * table.length)) {
+                /* launch cleanup in a separate thread, 
+                 * so it acquires its own lock, and put()
+                 * can return immediately */
+                Thread cleaner = new Thread(new CacheCleaner(hash));
+                cleaner.start();
+            }
+        }
+    }
+    
+
+    /* Gets a cached instance. Returns null if not found */
+    private final Object get(Object o) {
+        
+        int hash = hash(o);
+        int index = hash & (table.length - 1);
+        
+        CacheEntry entry = table[index];
+        WeakReference r;
+        Object q;
+        
+        /* try non-synched first */
+        for (CacheEntry e = entry; e != null; e = e.next) {
+            if (e.hash == o.hashCode()
+                    && (r = e.ref) != null
+                    && (q = r.get()) != null
+                    &&  eq(q, o)) {
+                return q;
+            }
+        }
+        
+        /* retry synched, only if the above attempt did not succeed,
+         * as another thread may, in the meantime, have added a
+         * corresponding entry */
+        CacheSegment segment = segments[hash & SEGMENT_MASK];
+        synchronized (segment) {
+            entry = table[index];
+            for (CacheEntry e = entry; e != null; e = e.next) {
+                if (e.hash == o.hashCode()
+                        && (r = e.ref) != null
+                        && (q = r.get()) != null
+                        &&  eq(q, o)) {
+                    return q;
+                }
+            }
+        }
+        return null;
+    }
+    
+    /*
+     * Recursively acquires locks on all 32 segments,
+     * then performs a check on the segments first to see `
+     * how many precisely exceed the threshold ( 2 x table.length ). 
+     * If this number exceeds half the amount of buckets, 
+     * extends the cache and redistributes the entries.
+     * 
+     * Example:
+     * For a cache with default size of 8 buckets, each bucket is
+     * a segment, and as such, rehash() will only have effect
+     * if more than 4 buckets exceed the size of 16 entries.
+     * 
+     */
+    private final void rehash(int index) {
+        
+        CacheSegment seg = segments[index];
+        synchronized (seg) {
+            if (index > 0) {
+                /* need to recursively acquire locks on all segments */
+                rehash(index - 1);
+            } else {
+                /* double the amount of buckets */
+                int newLength = table.length << 1;
+                if (newLength > 0) { //no overflow?
+                    /* Check segmentcounts first */
+                    int countSegments = 0;
+                    int threshold = table.length * 2;
+                    for (int i = segments.length; --i >= 0;) {
+                        if (segments[i].count > threshold) {
+                            countSegments++;
+                        }
+                    }
+                    
+                    if (countSegments <= (table.length / 2)) {
+                        return;
+                    } else {
+                        /* reset segmentcounts */
+                        for (int i = segments.length; --i >= 0;) {
+                            segments[i].count = 0;
+                        }
+                    }
+                    
+                    CacheEntry[] newTable = new CacheEntry[newLength];
+                    
+                    int hash, idx;
+                    WeakReference ref;
+                    Object o;
+                    newLength--;
+                    for (int i = table.length; --i >= 0;) {
+                        for (CacheEntry c = table[i]; c != null; c = c.next) {
+                            ref = c.ref;
+                            if ((o = ref.get()) != null) {
+                                hash = hash(o);
+                                idx = hash & newLength;
+                                newTable[idx] = new CacheEntry(c, newTable[idx]);
+                                segments[hash & SEGMENT_MASK].count++;
+                            }
+                        }
+                    }
+                    table = newTable;
+                }
+            }
+        }
+    }
+    
+    /**
+     *  Default constructor. 
+     */
+    public PropertyCache() {
+        for (int i = SEGMENT_MASK + 1; --i >= 0;) {
+            segments[i] = new CacheSegment();
+        }
+    }
+    
+    /**
+     *  Generic fetch() method.
+     *  Checks if the given <code>Object</code> is present in the cache - 
+     *  if so, returns a reference to the cached instance. 
+     *  Otherwise the given object is added to the cache and returned.
+     *  
+     *  @param obj   the Object to check for
+     *  @return  the cached instance
+     */
+    private final Object fetch(Object obj) {
+        if (obj == null) {
+            return null;
+        }
+
+        Object cacheEntry = get(obj);
+        if (cacheEntry != null) {
+            return cacheEntry;                
+        }
+        put(obj);
+        return obj;
+    }
     
     /**
-     *  Checks if the given property is present in the cache - if so, returns
-     *  a reference to the cached value. Otherwise the given object is added
-     *  to the cache and returned.
+     *  Checks if the given <code>Property</code> is present in the cache - 
+     *  if so, returns a reference to the cached instance. 
+     *  Otherwise the given object is added to the cache and returned.
+     *  
      *  @param prop the Property instance to check for
      *  @return the cached instance
      */
-    public Property fetch(Property prop) {
+    public final Property fetch(Property prop) {
         
-        WeakReference ref = (WeakReference) propCache.get(prop);
-        if (ref != null) {
-            Property cacheEntry = (Property)ref.get();
-            if (cacheEntry != null) {
-                return cacheEntry;                
-            }
-        }
-        propCache.put(prop, new WeakReference(prop));
-        return prop;
+        return (Property) fetch((Object) prop);
+    }
+    
+    /**
+     *  Checks if the given <code>CommonHyphenation</code> is present in the cache - 
+     *  if so, returns a reference to the cached instance. 
+     *  Otherwise the given object is added to the cache and returned.
+     *  
+     *  @param chy the CommonHyphenation instance to check for
+     *  @return the cached instance
+     */
+    public final CommonHyphenation fetch(CommonHyphenation chy) {
+        
+        return (CommonHyphenation) fetch((Object) chy);
+    }
+    
+    /**
+     *  Checks if the given <code>CachedCommonFont</code> is present in the cache - 
+     *  if so, returns a reference to the cached instance. 
+     *  Otherwise the given object is added to the cache and returned.
+     *  
+     *  @param ccf the CachedCommonFont instance to check for
+     *  @return the cached instance
+     */
+    public final CommonFont.CachedCommonFont fetch(CommonFont.CachedCommonFont ccf) {
+        
+        return (CommonFont.CachedCommonFont) fetch((Object) ccf);
+    }
+    
+    /**
+     *  Checks if the given <code>CommonFont</code> is present in the cache - 
+     *  if so, returns a reference to the cached instance. 
+     *  Otherwise the given object is added to the cache and returned.
+     *  
+     *  @param cf the CommonFont instance to check for
+     *  @return the cached instance
+     */
+    public final CommonFont fetch(CommonFont cf) {
+        
+        return (CommonFont) fetch((Object) cf);
     }
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontInfo.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontInfo.java?rev=578311&r1=578310&r2=578311&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontInfo.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontInfo.java Fri Sep 21 15:51:22 2007
@@ -41,6 +41,8 @@
  */
 public class FontInfo {
     
+    private static final FontTriplet[] TRIPLETS_TYPE = new FontTriplet[1];
+    
     /** logging instance */
     protected static Log log = LogFactory.getLog(FontInfo.class);
 
@@ -232,26 +234,35 @@
     }
     
     /**
-     * Lookup a font.
+     * Looks up a set of fonts.
      * <br>
-     * Locate the font name for a given family, style and weight.
-     * The font name can then be used as a key as it is unique for
+     * Locate the font name(s) for the given families, style and weight.
+     * The font name(s) can then be used as a key as they are unique for
      * the associated document.
-     * This also adds the font to the list of used fonts.
-     * @param family font family (priority list)
-     * @param style font style
-     * @param weight font weight
-     * @return font triplet of the font chosen
+     * This also adds the fonts to the list of used fonts.
+     * @param families  font families (priority list)
+     * @param style     font style
+     * @param weight    font weight
+     * @return the set of font triplets of all supported and chosen font-families
+     *          in the specified style and weight.
      */
-    public FontTriplet fontLookup(String[] family, String style,
+    public FontTriplet[] fontLookup(String[] families, String style,
                              int weight) {
-        for (int i = 0; i < family.length; i++) {
-            FontTriplet triplet = fontLookup(family[i], style, weight, (i >= family.length - 1));
+        FontTriplet triplet;
+        List tmpTriplets = new ArrayList();
+        for (int i = 0; i < families.length; i++) {
+            triplet = fontLookup(families[i], style, weight, (i >= families.length - 1));
             if (triplet != null) {
-                return triplet;
+                tmpTriplets.add(triplet);
             }
         }
-        throw new IllegalStateException("fontLookup must return a key on the last call");
+        if (tmpTriplets.size() != 0) {
+            FontTriplet[] triplets = (FontTriplet[]) tmpTriplets.toArray(TRIPLETS_TYPE);
+            return (FontTriplet[]) triplets;
+        }
+        throw new IllegalStateException(
+                    "fontLookup must return an array with at least one "
+                    + "FontTriplet on the last call.");
     }
     
     private void notifyFontReplacement(FontTriplet replacedKey, FontTriplet newKey) {

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java?rev=578311&r1=578310&r2=578311&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java Fri Sep 21 15:51:22 2007
@@ -30,6 +30,8 @@
 import org.apache.fop.area.LineArea;
 import org.apache.fop.datatypes.Length;
 import org.apache.fop.fonts.Font;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontTriplet;
 import org.apache.fop.layoutmgr.inline.InlineLayoutManager;
 import org.apache.fop.layoutmgr.inline.InlineLevelLayoutManager;
 import org.apache.fop.layoutmgr.inline.LineLayoutManager;
@@ -78,11 +80,11 @@
 
     public void initialize() {
         super.initialize();
-        Font fs = getBlockFO().getCommonFont().getFontState(
-                  getBlockFO().getFOEventHandler().getFontInfo(), this);
-        
-        lead = fs.getAscender();
-        follow = -fs.getDescender();
+        FontInfo fi = getBlockFO().getFOEventHandler().getFontInfo();
+        FontTriplet[] fontkeys = getBlockFO().getCommonFont().getFontState(fi);
+        Font initFont = fi.getFontInstance(fontkeys[0], getBlockFO().getCommonFont().fontSize.getValue(this));
+        lead = initFont.getAscender();
+        follow = -initFont.getDescender();
         //middleShift = -fs.getXHeight() / 2;
         lineHeight = getBlockFO().getLineHeight().getOptimum(this).getLength();
         startIndent = getBlockFO().getCommonMarginBlock().startIndent.getValue(this);

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java?rev=578311&r1=578310&r2=578311&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java Fri Sep 21 15:51:22 2007
@@ -21,6 +21,8 @@
 
 import org.apache.fop.fo.flow.Character;
 import org.apache.fop.fonts.Font;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontTriplet;
 import org.apache.fop.layoutmgr.InlineKnuthSequence;
 import org.apache.fop.layoutmgr.KnuthElement;
 import org.apache.fop.layoutmgr.KnuthGlue;
@@ -63,10 +65,12 @@
     
     /** {@inheritDoc} */
     public void initialize() {
-        font = fobj.getCommonFont().getFontState(fobj.getFOEventHandler().getFontInfo(), this);
+        FontInfo fi = fobj.getFOEventHandler().getFontInfo();
+        FontTriplet[] fontkeys = fobj.getCommonFont().getFontState(fi);
+        font = fi.getFontInstance(fontkeys[0], fobj.getCommonFont().fontSize.getValue(this));
         SpaceVal ls = SpaceVal.makeLetterSpacing(fobj.getLetterSpacing());
         letterSpaceIPD = ls.getSpace();
-        hyphIPD = font.getCharWidth(fobj.getCommonHyphenation().hyphenationCharacter);
+        hyphIPD = font.getCharWidth(fobj.getCommonHyphenation().hyphenationCharacter.getCharacter());
         borderProps = fobj.getCommonBorderPaddingBackground();
         setCommonBorderPaddingBackground(borderProps);
         org.apache.fop.area.inline.TextArea chArea = getCharacterInlineArea(fobj);

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java?rev=578311&r1=578310&r2=578311&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java Fri Sep 21 15:51:22 2007
@@ -39,6 +39,8 @@
 import org.apache.fop.fo.properties.CommonMarginInline;
 import org.apache.fop.fo.properties.SpaceProperty;
 import org.apache.fop.fonts.Font;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontTriplet;
 import org.apache.fop.layoutmgr.BlockKnuthSequence;
 import org.apache.fop.layoutmgr.BlockLevelLayoutManager;
 import org.apache.fop.layoutmgr.BreakElement;
@@ -87,6 +89,8 @@
     protected int dominantBaseline;
     /** The line height property */
     protected SpaceProperty lineHeight;
+    /** The keep-together property */
+    //private KeepProperty keepTogether;
     
     private AlignmentContext alignmentContext = null;
 
@@ -110,7 +114,9 @@
     /** {@inheritDoc} */
     public void initialize() {
         int padding = 0;
-        font = fobj.getCommonFont().getFontState(fobj.getFOEventHandler().getFontInfo(), this);
+        FontInfo fi = fobj.getFOEventHandler().getFontInfo();
+        FontTriplet[] fontkeys = fobj.getCommonFont().getFontState(fi);
+        font = fi.getFontInstance(fontkeys[0], fobj.getCommonFont().fontSize.getValue(this));
         lineHeight = fobj.getLineHeight();
         borderProps = fobj.getCommonBorderPaddingBackground();
         inlineProps = fobj.getCommonMarginInline();

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java?rev=578311&r1=578310&r2=578311&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java Fri Sep 21 15:51:22 2007
@@ -26,6 +26,8 @@
 import org.apache.fop.area.inline.TextArea;
 import org.apache.fop.fo.flow.Leader;
 import org.apache.fop.fonts.Font;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontTriplet;
 import org.apache.fop.layoutmgr.InlineKnuthSequence;
 import org.apache.fop.layoutmgr.KnuthElement;
 import org.apache.fop.layoutmgr.KnuthGlue;
@@ -67,7 +69,9 @@
     
     /** {@inheritDoc} */
     public void initialize() {
-        font = fobj.getCommonFont().getFontState(fobj.getFOEventHandler().getFontInfo(), this);
+        FontInfo fi = fobj.getFOEventHandler().getFontInfo();
+        FontTriplet[] fontkeys = fobj.getCommonFont().getFontState(fi);
+        font = fi.getFontInstance(fontkeys[0], fobj.getCommonFont().fontSize.getValue(this));
         // the property leader-alignment does not affect vertical positioning
         // (see section 7.21.1 in the XSL Recommendation)
         // setAlignment(node.getLeaderAlignment());

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java?rev=578311&r1=578310&r2=578311&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java Fri Sep 21 15:51:22 2007
@@ -59,6 +59,8 @@
 import java.util.LinkedList;
 import org.apache.fop.area.Trait;
 import org.apache.fop.fonts.Font;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontTriplet;
 
 import org.apache.fop.traits.MinOptMax;
 
@@ -569,7 +571,9 @@
 
     /** {@inheritDoc} */
     public LinkedList getNextKnuthElements(LayoutContext context, int alignment) {
-        Font fs = fobj.getCommonFont().getFontState(fobj.getFOEventHandler().getFontInfo(), this);
+        FontInfo fi = fobj.getFOEventHandler().getFontInfo();
+        FontTriplet[] fontkeys = fobj.getCommonFont().getFontState(fi);
+        Font fs = fi.getFontInstance(fontkeys[0], fobj.getCommonFont().fontSize.getValue(this));
         alignmentContext
           = new AlignmentContext(fs, lineHeight.getValue(this), context.getWritingMode());
         context.setAlignmentContext(alignmentContext);
@@ -941,7 +945,7 @@
                                         ? 0 : hyphenationLadderCount.getValue(),
                                         this);
    
-        if (hyphenationProperties.hyphenate == EN_TRUE 
+        if (hyphenationProperties.hyphenate.getEnum() == EN_TRUE 
                 && fobj.getWrapOption() != EN_NO_WRAP) {
             findHyphenationPoints(currPar);
         }
@@ -967,8 +971,8 @@
             }
    
             // now try something different
-            log.debug("Hyphenation possible? " + (hyphenationProperties.hyphenate == EN_TRUE));
-            if (hyphenationProperties.hyphenate == EN_TRUE
+            log.debug("Hyphenation possible? " + (hyphenationProperties.hyphenate.getEnum() == EN_TRUE));
+            if (hyphenationProperties.hyphenate.getEnum() == EN_TRUE
                 && !(allowedBreaks == BreakingAlgorithm.ONLY_FORCED_BREAKS)) {
                 // consider every hyphenation point as a legal break
                 allowedBreaks = BreakingAlgorithm.ALL_BREAKS;
@@ -983,10 +987,12 @@
                 // the second try failed too, try with a huge threshold
                 // and force the algorithm to find
                 // a set of breaking points
-                log.debug("No set of breaking points found with maxAdjustment = "
-                          + maxAdjustment
-                          + (hyphenationProperties.hyphenate == EN_TRUE
-                                  ? " and hyphenation" : ""));
+                if (log.isDebugEnabled()) {
+                    log.debug("No set of breaking points found with maxAdjustment = "
+                              + maxAdjustment
+                              + (hyphenationProperties.hyphenate.getEnum() == EN_TRUE
+                                      ? " and hyphenation" : ""));
+                }
                 maxAdjustment = 20;
                 iBPcount
                     = alg.findBreakingPoints(currPar,
@@ -1526,12 +1532,12 @@
         // since these properties inherit and could be specified
         // on an inline or wrapper below the block level.
         Hyphenation hyph
-            = Hyphenator.hyphenate(hyphenationProperties.language,
-                               hyphenationProperties.country,
+            = Hyphenator.hyphenate(hyphenationProperties.language.getString(),
+                               hyphenationProperties.country.getString(),
                                getFObj().getUserAgent().getFactory().getHyphenationTreeResolver(),
                                sbChars.toString(),
-                               hyphenationProperties.hyphenationRemainCharacterCount,
-                               hyphenationProperties.hyphenationPushCharacterCount);
+                               hyphenationProperties.hyphenationRemainCharacterCount.getValue(),
+                               hyphenationProperties.hyphenationPushCharacterCount.getValue());
         // They hyph structure contains the information we need
         // Now start from prev: reset to that position, ask that LM to get
         // a Position for the first hyphenation offset. If the offset isn't in

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLayoutManager.java?rev=578311&r1=578310&r2=578311&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLayoutManager.java Fri Sep 21 15:51:22 2007
@@ -27,6 +27,8 @@
 import org.apache.fop.area.inline.UnresolvedPageNumber;
 import org.apache.fop.area.inline.TextArea;
 import org.apache.fop.fonts.Font;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontTriplet;
 import org.apache.fop.layoutmgr.LayoutContext;
 import org.apache.fop.layoutmgr.LayoutManager;
 import org.apache.fop.layoutmgr.PositionIterator;
@@ -57,7 +59,9 @@
     
     /** {@inheritDoc} */
     public void initialize() {
-        font = fobj.getCommonFont().getFontState(fobj.getFOEventHandler().getFontInfo(), this);
+        FontInfo fi = fobj.getFOEventHandler().getFontInfo();
+        FontTriplet[] fontkeys = fobj.getCommonFont().getFontState(fi);
+        font = fi.getFontInstance(fontkeys[0], fobj.getCommonFont().fontSize.getValue(this));
         setCommonBorderPaddingBackground(fobj.getCommonBorderPaddingBackground());
     }
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java?rev=578311&r1=578310&r2=578311&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java Fri Sep 21 15:51:22 2007
@@ -24,6 +24,8 @@
 import org.apache.fop.area.inline.TextArea;
 import org.apache.fop.area.Trait;
 import org.apache.fop.fonts.Font;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontTriplet;
 import org.apache.fop.layoutmgr.LayoutContext;
 import org.apache.fop.layoutmgr.TraitSetter;
 import org.apache.fop.traits.MinOptMax;
@@ -49,7 +51,9 @@
     
     /** {@inheritDoc} */
     public void initialize() {
-        font = fobj.getCommonFont().getFontState(fobj.getFOEventHandler().getFontInfo(), this);
+        FontInfo fi = fobj.getFOEventHandler().getFontInfo();
+        FontTriplet[] fontkeys = fobj.getCommonFont().getFontState(fi);
+        font = fi.getFontInstance(fontkeys[0], fobj.getCommonFont().fontSize.getValue(this));
         setCommonBorderPaddingBackground(fobj.getCommonBorderPaddingBackground());
     }
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java?rev=578311&r1=578310&r2=578311&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java Fri Sep 21 15:51:22 2007
@@ -31,6 +31,8 @@
 import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.FOText;
 import org.apache.fop.fonts.Font;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontTriplet;
 import org.apache.fop.layoutmgr.InlineKnuthSequence;
 import org.apache.fop.layoutmgr.KnuthBox;
 import org.apache.fop.layoutmgr.KnuthElement;
@@ -186,12 +188,14 @@
     
     /** {@inheritDoc} */
     public void initialize() {
-        font = foText.getCommonFont().getFontState(foText.getFOEventHandler().getFontInfo(), this);
+        FontInfo fi = foText.getFOEventHandler().getFontInfo();
+        FontTriplet[] fontkeys = foText.getCommonFont().getFontState(fi);
+        font = fi.getFontInstance(fontkeys[0], foText.getCommonFont().fontSize.getValue(this));
         
         // With CID fonts, space isn't neccesary currentFontState.width(32)
         spaceCharIPD = font.getCharWidth(' ');
         // Use hyphenationChar property
-        hyphIPD = font.getCharWidth(foText.getCommonHyphenation().hyphenationCharacter);
+        hyphIPD = font.getCharWidth(foText.getCommonHyphenation().hyphenationCharacter.getCharacter());
         
         SpaceVal ls = SpaceVal.makeLetterSpacing(foText.getLetterSpacing());
         halfLS = new SpaceVal(MinOptMax.multiply(ls.getSpace(), 0.5),
@@ -504,7 +508,7 @@
                         && i == lastIndex 
                         && areaInfo.bHyphenated) {
                         // add the hyphenation character
-                        wordChars.append(foText.getCommonHyphenation().hyphenationCharacter);
+                        wordChars.append(foText.getCommonHyphenation().hyphenationCharacter.getCharacter());
                     }
                     textArea.addWord(wordChars.toString(), 0, letterAdjust);
                     wordStartIndex = -1;

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/TextAttributesConverter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/TextAttributesConverter.java?rev=578311&r1=578310&r2=578311&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/TextAttributesConverter.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/TextAttributesConverter.java Fri Sep 21 15:51:22 2007
@@ -142,16 +142,16 @@
                 RtfFontManager.getInstance().getFontNumber(font.getFirstFontFamily()));
         rtfAttr.setHalfPoints(RtfText.ATTR_FONT_SIZE, font.fontSize);
 
-        if (font.fontWeight == Constants.EN_700
-                || font.fontWeight == Constants.EN_800
-                || font.fontWeight == Constants.EN_900) {
+        if (font.getFontWeight() == Constants.EN_700
+                || font.getFontWeight() == Constants.EN_800
+                || font.getFontWeight() == Constants.EN_900) {
             //Everything from 700 and above is declared as bold
             rtfAttr.set("b", 1);
         } else {
             rtfAttr.set("b", 0);
         }
         
-        if (font.fontStyle == Constants.EN_ITALIC) {
+        if (font.getFontStyle() == Constants.EN_ITALIC) {
             rtfAttr.set(RtfText.ATTR_ITALIC, 1);
         } else {
             rtfAttr.set(RtfText.ATTR_ITALIC, 0);

Modified: xmlgraphics/fop/trunk/status.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/status.xml?rev=578311&r1=578310&r2=578311&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/status.xml (original)
+++ xmlgraphics/fop/trunk/status.xml Fri Sep 21 15:51:22 2007
@@ -28,6 +28,23 @@
 
   <changes>
     <release version="FOP Trunk">
+      <action context="code" dev="AD" type="update">
+        Facilitate the implementation for font-selection-strategy:
+        * Changed FontInfo.fontLookup to always return an array of FontTriplet
+        * Changed CommonFont.getFontState to return an array of FontTriplet
+        * Initial modifications to the related LMs: initialized with
+          the font corresponding to the first of the triplets
+      </action>
+      <action context="code" dev="AD" type="update">
+        PropertyCache phase 2:
+        * improvement of the PropertyCache itself should now guarantee acceptable
+          performance of the static caches in multi-session environments, which is 
+          a possible problem with synchronizedMap
+        * changed CommonFont to use the cache: 
+          added CachedCommonFont to contain the properties that are always cacheable
+          CommonFont itself is only cached if the remaining properties are absolutes
+        * changed CommonHyphenation, KeepProperty, ColorProperty and FontFamilyProperty to use the cache
+      </action>
       <action context="Code" dev="AD" type="fix" fixes-bug="42705">
         Fixed swallowing PCDATA in text-node children of
         retrieved markers.



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


Re: svn commit: r578311 - in /xmlgraphics/fop/trunk: ./ src/java/org/apache/fop/fo/ src/java/org/apache/fop/fo/expr/ src/java/org/apache/fop/fo/properties/ src/java/org/apache/fop/fonts/ src/java/org/apache/fop/layoutmgr/ src/java/org/apache/fop/layoutmgr/...

Posted by Andreas L Delmelle <a_...@pandora.be>.
On Sep 22, 2007, at 00:51, adelmelle@apache.org wrote:

Hi All

First of all, apologies for combining two changes in the same commit;  
there was some incidental overlap in CommonFont, CommonHyphenation  
and the LMs, but for the rest these are completely unrelated.

> Author: adelmelle
> Date: Fri Sep 21 15:51:22 2007
> New Revision: 578311
>
> URL: http://svn.apache.org/viewvc?rev=578311&view=rev
> Log:

> PropertyCache phase 2:

This one I know I initially wanted in the release, but I got  
sidetracked, unfortunately. Maybe all the better, since the trunk  
version of FOP is downloaded and used frequently enough (at least, so  
I gather). If there are still issues, those will at least be absent  
in the 0.94 release.

<snip />

> Facilitate the implementation for font-selection-strategy:

This one was also promised over a month ago, as I remember. Sorry,  
Manuel. :(



Cheers

Andreas