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 kl...@apache.org on 2001/03/04 22:29:46 UTC

cvs commit: xml-fop/src/org/apache/fop/fo PropertyManager.java ShorthandParser.java ListProperty.java BoxPropShorthandParser.java GenericShorthandParser.java EnumProperty.java FObj.java Property.java PropertyList.java PropertyListBuilder.java

klease      01/03/04 13:29:46

  Modified:    src/org/apache/fop/fo EnumProperty.java FObj.java
                        Property.java PropertyList.java
                        PropertyListBuilder.java
  Added:       src/org/apache/fop/fo PropertyManager.java
                        ShorthandParser.java ListProperty.java
                        BoxPropShorthandParser.java
                        GenericShorthandParser.java
  Log:
  Support for border-related shorthand properties and PropertyManager delegate object
  
  Revision  Changes    Path
  1.3       +6 -1      xml-fop/src/org/apache/fop/fo/EnumProperty.java
  
  Index: EnumProperty.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/org/apache/fop/fo/EnumProperty.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- EnumProperty.java	2001/01/02 21:35:38	1.2
  +++ EnumProperty.java	2001/03/04 21:29:46	1.3
  @@ -1,4 +1,4 @@
  -/*-- $Id: EnumProperty.java,v 1.2 2001/01/02 21:35:38 klease Exp $ -- 
  +/*-- $Id: EnumProperty.java,v 1.3 2001/03/04 21:29:46 klease Exp $ -- 
   
    ============================================================================
                      The Apache Software License, Version 1.1
  @@ -75,6 +75,11 @@
         return null;
       }
   
  +    public Property convertProperty(Property p,
  +	PropertyList propertyList, FObj fo) throws FOPException {
  +      if (p instanceof EnumProperty) return p;
  +      else return null;
  +    }
     }
   
       private int value;
  
  
  
  1.16      +15 -11    xml-fop/src/org/apache/fop/fo/FObj.java
  
  Index: FObj.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/org/apache/fop/fo/FObj.java,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- FObj.java	2001/02/23 03:47:08	1.15
  +++ FObj.java	2001/03/04 21:29:46	1.16
  @@ -1,4 +1,4 @@
  -/*-- $Id: FObj.java,v 1.15 2001/02/23 03:47:08 keiron Exp $ -- 
  +/*-- $Id: FObj.java,v 1.16 2001/03/04 21:29:46 klease Exp $ -- 
   
    ============================================================================
                      The Apache Software License, Version 1.1
  @@ -78,17 +78,23 @@
   
   //    protected PropertyList properties;
     public PropertyList properties;
  +  protected PropertyManager propMgr;
   
     protected String name;
   
     protected FObj(FObj parent, PropertyList propertyList) {
       super(parent);
  -    this.properties = propertyList;
  +    this.properties = propertyList;  // TO BE REMOVED!!!
       propertyList.setFObj(this);
  +    this.propMgr = makePropertyManager(propertyList);
       this.name = "default FO";
       setWritingMode();
     }
   
  +  protected PropertyManager makePropertyManager(PropertyList propertyList) {
  +    return new PropertyManager(propertyList);
  +  }
  +
     /**
      *  adds characters (does nothing here) 
      *  @param data text
  @@ -187,17 +193,15 @@
        * Set writing mode for this FO.
        * Find nearest ancestor, including self, which generates
        * reference areas and use the value of its writing-mode property.
  +     * If no such ancestor is found, use the value on the root FO.
        */
     private void setWritingMode() {
  -    FObj p = this;
  -    while (p!= null && !p.generatesReferenceAreas())
  -      p = p.getParent();
  -    if (p != null) {
  -      this.properties.setWritingMode(p.getProperty("writing-mode").getEnum());
  -    }
  -    else {
  -      // shouldn't happen!!!
  -    }
  +    FObj p ;
  +    FObj parent;
  +    for (p=this;
  +	 !p.generatesReferenceAreas() && (parent = p.getParent()) != null;
  +	 p=parent);
  +    this.properties.setWritingMode(p.getProperty("writing-mode").getEnum());
     }
   
   
  
  
  
  1.13      +46 -1     xml-fop/src/org/apache/fop/fo/Property.java
  
  Index: Property.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/org/apache/fop/fo/Property.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- Property.java	2001/01/02 21:35:41	1.12
  +++ Property.java	2001/03/04 21:29:46	1.13
  @@ -1,4 +1,4 @@
  -/*-- $Id: Property.java,v 1.12 2001/01/02 21:35:41 klease Exp $ -- 
  +/*-- $Id: Property.java,v 1.13 2001/03/04 21:29:46 klease Exp $ -- 
   
    ============================================================================
                      The Apache Software License, Version 1.1
  @@ -57,6 +57,7 @@
   import org.apache.fop.fo.expr.PropertyInfo;
   import org.apache.fop.fo.expr.PropertyException;
   import org.apache.fop.apps.FOPException;
  +import java.util.Vector;
   
   public class Property {
   
  @@ -231,6 +232,45 @@
         }
       }
   
  +    public Property convertShorthandProperty(PropertyList propertyList,
  +					  Property prop, FObj fo)
  +    {
  +      Property pret = null;
  +      try {
  +	pret = convertProperty(prop, propertyList, fo);
  +	if (pret == null) {
  +	  // If value is a name token, may be keyword or Enum
  +	  String sval = prop.getNCname();
  +	  if (sval != null) {
  +	    // System.err.println("Convert shorthand ncname " + sval);
  +	    pret = checkEnumValues(sval);
  +	    if (pret == null) {
  +	      /* Check for keyword shorthand values to be substituted. */
  +	      String pvalue = checkValueKeywords(sval);
  +	      if (!pvalue.equals(sval)) {
  +		// System.err.println("Convert shorthand keyword" + pvalue);
  +		// Substituted a value: must parse it
  +		Property p = PropertyParser.parse(pvalue,
  +			     new PropertyInfo(this, propertyList, fo));
  +		pret = convertProperty(p, propertyList, fo);
  +	      }
  +	    }
  +	  }
  +	}
  +      } catch (FOPException e) {
  +
  +	MessageHandler.errorln("convertShorthandProperty caught FOPException " + e);
  +      }
  +      catch (org.apache.fop.fo.expr.PropertyException propEx) {
  +	MessageHandler.errorln("convertShorthandProperty caught PropertyException " + propEx);
  +      }
  +      if (pret != null) {
  +	/* System.err.println("Return shorthand value " + pret.getString() +
  +	   " for " + getPropName());*/
  +      }
  +      return pret;
  +    }
  +
       protected boolean isCompoundMaker() {
         return false;
       }
  @@ -333,6 +373,10 @@
       	return false;
       }
   
  +    public Property getShorthand(PropertyList propertyList) {
  +    	return null;
  +    }
  +
     } // end of nested Maker class
   
     /** The original specified value for properties which inherit
  @@ -370,6 +414,7 @@
     */
     public int getEnum() { return 0; }
     public char getCharacter() { return 0;}
  +  public Vector getList() { return null; } // List of Property objects
   
     public Number getNumber() { return null; }
   
  
  
  
  1.12      +77 -8     xml-fop/src/org/apache/fop/fo/PropertyList.java
  
  Index: PropertyList.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/org/apache/fop/fo/PropertyList.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- PropertyList.java	2001/01/02 21:35:42	1.11
  +++ PropertyList.java	2001/03/04 21:29:46	1.12
  @@ -1,4 +1,4 @@
  -/*-- $Id: PropertyList.java,v 1.11 2001/01/02 21:35:42 klease Exp $ -- 
  +/*-- $Id: PropertyList.java,v 1.12 2001/03/04 21:29:46 klease Exp $ -- 
   
    ============================================================================
                      The Apache Software License, Version 1.1
  @@ -119,9 +119,56 @@
     /**
      * Return the value explicitly specified on this FO.
      * @param propertyName The name of the property whose value is desired.
  +   * It may be a compound name, such as space-before.optimum.
  +   * @return The value if the property is explicitly set or set by
  +   * a shorthand property, otherwise null.
  +   */
  +  public Property getExplicitOrShorthand(String propertyName) {
  +    /* Handle request for one part of a compound property */
  +    int sepchar = propertyName.indexOf('.');
  +    String baseName;
  +    if (sepchar > -1) {
  +      baseName = propertyName.substring(0,sepchar);
  +    }
  +    else baseName = propertyName;
  +    Property p =getExplicitBaseProp(baseName);
  +    if (p == null) {
  +      p = builder.getShorthand(this, namespace, element, baseName);
  +    }
  +    if (p != null && sepchar > -1) {
  +      return builder.getSubpropValue(namespace, element, baseName,
  +				     p, propertyName.substring(sepchar+1));
  +    }
  +    return p;
  +  }
  +
  +  /**
  +   * Return the value explicitly specified on this FO.
  +   * @param propertyName The name of the property whose value is desired.
  +   * It may be a compound name, such as space-before.optimum.
      * @return The value if the property is explicitly set, otherwise null.
      */
     public Property getExplicit(String propertyName) {
  +    /* Handle request for one part of a compound property */
  +    int sepchar = propertyName.indexOf('.');
  +    if (sepchar > -1) {
  +      String baseName = propertyName.substring(0,sepchar);
  +      Property p =getExplicitBaseProp(baseName);
  +      if (p != null) {
  +	return this.builder.getSubpropValue(namespace, element, baseName,
  +					    p, propertyName.substring(sepchar+1));
  +      }
  +      else return null;
  +    }
  +    return (Property)super.get(propertyName);
  +  }
  +
  +  /**
  +   * Return the value explicitly specified on this FO.
  +   * @param propertyName The name of the base property whose value is desired.
  +   * @return The value if the property is explicitly set, otherwise null.
  +   */
  +  public Property getExplicitBaseProp(String propertyName) {
       return (Property)super.get(propertyName);
     }
   
  @@ -158,25 +205,37 @@
        * we try to compute it from the corresponding relative property: this
        * happends in computeProperty.
        */
  -  private Property findProperty(String propertyName) {
  +  private Property findProperty(String propertyName, boolean bTryInherit) {
       Property p = null;
       if (builder.isCorrespondingForced(this, namespace, element, propertyName)) {
         p = builder.computeProperty(this,namespace, element, propertyName);
       }
       else {
  -        p = getExplicit(propertyName);
  +        p = getExplicitBaseProp(propertyName);
           if (p == null) {
             p = this.builder.computeProperty(this,namespace, element, propertyName);
  +        }
  +        if (p == null) { // check for shorthand specification
  +            p = builder.getShorthand(this, namespace, element, propertyName);
           }
  -        if (p == null) { // else inherit (if has parent and is inheritable)
  +        if (p == null && bTryInherit) { // else inherit (if has parent and is inheritable)
               if (this.parentPropertyList != null &&
       	    builder.isInherited(namespace, element, propertyName)) {
  -              p = parentPropertyList.findProperty(propertyName);
  +              p = parentPropertyList.findProperty(propertyName, true);
               }
           }
       }
       return p;
     }
  +
  +
  +  /**
  +   * Return the property on the current FlowObject if it is specified, or if a
  +   * corresponding property is specified. If neither is specified, it returns null.
  +   */
  +  public Property getSpecified(String propertyName) {
  +    return get(propertyName, false, false);
  +  }
     
   
     /**
  @@ -186,6 +245,16 @@
      * the default value.
      */
     public Property get(String propertyName) {
  +    return get(propertyName, true, true);
  +  }
  +
  +  /**
  +   * Return the property on the current FlowObject. Depending on the passed flags,
  +   * this will try to compute it based on other properties, or if it is
  +   * inheritable, to return the inherited value. If all else fails, it returns
  +   * the default value.
  +   */
  +  private Property get(String propertyName, boolean bTryInherit, boolean bTryDefault) {
   
       if (builder == null)
         MessageHandler.errorln("OH OH, builder has not been set");
  @@ -198,15 +267,15 @@
         propertyName = propertyName.substring(0,sepchar);
       }
   
  -    Property p = findProperty(propertyName);
  -    if (p == null) { // default value for this FO!
  +    Property p = findProperty(propertyName, bTryInherit);
  +    if (p == null && bTryDefault) { // default value for this FO!
         try {
   	p = this.builder.makeProperty(this,namespace, element,propertyName);
         } catch (FOPException e) {
   	// don't know what to do here
         }
       }
  -    if (subpropName != null) {
  +    if (subpropName != null && p != null) {
         return this.builder.getSubpropValue(namespace, element, propertyName,
   					   p, subpropName);
       }
  
  
  
  1.29      +13 -2     xml-fop/src/org/apache/fop/fo/PropertyListBuilder.java
  
  Index: PropertyListBuilder.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/org/apache/fop/fo/PropertyListBuilder.java,v
  retrieving revision 1.28
  retrieving revision 1.29
  diff -u -r1.28 -r1.29
  --- PropertyListBuilder.java	2001/01/02 21:35:43	1.28
  +++ PropertyListBuilder.java	2001/03/04 21:29:46	1.29
  @@ -1,4 +1,4 @@
  -/*-- $Id: PropertyListBuilder.java,v 1.28 2001/01/02 21:35:43 klease Exp $ -- 
  +/*-- $Id: PropertyListBuilder.java,v 1.29 2001/03/04 21:29:46 klease Exp $ -- 
   
    ============================================================================
                      The Apache Software License, Version 1.1
  @@ -175,7 +175,7 @@
   	    if (propertyMaker != null) {
   	      try {
   		if (subpropName != null) {
  -		    Property baseProp = p.getExplicit(propName);
  +		    Property baseProp = p.getExplicitBaseProp(propName);
   		    if (baseProp == null) {
   			// See if it is specified later in this list
   			String baseValue = attributes.getValue(propName);
  @@ -227,6 +227,17 @@
   	return false;
       }
       
  +    public Property getShorthand(PropertyList propertyList, String space,
  +    	 String element, String propertyName) {
  +	Property.Maker propertyMaker = findMaker(space, element, propertyName);
  +	if (propertyMaker != null) {
  +	    return propertyMaker.getShorthand(propertyList);
  +	} else {
  +	    MessageHandler.errorln("WARNING: no Maker for " + propertyName);
  +            return null;
  +	}
  +    }
  +
   
       public Property makeProperty(PropertyList propertyList, String space, String element, String propertyName) throws FOPException {
   	
  
  
  
  1.1                  xml-fop/src/org/apache/fop/fo/PropertyManager.java
  
  Index: PropertyManager.java
  ===================================================================
  /*-- $Id: PropertyManager.java,v 1.1 2001/03/04 21:29:46 klease Exp $ -- */
  /*
   * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
   * For details on use and redistribution please refer to the
   * LICENSE file included with these sources.
   */
  package org.apache.fop.fo;
  
  import org.apache.fop.layout.FontState;
  import org.apache.fop.layout.FontInfo;
  import org.apache.fop.layout.BorderAndPadding;
  import org.apache.fop.fo.properties.BreakBefore;
  import org.apache.fop.fo.properties.Constants;
  import org.apache.fop.layout.HyphenationProps;
  import org.apache.fop.apps.FOPException;
  import java.text.MessageFormat;
  import java.text.FieldPosition;
  
  public class PropertyManager {
  
    private PropertyList properties;
    private FontState fontState=null;
    private BorderAndPadding borderAndPadding = null;
    private HyphenationProps hyphProps = null;
  
    private String[] saLeft ;
    private String[] saRight;
    private String[] saTop ;
    private String[] saBottom ;
  
    private static MessageFormat msgColorFmt = new MessageFormat("border-{0}-color");
    private static MessageFormat msgStyleFmt = new MessageFormat("border-{0}-style");
    private static MessageFormat msgWidthFmt = new MessageFormat("border-{0}-width");
    private static MessageFormat msgPaddingFmt = new MessageFormat("padding-{0}");
  
    public PropertyManager(PropertyList pList) {
      this.properties = pList;
    }
  
    private void initDirections() {
      saLeft = new String[1];
      saRight = new String[1];
      saTop = new String[1];
      saBottom = new String[1];
        saTop[0] = properties.wmAbsToRel(PropertyList.TOP);
        saBottom[0] = properties.wmAbsToRel(PropertyList.BOTTOM);
        saLeft[0] = properties.wmAbsToRel(PropertyList.LEFT);
        saRight[0] = properties.wmAbsToRel(PropertyList.RIGHT);
    }
  
    public FontState getFontState(FontInfo fontInfo) throws FOPException {
      if (fontState == null) {
          String fontFamily = properties.get("font-family").getString();
          String fontStyle =properties.get("font-style").getString();
          String fontWeight =properties.get("font-weight").getString();
      // NOTE: this is incomplete. font-size may be specified with
      // various kinds of keywords too
          int fontSize =properties.get("font-size").getLength().mvalue();
          int fontVariant =properties.get("font-variant").getEnum();
  	// fontInfo is same for the whole FOP run but set in all FontState
  	fontState = new FontState(fontInfo, fontFamily,
                  fontStyle, fontWeight, fontSize, fontVariant);
      }
      return fontState ;
    }
  
  
    public BorderAndPadding getBorderAndPadding() {
      if (borderAndPadding == null) {
        this.borderAndPadding = new BorderAndPadding();
        initDirections();
  
        initBorderInfo(BorderAndPadding.TOP, saTop);
        initBorderInfo(BorderAndPadding.BOTTOM, saBottom);
        initBorderInfo(BorderAndPadding.LEFT, saLeft);
        initBorderInfo(BorderAndPadding.RIGHT, saRight);
  
        /****
        // Border color
        this.borderAndPadding.borderTopColor =
  	properties.get(msgFmt.format(saTop)).getColorType();
        this.borderAndPadding.borderBottomColor =
  	properties.get(msgFmt.format(saBottom)).getColorType();
        this.borderAndPadding.borderLeftColor =
  	properties.get(msgFmt.format(saLeft)).getColorType();
        this.borderAndPadding.borderRightColor =
  	properties.get(msgFmt.format(saRight)).getColorType();
  
        // Border style
        this.borderAndPadding.borderTopStyle =
  	properties.get(msgFmt.format(saTop)).getEnum();
        this.borderAndPadding.borderBottomStyle =
  	properties.get(msgFmt.format(saBottom)).getEnum();
        this.borderAndPadding.borderLeftStyle =
  	properties.get(msgFmt.format(saLeft)).getEnum();
        this.borderAndPadding.borderRightStyle =
  	properties.get(msgFmt.format(saRight)).getEnum();
  
        // Border width
        this.borderAndPadding.borderTopWidth =
  	properties.get(msgFmt.format(saTop)).getCondLength();
        this.borderAndPadding.borderBottomWidth =
  	properties.get(msgFmt.format(saBottom)).getCondLength();
        this.borderAndPadding.borderLeftWidth =
  	properties.get(msgFmt.format(saLeft)).getCondLength();
        this.borderAndPadding.borderRightWidth =
  	properties.get(msgFmt.format(saRight)).getCondLength();
        ****/
      }
      return borderAndPadding;
    }
  
    private void initBorderInfo(int whichSide, String[] saSide) {
      borderAndPadding.setPadding(whichSide,
  	properties.get(msgPaddingFmt.format(saSide)).getCondLength());
      // If style = none, force width to 0, don't get Color
      int style = properties.get(msgStyleFmt.format(saSide)).getEnum();
      if (style != Constants.NONE) {
        borderAndPadding.setBorder(whichSide, style,
  		properties.get(msgWidthFmt.format(saSide)).getCondLength(),
  	        properties.get(msgColorFmt.format(saSide)).getColorType());
      }
    }
  
    public HyphenationProps getHyphenationProps() {
      if (hyphProps == null) {
        this.hyphProps = new HyphenationProps();
        hyphProps.hyphenate = this.properties.get("hyphenate").getEnum();
        hyphProps.hyphenationChar = this.properties.get("hyphenation-character").getCharacter();
        hyphProps.hyphenationPushCharacterCount = this.properties.get( "hyphenation-push-character-count").getNumber().intValue();
        hyphProps.hyphenationRemainCharacterCount = this.properties.get( "hyphenation-remain-character-count").getNumber().intValue();
        hyphProps.language = this.properties.get("language").getString();
        hyphProps.country = this.properties.get("country").getString();
      }
      return hyphProps;
    }
  
    public int checkBreakBefore() {
      switch(properties.get("break-before").getEnum()) {
        case BreakBefore.PAGE:
         return Status.FORCE_PAGE_BREAK;
        case BreakBefore.ODD_PAGE:
         return Status.FORCE_PAGE_BREAK_ODD;
        case BreakBefore.EVEN_PAGE:
         return Status.FORCE_PAGE_BREAK_EVEN;
        case BreakBefore.COLUMN:
         return Status.FORCE_COLUMN_BREAK;
        default:
          return Status.OK;
      }
    }
  
  }
  
  
  
  1.1                  xml-fop/src/org/apache/fop/fo/ShorthandParser.java
  
  Index: ShorthandParser.java
  ===================================================================
  package org.apache.fop.fo;
  
  public interface ShorthandParser {
    public Property getValueForProperty(String propName, Property.Maker maker,
      PropertyList propertyList);
  }
  
  
  
  1.1                  xml-fop/src/org/apache/fop/fo/ListProperty.java
  
  Index: ListProperty.java
  ===================================================================
  package org.apache.fop.fo;
  
  import java.util.Vector;
  
  public class ListProperty extends Property {
  
    public static class Maker extends Property.Maker {
  
      public Maker(String name) {
  	super(name);
      }
  
      public Property convertProperty(Property p, PropertyList propertyList,
  				       FObj fo) {
        if (p instanceof ListProperty)
  	return p;
        else return new ListProperty(p);
      }
    }
  
    protected Vector list;
  
    public ListProperty(Property prop) {
      list = new Vector();
      list.addElement(prop);
    }
  
    public void addProperty(Property prop) {
      list.addElement(prop);
    }
  
    public Vector getList() { return list; }
    public Object getObject() { return list; }
  
  }
  
  
  
  1.1                  xml-fop/src/org/apache/fop/fo/BoxPropShorthandParser.java
  
  Index: BoxPropShorthandParser.java
  ===================================================================
  package org.apache.fop.fo;
  
  import org.apache.fop.apps.FOPException;
  
  public class BoxPropShorthandParser extends GenericShorthandParser {
  
    public BoxPropShorthandParser(ListProperty listprop) {
      super(listprop);
    }
  
    // Stores 1 to 4 values of same type
    // Set the given property based on the number of values set
    // Example: padding, border-width, border-color, border-style, margin
    protected Property convertValueForProperty(String propName,
      Property.Maker maker, PropertyList propertyList) {
      Property p = null;
      if (propName.indexOf("-top") >= 0) {
        p = getElement(0);
      }
      else if (propName.indexOf("-right") >= 0) {
        p = getElement(count()>1? 1:0);
      }
      else if (propName.indexOf("-bottom") >= 0) {
        p = getElement(count()>2? 2:0);
      }
      else if (propName.indexOf("-left") >= 0) {
        p = getElement(count()>3? 3: (count()>1?1:0));
      }
      // if p not null, try to convert it to a value of the correct type
      if (p != null) {
  	return maker.convertShorthandProperty(propertyList, p, null);
      }
      return p;
    }
  }
  
  
  
  1.1                  xml-fop/src/org/apache/fop/fo/GenericShorthandParser.java
  
  Index: GenericShorthandParser.java
  ===================================================================
  package org.apache.fop.fo;
  
  import java.util.Vector;
  import java.util.Enumeration;
  
  public class GenericShorthandParser implements ShorthandParser {
  
    protected Vector list; // Vector of Property objects
  
    public GenericShorthandParser(ListProperty listprop) {
      this.list=listprop.getList();
    }
  
    protected Property getElement(int index) {
      if (list.size() > index) return (Property)list.elementAt(index);
      else return null;
    }
  
    protected int count() {
      return list.size();
    }
  
    // Stores 1 to 3 values for border width, style, color
    // Used for: border, border-top, border-right etc
    public Property getValueForProperty(String propName, Property.Maker maker,
      PropertyList propertyList) {
      Property prop = null;
      // Check for keyword "inherit"
      if (count() == 1) {
        String sval = ((Property)list.elementAt(0)).getString();
        if (sval != null && sval.equals("inherit")) {
  	return propertyList.getFromParent(propName);
        }
      }
      return convertValueForProperty(propName, maker, propertyList);
    }
  
  
    protected Property convertValueForProperty(String propName, Property.Maker maker,
      PropertyList propertyList) {
      Property prop = null;
      // Try each of the stored values in turn
      Enumeration eprop = list.elements();
      while (eprop.hasMoreElements() && prop == null) {
        Property p = (Property)eprop.nextElement();
        prop = maker.convertShorthandProperty(propertyList, p, null);
      }
      return prop;
    }
  }