aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorfotis <fotis@unknown>2000-12-18 23:54:45 +0000
committerfotis <fotis@unknown>2000-12-18 23:54:45 +0000
commit2f8e0dcedae493b8c7ad9537c44c474aa951340d (patch)
tree93b9578cfa5cc58f9416cdd862de5414ebff36ba /src
parent7b89272e029808e7daa77eb4927305187ed950b3 (diff)
downloadxmlgraphics-fop-2f8e0dcedae493b8c7ad9537c44c474aa951340d.tar.gz
xmlgraphics-fop-2f8e0dcedae493b8c7ad9537c44c474aa951340d.zip
fixed: overlapping character with hyphenation on
added: hyphenation now works with hard hyphens in words and with quotation marks at the beginning of words git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@193909 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r--src/org/apache/fop/layout/LineArea.java152
1 files changed, 124 insertions, 28 deletions
diff --git a/src/org/apache/fop/layout/LineArea.java b/src/org/apache/fop/layout/LineArea.java
index 9967abb37..1da1435cb 100644
--- a/src/org/apache/fop/layout/LineArea.java
+++ b/src/org/apache/fop/layout/LineArea.java
@@ -392,7 +392,7 @@ public class LineArea extends Area {
}
} else if (this.wrapOption == WrapOption.WRAP) {
if (this.hyphenate == Hyphenate.TRUE) {
- return this.doHyphenation(data,i,wordStart,this.getContentWidth()-finalWidth-pendingWidth-spaceWidth);
+ return this.doHyphenation(data,i,wordStart,this.getContentWidth() - (finalWidth + spaceWidth + pendingWidth));
} else {
return wordStart;
}
@@ -734,7 +734,7 @@ public class LineArea extends Area {
/**
* extracts a complete word from the character data
*/
- private String getHyphenationWord (char [] characters, int wordStart) {
+ private String getHyphenationWord (char [] characters, int wordStart) {
boolean wordendFound = false;
int counter = 0;
char [] newWord = new char [100]; //create a buffer
@@ -752,46 +752,99 @@ public class LineArea extends Area {
private int doHyphenation (char [] characters, int position, int wordStart, int remainingWidth) {
- int hyphCharWidth = this.currentFontState.width(this.hyphenationChar);
- remainingWidth -= hyphCharWidth;
-
- String wordToHyphenate = getHyphenationWord(characters,wordStart);
//check whether the language property has been set
if (this.language.equalsIgnoreCase("none")) {
MessageHandler.errorln("if property 'hyphenate' is used, a language must be specified");
return wordStart;
}
- //are there any hyphenation points
- Hyphenation hyph = Hyphenator.hyphenate(language,country,wordToHyphenate,hyphenationRemainCharacterCount,hyphenationPushCharacterCount);
- if (hyph != null) {
- int [] hyphenationPoints = hyph.getHyphenationPoints();
- int index = 0;
- String wordBegin = "";
- int wordBeginWidth = 0;
+ /** remaining part string of hyphenation */
+ StringBuffer remainingString = new StringBuffer();
- while (wordBeginWidth < remainingWidth && hyph.length() > index) {
- wordBegin = hyph.getPreHyphenText(index);
- wordBeginWidth = getWordWidth(wordBegin);
- index++;
+ /** for words with some inword punctuation like / or - */
+ StringBuffer preString = null;
+
+ /** char before the word, probably whitespace */
+ char startChar = ' ' ;//characters[wordStart-1];
+
+ /** in word punctuation character */
+ char inwordPunctuation;
+
+ /** the complete word handed to the hyphenator */
+ String wordToHyphenate;
+
+ //width of hyphenation character
+ int hyphCharWidth = this.currentFontState.width(this.hyphenationChar);
+ remainingWidth -= hyphCharWidth;
+
+ //handles ' or " at the beginning of the word
+ if (characters[wordStart] == '"' || characters[wordStart] == '\'' ) {
+ remainingString.append(characters[wordStart]);
+ //extracts whole word from string
+ wordToHyphenate = getHyphenationWord(characters,wordStart+1);
+ } else {
+// remainingString = "";
+ wordToHyphenate = getHyphenationWord(characters,wordStart);
+ }
+
+
+
+ //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) {
+ inwordPunctuation = characters[wordStart+wordToHyphenate.length()];
+ if (inwordPunctuation == '-' ||
+ inwordPunctuation == '/' ) {
+ preString = new StringBuffer(wordToHyphenate);
+ preString = preString.append(inwordPunctuation);
+ wordToHyphenate = getHyphenationWord(characters,wordStart+wordToHyphenate.length()+1);
+ remainingWidth -= (getWordWidth(wordToHyphenate) + this.currentFontState.width(inwordPunctuation));
}
- if (index > 1) {
- wordBegin = hyph.getPreHyphenText(index-1) + this.hyphenationChar;
- wordBeginWidth = getWordWidth(wordBegin);
- InlineArea hia = new InlineArea(currentFontState,
- this.red, this.green, this.blue,
- wordBegin,wordBegin.length());
- this.addChild(new InlineSpace(currentFontState.width(32)));
- this.addChild(hia);
+ }
- //calculate the space needed
- finalWidth += wordBeginWidth + currentFontState.width(32);
- return wordStart + wordBegin.length()-1;
+ //are there any hyphenation points
+ Hyphenation hyph = Hyphenator.hyphenate(language,country,wordToHyphenate,hyphenationRemainCharacterCount,hyphenationPushCharacterCount);
+ //no hyphenation points and no inword non letter character
+ if (hyph == null && preString == null) {
+ if (remainingString.length() > 0) {
+ return wordStart-1;
+ } else {
+ return wordStart;
+ }
+
+ //no hyphenation points, but a inword non-letter character
+ } else if (hyph == null && preString != null){
+ remainingString.append(preString);
+ this.addWord(startChar,remainingString);
+ return wordStart + remainingString.length();
+ //hyphenation points and no inword non-letter character
+ } else if (hyph != null && preString == null) {
+ int index = getFinalHyphenationPoint(hyph,remainingWidth);
+ if (index != -1) {
+ remainingString.append(hyph.getPreHyphenText(index));
+ remainingString.append(this.hyphenationChar);
+ this.addWord(startChar,remainingString);
+ return wordStart + remainingString.length()-1;
+ }
+ //hyphenation points and a inword non letter character
+ } else if (hyph != null && preString != null) {
+ int index = getFinalHyphenationPoint(hyph,remainingWidth);
+ if (index != -1) {
+ remainingString.append(preString.append(hyph.getPreHyphenText(index)));
+ remainingString.append(this.hyphenationChar);
+ this.addWord(startChar,remainingString);
+ return wordStart + remainingString.length()-1;
+ } else {
+ remainingString.append(preString) ;
+ this.addWord(startChar,remainingString);
+ return wordStart + remainingString.length();
}
}
return wordStart;
}
+ /** calculates the wordWidth using the actual fontstate*/
private int getWordWidth (String word) {
int wordLength = word.length();
int width = 0;
@@ -832,4 +885,47 @@ public class LineArea extends Area {
return org.apache.fop.fo.flow.Character.OK;
}
}
+
+ /** adds a string to the line area children. insert a space before the word */
+ private void addWord (char startChar, StringBuffer wordBuf) {
+ String word = wordBuf.toString();
+ InlineArea hia;
+ int startCharWidth = this.currentFontState.width(startChar);
+ if (startChar == ' ') {
+ this.addChild(new InlineSpace(startCharWidth));
+ } else {
+ hia = new InlineArea(currentFontState,
+ this.red, this.green, this.blue,
+ new Character(startChar).toString(),1);
+ this.addChild(hia);
+ }
+ int wordWidth = this.getWordWidth(word);
+ hia = new InlineArea(currentFontState,
+ this.red, this.green, this.blue,
+ word,word.length());
+ this.addChild(hia);
+
+ //calculate the space needed
+ finalWidth += startCharWidth + wordWidth ;
+ }
+
+
+ private int getFinalHyphenationPoint(Hyphenation hyph, int remainingWidth) {
+ int [] hyphenationPoints = hyph.getHyphenationPoints();
+ int numberOfHyphenationPoints = hyphenationPoints.length;
+
+ int index = -1;
+ String wordBegin = "";
+ int wordBeginWidth = 0;
+
+ for (int i = 0;i < numberOfHyphenationPoints; i++){
+ wordBegin = hyph.getPreHyphenText(i);
+ if (this.getWordWidth(wordBegin) > remainingWidth){
+ break;
+ }
+ index = i;
+ }
+ return index;
+ }
+
}