import org.apache.fop.fo.expr.PropertyParser;
import org.apache.fop.fo.expr.PropertyValue;
import org.apache.fop.fo.expr.PropertyValueList;
+import org.apache.fop.fo.expr.PropertyTriplet;
import org.apache.fop.datastructs.Tree;
+import org.apache.fop.datatypes.Inherit;
import org.apache.fop.apps.FOPException;
import org.apache.fop.xml.XMLEvent;
import org.apache.fop.xml.SyncedXmlEventsBuffer;
import org.xml.sax.Attributes;
import java.util.LinkedList;
+import java.util.Iterator;
import java.util.ArrayList;
import java.util.HashMap;
import java.lang.reflect.Method;
protected XMLNamespaces namespaces;
/** The FO type. */
public final int type;
- /** The node identifier obtained from <tt>foTree</tt>. */
- public final int id;
/** The array of property value stacks */
protected LinkedList[] propertyStacks;
/** The attributes defined on this node. */
namespaces = xmlevents.getNamespaces();
propertyStacks = foTree.propertyStacks;
exprParser = foTree.exprParser;
- id = foTree.nextNodeID();
foAttributes = new FOAttributes(event, this);
if ( ! (attrSet == MARKER)) {
processProperties();
throw new PropertyException (e.getMessage());
}
}
+
+ /**
+ * Get the parent's <tt>PropertyTriplet</tt> for the given property.
+ * @param property - the property of interest.
+ * @return the <tt>PropertyTriplet</tt> of the parent node.
+ */
+ public PropertyTriplet getParentTriplet(int property) {
+ PropertyTriplet triplet = null;
+ LinkedList stack = foTree.propertyStacks[property];
+ int size = stack.size();
+ int next = size;
+ // There must be at least one
+ triplet = (PropertyTriplet)(stack.get(--next));
+ // Following equality can't be the case for initial values,
+ // as their stackedBy will be null.
+ if (triplet.getStackedBy() == this) {
+ triplet = (PropertyTriplet)(stack.get(--next));
+ }
+ return triplet;
+ }
+
+ /**
+ * Get the <tt>PropertyTriplet</tt> of the nearest ancestor with a
+ * specified value for the given property.
+ * @param property - the property of interest.
+ * @return the nearest specified <tt>PropertyTriplet</tt>.
+ */
+ public PropertyTriplet getNearestSpecifiedTriplet(int property)
+ throws PropertyException
+ {
+ PropertyTriplet triplet = null;
+ PropertyValue value = null;
+ Iterator stackp = foTree.propertyStacks[property].iterator();
+ while (stackp.hasNext()) {
+ triplet = (PropertyTriplet)(stackp.next());
+ // Following equality can't be the case for initial values,
+ // as their stackedBy will be null.
+ if (triplet.getStackedBy() == this) continue;
+ if ((value = triplet.getSpecified()) != null) break;
+ }
+ if (value == null)
+ throw new PropertyException
+ ("No specified value in stack for " + property + ": "
+ + PropNames.getPropertyName(property));
+ return triplet;
+ }
+
+ /**
+ * Get the computed value from nearest ancestor with a specified value.
+ * @param property - the index of both target and source properties.
+ * @return - the computed value corresponding to the nearest specified
+ * value (which may be the initial value) if it exists. If no computed
+ * value is available, return an <tt>Inherit</tt> object with a reference
+ * to the PropertyTriplet.
+ */
+ public PropertyValue fromNearestSpecified(int property)
+ throws PropertyException
+ {
+ return fromNearestSpecified(property, property);
+ }
+
+ /**
+ * Get the computed value from nearest ancestor with a specified value.
+ * @param property - the index of the target property.
+ * @param sourceProperty - the index of the source property.
+ * @return - the computed value corresponding to the nearest specified
+ * value (which may be the initial value) if it exists. If no computed
+ * value is available, return an <tt>Inherit</tt> object with a reference
+ * to the PropertyTriplet.
+ */
+ public PropertyValue fromNearestSpecified
+ (int property, int sourceProperty)
+ throws PropertyException
+ {
+ PropertyValue value;
+ PropertyTriplet triplet = getNearestSpecifiedTriplet(sourceProperty);
+ if ((value = triplet.getComputed()) == null) {
+ // No computed value is available. Use an IndirectValue
+ Inherit inherit = new Inherit(property, sourceProperty);
+ inherit.setInheritedTriplet(triplet);
+ return inherit;
+ }
+ return value;
+ }
+
+ /**
+ * Get the computed value from the parent FO of the source property.
+ * @param property - the index of both target and source properties.
+ * @return - the computed value from the parent FO node, if it exists.
+ * If not, get the computed initial value. If no computed
+ * value is available, return an <tt>Inherit</tt> object with a reference
+ * to the PropertyTriplet.
+ */
+ public PropertyValue fromParent(int property)
+ throws PropertyException
+ {
+ return fromParent(property, property);
+ }
+
+ /**
+ * Get the computed value from the parent FO of the source property.
+ * @param property - the index of the target property.
+ * @param sourceProperty - the index of the source property.
+ * @return - the computed value from the parent FO node, if it exists.
+ * If not, get the computed initial value. If no computed
+ * value is available, return an <tt>Inherit</tt> object with a reference
+ * to the PropertyTriplet.
+ */
+ public PropertyValue fromParent(int property, int sourceProperty)
+ throws PropertyException
+ {
+ PropertyTriplet triplet = null;
+ PropertyValue value = null;
+ triplet = getParentTriplet(sourceProperty);
+ if ((value = triplet.getComputed()) == null) {
+ // No computed value is available. Use an IndirectValue
+ Inherit inherit = new Inherit(property, sourceProperty);
+ inherit.setInheritedTriplet(triplet);
+ return inherit;
+ }
+ return value;
+ }
}// FONode