in fop-core/src/main/java/org/apache/fop/fo/XMLWhiteSpaceHandler.java [92:243]
public void handleWhiteSpace(FObjMixed fo,
FONode firstTextNode,
FONode nextChild) {
Block currentBlock = null;
int foId = fo.getNameId();
/* set the current block */
switch (foId) {
case Constants.FO_BLOCK:
currentBlock = (Block) fo;
if (nestedBlockStack.empty() || fo != nestedBlockStack.peek()) {
if (nextChild != null) {
/* if already in a block, push the current block
* onto the stack of nested blocks
*/
nestedBlockStack.push(currentBlock);
}
} else {
if (nextChild == null) {
nestedBlockStack.pop();
}
}
break;
case Constants.FO_RETRIEVE_MARKER:
/* look for the nearest block ancestor, if any */
FONode ancestor = fo;
do {
ancestor = ancestor.getParent();
} while (ancestor.getNameId() != Constants.FO_BLOCK
&& ancestor.getNameId() != Constants.FO_STATIC_CONTENT);
if (ancestor.getNameId() == Constants.FO_BLOCK) {
currentBlock = (Block) ancestor;
nestedBlockStack.push(currentBlock);
}
break;
default:
if (!nestedBlockStack.empty()) {
currentBlock = (Block) nestedBlockStack.peek();
}
}
if (currentBlock != null) {
linefeedTreatment = currentBlock.getLinefeedTreatment();
whiteSpaceCollapse = currentBlock.getWhitespaceCollapse();
whiteSpaceTreatment = currentBlock.getWhitespaceTreatment();
} else {
linefeedTreatment = Constants.EN_TREAT_AS_SPACE;
whiteSpaceCollapse = Constants.EN_TRUE;
whiteSpaceTreatment = Constants.EN_IGNORE_IF_SURROUNDING_LINEFEED;
}
endOfBlock = (nextChild == null && fo == currentBlock);
if (firstTextNode == null) {
//no text means no white-space to handle; return early
afterLinefeed = (fo == currentBlock && fo.firstChild == null);
nonWhiteSpaceCount = 0;
if (endOfBlock) {
handlePendingInlines();
}
return;
}
charIter = new RecursiveCharIterator(fo, firstTextNode);
inWhiteSpace = false;
if (firstTextNode.siblings != null && firstTextNode.siblings[0] != null
&& firstTextNode.siblings[0].getNameId() == Constants.FO_FLOAT) {
inWhiteSpace = ((Float) firstTextNode.siblings[0]).getInWhiteSpace();
}
if (fo == currentBlock
|| currentBlock == null
|| (foId == Constants.FO_RETRIEVE_MARKER
&& fo.getParent() == currentBlock)) {
if (firstTextNode == fo.firstChild) {
afterLinefeed = true;
} else {
int previousChildId = firstTextNode.siblings[0].getNameId();
afterLinefeed = (previousChildId == Constants.FO_BLOCK
|| previousChildId == Constants.FO_TABLE_AND_CAPTION
|| previousChildId == Constants.FO_TABLE
|| previousChildId == Constants.FO_LIST_BLOCK
|| previousChildId == Constants.FO_BLOCK_CONTAINER);
}
}
if (foId == Constants.FO_WRAPPER) {
FONode parent = fo.parent;
int parentId = parent.getNameId();
while (parentId == Constants.FO_WRAPPER) {
parent = parent.parent;
parentId = parent.getNameId();
}
if (parentId == Constants.FO_FLOW
|| parentId == Constants.FO_STATIC_CONTENT
|| parentId == Constants.FO_BLOCK_CONTAINER
|| parentId == Constants.FO_TABLE_CELL) {
endOfBlock = (nextChild == null);
}
}
if (nextChild != null) {
int nextChildId = nextChild.getNameId();
nextChildIsBlockLevel = (
nextChildId == Constants.FO_BLOCK
|| nextChildId == Constants.FO_TABLE_AND_CAPTION
|| nextChildId == Constants.FO_TABLE
|| nextChildId == Constants.FO_LIST_BLOCK
|| nextChildId == Constants.FO_BLOCK_CONTAINER);
} else {
nextChildIsBlockLevel = false;
}
handleWhiteSpace();
if (fo == currentBlock
&& (endOfBlock || nextChildIsBlockLevel)) {
handlePendingInlines();
}
if (nextChild == null) {
if (fo != currentBlock) {
/* current FO is not a block, and is about to end */
if (nonWhiteSpaceCount > 0 && pendingInlines != null) {
/* there is non-white-space text between the pending
* inline(s) and the end of the non-block node;
* clear list of pending inlines */
pendingInlines.clear();
}
if (inWhiteSpace) {
/* means there is at least one trailing space in the
inline FO that is about to end */
addPendingInline();
}
} else {
/* end of block: clear the references and pop the
* nested block stack */
if (!nestedBlockStack.empty()) {
nestedBlockStack.pop();
}
charIter = null;
firstWhiteSpaceInSeq = null;
}
}
if (nextChild instanceof Float) {
((Float) nextChild).setInWhiteSpace(inWhiteSpace);
}
}