Переглянути джерело

Minor improvement: avoid potential problems in case of nested blocks

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@434010 13f79535-47bb-0310-9956-ffa450edef68
tags/fop-0_93
Andreas L. Delmelle 18 роки тому
джерело
коміт
aa26e120ea
1 змінених файлів з 89 додано та 63 видалено
  1. 89
    63
      src/java/org/apache/fop/fo/XMLWhiteSpaceHandler.java

+ 89
- 63
src/java/org/apache/fop/fo/XMLWhiteSpaceHandler.java Переглянути файл

@@ -31,11 +31,11 @@ import org.apache.fop.util.CharUtilities;
*/
public class XMLWhiteSpaceHandler {
// True if we are in a run of white space
/** True if we are in a run of white space */
private boolean inWhiteSpace = false;
// True if the last char was a linefeed
/** True if the last char was a linefeed */
private boolean afterLinefeed = true;
// Counter, increased every time a non-white-space is encountered
/** Counter, increased every time a non-white-space is encountered */
private int nonWhiteSpaceCount;
private Block currentBlock;
@@ -50,6 +50,7 @@ public class XMLWhiteSpaceHandler {
private List discardableFOCharacters;
private List pendingInlines;
private List nestedBlockStack = new java.util.ArrayList(5);
private CharIterator firstWhiteSpaceInSeq;
/**
@@ -72,65 +73,66 @@ public class XMLWhiteSpaceHandler {
* @param firstTextNode the node at which to start
*/
public void handleWhiteSpace(FObjMixed fo, FONode firstTextNode) {
if (fo.getNameId() == Constants.FO_BLOCK
|| fo.getNameId() == Constants.FO_RETRIEVE_MARKER) {
if (fo.getNameId() == Constants.FO_BLOCK) {
this.currentBlock = (Block) fo;
} else {
FONode ancestor = fo.parent;
while (ancestor.getNameId() != Constants.FO_BLOCK
&& ancestor.getNameId() != Constants.FO_STATIC_CONTENT) {
ancestor = ancestor.getParent();
}
if (ancestor.getNameId() == Constants.FO_BLOCK) {
this.currentBlock = (Block) ancestor;
}
}
if (currentBlock != null) {
this.linefeedTreatment = currentBlock.getLinefeedTreatment();
this.whiteSpaceCollapse = currentBlock.getWhitespaceCollapse();
this.whiteSpaceTreatment =
currentBlock.getWhitespaceTreatment();
} else {
/* fo:retrieve-marker as direct child of static-content
* set properties to their initial values
int foId = fo.getNameId();
if (foId == Constants.FO_BLOCK) {
if (nextChild != null && currentBlock != null) {
/* if already in a block, push the current block
* onto the stack of nested blocks
*/
this.linefeedTreatment = Constants.EN_TREAT_AS_SPACE;
this.whiteSpaceCollapse = Constants.EN_TRUE;
this.whiteSpaceTreatment =
Constants.EN_IGNORE_IF_SURROUNDING_LINEFEED;
pushNestedBlockStack();
}
} else if (fo.getNameId() == Constants.FO_TITLE
|| fo.getNameId() == Constants.FO_BOOKMARK_TITLE) {
/* Two special types of FO that can contain #PCDATA
* set properties to their initial values
*/
this.linefeedTreatment = Constants.EN_TREAT_AS_SPACE;
this.whiteSpaceCollapse = Constants.EN_TRUE;
this.whiteSpaceTreatment =
Constants.EN_IGNORE_IF_SURROUNDING_LINEFEED;
currentBlock = (Block) fo;
} else if (foId == Constants.FO_RETRIEVE_MARKER) {
/* look for the nearest block ancestor, if any */
FONode ancestor;
do {
ancestor = fo.getParent();
} while (ancestor.getNameId() != Constants.FO_BLOCK
&& ancestor.getNameId() != Constants.FO_STATIC_CONTENT);
if (ancestor.getNameId() == Constants.FO_BLOCK) {
currentBlock = (Block) ancestor;
}
}
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;
}
currentFO = fo;

if (firstTextNode == null) {
//nothing to do but initialize related properties
return;
}
charIter = new RecursiveCharIterator(fo, firstTextNode);
inWhiteSpace = false;
int textNodeIndex = -1;
if (currentFO == currentBlock
|| currentBlock == null
|| (currentFO.getNameId() == Constants.FO_RETRIEVE_MARKER
|| (foId == Constants.FO_RETRIEVE_MARKER
&& currentFO.getParent() == currentBlock)) {
textNodeIndex = fo.childNodes.indexOf(firstTextNode);
afterLinefeed = ((textNodeIndex == 0)
|| (textNodeIndex > 0
int textNodeIndex = fo.childNodes.indexOf(firstTextNode);
afterLinefeed = (
(textNodeIndex == 0)
|| (textNodeIndex > 0
&& ((FONode) fo.childNodes.get(textNodeIndex - 1))
.getNameId() == Constants.FO_BLOCK));
.getNameId() == Constants.FO_BLOCK));
}
endOfBlock = (nextChild == null && currentFO == currentBlock);
if (nextChild != null) {
int nextChildId = nextChild.getNameId();
int nextChildId = this.nextChild.getNameId();
nextChildIsBlockLevel = (
nextChildId == Constants.FO_BLOCK
|| nextChildId == Constants.FO_TABLE_AND_CAPTION
@@ -140,7 +142,9 @@ public class XMLWhiteSpaceHandler {
} else {
nextChildIsBlockLevel = false;
}
handleWhiteSpace();
if (currentFO == currentBlock
&& pendingInlines != null
&& !pendingInlines.isEmpty()) {
@@ -151,7 +155,8 @@ public class XMLWhiteSpaceHandler {
PendingInline p;
for (int i = pendingInlines.size(); --i >= 0;) {
p = (PendingInline) pendingInlines.get(i);
charIter = (RecursiveCharIterator) p.firstTrailingWhiteSpace;
charIter =
(RecursiveCharIterator) p.firstTrailingWhiteSpace;
handleWhiteSpace();
pendingInlines.remove(p);
}
@@ -163,24 +168,28 @@ public class XMLWhiteSpaceHandler {
}
}
}
if (currentFO != currentBlock && nextChild == null) {
/* 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(fo);
}
}
if (currentFO == currentBlock && nextChild == null) {
/* end of block: clear the reference */
currentBlock = null;
if (nextChild == null) {
if (currentFO != 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(fo);
}
} else {
/* end of block: clear the references and pop the
* nested block stack */
popNestedBlockStack();
currentFO = null;
charIter = null;
}
}
}
@@ -311,6 +320,23 @@ public class XMLWhiteSpaceHandler {
pendingInlines.add(new PendingInline(fo, firstWhiteSpaceInSeq));
}
private void pushNestedBlockStack() {
this.nestedBlockStack.add(
this.nestedBlockStack.size(), this.currentBlock);
}
private void popNestedBlockStack() {
if (this.nestedBlockStack.isEmpty()) {
this.currentBlock = null;
} else {
this.currentBlock = (Block) this.nestedBlockStack.get(
this.nestedBlockStack.size() - 1);
this.nestedBlockStack.remove(this.currentBlock);
}
}
private class EOLchecker {
private boolean nextIsEOL = false;
private RecursiveCharIterator charIter;

Завантаження…
Відмінити
Зберегти