You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by ad...@apache.org on 2008/06/23 00:10:56 UTC
svn commit: r670422 - in /xmlgraphics/fop/trunk/src/java/org/apache/fop: fo/
fo/flow/ layoutmgr/ layoutmgr/inline/ render/rtf/
Author: adelmelle
Date: Sun Jun 22 15:10:55 2008
New Revision: 670422
URL: http://svn.apache.org/viewvc?rev=670422&view=rev
Log:
Switch FOText to use a java.nio.CharBuffer, and implement the CharSequence interface.
TextLayoutManager no longer duplicates the char array, operates on the FOText (charAt(i))
Additionally: endOfNode() for FOText and Character deferred until after white-space handling.
Modified:
xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOText.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOTreeBuilder.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FObjMixed.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/AbstractRetrieveMarker.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/RTFHandler.java
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOText.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOText.java?rev=670422&r1=670421&r2=670422&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOText.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOText.java Sun Jun 22 15:10:55 2008
@@ -20,6 +20,7 @@
package org.apache.fop.fo;
import java.awt.Color;
+import java.nio.CharBuffer;
import java.util.NoSuchElementException;
import org.xml.sax.Locator;
@@ -33,48 +34,17 @@
import org.apache.fop.fo.properties.KeepProperty;
import org.apache.fop.fo.properties.Property;
import org.apache.fop.fo.properties.SpaceProperty;
+import org.apache.fop.util.CharUtilities;
/**
* A text node (PCDATA) in the formatting object tree.
- *
- * Unfortunately the BufferManager implementation holds
- * onto references to the character data in this object
- * longer than the lifetime of the object itself, causing
- * excessive memory consumption and OOM errors.
*/
-public class FOText extends FONode {
+public class FOText extends FONode implements CharSequence {
- /**
- * the character array containing the text
- */
- public char[] ca;
-
- /**
- * The starting valid index of the ca array
- * to be processed.
- *
- * This value is originally equal to 0, but becomes
- * incremented during leading whitespace removal by the flow.Block class,
- * via the TextCharIterator.remove() method below.
- */
- public int startIndex = 0;
+ /** the <code>CharBuffer</code> containing the text */
+ private CharBuffer charBuffer;
- /**
- * The ending valid index of the ca array
- * to be processed.
- *
- * This value is originally equal to ca.length, but becomes
- * decremented during between-word whitespace removal by the
- * XMLWhiteSpaceHandler via the TextCharIterator.remove()
- * method below.
- */
- public int endIndex = 0;
-
- /** properties relevant for PCDATA */
- /* TODO: these are basically always the same as the parent FObj or FObjMixed
- * so maybe those can be removed, and the accessors could
- * dispatch the call to the parent?
- */
+ /** properties relevant for #PCDATA */
private CommonFont commonFont;
private CommonHyphenation commonHyphenation;
private Color color;
@@ -105,10 +75,10 @@
* which FOText nodes are descendants of the same block.
*/
private Block ancestorBlock = null;
-
+
/** Holds the text decoration values. May be null */
private CommonTextDecoration textDecoration;
-
+
private static final int IS_WORD_CHAR_FALSE = 0;
private static final int IS_WORD_CHAR_TRUE = 1;
private static final int IS_WORD_CHAR_MAYBE = 2;
@@ -126,33 +96,58 @@
protected void addCharacters(char[] data, int start, int length,
PropertyList list, Locator locator) throws FOPException {
- int calength = 0;
- char[] nca;
- if (ca != null) {
- calength = ca.length;
- nca = new char[calength + length];
- System.arraycopy(ca, 0, nca, 0, calength);
+ if (this.charBuffer == null) {
+ // buffer not yet initialized, do so now
+ this.charBuffer = CharBuffer.allocate(length);
} else {
- nca = new char[length];
+ // allocate a larger buffer, and transfer contents
+ int newLength = this.charBuffer.limit() + length;
+ CharBuffer newBuffer = CharBuffer.allocate(newLength);
+ this.charBuffer.rewind();
+ newBuffer.put(this.charBuffer);
+ this.charBuffer = newBuffer;
}
- System.arraycopy(data, start, nca, calength, length);
- endIndex = nca.length;
- this.ca = nca;
- }
+ // append characters
+ this.charBuffer.put(data, start, length);
+
+ }
/**
- * {@inheritDoc}
+ * Return the array of characters for this instance.
+ *
+ * @return a char array containing the text
*/
+ public char[] getCharArray() {
+
+ if (this.charBuffer == null) {
+ return null;
+ }
+
+ if (this.charBuffer.hasArray()) {
+ return this.charBuffer.array();
+ }
+
+ // only if the buffer implementation has
+ // no accessible backing array, return a new one
+ char[] ca = new char[this.charBuffer.limit()];
+ this.charBuffer.rewind();
+ this.charBuffer.get(ca);
+ return ca;
+
+ }
+
+ /** {@inheritDoc} */
public FONode clone(FONode parent, boolean removeChildren)
throws FOPException {
FOText ft = (FOText) super.clone(parent, removeChildren);
if (removeChildren) {
- //not really removing, but just make sure the char array
- //pointed to is really a different one, and reset any
- //possible whitespace-handling effects
- if (ca != null) {
- ft.ca = new char[ca.length];
- System.arraycopy(ca, 0, ft.ca, 0, ca.length);
+ // not really removing, just make sure the char buffer
+ // pointed to is really a different one
+ if (this.charBuffer != null) {
+ ft.charBuffer = CharBuffer.allocate(this.charBuffer.limit());
+ this.charBuffer.rewind();
+ ft.charBuffer.put(this.charBuffer);
+ ft.charBuffer.rewind();
}
}
ft.prevFOTextThisBlock = null;
@@ -161,29 +156,33 @@
return ft;
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void bind(PropertyList pList) throws FOPException {
- commonFont = pList.getFontProps();
- commonHyphenation = pList.getHyphenationProps();
- color = pList.get(Constants.PR_COLOR).getColor(getUserAgent());
- keepTogether = pList.get(Constants.PR_KEEP_TOGETHER).getKeep();
- lineHeight = pList.get(Constants.PR_LINE_HEIGHT).getSpace();
- letterSpacing = pList.get(Constants.PR_LETTER_SPACING);
- whiteSpaceCollapse = pList.get(Constants.PR_WHITE_SPACE_COLLAPSE).getEnum();
- whiteSpaceTreatment = pList.get(Constants.PR_WHITE_SPACE_TREATMENT).getEnum();
- textTransform = pList.get(Constants.PR_TEXT_TRANSFORM).getEnum();
- wordSpacing = pList.get(Constants.PR_WORD_SPACING);
- wrapOption = pList.get(Constants.PR_WRAP_OPTION).getEnum();
- textDecoration = pList.getTextDecorationProps();
- baselineShift = pList.get(Constants.PR_BASELINE_SHIFT).getLength();
+ this.commonFont = pList.getFontProps();
+ this.commonHyphenation = pList.getHyphenationProps();
+ this.color = pList.get(Constants.PR_COLOR).getColor(getUserAgent());
+ this.keepTogether = pList.get(Constants.PR_KEEP_TOGETHER).getKeep();
+ this.lineHeight = pList.get(Constants.PR_LINE_HEIGHT).getSpace();
+ this.letterSpacing = pList.get(Constants.PR_LETTER_SPACING);
+ this.whiteSpaceCollapse = pList.get(Constants.PR_WHITE_SPACE_COLLAPSE).getEnum();
+ this.whiteSpaceTreatment = pList.get(Constants.PR_WHITE_SPACE_TREATMENT).getEnum();
+ this.textTransform = pList.get(Constants.PR_TEXT_TRANSFORM).getEnum();
+ this.wordSpacing = pList.get(Constants.PR_WORD_SPACING);
+ this.wrapOption = pList.get(Constants.PR_WRAP_OPTION).getEnum();
+ this.textDecoration = pList.getTextDecorationProps();
+ this.baselineShift = pList.get(Constants.PR_BASELINE_SHIFT).getLength();
}
/** {@inheritDoc} */
protected void endOfNode() throws FOPException {
+ super.endOfNode();
+ getFOEventHandler().characters(
+ this.getCharArray(), 0, this.charBuffer.limit());
+ }
+
+ /** {@inheritDoc} */
+ public void finalizeNode() {
textTransform();
- getFOEventHandler().characters(ca, startIndex, endIndex - startIndex);
}
/**
@@ -197,16 +196,20 @@
*/
public boolean willCreateArea() {
if (whiteSpaceCollapse == Constants.EN_FALSE
- && endIndex - startIndex > 0) {
+ && this.charBuffer.limit() > 0) {
return true;
}
- for (int i = startIndex; i < endIndex; i++) {
- char ch = ca[i];
- if (!((ch == ' ')
- || (ch == '\n')
- || (ch == '\r')
- || (ch == '\t'))) { // whitespace
+ char ch;
+ this.charBuffer.rewind();
+ while (this.charBuffer.hasRemaining()) {
+ ch = this.charBuffer.get();
+ if (!((ch == CharUtilities.SPACE)
+ || (ch == CharUtilities.LINEFEED_CHAR)
+ || (ch == CharUtilities.CARRIAGE_RETURN)
+ || (ch == CharUtilities.TAB))) {
+ // not whitespace
+ this.charBuffer.rewind();
return true;
}
}
@@ -221,7 +224,7 @@
}
/**
- * This method is run as part of the ancestor Block's flushText(), to
+ * This method is run as part of the ancestor Block's flushText(), to
* create xref pointers to the previous FOText objects within the same Block
* @param ancestorBlock the ancestor fo:block
*/
@@ -229,7 +232,7 @@
this.ancestorBlock = ancestorBlock;
// if the last FOText is a sibling, point to it, and have it point here
if (ancestorBlock.lastFOTextProcessed != null) {
- if (ancestorBlock.lastFOTextProcessed.ancestorBlock
+ if (ancestorBlock.lastFOTextProcessed.ancestorBlock
== this.ancestorBlock) {
prevFOTextThisBlock = ancestorBlock.lastFOTextProcessed;
prevFOTextThisBlock.nextFOTextThisBlock = this;
@@ -240,16 +243,47 @@
}
/**
- * This method is run as part of the Constructor, to handle the
- * text-transform property.
+ * This method is run as part of endOfNode(), to handle the
+ * text-transform property for accumulated FOText
*/
private void textTransform() {
- if (getBuilderContext().inMarker()
+ if (getBuilderContext().inMarker()
|| textTransform == Constants.EN_NONE) {
return;
}
- for (int i = 0; i < endIndex; i++) {
- ca[i] = charTransform(i);
+
+ this.charBuffer.rewind();
+ CharBuffer tmp = this.charBuffer.slice();
+ char c;
+ int lim = this.charBuffer.limit();
+ int pos = -1;
+ while (++pos < lim) {
+ c = this.charBuffer.get();
+ switch (textTransform) {
+ case Constants.EN_UPPERCASE:
+ tmp.put(Character.toUpperCase(c));
+ break;
+ case Constants.EN_LOWERCASE:
+ tmp.put(Character.toLowerCase(c));
+ break;
+ case Constants.EN_CAPITALIZE:
+ if (isStartOfWord(pos)) {
+ /*
+ Use toTitleCase here. Apparently, some languages use
+ a different character to represent a letter when using
+ initial caps than when all of the letters in the word
+ are capitalized. We will try to let Java handle this.
+ */
+ tmp.put(Character.toTitleCase(c));
+ } else {
+ tmp.put(c);
+ }
+ break;
+ default:
+ //should never happen as the property subsystem catches that case
+ assert false;
+ //nop
+ }
}
}
@@ -260,7 +294,7 @@
* well, such as word-spacing. The definition of "word" is somewhat ambiguous
* and appears to be definable by the user agent.
*
- * @param i index into ca[]
+ * @param i index into charBuffer
*
* @return True if the character at this location is the start of a new
* word.
@@ -268,33 +302,33 @@
private boolean isStartOfWord(int i) {
char prevChar = getRelativeCharInBlock(i, -1);
/* All we are really concerned about here is of what type prevChar
- is. If inputChar is not part of a word, then the Java
- conversions will (we hope) simply return inputChar.
- */
- switch (isWordChar(prevChar)) {
- case IS_WORD_CHAR_TRUE:
- return false;
- case IS_WORD_CHAR_FALSE:
- return true;
- /* "MAYBE" implies that additional context is needed. An example is a
- * single-quote, either straight or closing, which might be interpreted
- * as a possessive or a contraction, or might be a closing quote.
+ * is. If inputChar is not part of a word, then the Java
+ * conversions will (we hope) simply return inputChar.
*/
- case IS_WORD_CHAR_MAYBE:
- char prevPrevChar = getRelativeCharInBlock(i, -2);
- switch (isWordChar(prevPrevChar)) {
+ switch (isWordChar(prevChar)) {
case IS_WORD_CHAR_TRUE:
return false;
case IS_WORD_CHAR_FALSE:
return true;
+ /* "MAYBE" implies that additional context is needed. An example is a
+ * single-quote, either straight or closing, which might be interpreted
+ * as a possessive or a contraction, or might be a closing quote.
+ */
case IS_WORD_CHAR_MAYBE:
- return true;
+ char prevPrevChar = getRelativeCharInBlock(i, -2);
+ switch (isWordChar(prevPrevChar)) {
+ case IS_WORD_CHAR_TRUE:
+ return false;
+ case IS_WORD_CHAR_FALSE:
+ return true;
+ case IS_WORD_CHAR_MAYBE:
+ return true;
+ default:
+ return false;
+ }
default:
return false;
}
- default:
- return false;
- }
}
/**
@@ -303,7 +337,7 @@
* block as one unit, allowing text in adjoining FOText objects to be
* returned if the parameters are outside of the current object.
*
- * @param i index into ca[]
+ * @param i index into the CharBuffer
* @param offset signed integer with relative position within the
* block of the character to return. To return the character immediately
* preceding i, pass -1. To return the character immediately after i,
@@ -312,30 +346,34 @@
* the offset points to an area outside of the block.
*/
private char getRelativeCharInBlock(int i, int offset) {
+
+ int charIndex = i + offset;
// The easy case is where the desired character is in the same FOText
- if (((i + offset) >= 0) && ((i + offset) <= this.endIndex)) {
- return ca[i + offset];
+ if (charIndex >= 0 && charIndex < this.length()) {
+ return this.charAt(i + offset);
}
+
// For now, we can't look at following FOText nodes
if (offset > 0) {
- return '\u0000';
- }
+ return CharUtilities.NULL_CHAR;
+ }
+
// Remaining case has the text in some previous FOText node
boolean foundChar = false;
- char charToReturn = '\u0000';
+ char charToReturn = CharUtilities.NULL_CHAR;
FOText nodeToTest = this;
int remainingOffset = offset + i;
while (!foundChar) {
if (nodeToTest.prevFOTextThisBlock == null) {
- foundChar = true;
break;
}
nodeToTest = nodeToTest.prevFOTextThisBlock;
- if ((nodeToTest.endIndex + remainingOffset) >= 0) {
- charToReturn = nodeToTest.ca[nodeToTest.endIndex + remainingOffset];
+ int diff = nodeToTest.length() + remainingOffset - 1;
+ if (diff >= 0) {
+ charToReturn = nodeToTest.charAt(diff);
foundChar = true;
} else {
- remainingOffset = remainingOffset + nodeToTest.endIndex;
+ remainingOffset += diff;
}
}
return charToReturn;
@@ -366,39 +404,6 @@
}
/**
- * Transforms one character in ca[] using the text-transform property.
- *
- * @param i the index into ca[]
- * @return char with transformed value
- */
- private char charTransform(int i) {
- switch (textTransform) {
- /* put NONE first, as this is probably the common case */
- case Constants.EN_NONE:
- return ca[i];
- case Constants.EN_UPPERCASE:
- return Character.toUpperCase(ca[i]);
- case Constants.EN_LOWERCASE:
- return Character.toLowerCase(ca[i]);
- case Constants.EN_CAPITALIZE:
- if (isStartOfWord(i)) {
- /*
- Use toTitleCase here. Apparently, some languages use
- a different character to represent a letter when using
- initial caps than when all of the letters in the word
- are capitalized. We will try to let Java handle this.
- */
- return Character.toTitleCase(ca[i]);
- } else {
- return ca[i];
- }
- default:
- assert false; //should never happen as the property subsystem catches that case
- return ca[i];
- }
- }
-
- /**
* Determines whether the input char should be considered part of a
* "word". This is used primarily to determine whether the character
* immediately following starts a new word, but may have other uses.
@@ -483,57 +488,64 @@
}
private class TextCharIterator extends CharIterator {
- private int curIndex = 0;
- /* Current space removal process: just increment the startIndex
- to "remove" leading spaces from ca, until an unremoved character
- is found. Then perform arraycopy's to remove extra spaces
- between words. nextCharCalled is used to determine if an
- unremoved character has already been found--if its value > 2
- than it means that has occurred (it is reset to zero each time we
- remove a space via incrementing the startIndex.) */
- private int nextCharCalled = 0;
-
+ int currentPosition = 0;
+
+ boolean canRemove = false;
+ boolean canReplace = false;
+
+ /** {@inheritDoc} */
public boolean hasNext() {
- if (curIndex == 0) {
-// log.debug("->" + new String(ca) + "<-");
- }
- return (curIndex < endIndex);
+ return (this.currentPosition < charBuffer.limit());
}
+ /** {@inheritDoc} */
public char nextChar() {
- if (curIndex < endIndex) {
- nextCharCalled++;
- // Just a char class? Don't actually care about the value!
- return ca[curIndex++];
+
+ if (this.currentPosition < charBuffer.limit()) {
+ this.canRemove = true;
+ this.canReplace = true;
+ return charBuffer.get(currentPosition++);
} else {
throw new NoSuchElementException();
}
+
}
+ /** {@inheritDoc} */
public void remove() {
- if (curIndex < endIndex && nextCharCalled < 2) {
- startIndex++;
- nextCharCalled = 0;
-// log.debug("removeA: " + new String(ca, startIndex, endIndex - startIndex));
- } else if (curIndex < endIndex) {
- // copy from curIndex to end to curIndex-1
- System.arraycopy(ca, curIndex, ca, curIndex - 1,
- endIndex - curIndex);
- endIndex--;
- curIndex--;
-// log.debug("removeB: " + new String(ca, startIndex, endIndex - startIndex));
- } else if (curIndex == endIndex) {
-// log.debug("removeC: " + new String(ca, startIndex, endIndex - startIndex));
- endIndex--;
- curIndex--;
+
+ if (this.canRemove) {
+ charBuffer.position(currentPosition);
+ // Slice the buffer at the current position
+ CharBuffer tmp = charBuffer.slice();
+ // Reset position to before current character
+ charBuffer.position(--currentPosition);
+ if (tmp.hasRemaining()) {
+ // Transfer any remaining characters
+ charBuffer.mark();
+ charBuffer.put(tmp);
+ charBuffer.reset();
+ }
+ // Decrease limit
+ charBuffer.limit(charBuffer.limit() - 1);
+ // Make sure following calls fail, unless nextChar() was called
+ this.canRemove = false;
+ } else {
+ throw new IllegalStateException();
}
+
}
+ /** {@inheritDoc} */
public void replaceChar(char c) {
- if (curIndex > 0 && curIndex <= endIndex) {
- ca[curIndex - 1] = c;
+
+ if (this.canReplace) {
+ charBuffer.put(currentPosition - 1, c);
+ } else {
+ throw new IllegalStateException();
}
+
}
}
@@ -559,7 +571,7 @@
return color;
}
- /**
+ /**
* @return the "keep-together" property.
*/
public KeepProperty getKeepTogether() {
@@ -570,40 +582,40 @@
* @return the "letter-spacing" property.
*/
public Property getLetterSpacing() {
- return letterSpacing;
+ return letterSpacing;
}
-
+
/**
* @return the "line-height" property.
*/
public SpaceProperty getLineHeight() {
return lineHeight;
}
-
+
/**
* @return the "white-space-treatment" property
*/
public int getWhitespaceTreatment() {
return whiteSpaceTreatment;
}
-
+
/**
* @return the "word-spacing" property.
*/
public Property getWordSpacing() {
- return wordSpacing;
+ return wordSpacing;
}
-
+
/**
* @return the "wrap-option" property.
*/
public int getWrapOption() {
- return wrapOption;
+ return wrapOption;
}
-
+
/** @return the "text-decoration" property. */
public CommonTextDecoration getTextDecoration() {
- return textDecoration;
+ return textDecoration;
}
/** @return the baseline-shift property */
@@ -613,14 +625,12 @@
/** {@inheritDoc} */
public String toString() {
- StringBuffer sb = new StringBuffer(super.toString());
- sb.append(" (").append(ca).append(")");
- return sb.toString();
+ return (this.charBuffer == null) ? "" : this.charBuffer.toString();
}
-
+
/** {@inheritDoc} */
public String getLocalName() {
- return null;
+ return "#PCDATA";
}
/** {@inheritDoc} */
@@ -630,10 +640,34 @@
/** {@inheritDoc} */
protected String gatherContextInfo() {
- if (getLocator() != null) {
+ if (this.locator != null) {
return super.gatherContextInfo();
} else {
- return new String(ca).trim();
+ return this.toString();
}
- }
-}
\ No newline at end of file
+ }
+
+ /** {@inheritDoc} */
+ public char charAt(int position) {
+ return this.charBuffer.get(position);
+ }
+
+ /** {@inheritDoc} */
+ public CharSequence subSequence(int start, int end) {
+ return this.charBuffer.subSequence(start, end);
+ }
+
+ /** {@inheritDoc} */
+ public int length() {
+ return this.charBuffer.limit();
+ }
+
+ /**
+ * Resets the backing <code>java.nio.CharBuffer</code>
+ */
+ public void resetBuffer() {
+ if (this.charBuffer != null) {
+ this.charBuffer.rewind();
+ }
+ }
+}
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOTreeBuilder.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOTreeBuilder.java?rev=670422&r1=670421&r2=670422&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOTreeBuilder.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOTreeBuilder.java Sun Jun 22 15:10:55 2008
@@ -144,7 +144,7 @@
log.debug("Building formatting object tree");
}
foEventHandler.startDocument();
- this.mainFOHandler = new MainFOHandler();
+ this.mainFOHandler = new MainFOHandler();
this.mainFOHandler.startDocument();
this.delegate = this.mainFOHandler;
}
@@ -224,7 +224,7 @@
} else {
//No formatting results available for output formats no
//involving the layout engine.
- return null;
+ return null;
}
}
@@ -316,7 +316,13 @@
if (propertyList != null && !builderContext.inMarker()) {
currentPropertyList = propertyList;
}
- currentFObj.startOfNode();
+
+ // fo:characters can potentially be removed during
+ // white-space handling.
+ // Do not notify the FOEventHandler.
+ if (currentFObj.getNameId() != Constants.FO_CHARACTER) {
+ currentFObj.startOfNode();
+ }
}
/** {@inheritDoc} */
@@ -333,7 +339,12 @@
+ ") vs. " + localName + " (" + uri + ")");
}
- currentFObj.endOfNode();
+ // fo:characters can potentially be removed during
+ // white-space handling.
+ // Do not notify the FOEventHandler.
+ if (currentFObj.getNameId() != Constants.FO_CHARACTER) {
+ currentFObj.endOfNode();
+ }
if (currentPropertyList != null
&& currentPropertyList.getFObj() == currentFObj
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FObjMixed.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FObjMixed.java?rev=670422&r1=670421&r2=670422&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FObjMixed.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FObjMixed.java Sun Jun 22 15:10:55 2008
@@ -28,27 +28,27 @@
* (= those that can contain both child {@link FONode}s and <code>#PCDATA</code>).
*/
public abstract class FObjMixed extends FObj {
-
+
/** Represents accumulated, pending FO text. See {@link #flushText()}. */
- protected FOText ft = null;
-
+ private FOText ft = null;
+
/** Used for white-space handling; start CharIterator at node ... */
protected FONode currentTextNode;
-
+
/** Used in creating pointers between subsequent {@link FOText} nodes
- * in the same {@link org.apache.fop.fo.flow.Block}
+ * in the same {@link org.apache.fop.fo.flow.Block}
* (for handling text-transform) */
protected FOText lastFOTextProcessed = null;
-
+
/**
* Base constructor
- *
+ *
* @param parent FONode that is the parent of this object
*/
protected FObjMixed(FONode parent) {
super(parent);
}
-
+
/** {@inheritDoc} */
protected void addCharacters(char[] data, int start, int length,
PropertyList pList,
@@ -65,20 +65,21 @@
/** {@inheritDoc} */
protected void endOfNode() throws FOPException {
- flushText();
- if (!inMarker()
- || getNameId() == FO_MARKER) {
- handleWhiteSpaceFor(this, null);
- }
+
super.endOfNode();
+ if (!inMarker() || getNameId() == FO_MARKER) {
+ // send character[s]() events to the FOEventHandler
+ sendCharacters();
+ }
+
}
/**
- * Handles white-space for the node that is passed in,
+ * Handles white-space for the node that is passed in,
* starting at its current text-node
- * (used by {@link org.apache.fop.fo.flow.RetrieveMarker}
+ * (used by {@link org.apache.fop.fo.flow.RetrieveMarker}
* to trigger 'end-of-node' white-space handling)
- *
+ *
* @param fobj the node for which to handle white-space
* @param nextChild the next child to be added
*/
@@ -86,86 +87,97 @@
fobj.getBuilderContext().getXMLWhiteSpaceHandler()
.handleWhiteSpace(fobj, fobj.currentTextNode, nextChild);
}
-
+
/**
- * Adds accumulated text as one FOText instance, unless
- * the one instance's <code>char</code> array contains more than
- * <code>Short.MAX_VALUE</code> characters. In the latter case the
- * instance is split up into more manageable chunks.
- *
+ * Creates block-pointers between subsequent FOText nodes
+ * in the same Block. (used for handling text-transform)
+ *
+ * TODO: !! Revisit: does not take into account fo:characters !!
+ *
* @throws FOPException if there is a problem during processing
*/
- protected void flushText() throws FOPException {
+ private void flushText() throws FOPException {
if (ft != null) {
FOText lft = ft;
/* make sure nested calls to itself have no effect */
ft = null;
- FOText tmpText;
- int indexStart = 0;
- int indexEnd = (lft.ca.length > Short.MAX_VALUE
- ? Short.MAX_VALUE : lft.ca.length) - 1;
- int charCount = 0;
- short tmpSize;
- while (charCount < lft.ca.length) {
- tmpSize = (short) (indexEnd - indexStart + 1);
- charCount += tmpSize;
- tmpText = (FOText) lft.clone(this, false);
- tmpText.ca = new char[tmpSize];
- tmpText.startIndex = 0;
- tmpText.endIndex = tmpSize;
- System.arraycopy(lft.ca, indexStart,
- tmpText.ca, 0, indexEnd - indexStart + 1);
- if (getNameId() == FO_BLOCK) {
- tmpText.createBlockPointers((org.apache.fop.fo.flow.Block) this);
- this.lastFOTextProcessed = tmpText;
- } else if (getNameId() != FO_MARKER
- && getNameId() != FO_TITLE
- && getNameId() != FO_BOOKMARK_TITLE) {
- FONode fo = parent;
- int foNameId = fo.getNameId();
- while (foNameId != FO_BLOCK
- && foNameId != FO_MARKER
- && foNameId != FO_TITLE
- && foNameId != FO_BOOKMARK_TITLE
- && foNameId != FO_PAGE_SEQUENCE) {
- fo = fo.getParent();
- foNameId = fo.getNameId();
- }
- if (foNameId == FO_BLOCK) {
- tmpText.createBlockPointers((org.apache.fop.fo.flow.Block) fo);
- ((FObjMixed) fo).lastFOTextProcessed = tmpText;
- } else if (foNameId == FO_PAGE_SEQUENCE
- && tmpText.willCreateArea()) {
- log.error("Could not create block pointers."
- + " FOText w/o Block ancestor.");
- }
+ if (getNameId() == FO_BLOCK) {
+ lft.createBlockPointers((org.apache.fop.fo.flow.Block) this);
+ this.lastFOTextProcessed = lft;
+ } else if (getNameId() != FO_MARKER
+ && getNameId() != FO_TITLE
+ && getNameId() != FO_BOOKMARK_TITLE) {
+ FONode fo = parent;
+ int foNameId = fo.getNameId();
+ while (foNameId != FO_BLOCK
+ && foNameId != FO_MARKER
+ && foNameId != FO_TITLE
+ && foNameId != FO_BOOKMARK_TITLE
+ && foNameId != FO_PAGE_SEQUENCE) {
+ fo = fo.getParent();
+ foNameId = fo.getNameId();
+ }
+ if (foNameId == FO_BLOCK) {
+ lft.createBlockPointers((org.apache.fop.fo.flow.Block) fo);
+ ((FObjMixed) fo).lastFOTextProcessed = lft;
+ } else if (foNameId == FO_PAGE_SEQUENCE
+ && lft.willCreateArea()) {
+ log.error("Could not create block pointers."
+ + " FOText w/o Block ancestor.");
+ }
+ }
+ this.addChildNode(lft);
+ }
+ }
+
+ private void sendCharacters() throws FOPException {
+
+ if (this.currentTextNode != null) {
+ FONodeIterator nodeIter
+ = this.getChildNodes(this.currentTextNode);
+ FONode node;
+ while (nodeIter.hasNext()) {
+ node = nodeIter.nextNode();
+ assert (node instanceof FOText
+ || node.getNameId() == FO_CHARACTER);
+ if (node.getNameId() == FO_CHARACTER) {
+ node.startOfNode();
}
- tmpText.endOfNode();
- addChildNode(tmpText);
- indexStart = indexEnd + 1;
- indexEnd = (((lft.ca.length - charCount) < Short.MAX_VALUE)
- ? lft.ca.length : charCount + Short.MAX_VALUE) - 1;
+ node.endOfNode();
}
}
+ this.currentTextNode = null;
}
/** {@inheritDoc} */
protected void addChildNode(FONode child) throws FOPException {
+
flushText();
if (!inMarker()) {
if (child instanceof FOText || child.getNameId() == FO_CHARACTER) {
- if (currentTextNode == null) {
- currentTextNode = child;
+ if (this.currentTextNode == null) {
+ this.currentTextNode = child;
}
} else {
// handle white-space for all text up to here
handleWhiteSpaceFor(this, child);
- currentTextNode = null;
+ // send character[s]() events to the FOEventHandler
+ sendCharacters();
}
}
super.addChildNode(child);
}
-
+
+ /** {@inheritDoc} */
+ public void finalizeNode() throws FOPException {
+
+ flushText();
+ if (!inMarker() || getNameId() == FO_MARKER) {
+ handleWhiteSpaceFor(this, null);
+ }
+
+ }
+
/**
* Returns a {@link CharIterator} over this FO's character content
*
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/AbstractRetrieveMarker.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/AbstractRetrieveMarker.java?rev=670422&r1=670421&r2=670422&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/AbstractRetrieveMarker.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/AbstractRetrieveMarker.java Sun Jun 22 15:10:55 2008
@@ -119,12 +119,10 @@
ft.bind(parentPropertyList);
addChildTo(newChild, (FObj) newParent);
}
-
+
+ // trigger end-of-node white-space handling
+ // and finalization for table-FOs
newChild.finalizeNode();
- // trigger 'end-of-node' white-space handling
- if (newChild instanceof FObjMixed) {
- handleWhiteSpaceFor((FObjMixed) newChild, null);
- }
}
}
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java?rev=670422&r1=670421&r2=670422&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java Sun Jun 22 15:10:55 2008
@@ -41,8 +41,8 @@
import org.apache.fop.fo.flow.ExternalGraphic;
import org.apache.fop.fo.flow.Footnote;
import org.apache.fop.fo.flow.Inline;
-import org.apache.fop.fo.flow.InlineLevel;
import org.apache.fop.fo.flow.InlineContainer;
+import org.apache.fop.fo.flow.InlineLevel;
import org.apache.fop.fo.flow.InstreamForeignObject;
import org.apache.fop.fo.flow.Leader;
import org.apache.fop.fo.flow.ListBlock;
@@ -224,7 +224,7 @@
public static class FOTextLayoutManagerMaker extends Maker {
public void make(FONode node, List lms) {
FOText foText = (FOText) node;
- if (foText.endIndex - foText.startIndex > 0) {
+ if (foText.length() > 0) {
lms.add(new TextLayoutManager(foText));
}
}
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java?rev=670422&r1=670421&r2=670422&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java Sun Jun 22 15:10:55 2008
@@ -61,20 +61,20 @@
* Number of word-spaces?
*/
private class AreaInfo {
- private final short startIndex;
- private final short breakIndex;
- private final short wordSpaceCount;
- private short letterSpaceCount;
+ private final int startIndex;
+ private final int breakIndex;
+ private final int wordSpaceCount;
+ private int letterSpaceCount;
private final MinOptMax areaIPD;
private final boolean isHyphenated;
private final boolean isSpace;
private boolean breakOppAfter;
private final Font font;
- AreaInfo(final short startIndex,
- final short breakIndex,
- final short wordSpaceCount,
- final short letterSpaceCount,
+ AreaInfo(final int startIndex,
+ final int breakIndex,
+ final int wordSpaceCount,
+ final int letterSpaceCount,
final MinOptMax areaIPD,
final boolean isHyphenated,
final boolean isSpace,
@@ -132,7 +132,7 @@
private static final MinOptMax ZERO_MINOPTMAX = new MinOptMax(0);
private final FOText foText;
- private final char[] textArray;
+
/**
* Contains an array of widths to adjust for kerning. The first entry can
* be used to influence the start position of the first letter. The entry i+1 defines the
@@ -143,7 +143,7 @@
/** Font used for the space between words. */
private Font spaceFont = null;
/** Start index of next TextArea */
- private short nextStart = 0;
+ private int nextStart = 0;
/** size of a space character (U+0020) glyph in current font */
private int spaceCharIPD;
private MinOptMax wordSpaceIPD;
@@ -155,8 +155,8 @@
private boolean hasChanged = false;
private int returnedIndex = 0;
- private short thisStart = 0;
- private short tempStart = 0;
+ private int thisStart = 0;
+ private int tempStart = 0;
private List changeList = null;
private AlignmentContext alignmentContext = null;
@@ -177,10 +177,7 @@
super();
this.foText = node;
- this.textArray = new char[node.endIndex - node.startIndex];
- System.arraycopy(node.ca, node.startIndex, this.textArray, 0,
- node.endIndex - node.startIndex);
- this.letterAdjustArray = new MinOptMax[this.textArray.length + 1];
+ this.letterAdjustArray = new MinOptMax[node.length() + 1];
this.vecAreaInfo = new java.util.ArrayList();
}
@@ -205,6 +202,8 @@
/** {@inheritDoc} */
public void initialize() {
+ this.foText.resetBuffer();
+
this.spaceFont = FontSelector.selectFontForCharacterInText(' ', this.foText, this);
// With CID fonts, space isn't neccesary currentFontState.width(32)
@@ -296,7 +295,7 @@
int letterSpaceCount, final int firstAreaInfoIndex,
final int lastAreaInfoIndex, final MinOptMax realWidth, final LayoutContext context) {
- // TODO: These two statements (if, for) where like this before my recent
+ // TODO: These two statements (if, for) were like this before my recent
// changes. However, it seems as if they should use the AreaInfo from
// firstAreaInfoIndex.. lastAreaInfoIndex rather than just the last ai.
// This needs to be checked.
@@ -441,7 +440,7 @@
// areaInfo stores information about spaces
// add the spaces - except zero-width spaces - to the TextArea
for (int j = areaInfo.startIndex; j < areaInfo.breakIndex; j++) {
- final char spaceChar = this.textArray[j];
+ final char spaceChar = this.foText.charAt(j);
if (!CharUtilities.isZeroWidthSpace(spaceChar)) {
textArea.addSpace(spaceChar, 0,
CharUtilities.isAdjustableSpace(spaceChar));
@@ -469,8 +468,15 @@
for (int j = wordStartIndex; j <= i; j++) {
final AreaInfo ai = (AreaInfo) this.vecAreaInfo.get(j);
int lsCount = ai.letterSpaceCount;
- wordChars.append(this.textArray, ai.startIndex,
- ai.breakIndex - ai.startIndex);
+ /* TODO: in Java 5, StringBuffer has an append() variant
+ * for CharSequence, so the below iteration can be replaced
+ * by:
+ * wordChars.append(this.foText, ai.startIndex,
+ * ai.breakIndex - ai.startIndex);
+ */
+ for (int ci = ai.startIndex; ci < ai.breakIndex; ci++) {
+ wordChars.append(this.foText.charAt(ci));
+ }
for (int k = 0; k < ai.breakIndex - ai.startIndex; k++) {
final MinOptMax adj = this.letterAdjustArray[ai.startIndex + k];
if (letter > 0) {
@@ -522,7 +528,7 @@
|| CharUtilities.isNonBreakableSpace(ch)
|| CharUtilities.isFixedWidthSpace(ch);
}
-
+
/** {@inheritDoc} */
public List getNextKnuthElements(final LayoutContext context, final int alignment) {
this.lineStartBAP = context.getLineStartBorderAndPaddingWidth();
@@ -540,8 +546,8 @@
boolean inWord = false;
boolean inWhitespace = false;
char ch = 0;
- while (this.nextStart < this.textArray.length) {
- ch = this.textArray[this.nextStart];
+ while (this.nextStart < this.foText.length()) {
+ ch = this.foText.charAt(this.nextStart);
boolean breakOpportunity = false;
final byte breakAction = this.keepTogether ? LineBreakStatus.PROHIBITED_BREAK
: lbs.nextChar(ch);
@@ -560,10 +566,10 @@
TextLayoutManager.LOG.error("Unexpected breakAction: " + breakAction);
}
if (inWord) {
- if (breakOpportunity
+ if (breakOpportunity
|| TextLayoutManager.isSpace(ch)
|| CharUtilities.isExplicitBreak(ch)) {
- // this.textArray[lastIndex] == CharUtilities.SOFT_HYPHEN
+ // this.foText.charAt(lastIndex) == CharUtilities.SOFT_HYPHEN
prevAi = this.processWord(alignment, sequence, prevAi, ch,
breakOpportunity, true);
}
@@ -588,24 +594,24 @@
|| ch == CharUtilities.NBSPACE) {
// preserved space or non-breaking space:
// create the AreaInfo object
- ai = new AreaInfo(this.nextStart, (short) (this.nextStart + 1),
- (short) 1, (short) 0, this.wordSpaceIPD, false, true,
+ ai = new AreaInfo(this.nextStart, this.nextStart + 1,
+ 1, 0, this.wordSpaceIPD, false, true,
breakOpportunity, this.spaceFont);
- this.thisStart = (short) (this.nextStart + 1);
+ this.thisStart = this.nextStart + 1;
} else if (CharUtilities.isFixedWidthSpace(ch) || CharUtilities.isZeroWidthSpace(ch)) {
// create the AreaInfo object
final Font font = FontSelector.selectFontForCharacterInText(ch,
this.foText, this);
final MinOptMax ipd = new MinOptMax(font.getCharWidth(ch));
- ai = new AreaInfo(this.nextStart, (short) (this.nextStart + 1),
- (short) 0, (short) 0, ipd, false, true,
+ ai = new AreaInfo(this.nextStart, this.nextStart + 1,
+ 0, 0, ipd, false, true,
breakOpportunity, font);
- this.thisStart = (short) (this.nextStart + 1);
+ this.thisStart = this.nextStart + 1;
} else if (CharUtilities.isExplicitBreak(ch)) {
//mandatory break-character: only advance index
- this.thisStart = (short) (this.nextStart + 1);
+ this.thisStart = this.nextStart + 1;
}
-
+
inWord = !TextLayoutManager.isSpace(ch)
&& !CharUtilities.isExplicitBreak(ch);
inWhitespace = ch == CharUtilities.SPACE
@@ -619,17 +625,17 @@
} else if (inWhitespace) {
this.processWhitespace(alignment, sequence, true);
} else if (ai != null) {
- ai = this.processLeftoverAi(alignment, sequence, ai, ch,
+ this.processLeftoverAi(alignment, sequence, ai, ch,
ch == CharUtilities.ZERO_WIDTH_SPACE);
} else if (CharUtilities.isExplicitBreak(ch)) {
- sequence = this.processLinebreak(returnList, sequence);
+ this.processLinebreak(returnList, sequence);
}
if (((List) ListUtil.getLast(returnList)).isEmpty()) {
//Remove an empty sequence because of a trailing newline
ListUtil.removeLast(returnList);
}
-
+
this.setFinished(true);
if (returnList.isEmpty()) {
return null;
@@ -663,24 +669,20 @@
private AreaInfo processWhitespace(final int alignment,
final KnuthSequence sequence, final boolean breakOpportunity) {
- AreaInfo ai;
- AreaInfo prevAi;
// End of whitespace
// create the AreaInfo object
- ai = new AreaInfo(this.thisStart, this.nextStart,
- (short) (this.nextStart - this.thisStart), (short) 0,
+ AreaInfo ai = new AreaInfo(this.thisStart, this.nextStart,
+ this.nextStart - this.thisStart, 0,
MinOptMax.multiply(this.wordSpaceIPD, this.nextStart
- this.thisStart), false, true,
breakOpportunity, this.spaceFont);
this.vecAreaInfo.add(ai);
- prevAi = ai;
// create the elements
this.addElementsForASpace(sequence, alignment, ai, this.vecAreaInfo.size() - 1);
- ai = null;
this.thisStart = this.nextStart;
- return prevAi;
+ return ai;
}
private AreaInfo processWord(final int alignment, final KnuthSequence sequence,
@@ -688,21 +690,21 @@
final boolean checkEndsWithHyphen) {
AreaInfo ai;
//Word boundary found, process widths and kerning
- short lastIndex = this.nextStart;
+ int lastIndex = this.nextStart;
while (lastIndex > 0
- && this.textArray[lastIndex - 1] == CharUtilities.SOFT_HYPHEN) {
+ && this.foText.charAt(lastIndex - 1) == CharUtilities.SOFT_HYPHEN) {
lastIndex--;
}
final boolean endsWithHyphen = checkEndsWithHyphen
- && this.textArray[lastIndex] == CharUtilities.SOFT_HYPHEN;
+ && this.foText.charAt(lastIndex) == CharUtilities.SOFT_HYPHEN;
final Font font = FontSelector
- .selectFontForCharactersInText(this.textArray,
+ .selectFontForCharactersInText(this.foText,
this.thisStart, lastIndex, this.foText, this);
final int wordLength = lastIndex - this.thisStart;
final boolean kerning = font.hasKerning();
final MinOptMax wordIPD = new MinOptMax(0);
for (int i = this.thisStart; i < lastIndex; i++) {
- final char c = this.textArray[i];
+ final char c = this.foText.charAt(i);
//character width
final int charWidth = font.getCharWidth(c);
@@ -712,10 +714,10 @@
if (kerning) {
int kern = 0;
if (i > this.thisStart) {
- final char previous = this.textArray[i - 1];
+ final char previous = this.foText.charAt(i - 1);
kern = font.getKernValue(previous, c) * font.getFontSize() / 1000;
} else if (prevAi != null && !prevAi.isSpace && prevAi.breakIndex > 0) {
- final char previous = this.textArray[prevAi.breakIndex - 1];
+ final char previous = this.foText.charAt(prevAi.breakIndex - 1);
kern = font.getKernValue(previous, c) * font.getFontSize() / 1000;
}
if (kern != 0) {
@@ -730,7 +732,7 @@
&& lastIndex > 0
&& endsWithHyphen) {
final int kern = font.getKernValue(
- this.textArray[lastIndex - 1], ch)
+ this.foText.charAt(lastIndex - 1), ch)
* font.getFontSize() / 1000;
if (kern != 0) {
this.addToLetterAdjust(lastIndex, kern);
@@ -746,8 +748,8 @@
wordIPD.add(MinOptMax.multiply(this.letterSpaceIPD, iLetterSpaces));
// create the AreaInfo object
- ai = new AreaInfo(this.thisStart, lastIndex, (short) 0,
- (short) iLetterSpaces, wordIPD,
+ ai = new AreaInfo(this.thisStart, lastIndex, 0,
+ iLetterSpaces, wordIPD,
endsWithHyphen,
false, breakOpportunity, font);
prevAi = ai;
@@ -776,7 +778,7 @@
final AreaInfo ai = (AreaInfo) this.vecAreaInfo.get(idx);
ai.letterSpaceCount++;
ai.areaIPD.add(this.letterSpaceIPD);
- if (TextLayoutManager.BREAK_CHARS.indexOf(this.textArray[this.tempStart - 1]) >= 0) {
+ if (TextLayoutManager.BREAK_CHARS.indexOf(this.foText.charAt(this.tempStart - 1)) >= 0) {
// the last character could be used as a line break
// append new elements to oldList
oldListIterator = oldList.listIterator(oldList.size());
@@ -867,7 +869,7 @@
//log.info("Word: " + new String(textArray, startIndex, stopIndex - startIndex));
for (int i = startIndex; i < stopIndex; i++) {
- final char c = this.textArray[i];
+ final char c = this.foText.charAt(i);
newIPD.add(new MinOptMax(font.getCharWidth(c)));
//if (i > startIndex) {
if (i < stopIndex) {
@@ -899,8 +901,8 @@
this.changeList = new LinkedList();
}
this.changeList.add(new PendingChange(new AreaInfo(
- (short) startIndex, (short) stopIndex, (short) 0,
- (short) (isWordEnd ? stopIndex - startIndex - 1
+ startIndex, stopIndex, 0,
+ (isWordEnd ? stopIndex - startIndex - 1
: stopIndex - startIndex), newIPD,
hyphenFollows, false, false, font),
((LeafPosition) pos).getLeafPos()));
@@ -973,7 +975,9 @@
final int leafValue = ((LeafPosition) pos).getLeafPos();
if (leafValue != -1) {
final AreaInfo ai = (AreaInfo) this.vecAreaInfo.get(leafValue);
- sbChars.append(this.textArray, ai.startIndex, ai.breakIndex - ai.startIndex);
+ for (int i = ai.startIndex; i < ai.breakIndex; ++i) {
+ sbChars.append(this.foText.charAt(i));
+ }
}
}
@@ -999,7 +1003,7 @@
mainPosition, true));
}
} else {
- if (this.textArray[ai.startIndex] != CharUtilities.SPACE
+ if (this.foText.charAt(ai.startIndex) != CharUtilities.SPACE
|| this.foText.getWhitespaceTreatment() == Constants.EN_PRESERVE) {
// a breaking space that needs to be preserved
this.addElementsForBreakingSpace(baseList, alignment, ai,
@@ -1153,7 +1157,7 @@
// or it ends with a character that can be used as a line break
if (ai.isHyphenated) {
MinOptMax widthIfNoBreakOccurs = null;
- if (ai.breakIndex < this.textArray.length) {
+ if (ai.breakIndex < this.foText.length()) {
//Add in kerning in no-break condition
widthIfNoBreakOccurs = this.letterAdjustArray[ai.breakIndex];
}
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/RTFHandler.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/RTFHandler.java?rev=670422&r1=670421&r2=670422&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/RTFHandler.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/RTFHandler.java Sun Jun 22 15:10:55 2008
@@ -1568,7 +1568,7 @@
} else if (foNode instanceof FOText) {
if (bStart) {
FOText text = (FOText) foNode;
- text(text, text.ca, text.startIndex, text.endIndex);
+ text(text, text.getCharArray(), 0, text.length());
}
} else if (foNode instanceof Character) {
if (bStart) {
---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org
Re: svn commit: r670422 - in /xmlgraphics/fop/trunk/src/java/org/apache/fop:
fo/ fo/flow/ layoutmgr/ layoutmgr/inline/ render/rtf/
Posted by Max Berger <ma...@berger.name>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Andreas,
Alhtough the testcases pass, this broke MathML. I get the (attached)
error message on this fo file (which worked fine before updating).
Please note that I get the same error message no matter if the JEuclid
extension is installed or not.
Max
P.S. maybe we should add this as a test file for fop? Of course, there
is no expected output without the extension, but it should not throw an
exception, just a warning.
- --- choose.fo
<root xmlns="http://www.w3.org/1999/XSL/Format">
<layout-master-set>
<simple-page-master master-name="master">
<region-body/>
</simple-page-master>
</layout-master-set>
<page-sequence master-reference="master">
<flow flow-name="xsl-region-body">
<block>
<instream-foreign-object>
<math xmlns="http://www.w3.org/1998/Math/MathML">
<mfrac linethickness="0">
<mi>a</mi>
<mi>b</mi>
</mfrac>
</math>
</instream-foreign-object>
</block>
</flow>
</page-sequence>
</root>
- --- stacktrace
fop -fo choose.fo -pdf choose.pdf
23.06.2008 15:42:13 org.apache.fop.cli.Main startFOP
SCHWERWIEGEND: Exception
java.lang.StringIndexOutOfBoundsException: String index out of range: -356
at org.apache.fop.cli.InputHandler.transformTo(InputHandler.java:217)
at org.apache.fop.cli.InputHandler.renderTo(InputHandler.java:125)
at org.apache.fop.cli.Main.startFOP(Main.java:169)
at org.apache.fop.cli.Main.main(Main.java:200)
- ---------
java.lang.StringIndexOutOfBoundsException: String index out of range: -356
at java.lang.String.<init>(String.java:208)
at org.apache.fop.fo.XMLObj.addCharacters(XMLObj.java:217)
at
org.apache.fop.fo.FOTreeBuilder$MainFOHandler.characters(FOTreeBuilder.java:374)
at org.apache.fop.fo.FOTreeBuilder.characters(FOTreeBuilder.java:130)
at
org.apache.xalan.transformer.TransformerIdentityImpl.characters(TransformerIdentityImpl.java:1125)
at org.apache.xerces.parsers.AbstractSAXParser.characters(Unknown Source)
at org.apache.xerces.xinclude.XIncludeHandler.characters(Unknown Source)
at
org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanContent(Unknown
Source)
at
org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown
Source)
at
org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown
Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at
org.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:484)
at org.apache.fop.cli.InputHandler.transformTo(InputHandler.java:214)
at org.apache.fop.cli.InputHandler.renderTo(InputHandler.java:125)
at org.apache.fop.cli.Main.startFOP(Main.java:169)
at org.apache.fop.cli.Main.main(Main.java:200)
adelmelle@apache.org schrieb:
> Author: adelmelle
> Date: Sun Jun 22 15:10:55 2008
> New Revision: 670422
>
> URL: http://svn.apache.org/viewvc?rev=670422&view=rev
> Log:
> Switch FOText to use a java.nio.CharBuffer, and implement the CharSequence interface.
> TextLayoutManager no longer duplicates the char array, operates on the FOText (charAt(i))
> Additionally: endOfNode() for FOText and Character deferred until after white-space handling.
>
> Modified:
> xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOText.java
> xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FOTreeBuilder.java
> xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/FObjMixed.java
> xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/AbstractRetrieveMarker.java
> xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java
> xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
> xmlgraphics/fop/trunk/src/java/org/apache/fop/render/rtf/RTFHandler.java
>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFIX6rB+Gr+4pk71JwRAgRhAJ4yiAe0sRIc1ez6cVC73PdKaWlRtACdGtyU
cIwGzxNrUfCxhnOXEsaFM6Q=
=vvMe
-----END PGP SIGNATURE-----