* The correction offset for the next area\r
*/\r
protected int offset = 0;\r
+ \r
+ /**\r
+ * Is this space adjustable?\r
+ */\r
+ protected boolean isAdjustable;\r
\r
/**\r
- * Create a text inline area\r
+ * Create a space area\r
* @param s the space character\r
+ * @param o the offset for the next area\r
+ * @param a is this space adjustable?\r
*/\r
- public SpaceArea(char s) {\r
+ public SpaceArea(char s, int o, boolean a) {\r
space = new String() + s;\r
+ offset = o;\r
+ isAdjustable = a;\r
}\r
\r
/**\r
package org.apache.fop.area.inline;
-import org.apache.fop.util.CharUtilities;
-
/**
* A text inline area.
*/
}
/**
- * Set the text string
- *
- * @param t the text string
+ * Remove the old text
*/
- public void setText(String t) {
- // split the text and create WordAreas and SpaceAreas
- char charArray[] = t.toCharArray();
- int wordStartIndex = -1;
- for (int i = 0; i < charArray.length; i ++) {
- if (CharUtilities.isAnySpace(charArray[i])) {
- // a space character
- // create a SpaceArea child
- SpaceArea space = new SpaceArea(charArray[i]);
- this.addChildArea(space);
- space.setParentArea(this);
- } else {
- // a non-space character
- if (wordStartIndex == -1) {
- // first character of the text, or after a space
- wordStartIndex = i;
- }
- if (i == charArray.length - 1
- || CharUtilities.isAnySpace(charArray[i + 1])) {
- // last character before the end of the text or a space:
- // create a WordArea child
- WordArea word = new WordArea(t.substring(wordStartIndex, i + 1));
- this.addChildArea(word);
- word.setParentArea(this);
- wordStartIndex = -1;
- }
- }
- }
+ public void removeText() {
+ inlines.clear();
}
-
+
+ /**
+ * Create and add a WordArea child to this TextArea.
+ *
+ * @param word the word string
+ * @param offset the offset for the next area
+ */
+ public void addWord(String word, int offset) {
+ WordArea wordArea = new WordArea(word, offset);
+ addChildArea(wordArea);
+ wordArea.setParentArea(this);
+ }
+
+ /**
+ * Create and add a SpaceArea child to this TextArea
+ *
+ * @param space the space character
+ * @param offset the offset for the next area
+ * @param adjustable is this space adjustable?
+ */
+ public void addSpace(char space, int offset, boolean adjustable) {
+ SpaceArea spaceArea = new SpaceArea(space, offset, adjustable);
+ addChildArea(spaceArea);
+ spaceArea.setParentArea(this);
+ }
+
/**
- * Get the text string.
+ * Get the whole text string.
+ * Renderers whose space adjustment handling is not affected
+ * by multi-byte characters can use this method to render the
+ * whole TextArea at once; the other renderers (for example
+ * PDFRenderer) have to implement renderWord(WordArea) and
+ * renderSpace(SpaceArea) in order to correctly place each
+ * text fragment.
*
* @return the text string
*/
- public String getTextArea() {
+ public String getText() {
StringBuffer text = new StringBuffer();
InlineArea child;
// assemble the text
if (pageIDRef.equals(id) && pages != null) {
resolved = true;
PageViewport page = (PageViewport)pages.get(0);
- setText(page.getPageNumberString());
+ // replace the text
+ removeText();
+ addWord(page.getPageNumberString(), 0);
// update ipd
updateIPD(getStringWidth(text));
// set the Font object to null, as we don't need it any more
protected int offset = 0;\r
\r
/**\r
- * Create a text inline area\r
+ * Create a word area\r
* @param w the word string\r
+ * @param o the offset for the next area\r
*/\r
- public WordArea(String w) {\r
+ public WordArea(String w, int o) {\r
word = w;\r
+ offset = o;\r
}\r
\r
/**\r
char dot = '.'; // userAgent.getLeaderDotCharacter();
int width = font.getCharWidth(dot);
- t.setText("" + dot);
+ t.addWord("" + dot, 0);
t.setIPD(width);
t.setBPD(width);
t.setBaselineOffset(width);
import org.apache.fop.area.inline.InlineArea;
import org.apache.fop.area.inline.UnresolvedPageNumber;
import org.apache.fop.area.inline.TextArea;
-import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.fonts.Font;
import org.apache.fop.layoutmgr.LayoutContext;
import org.apache.fop.layoutmgr.LayoutManager;
TextArea text = new TextArea();
inline = text;
int width = getStringWidth(str);
- text.setText(str);
+ text.addWord(str, 0);
inline.setIPD(width);
resolved = true;
import org.apache.fop.area.inline.InlineArea;
import org.apache.fop.area.inline.TextArea;
import org.apache.fop.area.Trait;
-import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.fonts.Font;
import org.apache.fop.layoutmgr.LayoutContext;
import org.apache.fop.layoutmgr.TraitSetter;
TextArea text = new TextArea();
String str = getCurrentPV().getPageNumberString();
int width = getStringWidth(str);
- text.setText(str);
+ text.addWord(str, 0);
text.setIPD(width);
text.setBPD(font.getAscender() - font.getDescender());
text.setBaselineOffset(font.getAscender());
private void updateContent(TextArea area) {
// get the page number of the page actually being built
- area.setText(getCurrentPV().getPageNumberString());
+ area.removeText();
+ area.addWord(getCurrentPV().getPageNumberString(), 0);
// update the ipd of the area
- area.updateIPD(getStringWidth(area.getTextArea()));
+ area.updateIPD(getStringWidth(area.getText()));
// update the width stored in the AreaInfo object
areaInfo.ipdArea = new MinOptMax(area.getIPD());
}
import java.util.ListIterator;
import org.apache.fop.area.Trait;
-import org.apache.fop.area.inline.InlineArea;
import org.apache.fop.area.inline.TextArea;
import org.apache.fop.fo.FOText;
import org.apache.fop.fo.flow.Inline;
import org.apache.fop.layoutmgr.TraitSetter;
import org.apache.fop.traits.MinOptMax;
import org.apache.fop.traits.SpaceVal;
+import org.apache.fop.util.CharUtilities;
/**
* LayoutManager for text (a sequence of characters) which generates one
// Add word areas
AreaInfo ai = null;
- int iStart = -1;
int iWScount = 0;
int iLScount = 0;
+ int firstAreaInfoIndex = -1;
+ int lastAreaInfoIndex = 0;
MinOptMax realWidth = new MinOptMax(0);
/* On first area created, add any leading space.
//
if (tbpNext.getLeafPos() != -1) {
ai = (AreaInfo) vecAreaInfo.get(tbpNext.getLeafPos());
- if (iStart == -1) {
- iStart = ai.iStartIndex;
+ if (firstAreaInfoIndex == -1) {
+ firstAreaInfoIndex = tbpNext.getLeafPos();
}
iWScount += ai.iWScount;
iLScount += ai.iLScount;
realWidth.add(ai.ipdArea);
+ lastAreaInfoIndex = tbpNext.getLeafPos();
}
}
if (ai == null) {
iLScount--;
}
- // Make an area containing all characters between start and end.
- InlineArea word = null;
- int adjust = 0;
-
- // ignore newline character
- if (textArray[ai.iBreakIndex - 1] == NEWLINE) {
- adjust = 1;
- }
- String str = new String(textArray, iStart,
- ai.iBreakIndex - iStart - adjust);
-
// add hyphenation character if the last word is hyphenated
if (context.isLastArea() && ai.bHyphenated) {
- str += foText.getCommonHyphenation().hyphenationCharacter;
realWidth.add(new MinOptMax(hyphIPD));
}
iTotalAdjust = iDifference;
}
- TextArea t = createTextArea(str, realWidth, iTotalAdjust, context,
- wordSpaceIPD.opt - spaceCharIPD);
+ TextArea t = createTextArea(realWidth, iTotalAdjust, context,
+ wordSpaceIPD.opt - spaceCharIPD,
+ firstAreaInfoIndex, lastAreaInfoIndex,
+ context.isLastArea());
// iWordSpaceDim is computed in relation to wordSpaceIPD.opt
// but the renderer needs to know the adjustment in relation
t.setSpaceDifference(wordSpaceIPD.opt - spaceCharIPD
- 2 * t.getTextLetterSpaceAdjust());
}
- word = t;
- if (word != null) {
- parentLM.addChildArea(word);
- }
+ parentLM.addChildArea(t);
}
/**
* Create an inline word area.
* This creates a TextArea and sets up the various attributes.
*
- * @param str the string for the TextArea
* @param width the MinOptMax width of the content
* @param adjust the total ipd adjustment with respect to the optimal width
* @param context the layout context
* @param spaceDiff unused
+ * @param firstIndex the index of the first AreaInfo used for the TextArea
+ * @param lastIndex the index of the last AreaInfo used for the TextArea
+ * @param isLastArea is this TextArea the last in a line?
* @return the new text area
*/
- protected TextArea createTextArea(String str, MinOptMax width, int adjust,
- LayoutContext context, int spaceDiff) {
+ protected TextArea createTextArea(MinOptMax width, int adjust,
+ LayoutContext context, int spaceDiff,
+ int firstIndex, int lastIndex, boolean isLastArea) {
TextArea textArea;
if (context.getIPDAdjust() == 0.0) {
// create just a TextArea
textArea.setOffset(alignmentContext.getOffset());
}
- textArea.setText(str);
+ // set the text of the TextArea, split into words and spaces
+ int wordStartIndex = -1;
+ AreaInfo areaInfo;
+ for (int i = firstIndex; i <= lastIndex; i ++) {
+ areaInfo = (AreaInfo) vecAreaInfo.get(i);
+ if (areaInfo.iWScount > 0) {
+ // areaInfo stores information about a space
+ // add a space to the TextArea
+ char spaceChar = textArray[areaInfo.iStartIndex];
+ textArea.addSpace(spaceChar, 0,
+ CharUtilities.isAdjustableSpace(spaceChar));
+ } else {
+ // areaInfo stores information about a word fragment
+ if (wordStartIndex == -1) {
+ // here starts a new word
+ wordStartIndex = areaInfo.iStartIndex;
+ }
+ if (i == lastIndex || ((AreaInfo) vecAreaInfo.get(i + 1)).iWScount > 0) {
+ // here ends a new word
+ // add a word to the TextArea
+ String wordChars = new String(textArray, wordStartIndex, areaInfo.iBreakIndex - wordStartIndex);
+ if (isLastArea
+ && i == lastIndex
+ && areaInfo.bHyphenated) {
+ // add the hyphenation character
+ wordChars += foText.getCommonHyphenation().hyphenationCharacter;
+ }
+ textArea.addWord(wordChars, 0);
+ wordStartIndex = -1;
+ }
+ }
+ }
textArea.addTrait(Trait.FONT_NAME, font.getFontName());
textArea.addTrait(Trait.FONT_SIZE, new Integer(font.getFontSize()));
textArea.addTrait(Trait.COLOR, foText.getColor());
if (inline instanceof Character) {
sb.append(((Character) inline).getChar());
} else if (inline instanceof TextArea) {
- sb.append(((TextArea) inline).getTextArea());
+ sb.append(((TextArea) inline).getText());
} else if (inline instanceof InlineParent) {
sb.append(convertToString(
((InlineParent) inline).getChildAreas()));
ColorType ct = (ColorType) text.getTrait(Trait.COLOR);
state.updateColor(ct, false, null);
- String s = text.getTextArea();
+ String s = text.getText();
state.getGraph().drawString(s, x / 1000f, y / 1000f);
// getLogger().debug("renderText(): \"" + s + "\", x: "
* @see org.apache.fop.render.AbstractRenderer#renderText(TextArea)
*/
public void renderText(TextArea area) {
- String text = area.getTextArea();
+ String text = area.getText();
renderText(area, text);
super.renderText(area); //Updates IPD
}
currentIPPosition / 1000,
(currentBPPosition + text.getOffset()
+ text.getBaselineOffset()) / 1000,
- text.getTextArea());
+ text.getText());
currentPageG.appendChild(textElement);
super.renderText(text);
|| c == ZERO_WIDTH_NOBREAK_SPACE); // zero width no-break space
}
+ /**
+ * Method to determine if the character is an adjustable
+ * space.
+ * @param c character to check
+ * @return True if the character is adjustable
+ */
+ public static boolean isAdjustableSpace(char c) {
+ //TODO: are there other kinds of adjustable spaces?
+ return
+ (c == '\u0020' // normal space
+ /*|| c == ''*/);
+ }
+
/**
* Determines if the character represents any kind of space.
* @param c character to check