package org.apache.fop.fo; import org.apache.fop.fo.Constants; import java.util.BitSet; import java.util.ArrayList; public class PropertySets { private static short[][] mapping = null; private Element[] elements = new Element[Constants.ELEMENT_COUNT+1]; private BitSet block_elems = new BitSet(); private BitSet inline_elems = new BitSet(); public void initializeElements() { block_elems.set(Constants.FO_BLOCK); block_elems.set(Constants.FO_BLOCK_CONTAINER); block_elems.set(Constants.FO_TABLE_AND_CAPTION); block_elems.set(Constants.FO_TABLE); block_elems.set(Constants.FO_LIST_BLOCK); inline_elems.set(Constants.FO_BIDI_OVERRIDE); inline_elems.set(Constants.FO_CHARACTER); inline_elems.set(Constants.FO_EXTERNAL_GRAPHIC); inline_elems.set(Constants.FO_INSTREAM_FOREIGN_OBJECT); inline_elems.set(Constants.FO_INLINE); inline_elems.set(Constants.FO_INLINE_CONTAINER); inline_elems.set(Constants.FO_LEADER); inline_elems.set(Constants.FO_PAGE_NUMBER); inline_elems.set(Constants.FO_PAGE_NUMBER_CITATION); inline_elems.set(Constants.FO_BASIC_LINK); inline_elems.set(Constants.FO_MULTI_TOGGLE); } public void initializeCommon() { } public void initialize() { // define the fo: elements for (int i = 1; i < elements.length; i++) { elements[i] = new Element(i); } // populate the elements with properties and content elements. Element elem; // Merge the attributes from the children into the parent. for (boolean dirty = true; dirty; ) { dirty = false; for (int i = 1; i < elements.length; i++) { dirty = dirty || elements[i].merge(); } } // Calculate the sparse indices for each element. for (int i = 1; i < elements.length; i++) { mapping[i] = makeSparseIndices(elements[i].valid); } } /** * Turn a BitSet into an array of shorts with the first element * on the array the number of set bits in the BitSet. */ private static short[] makeSparseIndices(BitSet set) { short[] indices = new short[Constants.PROPERTY_COUNT+1]; int j = 1; for (int i = 0; i < Constants.PROPERTY_COUNT+1; i++) { if (set.get(i)) { indices[i] = (short) j++; } } indices[0] = (short)j; return indices; } public static short[] getPropertySet(int elementId) { if (mapping == null) { mapping = new short[Constants.ELEMENT_COUNT+1][]; PropertySets ps = new PropertySets(); ps.initializeElements(); ps.initializeCommon(); ps.initialize(); } return mapping[elementId]; } /** * An object that represent the properties and contents of a fo element */ class Element { BitSet relevant = new BitSet(); BitSet valid = new BitSet(); int elementId; ArrayList children; Element(int elementId) { this.elementId = elementId; } /** * Add a single property to the element. */ public void addProperty(int propId) { relevant.set(propId); valid.set(propId); } /** * Add a set of properties to the element. */ public void addProperties(BitSet properties) { relevant.or(properties); valid.or(properties); } /** * Add a single fo element as a content child. */ public void addContent(int elementId) { if (children == null) { children = new ArrayList(); } children.add(elements[elementId]); } /** * Add a set of fo elements as content children. */ public void addContent(BitSet elements) { for (int i = 0; i < elements.size(); i++) { if (elements.get(i)) { addContent(i); } } } /** * Merge the properties from the children into the set of valid * properties. Return true if at least one property could be added. */ public boolean merge() { if (children == null) { return false; } boolean dirty = false; for (int i = 0; i < children.size(); i++) { Element child = (Element) children.get(i); BitSet childValid = child.valid; int n = childValid.length(); for (int j = 0; j < n; j++) { if (childValid.get(j) && !valid.get(j)) { dirty = true; valid.set(j); } } } return dirty; } } } BitSet = new BitSet(); .set(Constants.PR_ ); elem = elements[Constants.FO_ ]; elem.addProperties( ); elem.addProperty(Constants.PR_ ); Constants.FO_ elem.addContent(block_elems); elem.addContent(inline_elems); elem.addContent( );