From 717437417a1ad3770d79732355b46f7183b3ca10 Mon Sep 17 00:00:00 2001 From: Keiron Liddle Date: Thu, 1 Feb 2001 23:51:39 +0000 Subject: [PATCH] simplified block area moved adding text, leader out so that a line area is obtained then the stuff is added to it git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@194012 13f79535-47bb-0310-9956-ffa450edef68 --- src/org/apache/fop/fo/FOText.java | 114 +++++++++- src/org/apache/fop/fo/flow/Character.java | 3 + src/org/apache/fop/fo/flow/Leader.java | 64 +++++- src/org/apache/fop/fo/flow/PageNumber.java | 2 +- .../fop/fo/flow/PageNumberCitation.java | 5 +- src/org/apache/fop/layout/BlockArea.java | 206 +----------------- 6 files changed, 194 insertions(+), 200 deletions(-) diff --git a/src/org/apache/fop/fo/FOText.java b/src/org/apache/fop/fo/FOText.java index 6fc253fa5..3dffff813 100644 --- a/src/org/apache/fop/fo/FOText.java +++ b/src/org/apache/fop/fo/FOText.java @@ -56,7 +56,7 @@ import org.apache.fop.layout.Area; import org.apache.fop.messaging.MessageHandler; import org.apache.fop.layout.BlockArea; import org.apache.fop.layout.FontState; -import org.apache.fop.layout.TextState; +import org.apache.fop.layout.*; import org.apache.fop.datatypes.*; import org.apache.fop.fo.properties.*; import org.apache.fop.apps.FOPException; @@ -164,7 +164,7 @@ public class FOText extends FONode { this.marker = this.start; } int orig_start = this.marker; - this.marker = ((BlockArea) area).addText(fs, red, green, blue, + this.marker = addText((BlockArea)area, fs, red, green, blue, wrapOption, this.getLinkSet(), whiteSpaceCollapse, ca, this.marker, length, ts); if (this.marker == -1) { @@ -187,4 +187,114 @@ public class FOText extends FONode { return new Status(Status.AREA_FULL_NONE); } } + + // font-variant support : addText is a wrapper for addRealText + // added by Eric SCHAEFFER + public static int addText(BlockArea ba, FontState fontState, float red, float green, + float blue, int wrapOption, LinkSet ls, + int whiteSpaceCollapse, char data[], int start, int end, + TextState textState) { + if (fontState.getFontVariant() == FontVariant.SMALL_CAPS) { + FontState smallCapsFontState; + try { + int smallCapsFontHeight = (int) (((double) fontState.getFontSize()) * 0.8d); + smallCapsFontState = new FontState( + fontState.getFontInfo(), + fontState.getFontFamily(), + fontState.getFontStyle(), + fontState.getFontWeight(), + smallCapsFontHeight, + FontVariant.NORMAL); + } catch (FOPException ex) { + smallCapsFontState = fontState; + MessageHandler.errorln("Error creating small-caps FontState: " + ex.getMessage()); + } + + // parse text for upper/lower case and call addRealText + char c; + boolean isLowerCase; + int caseStart; + FontState fontStateToUse; + for (int i = start; i < end; ) { + caseStart = i; + c = data[i]; + isLowerCase = (java.lang.Character.isLetter(c) && java.lang.Character.isLowerCase(c)); + while (isLowerCase == (java.lang.Character.isLetter(c) && java.lang.Character.isLowerCase(c))) { + if (isLowerCase) { + data[i] = java.lang.Character.toUpperCase(c); + } + i++; + if (i == end) + break; + c = data[i]; + } + if (isLowerCase) { + fontStateToUse = smallCapsFontState; + } else { + fontStateToUse = fontState; + } + int index = addRealText(ba, fontStateToUse, red, green, blue, wrapOption, ls, + whiteSpaceCollapse, data, caseStart, i, textState); + if (index != -1) { + return index; + } + } + + return -1; + } + + // font-variant normal + return addRealText(ba, fontState, red, green, blue, wrapOption, ls, + whiteSpaceCollapse, data, start, end, textState); + } + + protected static int addRealText(BlockArea ba, FontState fontState, float red, float green, + float blue, int wrapOption, LinkSet ls, + int whiteSpaceCollapse, char data[], int start, int end, + TextState textState) { + int ts, te; + char[] ca; + + ts = start; + te = end; + ca = data; + + LineArea la = ba.getCurrentLineArea(); + if (la == null) { + return start; + } + + la.changeFont(fontState); + la.changeColor(red, green, blue); + la.changeWrapOption(wrapOption); + la.changeWhiteSpaceCollapse(whiteSpaceCollapse); +// la.changeHyphenation(language, country, hyphenate, +// hyphenationChar, hyphenationPushCharacterCount, +// hyphenationRemainCharacterCount); + ba.setupLinkSet(ls); + + ts = la.addText(ca, ts, te, ls, textState); +// this.hasLines = true; + + while (ts != -1) { + la = ba.createNextLineArea(); + if (la == null) { + return ts; + } + la.changeFont(fontState); + la.changeColor(red, green, blue); + la.changeWrapOption(wrapOption); + la.changeWhiteSpaceCollapse( + whiteSpaceCollapse); +// la.changeHyphenation(language, country, hyphenate, +// hyphenationChar, hyphenationPushCharacterCount, +// hyphenationRemainCharacterCount); + ba.setupLinkSet(ls); + + ts = la.addText(ca, ts, te, ls, textState); + } + return -1; + } + + } diff --git a/src/org/apache/fop/fo/flow/Character.java b/src/org/apache/fop/fo/flow/Character.java index c7168cbc8..0216476d4 100644 --- a/src/org/apache/fop/fo/flow/Character.java +++ b/src/org/apache/fop/fo/flow/Character.java @@ -145,6 +145,9 @@ public class Character extends FObj { blockArea.getIDReferences().initializeID(id, blockArea); LineArea la = blockArea.getCurrentLineArea(); + if(la == null) { + return new Status(Status.AREA_FULL_NONE); + } la.changeFont(fontstate); la.changeColor(red, green, blue); la.changeWrapOption(wrapOption); diff --git a/src/org/apache/fop/fo/flow/Leader.java b/src/org/apache/fop/fo/flow/Leader.java index 32d62765f..8a6842799 100644 --- a/src/org/apache/fop/fo/flow/Leader.java +++ b/src/org/apache/fop/fo/flow/Leader.java @@ -57,6 +57,7 @@ import org.apache.fop.datatypes.*; import org.apache.fop.layout.Area; import org.apache.fop.layout.BlockArea; import org.apache.fop.layout.inline.LeaderArea; +import org.apache.fop.layout.LineArea; import org.apache.fop.layout.FontState; import org.apache.fop.apps.FOPException; import org.apache.fop.messaging.MessageHandler; @@ -140,7 +141,7 @@ public class Leader extends FObjMixed { blockArea.getIDReferences().initializeID(id, blockArea); //adds leader to blockarea, there the leaderArea is generated - int succeeded = blockArea.addLeader(fontstate, red, green, blue, + int succeeded = addLeader(blockArea, fontstate, red, green, blue, leaderPattern, leaderLengthMinimum, leaderLengthOptimum, leaderLengthMaximum, ruleThickness, ruleStyle, leaderPatternWidth, @@ -161,4 +162,65 @@ public class Leader extends FObjMixed { */ + /** + * adds a leader to current line area of containing block area + * the actual leader area is created in the line area + * + * @return int +1 for success and -1 for none + */ + public int addLeader(BlockArea ba, FontState fontState, float red, float green, + float blue, int leaderPattern, int leaderLengthMinimum, + int leaderLengthOptimum, int leaderLengthMaximum, + int ruleThickness, int ruleStyle, int leaderPatternWidth, + int leaderAlignment) { + + LineArea la = ba.getCurrentLineArea(); + //this should start a new page + if (la == null) { + return -1; + } + + la.changeFont(fontState); + la.changeColor(red, green, blue); + + //check whether leader fits into the (rest of the) line + //using length.optimum to determine where to break the line as defined + // 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())) { + la.addLeader(leaderPattern, + leaderLengthMinimum, leaderLengthOptimum, + leaderLengthMaximum, ruleStyle, ruleThickness, + leaderPatternWidth, leaderAlignment); + } else { + la = ba.createNextLineArea(); + if(la == null) { + // not enough room + return -1; + } + la.changeFont(fontState); + la.changeColor(red, green, blue); + + //check whether leader fits into LineArea at all, otherwise + //clip it (should honor the clip option of containing area) + if (leaderLengthMinimum <= + la.getContentWidth()) { + la.addLeader(leaderPattern, + leaderLengthMinimum, leaderLengthOptimum, + leaderLengthMaximum, ruleStyle, ruleThickness, + leaderPatternWidth, leaderAlignment); + } else { + MessageHandler.errorln("Leader doesn't fit into line, it will be clipped to fit."); + la.addLeader(leaderPattern, + la.getRemainingWidth(), + leaderLengthOptimum, leaderLengthMaximum, + ruleStyle, ruleThickness, leaderPatternWidth, + leaderAlignment); + } + } +// this.hasLines = true; + return 1; + } + } diff --git a/src/org/apache/fop/fo/flow/PageNumber.java b/src/org/apache/fop/fo/flow/PageNumber.java index 4dbe320fc..0139d7f32 100644 --- a/src/org/apache/fop/fo/flow/PageNumber.java +++ b/src/org/apache/fop/fo/flow/PageNumber.java @@ -127,7 +127,7 @@ public class PageNumber extends FObj { } String p = Integer.toString(area.getPage().getNumber()); - this.marker = ((BlockArea) area).addText(fs, red, green, blue, + this.marker = FOText.addText((BlockArea) area, fs, red, green, blue, wrapOption, null, whiteSpaceCollapse, p.toCharArray(), 0, p.length(), ts); return new Status(Status.OK); diff --git a/src/org/apache/fop/fo/flow/PageNumberCitation.java b/src/org/apache/fop/fo/flow/PageNumberCitation.java index 817a647e1..86acb8923 100644 --- a/src/org/apache/fop/fo/flow/PageNumberCitation.java +++ b/src/org/apache/fop/fo/flow/PageNumberCitation.java @@ -203,13 +203,16 @@ public class PageNumberCitation extends FObj { pageNumber = idReferences.getPageNumber(refId); if (pageNumber != null) { // if we already know the page number - this.marker = ((BlockArea) area).addText(fs, red, green, blue, + this.marker = FOText.addText((BlockArea) area, fs, red, green, blue, wrapOption, null, whiteSpaceCollapse, pageNumber.toCharArray(), 0, pageNumber.length(), ts); } else { // add pageNumberCitation to area to be resolved during rendering BlockArea blockArea = (BlockArea)area; LineArea la = blockArea.getCurrentLineArea(); + if(la == null) { + return new Status(Status.AREA_FULL_NONE); + } la.changeFont(fs); la.changeColor(red, green, blue); la.changeWrapOption(wrapOption); diff --git a/src/org/apache/fop/layout/BlockArea.java b/src/org/apache/fop/layout/BlockArea.java index 30744ef71..fe45160d9 100644 --- a/src/org/apache/fop/layout/BlockArea.java +++ b/src/org/apache/fop/layout/BlockArea.java @@ -152,216 +152,32 @@ public class BlockArea extends Area { } } - // font-variant support : addText is a wrapper for addRealText - // added by Eric SCHAEFFER - public int addText(FontState fontState, float red, float green, - float blue, int wrapOption, LinkSet ls, - int whiteSpaceCollapse, char data[], int start, int end, - TextState textState) { - if (fontState.getFontVariant() == FontVariant.SMALL_CAPS) { - FontState smallCapsFontState; - try { - int smallCapsFontHeight = (int) (((double) fontState.getFontSize()) * 0.8d); - smallCapsFontState = new FontState( - fontState.getFontInfo(), - fontState.getFontFamily(), - fontState.getFontStyle(), - fontState.getFontWeight(), - smallCapsFontHeight, - FontVariant.NORMAL); - } catch (FOPException ex) { - smallCapsFontState = fontState; - MessageHandler.errorln("Error creating small-caps FontState: " + ex.getMessage()); - } - - // parse text for upper/lower case and call addRealText - char c; - boolean isLowerCase; - int caseStart; - FontState fontStateToUse; - for (int i = start; i < end; ) { - caseStart = i; - c = data[i]; - isLowerCase = (java.lang.Character.isLetter(c) && java.lang.Character.isLowerCase(c)); - while (isLowerCase == (java.lang.Character.isLetter(c) && java.lang.Character.isLowerCase(c))) { - if (isLowerCase) { - data[i] = java.lang.Character.toUpperCase(c); - } - i++; - if (i == end) - break; - c = data[i]; - } - if (isLowerCase) { - fontStateToUse = smallCapsFontState; - } else { - fontStateToUse = fontState; - } - int index = this.addRealText(fontStateToUse, red, green, blue, wrapOption, ls, - whiteSpaceCollapse, data, caseStart, i, textState); - if (index != -1) { - return index; - } - } - - return -1; - } - - // font-variant normal - return this.addRealText(fontState, red, green, blue, wrapOption, ls, - whiteSpaceCollapse, data, start, end, textState); - } - - protected int addRealText(FontState fontState, float red, float green, - float blue, int wrapOption, LinkSet ls, - int whiteSpaceCollapse, char data[], int start, int end, - TextState textState) { - int ts, te; - char[] ca; - - ts = start; - te = end; - ca = data; - - if (currentHeight + currentLineArea.getHeight() > maxHeight) { - return start; - } - - this.currentLineArea.changeFont(fontState); - this.currentLineArea.changeColor(red, green, blue); - this.currentLineArea.changeWrapOption(wrapOption); - this.currentLineArea.changeWhiteSpaceCollapse(whiteSpaceCollapse); - this.currentLineArea.changeHyphenation(language, country, hyphenate, - hyphenationChar, hyphenationPushCharacterCount, - hyphenationRemainCharacterCount); - if (ls != null) { - this.currentLinkSet = ls; - ls.setYOffset(currentHeight); - } - - ts = this.currentLineArea.addText(ca, ts, te, ls, textState); - this.hasLines = true; - - while (ts != -1) { - this.currentLineArea.align(this.align); - this.addLineArea(this.currentLineArea); - - this.currentLineArea = - new LineArea(fontState, lineHeight, halfLeading, - allocationWidth, startIndent, endIndent, - currentLineArea); - if (currentHeight + currentLineArea.getHeight() > - this.maxHeight) { - return ts; - } - this.currentLineArea.changeFont(fontState); - this.currentLineArea.changeColor(red, green, blue); - this.currentLineArea.changeWrapOption(wrapOption); - this.currentLineArea.changeWhiteSpaceCollapse( - whiteSpaceCollapse); - this.currentLineArea.changeHyphenation(language, country, hyphenate, - hyphenationChar, hyphenationPushCharacterCount, - hyphenationRemainCharacterCount); - if (ls != null) { - ls.setYOffset(currentHeight); - } - - ts = this.currentLineArea.addText(ca, ts, te, ls, textState); - } - return -1; - } - - - /** - * adds a leader to current line area of containing block area - * the actual leader area is created in the line area - * - * @return int +1 for success and -1 for none - */ - public int addLeader(FontState fontState, float red, float green, - float blue, int leaderPattern, int leaderLengthMinimum, - int leaderLengthOptimum, int leaderLengthMaximum, - int ruleThickness, int ruleStyle, int leaderPatternWidth, - int leaderAlignment) { - - //this should start a new page - if (currentHeight + currentLineArea.getHeight() > maxHeight) { - return -1; - } - - this.currentLineArea.changeFont(fontState); - this.currentLineArea.changeColor(red, green, blue); - - //check whether leader fits into the (rest of the) line - //using length.optimum to determine where to break the line as defined - // 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 <= (this.getContentWidth() - - this.currentLineArea.finalWidth - - this.currentLineArea.pendingWidth)) { - this.currentLineArea.addLeader(leaderPattern, - leaderLengthMinimum, leaderLengthOptimum, - leaderLengthMaximum, ruleStyle, ruleThickness, - leaderPatternWidth, leaderAlignment); - } else { - //finish current line area and put it into children vector - this.currentLineArea.align(this.align); - this.addLineArea(this.currentLineArea); - - //create new line area - this.currentLineArea = - new LineArea(fontState, lineHeight, halfLeading, - allocationWidth, startIndent, endIndent, - currentLineArea); - this.currentLineArea.changeFont(fontState); - this.currentLineArea.changeColor(red, green, blue); - - if (currentHeight + currentLineArea.getHeight() > - this.maxHeight) { - return -1; - } - - //check whether leader fits into LineArea at all, otherwise - //clip it (should honor the clip option of containing area) - if (leaderLengthMinimum <= - this.currentLineArea.getContentWidth()) { - this.currentLineArea.addLeader(leaderPattern, - leaderLengthMinimum, leaderLengthOptimum, - leaderLengthMaximum, ruleStyle, ruleThickness, - leaderPatternWidth, leaderAlignment); - } else { - MessageHandler.errorln("Leader doesn't fit into line, it will be clipped to fit."); - this.currentLineArea.addLeader(leaderPattern, - this.currentLineArea.getContentWidth() - - this.currentLineArea.finalWidth - - this.currentLineArea.pendingWidth, - leaderLengthOptimum, leaderLengthMaximum, - ruleStyle, ruleThickness, leaderPatternWidth, - leaderAlignment); - } - } - this.hasLines = true; - return 1; - } - public LineArea getCurrentLineArea() { + if (currentHeight + this.currentLineArea.getHeight() > maxHeight) { + return null; + } + this.currentLineArea.changeHyphenation(language, country, hyphenate, + hyphenationChar, hyphenationPushCharacterCount, + hyphenationRemainCharacterCount); + this.hasLines = true; return this.currentLineArea; } public LineArea createNextLineArea() { if (this.hasLines) { - this.currentLineArea.addPending(); +// this.currentLineArea.addPending(); this.currentLineArea.align(this.align); -// this.currentLineArea.verticalAlign(); this.addLineArea(this.currentLineArea); } this.currentLineArea = new LineArea(fontState, lineHeight, halfLeading, allocationWidth, startIndent, endIndent, currentLineArea); + this.currentLineArea.changeHyphenation(language, country, hyphenate, + hyphenationChar, hyphenationPushCharacterCount, + hyphenationRemainCharacterCount); if (currentHeight + lineHeight > maxHeight) { return null; } -- 2.39.5