import org.apache.fop.fo.expr.PropertyParser;
import org.apache.fop.datatypes.PropertyValue;
import org.apache.fop.datatypes.PropertyValueList;
-import org.apache.fop.datatypes.PropertyTriplet;
import org.apache.fop.datastructs.Tree;
+import org.apache.fop.datastructs.ROBitSet;
import org.apache.fop.datatypes.indirect.Inherit;
+import org.apache.fop.datatypes.indirect.IndirectValue;
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.BitSet;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.HashMap;
private static final String tag = "$Name$";
private static final String revision = "$Revision$";
- /**
- * Constants for the set of attributes of interest with this FONode
- */
- public static final int
- NONE = 0
- ,ROOT = 1
- ,LAYOUT = 2
- ,PAGESEQ = 3
- ,FLOW = 4
- ,STATIC = 5
- ,MARKER = 6
- ;
/** The <tt>FOTree</tt> of which this node is a member. */
protected FOTree foTree;
+ /** The parent <tt>FONode</tt> of this node. */
+ protected FONode parent;
/** The <tt>XMLEvent</tt> which triggered this node. */
protected XMLEvent event;
/** The buffer from which parser events are drawn. */
protected XMLNamespaces namespaces;
/** The FO type. */
public final int type;
- /** The array of property value stacks */
- protected LinkedList[] propertyStacks;
/** The attributes defined on this node. */
public FOAttributes foAttributes;
- /** The properties defined on this node. */
+ /** The unmodifiable map of properties defined on this node. */
public HashMap foProperties = null;
+ /** The sorted keys of <i>foProperties</i>. */
+ protected Integer[] foKeys = null;
+ /** The size of <i>foKeys</i>. */
+ private int numAttrs = 0;
/** The property expression parser in the FOTree. */
protected PropertyParser exprParser;
+ /** The property set for this node. */
+ protected PropertyValue[] propertySet;
+ /** BitSet of properties for which specified values have been stacked. */
+ private BitSet stackedProps =
+ new BitSet(PropNames.LAST_PROPERTY_INDEX + 1);
+ /** The <i>attrSet</i> argument. */
+ public final int attrSet;
+ /** The <tt>ROBitSet</tt> of the <i>attrSet</i> argument. */
+ protected ROBitSet nodeAttrBitSet;
/** Ancestor reference area of this FONode. */
protected FONode ancestorRefArea = null;
foTree.super(parent);
this.foTree = foTree;
this.type = type;
+ this.parent = parent;
this.event = event;
+ this.attrSet = attrSet;
xmlevents = foTree.xmlevents;
namespaces = xmlevents.getNamespaces();
- propertyStacks = foTree.propertyStacks;
exprParser = foTree.exprParser;
+ propertySet = new PropertyValue[PropNames.LAST_PROPERTY_INDEX + 1];
foAttributes = new FOAttributes(event, this);
- if ( ! (attrSet == MARKER)) {
- processProperties();
+ if ( ! (attrSet == FObjects.MARKER_SET)) {
+ processAttributes();
}
}
- private void processProperties() throws PropertyException {
+ private void processAttributes() throws PropertyException {
// Process the FOAttributes - parse and stack the values
// Build a HashMap of the properties defined on this node
foProperties = foAttributes.getFoAttrMap();
- PropertyValue props;
- for (int prop = 1; prop <= PropNames.LAST_PROPERTY_INDEX; prop++) {
- String value = foAttributes.getFoAttrValue(prop);
- if (value != null) { // property is defined in the attributes
- props = handleAttrValue(prop, value);
+ numAttrs = foProperties.size();
+ if (numAttrs > 0) {
+ foKeys = foAttributes.getFoAttrKeys();
+ }
+ for (int propx = 0; propx < numAttrs; propx++) {
+ PropertyValue props;
+ int type;
+ int prop = foKeys[propx].intValue();
+ String attrValue = foAttributes.getFoAttrValue(prop);
+ props = handleAttrValue(prop, attrValue);
+ type = props.getType();
+ if (type != PropertyValue.LIST) {
+ stackValue(props);
+ // Handle corresponding properties here
+ // Update the propertySet
+ propertySet[props.getProperty()] = props;
+ } else { // a list
+ PropertyValue value;
+ Iterator propvals = ((PropertyValueList)props).iterator();
+ while (propvals.hasNext()) {
+ value = (PropertyValue)(propvals.next());
+ stackValue(value);
+ // Handle corresponding properties here
+ propertySet[value.getProperty()] = value;
+ }
}
}
}
}
}
+ private void stackValue(PropertyValue value) throws PropertyException {
+ int property = value.getProperty();
+ PropertyValue currentValue = foTree.getCurrentPropertyValue(property);
+ if (currentValue.getStackedBy() == this)
+ foTree.popPropertyValue(property);
+ value.setStackedBy(this);
+ foTree.pushPropertyValue(value);
+ stackedProps.set(property);
+ }
+
+ private void unstackValues() throws PropertyException {
+ for (int prop = stackedProps.nextSetBit(0);
+ prop >=0;
+ prop = stackedProps.nextSetBit(++prop)
+ ) {
+ PropertyValue value = foTree.popPropertyValue(prop);
+ if (value.getStackedBy() != this)
+ throw new PropertyException
+ ("Unstacked property not stacked by this node.");
+ }
+ }
+
/**
- * Get the parent's <tt>PropertyTriplet</tt> for the given property.
+ * Get the parent's <tt>PropertyValue</tt> for the given property.
* @param property - the property of interest.
- * @return the <tt>PropertyTriplet</tt> of the parent node.
+ * @return the <tt>PropertyValue</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;
+ public PropertyValue getParentPropertyValue(int property) {
+ return parent.propertySet[property];
}
/**
- * Get the <tt>PropertyTriplet</tt> of the nearest ancestor with a
+ * Get the <tt>PropertyValue</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>.
+ * @return the nearest specified <tt>PropertyValue</tt>.
*/
- public PropertyTriplet getNearestSpecifiedTriplet(int property)
+ public PropertyValue getNearestSpecifiedValue(int property)
throws PropertyException
{
- PropertyTriplet triplet = null;
PropertyValue value = null;
- Iterator stackp = foTree.propertyStacks[property].iterator();
- while (stackp.hasNext()) {
- triplet = (PropertyTriplet)(stackp.next());
+ ArrayList stack = foTree.propertyStacks[property];
+ int stackp = stack.size();
+ while (stackp-- > 0) {
+ value = (PropertyValue)(stack.get(stackp));
// 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.getStackedBy() == this) continue;
+ return value;
}
- if (value == null)
- throw new PropertyException
- ("No specified value in stack for " + property + ": "
+ throw new PropertyException
+ ("No specified value in stack for " + property + ": "
+ PropNames.getPropertyName(property));
- return triplet;
}
/**
(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
+ PropertyValue value = getNearestSpecifiedValue(sourceProperty);
+ // Determine whether an indirect value is required
+ if (IndirectValue.isUnresolved(value)) {
Inherit inherit = new Inherit(property, sourceProperty);
- inherit.setInheritedTriplet(triplet);
+ inherit.setInheritedValue(value);
return inherit;
}
return value;
public PropertyValue fromParent(int property, int sourceProperty)
throws PropertyException
{
- PropertyTriplet triplet = null;
- PropertyValue value = null;
- triplet = getParentTriplet(sourceProperty);
- if ((value = triplet.getComputed()) == null) {
+ PropertyValue value = getParentPropertyValue(sourceProperty);
+ if (value == null) {
// No computed value is available. Use an IndirectValue
Inherit inherit = new Inherit(property, sourceProperty);
- inherit.setInheritedTriplet(triplet);
+ inherit.setInheritedValue(value);
return inherit;
}
return value;