]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Support for border-related shorthand properties and PropertyManager delegate object
authorKaren Lease <klease@apache.org>
Sun, 4 Mar 2001 21:29:46 +0000 (21:29 +0000)
committerKaren Lease <klease@apache.org>
Sun, 4 Mar 2001 21:29:46 +0000 (21:29 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@194124 13f79535-47bb-0310-9956-ffa450edef68

src/org/apache/fop/fo/BoxPropShorthandParser.java [new file with mode: 0644]
src/org/apache/fop/fo/EnumProperty.java
src/org/apache/fop/fo/FObj.java
src/org/apache/fop/fo/GenericShorthandParser.java [new file with mode: 0644]
src/org/apache/fop/fo/ListProperty.java [new file with mode: 0644]
src/org/apache/fop/fo/Property.java
src/org/apache/fop/fo/PropertyList.java
src/org/apache/fop/fo/PropertyListBuilder.java
src/org/apache/fop/fo/PropertyManager.java [new file with mode: 0644]
src/org/apache/fop/fo/ShorthandParser.java [new file with mode: 0644]

diff --git a/src/org/apache/fop/fo/BoxPropShorthandParser.java b/src/org/apache/fop/fo/BoxPropShorthandParser.java
new file mode 100644 (file)
index 0000000..362d4e0
--- /dev/null
@@ -0,0 +1,35 @@
+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;
+  }
+}
index 0a46c6e535e40809d88664889951b0e6b37e56c8..41a5194912faf0f7b83a6c74f3e46bfe5800ae23 100644 (file)
@@ -75,6 +75,11 @@ public class EnumProperty extends Property {
       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;
index 2011ef1409f430eebae47a395ab8e9191d6be8af..053758b1147fcb018aa51ac86d3e373c91258e23 100644 (file)
@@ -78,17 +78,23 @@ public class FObj extends FONode {
 
 //    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 @@ public class FObj extends FONode {
      * 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());
   }
 
 
diff --git a/src/org/apache/fop/fo/GenericShorthandParser.java b/src/org/apache/fop/fo/GenericShorthandParser.java
new file mode 100644 (file)
index 0000000..90f2b72
--- /dev/null
@@ -0,0 +1,50 @@
+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;
+  }
+}
diff --git a/src/org/apache/fop/fo/ListProperty.java b/src/org/apache/fop/fo/ListProperty.java
new file mode 100644 (file)
index 0000000..6c76a1e
--- /dev/null
@@ -0,0 +1,35 @@
+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; }
+
+}
index f2fe1bb09a9b9ebf1fcd5770347af1d1dac90888..3319ab7dde3042390b8bc20addecd9f1b85f31f7 100644 (file)
@@ -57,6 +57,7 @@ import org.apache.fop.fo.expr.PropertyParser;
 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 class Property {
       }
     }
 
+    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 @@ public class Property {
        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 class Property {
   */
   public int getEnum() { return 0; }
   public char getCharacter() { return 0;}
+  public Vector getList() { return null; } // List of Property objects
 
   public Number getNumber() { return null; }
 
index d3bf0541fe3067285d1c110c26353a07bc290cde..52109d4fb8a65a92d9e9833e5f5fca4454392ca7 100644 (file)
@@ -119,9 +119,56 @@ public class PropertyList extends Hashtable {
   /**
    * 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 @@ public class PropertyList extends Hashtable {
      * 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) { // else inherit (if has parent and is inheritable)
+        if (p == null) { // check for shorthand specification
+            p = builder.getShorthand(this, namespace, element, propertyName);
+        }
+        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 @@ public class PropertyList extends Hashtable {
    * 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 @@ public class PropertyList extends Hashtable {
       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);
     }
index c4da11f1bd5bc18602ea152d57054bdfcc1e1540..d7eaa79416bbbeea0f4dcf99563ffb5e13684ce0 100644 (file)
@@ -175,7 +175,7 @@ public class PropertyListBuilder {
            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 @@ public class PropertyListBuilder {
        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 {
        
diff --git a/src/org/apache/fop/fo/PropertyManager.java b/src/org/apache/fop/fo/PropertyManager.java
new file mode 100644 (file)
index 0000000..ed8a2c5
--- /dev/null
@@ -0,0 +1,153 @@
+/*-- $Id$ -- */
+/*
+ * 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;
+    }
+  }
+
+}
diff --git a/src/org/apache/fop/fo/ShorthandParser.java b/src/org/apache/fop/fo/ShorthandParser.java
new file mode 100644 (file)
index 0000000..a8a9a55
--- /dev/null
@@ -0,0 +1,6 @@
+package org.apache.fop.fo;
+
+public interface ShorthandParser {
+  public Property getValueForProperty(String propName, Property.Maker maker,
+    PropertyList propertyList);
+}