Some simplification in TextLM#addAreas(). git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@328882 13f79535-47bb-0310-9956-ffa450edef68pull/34/head
@@ -31,13 +31,22 @@ public class SpaceArea extends InlineArea { | |||
* The correction offset for the next area | |||
*/ | |||
protected int offset = 0; | |||
/** | |||
* Is this space adjustable? | |||
*/ | |||
protected boolean isAdjustable; | |||
/** | |||
* Create a text inline area | |||
* Create a space area | |||
* @param s the space character | |||
* @param o the offset for the next area | |||
* @param a is this space adjustable? | |||
*/ | |||
public SpaceArea(char s) { | |||
public SpaceArea(char s, int o, boolean a) { | |||
space = new String() + s; | |||
offset = o; | |||
isAdjustable = a; | |||
} | |||
/** |
@@ -18,8 +18,6 @@ | |||
package org.apache.fop.area.inline; | |||
import org.apache.fop.util.CharUtilities; | |||
/** | |||
* A text inline area. | |||
*/ | |||
@@ -43,46 +41,49 @@ public class TextArea extends AbstractTextArea { | |||
} | |||
/** | |||
* 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 |
@@ -70,7 +70,9 @@ public class UnresolvedPageNumber extends TextArea implements Resolvable { | |||
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 |
@@ -33,11 +33,13 @@ public class WordArea extends InlineArea { | |||
protected int offset = 0; | |||
/** | |||
* Create a text inline area | |||
* Create a word area | |||
* @param w the word string | |||
* @param o the offset for the next area | |||
*/ | |||
public WordArea(String w) { | |||
public WordArea(String w, int o) { | |||
word = w; | |||
offset = o; | |||
} | |||
/** |
@@ -129,7 +129,7 @@ public class LeaderLayoutManager extends LeafNodeLayoutManager { | |||
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); |
@@ -25,7 +25,6 @@ import org.apache.fop.area.Trait; | |||
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; | |||
@@ -105,7 +104,7 @@ public class PageNumberCitationLayoutManager extends LeafNodeLayoutManager { | |||
TextArea text = new TextArea(); | |||
inline = text; | |||
int width = getStringWidth(str); | |||
text.setText(str); | |||
text.addWord(str, 0); | |||
inline.setIPD(width); | |||
resolved = true; |
@@ -22,7 +22,6 @@ import org.apache.fop.fo.flow.PageNumber; | |||
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; | |||
@@ -75,7 +74,7 @@ public class PageNumberLayoutManager extends LeafNodeLayoutManager { | |||
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()); | |||
@@ -109,9 +108,10 @@ public class PageNumberLayoutManager extends LeafNodeLayoutManager { | |||
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()); | |||
} |
@@ -24,7 +24,6 @@ import java.util.LinkedList; | |||
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; | |||
@@ -41,6 +40,7 @@ import org.apache.fop.layoutmgr.PositionIterator; | |||
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 | |||
@@ -260,9 +260,10 @@ public class TextLayoutManager extends LeafNodeLayoutManager { | |||
// 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. | |||
@@ -273,12 +274,13 @@ public class TextLayoutManager extends LeafNodeLayoutManager { | |||
// | |||
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) { | |||
@@ -291,20 +293,8 @@ public class TextLayoutManager extends LeafNodeLayoutManager { | |||
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)); | |||
} | |||
@@ -355,8 +345,10 @@ public class TextLayoutManager extends LeafNodeLayoutManager { | |||
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 | |||
@@ -378,25 +370,25 @@ public class TextLayoutManager extends LeafNodeLayoutManager { | |||
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 | |||
@@ -417,7 +409,38 @@ public class TextLayoutManager extends LeafNodeLayoutManager { | |||
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()); |
@@ -188,7 +188,7 @@ public abstract class AbstractRenderer | |||
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())); |
@@ -741,7 +741,7 @@ public abstract class Java2DRenderer extends AbstractRenderer implements Printab | |||
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: " |
@@ -796,7 +796,7 @@ public class PSRenderer extends AbstractPathOrientedRenderer { | |||
* @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 | |||
} |
@@ -393,7 +393,7 @@ public class SVGRenderer extends AbstractRenderer implements XMLHandler { | |||
currentIPPosition / 1000, | |||
(currentBPPosition + text.getOffset() | |||
+ text.getBaselineOffset()) / 1000, | |||
text.getTextArea()); | |||
text.getText()); | |||
currentPageG.appendChild(textElement); | |||
super.renderText(text); |
@@ -119,6 +119,19 @@ public class CharUtilities { | |||
|| 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 |