Browse Source

Added:

getPrecedingSibling
getFollowingSibling
precedingLeaf
followingLeaf
to support resolution of keeps and space-specifiers.


git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/FOP_0-20-0_Alt-Design@197284 13f79535-47bb-0310-9956-ffa450edef68
tags/Alt-Design_pre_awt_renderer_import
Peter Bernard West 20 years ago
parent
commit
aed2f710bc
1 changed files with 151 additions and 10 deletions
  1. 151
    10
      src/java/org/apache/fop/datastructs/Node.java

+ 151
- 10
src/java/org/apache/fop/datastructs/Node.java View File

@@ -181,7 +181,7 @@ public class Node implements Cloneable {
}

/**
* Insert a subtree at a specified index position in the child list.
* Inserts a subtree at a specified index position in the child list.
* @param index position of subtree within children
* @param subtree to insert
* @throws IndexOutOfBoundsException
@@ -194,7 +194,7 @@ public class Node implements Cloneable {
}

/**
* Add a subtree to the child list.
* Adds a subtree to the child list.
* @param subtree to insert
* @throws IndexOutOfBoundsException
*/
@@ -382,7 +382,7 @@ public class Node implements Cloneable {
}

/**
* Delete <code>this</code> subtree and return a count of the deleted
* Deletes <code>this</code> subtree and returns a count of the deleted
* nodes. The deletion is effected by cutting the references between
* <code>this</code> and its parent (if any). All other relationships
* within the subtree are maintained.
@@ -430,7 +430,7 @@ public class Node implements Cloneable {
}

/**
* Get the parent of this <tt>Node</tt>.
* Gets the parent of this <tt>Node</tt>.
* @return the parent <tt>Node</tt>.
*/
public Node getParent() {
@@ -443,7 +443,7 @@ public class Node implements Cloneable {
}

/**
* Set the <i>parent</i> field of this node.
* Sets the <i>parent</i> field of this node.
* @param parent the reference to set
*/
public void setParent(Node parent) {
@@ -457,7 +457,7 @@ public class Node implements Cloneable {
}

/**
* Nullify the parent <tt>Node</tt> of this node.
* Nullifies the parent <tt>Node</tt> of this node.
*/
public void unsetParent() {
if (synchronize) {
@@ -469,7 +469,7 @@ public class Node implements Cloneable {
}

/**
* Get the n'th child of this node.
* Gets the n'th child of this node.
* @param n - the <tt>int</tt> index of the child to return.
* @return the <tt>Node</tt> reference to the n'th child.
*/
@@ -485,7 +485,7 @@ public class Node implements Cloneable {
}

/**
* Get an <tt>Iterator</tt> over the children of this node.
* Gets an <tt>Iterator</tt> over the children of this node.
* @return the <tt>Iterator</tt>.
*/
public Iterator nodeChildren() {
@@ -500,7 +500,7 @@ public class Node implements Cloneable {
}

/**
* Get the number of children of this node.
* Gets the number of children of this node.
* @return the <tt>int</tt> number of children.
*/
public int numChildren() {
@@ -513,7 +513,148 @@ public class Node implements Cloneable {
if (children == null) return 0;
return children.size();
}

/**
* Gets the preceding sibling of this <code>Node</code>,
* or <code>null</code> if none.
* @return the sibling node
*/
public Node getPrecedingSibling() {
if (synchronize) {
synchronized (this) {
if (this.parent == null) return null;
int thisChild = parent.children.indexOf(this);
if (thisChild == 0) return null;
return parent.getChild(--thisChild);
}
}
if (this.parent == null) return null;
int thisChild = parent.children.indexOf(this);
if (thisChild == 0) return null;
return parent.getChild(--thisChild);
}
/**
* Gets the following sibling of this <code>Node</code>,
* or <code>null</code> if none.
* @return the sibling node
*/
public Node getFollowingSibling() {
if (synchronize) {
synchronized (this) {
if (this.parent == null) return null;
int thisChild = parent.children.indexOf(this);
if (++thisChild >= parent.numChildren()) return null;
return parent.getChild(thisChild);
}
}
if (this.parent == null) return null;
int thisChild = parent.children.indexOf(this);
if (++thisChild >= parent.numChildren()) return null;
return parent.getChild(thisChild);
}
/**
* Gets the leaf <code>Node</code> immediately preceding this node in the
* pre-order tree rooted on the <code>nominalRoot</code>, or, if the
* nominal root is not encountered, the actual root.
* In a pre-order tree, all children follow their parent.
* @param nominalRoot the root node for the purposes of this operation
* @return the preceding leaf node or <code>null</code>
*/
public Node precedingLeaf(Node nominalRoot) {
if (synchronize) {
synchronized (this) {
return getPrecedingLeaf(nominalRoot);
}
}
return getPrecedingLeaf(nominalRoot);
}
/**
* Realizes <code>precedingLeaf()</code>. Climbs the tree rooted at
* <code>nominalRoot</code> from <code>this</code>, searching for an
* ancestor with a branch preceding this.
* If none is found, there is no preceding leaf node.
* If one is found, it is descended to the last pre-order node,
* i.e. the leaf most closely preceding <code>this</code>.
* @param nominalRoot the root node for the purposes of this operation
* @return the preceding leaf node or <code>null</code>
*/
private Node getPrecedingLeaf(Node nominalRoot) {
if (this == nominalRoot || this.parent == null) {
return null;
}
Node sibling = null;
Node pivot = this.parent;
while (pivot != nominalRoot) {
if ((sibling = pivot.getPrecedingSibling()) != null) {
break;
}
pivot = pivot.parent;
}
if (pivot == nominalRoot) { // No preceding leaf node
return null;
}
// We have the pivot preceding sibling - now descend the
// preceding subtree to the last leaf
int numChildren;
while ((numChildren = sibling.numChildren()) > 0) {
sibling = sibling.getChild(--numChildren);
}
return sibling;
}
/**
* Gets the leaf <code>Node</code> immediately following this node in the
* post-order tree rooted on the <code>nominalRoot</code>, or, if the
* nominal root is not encountered, the actual root.
* In a post-order tree, all children precede their parent.
* @param nominalRoot the root node for the purposes of this operation
* @return the following leaf node or <code>null</code>
*/
public Node followingLeaf(Node nominalRoot) {
if (synchronize) {
synchronized (this) {
return getFollowingLeaf(nominalRoot);
}
}
return getFollowingLeaf(nominalRoot);
}
/**
* Realizes <code>followingLeaf()</code>. Climbs the tree rooted at
* <code>nominalRoot</code> from <code>this</code>, searching for an
* ancestor with a branch following this.
* If none is found, there is no following leaf node.
* If one is found, it is descended to the first post-order node,
* i.e. the leaf most closely following <code>this</code>.
* @param nominalRoot the root node for the purposes of this operation
* @return the following leaf node or <code>null</code>
*/
private Node getFollowingLeaf(Node nominalRoot) {
if (this == nominalRoot || this.parent == null) {
return null;
}
Node sibling = null;
Node pivot = this.parent;
while (pivot != nominalRoot) {
if ((sibling = pivot.getFollowingSibling()) != null) {
break;
}
pivot = pivot.parent;
}
if (pivot == nominalRoot) { // No preceding leaf node
return null;
}
// We have the pivot following sibling - now descend the
// following subtree to the first leaf
while (sibling.numChildren() > 0) {
sibling = sibling.getChild(0);
}
return sibling;
}
/**
* Class <tt>PreOrder</tt> is a member class of <tt>Node</tt>.
*

Loading…
Cancel
Save