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(
);