From: Joerg Pietschmann Date: Sun, 2 Feb 2003 21:17:41 +0000 (+0000) Subject: Fixed leader generation to be more conformant with common expectations. X-Git-Tag: fop-0_20_5rc2~30 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=ec033cb9aeb4662244ac7e8f98a2cfb0404ea4ce;p=xmlgraphics-fop.git Fixed leader generation to be more conformant with common expectations. Everything assuming leaders automatically expand as much as possible is broken now, leaders expand ONLY due to text justification. Expanding multiple leaders on a line is simplistic. Fixed leader-alignment="reference" to some extend. Leaders may be still misaligned if text justification causes spaces to expand, i.e. slack space was not taken completely by leaders. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/fop-0_20_2-maintain@195925 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/org/apache/fop/fo/FOText.java b/src/org/apache/fop/fo/FOText.java index e5af635a2..5ae14970d 100644 --- a/src/org/apache/fop/fo/FOText.java +++ b/src/org/apache/fop/fo/FOText.java @@ -230,7 +230,6 @@ public class FOText extends FONode { ba.setupLinkSet(ls); start = la.addText(data, start, end, ls, textState); - // this.hasLines = true; while ( start != -1) { la = ba.createNextLineArea(); diff --git a/src/org/apache/fop/fo/flow/Leader.java b/src/org/apache/fop/fo/flow/Leader.java index 0bc6a7c83..e4d6ddfb7 100644 --- a/src/org/apache/fop/fo/flow/Leader.java +++ b/src/org/apache/fop/fo/flow/Leader.java @@ -108,17 +108,29 @@ public class Leader extends FObjMixed { // determines the pattern of leader; allowed values: space, rule,dots, use-content int leaderPattern = this.properties.get("leader-pattern").getEnum(); // length of the leader - int leaderLengthOptimum = - this.properties.get("leader-length.optimum").getLength().mvalue(); - int leaderLengthMinimum = - this.properties.get("leader-length.minimum").getLength().mvalue(); - Length maxlength = this.properties.get("leader-length.maximum").getLength(); + Length length = this.properties.get("leader-length.minimum").getLength(); + int leaderLengthMinimum; + if (length instanceof PercentLength) { + leaderLengthMinimum = (int)(((PercentLength)length).value() + * area.getAllocationWidth()); + } else { + leaderLengthMinimum = length.mvalue(); + } + length = this.properties.get("leader-length.optimum").getLength(); + int leaderLengthOptimum; + if (length instanceof PercentLength) { + leaderLengthOptimum = (int)(((PercentLength)length).value() + * area.getAllocationWidth()); + } else { + leaderLengthOptimum = length.mvalue(); + } + length = this.properties.get("leader-length.maximum").getLength(); int leaderLengthMaximum; - if(maxlength instanceof PercentLength) { - leaderLengthMaximum = (int)(((PercentLength)maxlength).value() + if (length instanceof PercentLength) { + leaderLengthMaximum = (int)(((PercentLength)length).value() * area.getAllocationWidth()); } else { - leaderLengthMaximum = maxlength.mvalue(); + leaderLengthMaximum = length.mvalue(); } // the following properties only apply for leader-pattern = "rule" int ruleThickness = @@ -177,7 +189,7 @@ public class Leader extends FObjMixed { // in the xsl:fo spec: "User agents may choose to use the value of 'leader-length.optimum' // to determine where to break the line" (7.20.4) // if leader is longer then create a new LineArea and put leader there - if (leaderLengthOptimum <= (la.getRemainingWidth())) { + if (leaderLengthOptimum <= la.getRemainingWidth()) { la.addLeader(leaderPattern, leaderLengthMinimum, leaderLengthOptimum, leaderLengthMaximum, ruleStyle, ruleThickness, leaderPatternWidth, leaderAlignment); @@ -200,12 +212,11 @@ public class Leader extends FObjMixed { } else { log.error("Leader doesn't fit into line, it will be clipped to fit."); la.addLeader(leaderPattern, la.getRemainingWidth(), - leaderLengthOptimum, leaderLengthMaximum, + la.getRemainingWidth(), la.getRemainingWidth(), ruleStyle, ruleThickness, leaderPatternWidth, leaderAlignment); } } - // this.hasLines = true; return 1; } diff --git a/src/org/apache/fop/layout/BlockArea.java b/src/org/apache/fop/layout/BlockArea.java index cd390dd55..04de490b1 100644 --- a/src/org/apache/fop/layout/BlockArea.java +++ b/src/org/apache/fop/layout/BlockArea.java @@ -51,9 +51,6 @@ public class BlockArea extends Area { protected LineArea currentLineArea; protected LinkSet currentLinkSet; - /* have any line areas been used? */ - protected boolean hasLines = false; - /* hyphenation */ protected HyphenationProps hyphProps; @@ -114,18 +111,23 @@ public class BlockArea extends Area { /** * Get the current line area in this block area. * This is used to get the current line area for adding - * inline objects to. + * inline objects. * This will return null if there is not enough room left * in the block area to accomodate the line area. * - * @return the line area to be used to add inlie objects + * @return the line area to be used to add inline objects */ public LineArea getCurrentLineArea() { if (currentHeight + lineHeight > maxHeight) { return null; } - this.currentLineArea.changeHyphenation(hyphProps); - this.hasLines = true; + if (this.currentLineArea==null ) { + this.currentLineArea = new LineArea(fontState, lineHeight, + halfLeading, allocationWidth, + startIndent + textIndent, + endIndent, null); + this.currentLineArea.changeHyphenation(hyphProps); + } return this.currentLineArea; } @@ -140,18 +142,18 @@ public class BlockArea extends Area { * @return the new current line area, which will be empty. */ public LineArea createNextLineArea() { - if (this.hasLines) { + if (this.currentLineArea!=null) { this.currentLineArea.align(this.align); this.addLineArea(this.currentLineArea); } + if (currentHeight + lineHeight > maxHeight) { + return null; + } this.currentLineArea = new LineArea(fontState, lineHeight, halfLeading, allocationWidth, startIndent, endIndent, currentLineArea); this.currentLineArea.changeHyphenation(hyphProps); - if (currentHeight + lineHeight > maxHeight) { - return null; - } return this.currentLineArea; } @@ -168,7 +170,7 @@ public class BlockArea extends Area { * add (if any) the current line area. */ public void end() { - if (this.hasLines) { + if (this.currentLineArea!=null) { this.currentLineArea.addPending(); this.currentLineArea.align(this.alignLastLine); this.addLineArea(this.currentLineArea); @@ -176,10 +178,6 @@ public class BlockArea extends Area { } public void start() { - currentLineArea = new LineArea(fontState, lineHeight, halfLeading, - allocationWidth, - startIndent + textIndent, endIndent, - null); } public int getEndIndent() { diff --git a/src/org/apache/fop/layout/LineArea.java b/src/org/apache/fop/layout/LineArea.java index 328102f59..160080be8 100644 --- a/src/org/apache/fop/layout/LineArea.java +++ b/src/org/apache/fop/layout/LineArea.java @@ -100,6 +100,172 @@ public class LineArea extends Area { protected boolean prevOlState = false; protected boolean prevLTState = false; + public class Leader { + int leaderPattern; + int leaderLengthMinimum; + int leaderLengthOptimum; + int leaderLengthMaximum; + int ruleStyle; + int ruleThickness; + int leaderPatternWidth; + int leaderAlignment; + FontState fontState; + float red; + float green; + float blue; + int placementOffset; + int position; + + Leader(int leaderPattern, int leaderLengthMinimum, + int leaderLengthOptimum, int leaderLengthMaximum, + int ruleStyle, int ruleThickness, + int leaderPatternWidth, int leaderAlignment, + FontState fontState, + float red, float green, float blue, + int placementOffset, + int position) { + this.leaderPattern=leaderPattern; + this.leaderLengthMinimum=leaderLengthMinimum; + this.leaderLengthOptimum=leaderLengthOptimum; + this.leaderLengthMaximum=leaderLengthMaximum; + this.ruleStyle=ruleStyle; + this.ruleThickness=ruleThickness; + this.leaderPatternWidth=leaderPatternWidth; + this.leaderAlignment=leaderAlignment; + this.fontState=fontState; + this.red=red; + this.green=green; + this.blue=blue; + this.placementOffset=placementOffset; + this.position = position; + } + void expand(int leaderLength) { + char dot = '.'; + int dotWidth = getCharWidth(dot); + char space = ' '; + int spaceWidth = getCharWidth(space); + int idx=children.indexOf(this); + children.remove(this); + switch (leaderPattern) { + case LeaderPattern.SPACE: + InlineSpace spaceArea = new InlineSpace(leaderLength,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); + children.add(idx,leaderArea); + break; + case LeaderPattern.DOTS: + // if the width of a dot is larger than leader-pattern-width + // ignore this property + if (this.leaderPatternWidth < dotWidth) { + this.leaderPatternWidth = 0; + } + // if value of leader-pattern-width is 'use-font-metrics' (0) + if (this.leaderPatternWidth == 0) { + if (dotWidth == 0) { + MessageHandler.errorln("char " + dot + + " has width 0. Using width 100 instead."); + dotWidth = 100; + } + // if leader-alignment is used, calculate space to + // insert before leader so that all dots will be + // parallel. + if (leaderAlignment == LeaderAlignment.REFERENCE_AREA) { + int nextRepeatedLeaderPatternCycle + = (int)Math.ceil((double)position/(double)dotWidth); + int spaceBeforeLeader = + dotWidth * nextRepeatedLeaderPatternCycle + - position; + // appending indent space leader-alignment setting + // InlineSpace to false, so it is not used in line + // justification + System.out.println("align, space="+spaceBeforeLeader); + if (spaceBeforeLeader > 0) { + children.add(idx, new InlineSpace(spaceBeforeLeader, + false)); + idx++; + // shorten leaderLength, otherwise - in + // case of leaderLength=remaining length - + // it will cut off the end of leaderlength + leaderLength -= spaceBeforeLeader; + } + } + int factor = (int)Math.floor(leaderLength / 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); + children.add(idx, leaderPatternArea); + } else { + // if leader-alignment is used, calculate space to + // insert before leader so that all dots will be + // parallel. + if (leaderAlignment == LeaderAlignment.REFERENCE_AREA) { + int nextRepeatedLeaderPatternCycle + = (int)Math.ceil((double)position/(double)leaderPatternWidth); + int spaceBeforeLeader = + leaderPatternWidth * nextRepeatedLeaderPatternCycle + - position; + // appending indent space leader-alignment setting + // InlineSpace to false, so it is not used in line + // justification + System.out.println("align, space="+spaceBeforeLeader); + if (spaceBeforeLeader > 0) { + children.add(idx, new InlineSpace(spaceBeforeLeader, + false)); + idx++; + // shorten leaderLength, otherwise - in + // case of leaderLength=remaining length - + // it will cut off the end of leaderlength + leaderLength -= 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)); + // 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); + WordArea leaderPatternArea = + new WordArea(this.fontState, + this.red, this.green, this.blue, + new String("."), dotWidth); + leaderPatternArea.setYOffset(this.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 + - dotsFactor + * this.leaderPatternWidth)); + idx++; + } + break; + // leader pattern use-content not implemented. + case LeaderPattern.USECONTENT: + MessageHandler.errorln("leader-pattern=\"use-content\" not " + + "supported by this version of Fop"); + return; + } + } + } + public LineArea(FontState fontState, int lineHeight, int halfLeading, int allocationWidth, int startIndent, int endIndent, LineArea prevLineArea) { @@ -109,11 +275,11 @@ public class LineArea extends Area { this.lineHeight = lineHeight; this.nominalFontSize = fontState.getFontSize(); this.nominalGlyphHeight = fontState.getAscender() - - fontState.getDescender(); + - fontState.getDescender(); this.placementOffset = fontState.getAscender(); this.contentRectangleWidth = allocationWidth - startIndent - - endIndent; + - endIndent; this.fontState = fontState; this.allocationHeight = this.nominalGlyphHeight; @@ -169,9 +335,11 @@ public class LineArea extends Area { int width = 3*getCharWidth(' '); - PageNumberInlineArea pia = new PageNumberInlineArea(currentFontState, - this.red, this.green, this.blue, refid, width); - + PageNumberInlineArea pia + = new PageNumberInlineArea(currentFontState, + this.red, this.green, this.blue, + refid, width); + pia.setYOffset(placementOffset); pendingAreas.add(pia); pendingWidth += width; @@ -209,7 +377,7 @@ public class LineArea extends Area { /* get the character */ char c = data[i]; if (!(isSpace(c) || (c == '\n') || (c == '\r') || (c == '\t') - || (c == '\u2028'))) { + || (c == '\u2028'))) { charWidth = getCharWidth(c); isText = true; isMultiByteChar = (c > 127); @@ -388,7 +556,7 @@ public class LineArea extends Area { wordWidth = charWidth; if ((finalWidth + spaceWidth + wordWidth) - > this.getContentWidth()) { + > this.getContentWidth()) { if (overrun) MessageHandler.log("area contents overflows area"); if (this.wrapOption == WrapOption.WRAP) { @@ -425,13 +593,13 @@ public class LineArea extends Area { for (int j = 0; j < pendingAreas.size(); j++ ) { Box box = (Box)pendingAreas.get(j); if (box instanceof InlineArea) { - if (ls != null) { - Rectangle lr = - new Rectangle(finalWidth, 0, - ((InlineArea)box).getContentWidth(), - fontState.getFontSize()); - ls.addRect(lr, this, (InlineArea)box); - } + if (ls != null) { + Rectangle lr = + new Rectangle(finalWidth, 0, + ((InlineArea)box).getContentWidth(), + fontState.getFontSize()); + ls.addRect(lr, this, (InlineArea)box); + } } addChild(box); } @@ -468,19 +636,19 @@ public class LineArea extends Area { } if ((finalWidth + spaceWidth + pendingWidth + wordWidth) - > this.getContentWidth()) { + > this.getContentWidth()) { // BREAK MID WORD /* if (canBreakMidWord()) { - addSpacedWord(new String(data, wordStart, wordLength - 1), - ls, - finalWidth + spaceWidth - + embeddedLinkStart, spaceWidth, - textState, false); - finalWidth += wordWidth; - wordWidth = 0; - return i; - } + addSpacedWord(new String(data, wordStart, wordLength - 1), + ls, + finalWidth + spaceWidth + + embeddedLinkStart, spaceWidth, + textState, false); + finalWidth += wordWidth; + wordWidth = 0; + return i; + } */ if (this.wrapOption == WrapOption.WRAP) { @@ -574,115 +742,29 @@ public class LineArea extends Area { int leaderLengthOptimum, int leaderLengthMaximum, int ruleStyle, int ruleThickness, int leaderPatternWidth, int leaderAlignment) { - WordArea leaderPatternArea; - int leaderLength = 0; - char dot = '.'; - int dotWidth = getCharWidth(dot); - char space = ' '; - int spaceWidth = getCharWidth(space); - - int remainingWidth = this.getRemainingWidth(); - - /** - * checks whether leaderLenghtOptimum fits into rest of line; - * should never overflow, as it has been checked already in BlockArea - * first check: use remaining width if it smaller than optimum oder maximum - */ - if ((remainingWidth <= leaderLengthOptimum) - || (remainingWidth <= leaderLengthMaximum)) { - leaderLength = remainingWidth; - } else if ((remainingWidth > leaderLengthOptimum) - && (remainingWidth > leaderLengthMaximum)) { - leaderLength = leaderLengthMaximum; - } else if ((leaderLengthOptimum > leaderLengthMaximum) - && (leaderLengthOptimum < remainingWidth)) { - leaderLength = leaderLengthOptimum; - } - - // stop if leader-length is too small - if (leaderLength <= 0) { + System.out.println( + "min="+leaderLengthMinimum+ + " opt="+leaderLengthOptimum+ + " max="+leaderLengthMaximum+ + " th="+ruleThickness+ + " al="+leaderAlignment); + if (leaderLengthMinimum>leaderLengthOptimum + || leaderLengthOptimum>leaderLengthMaximum) { + MessageHandler.errorln("leader sizes wrong"); return; } - - switch (leaderPattern) { - case LeaderPattern.SPACE: - InlineSpace spaceArea = new InlineSpace(leaderLength); - pendingAreas.add(spaceArea); - break; - case LeaderPattern.RULE: - LeaderArea leaderArea = new LeaderArea(fontState, red, green, - blue, "", leaderLength, - leaderPattern, - ruleThickness, ruleStyle); - leaderArea.setYOffset(placementOffset); - pendingAreas.add(leaderArea); - break; - case LeaderPattern.DOTS: - // if the width of a dot is larger than leader-pattern-width - // ignore this property - if (leaderPatternWidth < dotWidth) { - leaderPatternWidth = 0; - } - // if value of leader-pattern-width is 'use-font-metrics' (0) - if (leaderPatternWidth == 0) { - pendingAreas.add(this.buildSimpleLeader(dot, leaderLength)); - } else { - // if leader-alignment is used, calculate space to - // insert before leader so that all dots will be - // parallel. - if (leaderAlignment == LeaderAlignment.REFERENCE_AREA) { - int spaceBeforeLeader = - this.getLeaderAlignIndent(leaderLength, - leaderPatternWidth); - // appending indent space leader-alignment setting - // InlineSpace to false, so it is not used in line - // justification - if (spaceBeforeLeader != 0) { - pendingAreas.add(new InlineSpace(spaceBeforeLeader, false)); - pendingWidth += spaceBeforeLeader; - // shorten leaderLength, otherwise - in case of - // leaderLength=remaining length - it will cut off the end of - // leaderlength - leaderLength -= spaceBeforeLeader; - } - } - - // calculate the space to insert between the dots and create a - // inline area with this width - InlineSpace spaceBetweenDots = - new InlineSpace(leaderPatternWidth - dotWidth, false); - - leaderPatternArea = new WordArea(currentFontState, this.red, - this.green, this.blue, - new String("."), dotWidth); - leaderPatternArea.setYOffset(placementOffset); - int dotsFactor = - (int)Math.floor(((double)leaderLength) - / ((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++) { - pendingAreas.add(leaderPatternArea); - pendingAreas.add(spaceBetweenDots); - } - // append at the end some space to fill up to leader length - pendingAreas.add(new InlineSpace(leaderLength - - dotsFactor - * leaderPatternWidth)); - } - break; - // leader pattern use-content not implemented. - case LeaderPattern.USECONTENT: - MessageHandler.errorln("leader-pattern=\"use-content\" not " - + "supported by this version of Fop"); + if (leaderLengthOptimum>getRemainingWidth()) { + MessageHandler.errorln("leader width assertion failed"); return; } - // adds leader length to length of pending inline areas - pendingWidth += leaderLength; - // sets prev to TEXT and makes so sure, that also blocks only - // containing leaders are processed - prev = TEXT; + addPending(); + children.add(new LineArea.Leader(leaderPattern, leaderLengthMinimum, + leaderLengthOptimum, leaderLengthMaximum, + ruleStyle, ruleThickness, + leaderPatternWidth, leaderAlignment, + fontState, red, green, blue, + placementOffset, getCurrentXPosition())); + finalWidth += leaderLengthOptimum; } /** @@ -715,52 +797,103 @@ public class LineArea extends Area { */ 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++ ) { - Box b = (Box)children.get(i); - if (b instanceof InlineSpace) { - InlineSpace space = (InlineSpace)b; + Object o = children.get(i); + if (o instanceof InlineSpace) { + InlineSpace space = (InlineSpace)o; if (space.getResizeable()) { spaceCount++; } + } else if(o instanceof LineArea.Leader) { + leaderCount++; } } - if (spaceCount > 0) { - padding = (this.getContentWidth() - finalWidth) / spaceCount; - } else { // no spaces - padding = 0; - } - // second pass - add additional space - spaceCount = 0; - for (int i = 0; i < children.size(); i++) { - Box b = (Box)children.get(i); - if (b instanceof InlineSpace) { - InlineSpace space = (InlineSpace)b; - if (space.getResizeable()) { - space.setSize(space.getSize() + padding); - spaceCount++; + 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); } - } else if (b instanceof InlineArea) { - ((InlineArea)b).setXOffset(spaceCount * padding); } - } + default: + MessageHandler.errorln("bad align: "+type); } } @@ -872,27 +1005,6 @@ public class LineArea extends Area { return leaderPatternArea; } - /** - * calculates the width of space which has to be inserted before the - * start of the leader, so that all leader characters are aligned. - * is used if property leader-align is set. At the moment only the value - * for leader-align="reference-area" is supported. - * - */ - private int getLeaderAlignIndent(int leaderLength, - int leaderPatternWidth) { - // calculate position of used space in line area - double position = getCurrentXPosition(); - // calculate factor of next leader pattern cycle - double nextRepeatedLeaderPatternCycle = Math.ceil(position - / leaderPatternWidth); - // calculate difference between start of next leader - // pattern cycle and already used space - double difference = - (leaderPatternWidth * nextRepeatedLeaderPatternCycle) - position; - return (int)difference; - } - /** * calculates the used space in this line area */ @@ -974,7 +1086,7 @@ public class LineArea extends Area { if (getWordWidth(wordToHyphenate) < remainingWidth) { inwordPunctuation = characters[wordStart + remainingString.length() - + wordToHyphenate.length()]; + + wordToHyphenate.length()]; if (inwordPunctuation == '-' || inwordPunctuation == '/') { preString = new StringBuffer(wordToHyphenate); preString = preString.append(inwordPunctuation); @@ -1083,7 +1195,7 @@ public class LineArea extends Area { } else { // if whitespace-collapse == true, discard character if (Character.isSpaceChar(data) - && whiteSpaceCollapse == WhiteSpaceCollapse.TRUE) { + && whiteSpaceCollapse == WhiteSpaceCollapse.TRUE) { return org.apache.fop.fo.flow.Character.OK; } // create new InlineArea @@ -1135,9 +1247,9 @@ public class LineArea extends Area { if (box instanceof InlineArea) { if (ls != null) { Rectangle lr = - new Rectangle(finalWidth, 0, - ((InlineArea)box).getContentWidth(), - fontState.getFontSize()); + new Rectangle(finalWidth, 0, + ((InlineArea)box).getContentWidth(), + fontState.getFontSize()); ls.addRect(lr, this, (InlineArea)box); } } @@ -1152,8 +1264,8 @@ public class LineArea extends Area { String word = (wordBuf != null) ? wordBuf.toString() : ""; int wordWidth = this.getWordWidth(word); WordArea hia = new WordArea(currentFontState, - this.red, this.green, this.blue, - word, wordWidth); + this.red, this.green, this.blue, + word, wordWidth); hia.setYOffset(placementOffset); hia.setUnderlined(textState.getUnderlined()); prevUlState = textState.getUnderlined(); @@ -1165,10 +1277,10 @@ public class LineArea extends Area { this.addChild(hia); if (ls != null) { - Rectangle lr = new Rectangle(startw, 0, - hia.getContentWidth(), - fontState.getFontSize()); - ls.addRect(lr, this, hia); + Rectangle lr = new Rectangle(startw, 0, + hia.getContentWidth(), + fontState.getFontSize()); + ls.addRect(lr, this, hia); } // calculate the space needed finalWidth += wordWidth; @@ -1205,10 +1317,10 @@ public class LineArea extends Area { private boolean canBreakMidWord() { boolean ret = false; if (hyphProps != null && hyphProps.language != null - &&!hyphProps.language.equals("NONE")) { + &&!hyphProps.language.equals("NONE")) { String lang = hyphProps.language.toLowerCase(); if ("zh".equals(lang) || "ja".equals(lang) || "ko".equals(lang) - || "vi".equals(lang)) + || "vi".equals(lang)) ret = true; } return ret; @@ -1230,7 +1342,7 @@ public class LineArea extends Area { // the mapping returns '#' for unmapped characters in standard fonts // what happens for other fonts? if (mappedChar != '#') { - // should do something to discover non-proportional fonts + // should do something to discover non-proportional fonts return (getEmWidth()*9)/10; } else { return currentFontState.width(mappedChar); @@ -1304,17 +1416,17 @@ public class LineArea extends Area { */ private boolean isSpace(char c) { if (c == ' ' || c == '\u2000' || // en quad - c == '\u2001' || // em quad - c == '\u2002' || // en space - c == '\u2003' || // em space - c == '\u2004' || // three-per-em space - c == '\u2005' || // four--per-em space - c == '\u2006' || // six-per-em space - c == '\u2007' || // figure space - c == '\u2008' || // punctuation space - c == '\u2009' || // thin space - c == '\u200A' || // hair space - c == '\u200B') // zero width space + c == '\u2001' || // em quad + c == '\u2002' || // en space + c == '\u2003' || // em space + c == '\u2004' || // three-per-em space + c == '\u2005' || // four--per-em space + c == '\u2006' || // six-per-em space + c == '\u2007' || // figure space + c == '\u2008' || // punctuation space + c == '\u2009' || // thin space + c == '\u200A' || // hair space + c == '\u200B') // zero width space return true; else return false; @@ -1327,8 +1439,8 @@ public class LineArea extends Area { */ private boolean isNBSP(char c) { if (c == '\u00A0' || c == '\u202F' || // narrow no-break space - c == '\u3000' || // ideographic space - c == '\uFEFF') { // zero width no-break space + c == '\u3000' || // ideographic space + c == '\uFEFF') { // zero width no-break space return true; } else return false; @@ -1355,7 +1467,7 @@ public class LineArea extends Area { String currentWord = st.nextToken(); if (currentWord.length() == 1 - && (isNBSP(currentWord.charAt(0)))) { + && (isNBSP(currentWord.charAt(0)))) { // Add an InlineSpace int spaceWidth = getCharWidth(currentWord.charAt(0)); if (spaceWidth > 0) { @@ -1412,4 +1524,3 @@ public class LineArea extends Area { } -