*/
package org.apache.fop.layout;
+// Java
+import java.util.ArrayList;
+import java.util.StringTokenizer;
+import java.awt.Rectangle;
+
// FOP
-import org.apache.fop.render.Renderer;
-import org.apache.fop.messaging.MessageHandler;
-import org.apache.fop.layout.inline.*;
-import org.apache.fop.fo.properties.WrapOption;
-import org.apache.fop.fo.properties.WhiteSpaceCollapse;
-import org.apache.fop.fo.properties.TextAlign;
-import org.apache.fop.fo.properties.LeaderPattern;
+import org.apache.fop.datatypes.IDReferences;
import org.apache.fop.fo.properties.Hyphenate;
import org.apache.fop.fo.properties.LeaderAlignment;
+import org.apache.fop.fo.properties.LeaderPattern;
+import org.apache.fop.fo.properties.TextAlign;
import org.apache.fop.fo.properties.VerticalAlign;
+import org.apache.fop.fo.properties.WhiteSpaceCollapse;
+import org.apache.fop.fo.properties.WrapOption;
import org.apache.fop.layout.hyphenation.Hyphenation;
import org.apache.fop.layout.hyphenation.Hyphenator;
-
-// Java
-import java.util.ArrayList;
-import java.util.StringTokenizer;
-import java.awt.Rectangle;
+import org.apache.fop.layout.inline.*;
+import org.apache.fop.messaging.MessageHandler;
+import org.apache.fop.render.Renderer;
public class LineArea extends Area {
protected int endIndent;
private int placementOffset;
+ private int textAlign;
private FontState currentFontState; // not the nominal, which is
// in this.fontState
private float red, green, blue;
private int wrapOption;
private int whiteSpaceCollapse;
- int vAlign;
+ private int vAlign;
/* hyphenation */
- HyphenationProps hyphProps;
+ private HyphenationProps hyphProps;
/*
* the width of text that has definitely made it into the line
* area
*/
- protected int finalWidth = 0;
+ private int finalWidth = 0;
- /* the position to shift a link rectangle in order to compensate for links embedded within a word */
+ /* the position to shift a link rectangle in order to compensate
+ * for links embedded within a word
+ */
protected int embeddedLinkStart = 0;
/* the width of the current word so far */
protected static final int MULTIBYTECHAR = 3;
/* the character type of the previous character */
- protected int prev = NOTHING;
-
- /* the position in data[] of the start of the current word */
- // protected int wordStart;
-
- /* the length (in characters) of the current word */
- // protected int wordLength = 0;
+ private int prev = NOTHING;
/* width of spaces before current word */
- protected int spaceWidth = 0;
+ private int spaceWidth = 0;
/*
* the inline areas that have not yet been added to the line
* because subsequent characters to come (in a different addText)
* may be part of the same word
*/
- protected ArrayList pendingAreas = new ArrayList();
+ private ArrayList pendingAreas = new ArrayList();
/* the width of the pendingAreas */
- /* public for problem check in AbstractRenderer */
- public int pendingWidth = 0;
+ private int pendingWidth = 0;
/* text-decoration of the previous text */
protected boolean prevUlState = false;
protected boolean prevOlState = false;
protected boolean prevLTState = false;
+ // Whether the line has already be aligned text and expanded
+ // leaders.
+ private boolean aligned = false;
+ private boolean hasPageNumbers = false;
+
public class Leader {
int leaderPattern;
int leaderLengthMinimum;
this.placementOffset=placementOffset;
this.position = position;
}
- void expand(int leaderLength) {
+ void expand() {
char dot = '.';
- int dotWidth = getCharWidth(dot);
+ int dotWidth = currentFontState.getCharWidth(dot);
char space = ' ';
- int spaceWidth = getCharWidth(space);
+ int spaceWidth = currentFontState.getCharWidth(space);
int idx=children.indexOf(this);
children.remove(this);
switch (leaderPattern) {
case LeaderPattern.SPACE:
- InlineSpace spaceArea = new InlineSpace(leaderLength,false);
+ InlineSpace spaceArea = new InlineSpace(leaderLengthOptimum
+ , false);
children.add(idx,spaceArea);
break;
case LeaderPattern.RULE:
- LeaderArea leaderArea = new LeaderArea(this.fontState, this.red, this.green,
- this.blue, "", leaderLength,
- this.leaderPattern,
- this.ruleThickness, this.ruleStyle);
- leaderArea.setYOffset(this.placementOffset);
+ LeaderArea leaderArea = new LeaderArea(fontState, red, green,
+ blue, "",
+ leaderLengthOptimum,
+ leaderPattern,
+ ruleThickness,
+ ruleStyle);
+ leaderArea.setYOffset(placementOffset);
children.add(idx,leaderArea);
break;
case LeaderPattern.DOTS:
// shorten leaderLength, otherwise - in
// case of leaderLength=remaining length -
// it will cut off the end of leaderlength
- leaderLength -= spaceBeforeLeader;
+ leaderLengthOptimum -= spaceBeforeLeader;
}
}
- int factor = (int)Math.floor(leaderLength / dotWidth);
+ int factor = (int)Math.floor(leaderLengthOptimum / dotWidth);
char[] leaderChars = new char[factor];
for (int i = 0; i < factor; i++) {
leaderChars[i] = dot;
}
WordArea leaderPatternArea =
- new WordArea(currentFontState,
- this.red, this.green, this.blue,
- new String(leaderChars), leaderLength);
- leaderPatternArea.setYOffset(this.placementOffset);
+ new WordArea(currentFontState, red, green, blue,
+ new String(leaderChars),
+ leaderLengthOptimum);
+ leaderPatternArea.setYOffset(placementOffset);
children.add(idx, leaderPatternArea);
} else {
// if leader-alignment is used, calculate space to
// shorten leaderLength, otherwise - in
// case of leaderLength=remaining length -
// it will cut off the end of leaderlength
- leaderLength -= spaceBeforeLeader;
+ leaderLengthOptimum -= spaceBeforeLeader;
}
}
// calculate the space to insert between the dots
// and create a inline area with this width
int dotsFactor =
- (int)Math.floor(((double)leaderLength)
- / ((double)this.leaderPatternWidth));
+ (int)Math.floor(((double)leaderLengthOptimum)
+ / ((double)leaderPatternWidth));
// add combination of dot + space to fill leader
// is there a way to do this in a more effective way?
for (int i = 0; i < dotsFactor; i++) {
InlineSpace spaceBetweenDots =
- new InlineSpace(this.leaderPatternWidth - dotWidth, false);
+ new InlineSpace(leaderPatternWidth - dotWidth,
+ false);
WordArea leaderPatternArea =
new WordArea(this.fontState,
this.red, this.green, this.blue,
new String("."), dotWidth);
- leaderPatternArea.setYOffset(this.placementOffset);
+ leaderPatternArea.setYOffset(placementOffset);
children.add(idx,leaderPatternArea);
idx++;
children.add(idx,spaceBetweenDots);
idx++;
}
// append at the end some space to fill up to leader length
- children.add(idx,new InlineSpace(leaderLength
+ children.add(idx,new InlineSpace(leaderLengthOptimum
- dotsFactor
- * this.leaderPatternWidth));
+ * leaderPatternWidth));
idx++;
}
break;
}
public void render(Renderer renderer) {
+ if (pendingWidth > 0) {
+ MessageHandler.error("Areas pending, text probably lost in line"
+ + getLineText());
+ }
+ if (hasPageNumbers) {
+ IDReferences idReferences = renderer.getIDReferences();
+ for (int i = 0; i < children.size(); i++) {
+ Object o = children.get(i);
+ if ( o instanceof PageNumberInlineArea) {
+ PageNumberInlineArea pia = (PageNumberInlineArea)o;
+ FontState piaFontState = pia.getFontState();
+ finalWidth-=piaFontState.getWordWidth(pia.getText());
+ pia.resolve(idReferences);
+ finalWidth+=piaFontState.getWordWidth(pia.getText());
+ }
+ }
+ }
+ if (!aligned) {
+ int padding = 0;
+ switch (textAlign) {
+ case TextAlign.START: // left
+ padding = this.getContentWidth() - finalWidth;
+ endIndent += padding;
+ for (int i = 0; i < children.size(); i++) {
+ Object o = children.get(i);
+ if (o instanceof LineArea.Leader) {
+ LineArea.Leader leader = (LineArea.Leader)o;
+ leader.expand();
+ }
+ }
+ break;
+ case TextAlign.END: // right
+ padding = this.getContentWidth() - finalWidth;
+ startIndent += padding;
+ for (int i = 0; i < children.size(); i++) {
+ Object o = children.get(i);
+ if (o instanceof LineArea.Leader) {
+ LineArea.Leader leader = (LineArea.Leader)o;
+ leader.expand();
+ }
+ }
+ break;
+ case TextAlign.CENTER: // center
+ padding = (this.getContentWidth() - finalWidth) / 2;
+ startIndent += padding;
+ endIndent += padding;
+ for (int i = 0; i < children.size(); i++) {
+ Object o = children.get(i);
+ if (o instanceof LineArea.Leader) {
+ LineArea.Leader leader = (LineArea.Leader)o;
+ leader.expand();
+ }
+ }
+ break;
+ case TextAlign.JUSTIFY: // justify
+ // first pass - count the spaces
+ int leaderCount = 0;
+ int spaceCount = 0;
+ for (int i = 0; i < children.size(); i++ ) {
+ Object o = children.get(i);
+ if (o instanceof InlineSpace) {
+ InlineSpace space = (InlineSpace)o;
+ if (space.getResizeable()) {
+ spaceCount++;
+ }
+ } else if(o instanceof LineArea.Leader) {
+ leaderCount++;
+ }
+ }
+ padding = (this.getContentWidth() - finalWidth);
+ if (padding!=0) {
+ if (leaderCount>0) {
+ int offset=0;
+ for (int i = 0; i < children.size(); i++) {
+ Object o = children.get(i);
+ if (o instanceof LineArea.Leader) {
+ LineArea.Leader leader = (LineArea.Leader)o;
+ int leaderExpansionMaximum=
+ leader.leaderLengthMaximum - leader.leaderLengthOptimum;
+ int leaderExpansionMinimum=
+ leader.leaderLengthMinimum - leader.leaderLengthOptimum;
+ if (leaderExpansionMaximum < padding) {
+ leader.leaderLengthOptimum =
+ leader.leaderLengthMaximum;
+ leader.expand();
+ padding-=leaderExpansionMaximum;
+ offset+=leaderExpansionMaximum;
+ } else if (padding < leaderExpansionMinimum) {
+ leader.leaderLengthOptimum =
+ leader.leaderLengthMinimum;
+ leader.expand();
+ padding-=leaderExpansionMinimum;
+ offset+=leaderExpansionMinimum;
+ } else {
+ leader.leaderLengthOptimum += padding;
+ leader.expand();
+ padding=0;
+ offset+=padding;
+ }
+ } else if (o instanceof InlineArea) {
+ ((InlineArea)o).setXOffset(((InlineArea)o).getXOffset() + offset);
+ }
+ }
+ }
+ if (padding != 0) {
+ if (spaceCount > 0) {
+ if (padding > 0) {
+ // The line is actually short of
+ // padding mod spaceCount
+ // millipoints. Should implement
+ // Bresenham-like algorithm for
+ // compensating, but it's not worth
+ // yet.
+ // If there are ref-area aligned leaders,
+ // they will be no longer aligned.
+ padding = padding/spaceCount;
+ spaceCount = 0;
+ // second pass - add additional space
+ for (int i = 0; i < children.size(); i++) {
+ Object o = children.get(i);
+ if (o instanceof InlineSpace) {
+ InlineSpace space = (InlineSpace)o;
+ if (space.getResizeable()) {
+ space.setSize(space.getSize() + padding);
+ spaceCount++;
+ }
+ } else if (o instanceof InlineArea) {
+ ((InlineArea)o).setXOffset(((InlineArea)o).getXOffset() + i * padding);
+ }
+ }
+ } else {
+ MessageHandler.log("Area overflow in line "
+ + getLineText());
+ }
+ } else {
+ // no spaces
+ MessageHandler.log("No spaces to justify text in line "
+ + getLineText());
+ }
+ }
+ }
+ break;
+ default:
+ MessageHandler.errorln("bad align: "+textAlign);
+ break;
+ }
+ }
renderer.renderLineArea(this);
}
// Space must be allocated for the page number, so currently we
// give it 3 spaces
- int width = 3*getCharWidth(' ');
+ int width = 3*currentFontState.getCharWidth(' ');
PageNumberInlineArea pia
pendingAreas.add(pia);
pendingWidth += width;
prev = TEXT;
+ hasPageNumbers = true;
return -1;
}
int wordLength = 0;
int wordWidth = 0;
// With CID fonts, space isn't neccesary currentFontState.width(32)
- int whitespaceWidth = getCharWidth(' ');
+ int whitespaceWidth = currentFontState.getCharWidth(' ');
boolean isText = false;
boolean isMultiByteChar = false;
char c = data[i];
if (!(isSpace(c) || (c == '\n') || (c == '\r') || (c == '\t')
|| (c == '\u2028'))) {
- charWidth = getCharWidth(c);
+ charWidth = currentFontState.getCharWidth(c);
isText = true;
isMultiByteChar = (c > 127);
// Add support for zero-width spaces
if ((c == '\n') || (c == '\r') || (c == '\t'))
charWidth = whitespaceWidth;
else
- charWidth = getCharWidth(c);
+ charWidth = currentFontState.getCharWidth(c);
isText = false;
isMultiByteChar = false;
if (this.whiteSpaceCollapse == WhiteSpaceCollapse.FALSE) {
if (isSpace(c)) {
- spaceWidth += getCharWidth(c);
+ spaceWidth += currentFontState.getCharWidth(c);
} else if (c == '\n' || c == '\u2028') {
// force line break
if (spaceWidth > 0) {
embeddedLinkStart =
0; // reset embeddedLinkStart since a space was encountered
- spaceWidth = getCharWidth(c);
+ spaceWidth = currentFontState.getCharWidth(c);
/*
* here is the place for white-space-treatment value 'ignore':
if (this.whiteSpaceCollapse == WhiteSpaceCollapse.FALSE) {
if (isSpace(c)) {
prev = WHITESPACE;
- spaceWidth = getCharWidth(c);
+ spaceWidth = currentFontState.getCharWidth(c);
} else if (c == '\n') {
// force line break
// textdecoration not used because spaceWidth is 0
if ((finalWidth + spaceWidth + wordWidth)
> this.getContentWidth()) {
if (overrun)
- MessageHandler.log("area contents overflows area");
+ MessageHandler.log("area contents overflows area "
+ + "in line "
+ + getLineText());
if (this.wrapOption == WrapOption.WRAP) {
return i;
}
(wordStart == start) &&
(finalWidth == 0)) {
- MessageHandler.log("area contents overflows area");
+ MessageHandler.log("area contents overflows"
+ + " area in line "
+ + getLineText());
addSpacedWord(new String(data, wordStart, wordLength - 1),
ls,
embeddedLinkStart,
}
if (overrun)
- MessageHandler.log("area contents overflows area");
+ MessageHandler.log("area contents overflows area in line "
+ + getLineText());
return -1;
}
}
/**
- * aligns line area
- *
+ * Store text alignment.
+ * The line is aligned immediately before rendering, after
+ * page numbers have been resolved.
*/
public void align(int type) {
- int padding = 0;
-
- switch (type) {
- case TextAlign.START: // left
- padding = this.getContentWidth() - finalWidth;
- endIndent += padding;
- for (int i = 0; i < children.size(); i++) {
- Object o = children.get(i);
- if (o instanceof LineArea.Leader) {
- LineArea.Leader leader = (LineArea.Leader)o;
- leader.expand(leader.leaderLengthOptimum);
- }
- }
- break;
- case TextAlign.END: // right
- padding = this.getContentWidth() - finalWidth;
- startIndent += padding;
- for (int i = 0; i < children.size(); i++) {
- Object o = children.get(i);
- if (o instanceof LineArea.Leader) {
- LineArea.Leader leader = (LineArea.Leader)o;
- leader.expand(leader.leaderLengthOptimum);
- }
- }
- break;
- case TextAlign.CENTER: // center
- padding = (this.getContentWidth() - finalWidth) / 2;
- startIndent += padding;
- endIndent += padding;
- for (int i = 0; i < children.size(); i++) {
- Object o = children.get(i);
- if (o instanceof LineArea.Leader) {
- LineArea.Leader leader = (LineArea.Leader)o;
- leader.expand(leader.leaderLengthOptimum);
- }
- }
- break;
- case TextAlign.JUSTIFY: // justify
- // first pass - count the spaces
- int leaderCount = 0;
- int spaceCount = 0;
- for (int i = 0; i < children.size(); i++ ) {
- Object o = children.get(i);
- if (o instanceof InlineSpace) {
- InlineSpace space = (InlineSpace)o;
- if (space.getResizeable()) {
- spaceCount++;
- }
- } else if(o instanceof LineArea.Leader) {
- leaderCount++;
- }
- }
- padding = (this.getContentWidth() - finalWidth);
- if (padding>0) {
- if (leaderCount>0) {
- int offset=0;
- for (int i = 0; i < children.size(); i++) {
- Object o = children.get(i);
- if (o instanceof LineArea.Leader) {
- LineArea.Leader leader = (LineArea.Leader)o;
- int leaderExpansionMaximum=
- leader.leaderLengthMaximum - leader.leaderLengthOptimum;
- if (leaderExpansionMaximum < padding) {
- leader.expand(leader.leaderLengthMaximum);
- padding-=leaderExpansionMaximum;
- offset+=leaderExpansionMaximum;
- } else {
- leader.expand(leader.leaderLengthOptimum + padding);
- padding=0;
- offset+=padding;
- }
- } else if (o instanceof InlineArea) {
- ((InlineArea)o).setXOffset(((InlineArea)o).getXOffset() + offset);
- }
- }
- }
- if (spaceCount > 0 && padding > 0) {
- padding = padding/spaceCount;
- } else { // no spaces
- padding = 0;
- }
- spaceCount = 0;
- // second pass - add additional space
- for (int i = 0; i < children.size(); i++) {
- Object o = children.get(i);
- if (o instanceof InlineSpace) {
- InlineSpace space = (InlineSpace)o;
- if (space.getResizeable()) {
- space.setSize(space.getSize() + padding);
- spaceCount++;
- }
- } else if (o instanceof InlineArea) {
- ((InlineArea)o).setXOffset(((InlineArea)o).getXOffset() + i * padding);
- }
- }
- }
- break;
- default:
- MessageHandler.errorln("bad align: "+type);
- break;
- }
+ textAlign = type;
}
/**
int superHeight = -this.placementOffset;
int maxHeight = this.allocationHeight;
for (int i = 0; i < children.size(); i++ ) {
- Box b = (Box)children.get(i);
- if (b instanceof InlineArea) {
- InlineArea ia = (InlineArea)b;
+ Object o = children.get(i);
+ if (o instanceof InlineArea) {
+ InlineArea ia = (InlineArea)o;
if (ia instanceof WordArea) {
ia.setYOffset(placementOffset);
}
int fh = fontState.getAscender();
ia.setYOffset((int)(placementOffset + (2 * fh / 3.0)));
}
- } else {}
+ }
}
// adjust the height of this line to the
// resulting alignment height.
* and wraps it in an InlineArea which is returned
*/
private InlineArea buildSimpleLeader(char c, int leaderLength) {
- int width = getCharWidth(c);
+ int width = currentFontState.getCharWidth(c);
if (width == 0) {
MessageHandler.errorln("char " + c
+ " has width 0. Using width 100 instead.");
TextState textState) {
// check whether the language property has been set
if (this.hyphProps.language.equalsIgnoreCase("none")) {
- MessageHandler.errorln("if property 'hyphenate' is used, a language must be specified");
+ MessageHandler.errorln("if property 'hyphenate' is used, a "
+ + "language must be specified in line "
+ + getLineText());
return wordStart;
}
String wordToHyphenate;
// width of hyphenation character
- int hyphCharWidth = getCharWidth(this.hyphProps.hyphenationChar);
+ int hyphCharWidth = currentFontState
+ .getCharWidth(this.hyphProps.hyphenationChar);
remainingWidth -= hyphCharWidth;
// handles ' or " at the beginning of the word
// if the extracted word is smaller than the remaining width
// we have a non letter character inside the word. at the moment
// we will only handle hard hyphens and slashes
- if (getWordWidth(wordToHyphenate) < remainingWidth) {
+ if (currentFontState.getWordWidth(wordToHyphenate) < remainingWidth) {
inwordPunctuation =
characters[wordStart + remainingString.length()
+ wordToHyphenate.length()];
wordStart + remainingString.length()
+ wordToHyphenate.length() + 1);
remainingWidth -=
- (getWordWidth(wordToHyphenate)
- + getCharWidth(inwordPunctuation));
+ (currentFontState.getWordWidth(wordToHyphenate)
+ + currentFontState.getCharWidth(inwordPunctuation));
}
}
return wordStart;
}
-
- /**
- * Calculates the wordWidth using the actual fontstate
- */
- private int getWordWidth(String word) {
- if (word == null)
- return 0;
- int wordLength = word.length();
- int width = 0;
- char[] characters = new char[wordLength];
- word.getChars(0, wordLength, characters, 0);
-
- for (int i = 0; i < wordLength; i++) {
- width += getCharWidth(characters[i]);
- }
- return width;
- }
-
public int getRemainingWidth() {
return this.getContentWidth() + startIndent - this.getCurrentXPosition();
}
public int addCharacter(char data, LinkSet ls, boolean ul) {
WordArea ia = null;
int remainingWidth = this.getRemainingWidth();
- int width = getCharWidth(data);
+ int width = currentFontState.getCharWidth(data);
// if it doesn't fit, return
if (width > remainingWidth) {
return org.apache.fop.fo.flow.Character.DOESNOT_FIT;
pendingWidth = 0;
pendingAreas = new ArrayList();
String word = (wordBuf != null) ? wordBuf.toString() : "";
- int wordWidth = this.getWordWidth(word);
+ int wordWidth = currentFontState.getWordWidth(word);
WordArea hia = new WordArea(currentFontState,
this.red, this.green, this.blue,
word, wordWidth);
for (int i = 0; i < numberOfHyphenationPoints; i++) {
wordBegin = hyph.getPreHyphenText(i);
- if (this.getWordWidth(wordBegin) > remainingWidth) {
+ if (currentFontState.getWordWidth(wordBegin) > remainingWidth) {
break;
}
index = i;
return ret;
}
- private final int getEmWidth() {
- char mappedChar = currentFontState.mapChar('m');
- // the mapping returns '#' for unmapped characters in standard fonts
- // what happens for other fonts?
- if (mappedChar == '#') {
- return 500 * currentFontState.getFontSize();
- } else {
- return currentFontState.width(mappedChar);
- }
- }
-
- private final int getEnWidth() {
- char mappedChar = currentFontState.mapChar('n');
- // the mapping returns '#' for unmapped characters in standard fonts
- // what happens for other fonts?
- if (mappedChar != '#') {
- // should do something to discover non-proportional fonts
- return (getEmWidth()*9)/10;
- } else {
- return currentFontState.width(mappedChar);
- }
- }
-
- /**
- * Helper method for getting the width of a unicode char
- * from the current fontstate.
- * This also performs some guessing on widths on various
- * versions of space that might not exists in the font.
- */
- private int getCharWidth(char c) {
- if ((c == '\n') || (c == '\r') || (c == '\t')) {
- return getCharWidth(' ');
- } else {
- char mappedChar = currentFontState.mapChar(c);
- if (mappedChar == '#' || mappedChar == 0) {
- // Estimate the width of spaces not represented in
- // the font
- if (c == '#') {
- return currentFontState.width(mappedChar);
- } else if (c == ' ') {
- return getEmWidth();
- } else if (c == '\u00A0') {
- return getCharWidth(' ');
- } else if (c == '\u2000') {
- return getEnWidth();
- } else if (c == '\u2001') {
- return getEmWidth();
- } else if (c == '\u2002') {
- return getEnWidth();
- } else if (c == '\u2003') {
- return getEmWidth();
- } else if (c == '\u2004') {
- return getEmWidth() / 3;
- } else if (c == '\u2005') {
- return getEmWidth() / 4;
- } else if (c == '\u2006') {
- return getEmWidth() / 6;
- } else if (c == '\u2007') {
- return getCharWidth(' ');
- } else if (c == '\u2008') {
- return getCharWidth('.');
- } else if (c == '\u2009') {
- return getEmWidth() / 5;
- } else if (c == '\u200A') {
- return getEmWidth() / 10;
- } else if (c == '\u200B') {
- return 1;
- } else if (c == '\u202F') {
- return getCharWidth(' ') / 2;
- } else if (c == '\u3000') {
- return getCharWidth(' ') * 2;
- } else if (c == '\u3000') {
- return getCharWidth(' ') * 2;
- } else {
- return currentFontState.width(mappedChar);
- }
- } else {
- return currentFontState.width(mappedChar);
- }
- }
- }
/**
if (currentWord.length() == 1
&& (isNBSP(currentWord.charAt(0)))) {
// Add an InlineSpace
- int spaceWidth = getCharWidth(currentWord.charAt(0));
+ int spaceWidth = currentFontState
+ .getCharWidth(currentWord.charAt(0));
if (spaceWidth > 0) {
InlineSpace is = new InlineSpace(spaceWidth);
startw += spaceWidth;
}
}
} else {
- int wordWidth = getWordWidth(currentWord);
+ int wordWidth = currentFontState.getWordWidth(currentWord);
WordArea ia = new WordArea(currentFontState, this.red,
this.green, this.blue,
currentWord,
}
}
+ public String getLineText() {
+ StringBuffer b = new StringBuffer(120);
+ for (int i=0;i<children.size();i++) {
+ Object o = children.get(i);
+ if (o instanceof WordArea) {
+ b.append(((WordArea)o).getText());
+ } else if (o instanceof InlineSpace) {
+ b.append(' ');
+ } else if (o instanceof org.apache.fop.image.ImageArea) {
+ b.append("<img>");
+ } else {
+ b.append('<');
+ b.append(o.getClass().getName());
+ b.append('>');
+ }
+ }
+ return b.toString();
+ }
}