diff options
author | Sebastian Geerken <devnull@localhost> | 2013-04-28 10:43:21 +0200 |
---|---|---|
committer | Sebastian Geerken <devnull@localhost> | 2013-04-28 10:43:21 +0200 |
commit | 66d8f3a6b0ed29acbfec749ccbbdad52068e6762 (patch) | |
tree | 5c762e4e49b0de92430d83c9296bf05debd3bf80 | |
parent | 4d3637ee88da2c97a2077821f39635fe10069a2f (diff) |
Some cleanup (originally in floats repo).
-rw-r--r-- | dw/textblock.hh | 5 | ||||
-rw-r--r-- | dw/textblock_linebreaking.cc | 177 |
2 files changed, 106 insertions, 76 deletions
diff --git a/dw/textblock.hh b/dw/textblock.hh index 90185cd2..b39d072d 100644 --- a/dw/textblock.hh +++ b/dw/textblock.hh @@ -566,6 +566,11 @@ protected: int *maxOfMinWidth, int *sumOfMaxWidth); void processWord (int wordIndex); virtual void wordWrap (int wordIndex, bool wrapAll); + int searchMinBap (int firstWord, int lastWordm, int penaltyIndex, + bool correctAtEnd); + int considerHyphenation (int firstIndex, int breakPos); + bool isHyphenationCandidate (Word *word); + void handleWordExtremes (int wordIndex); void correctLastWordExtremes (); diff --git a/dw/textblock_linebreaking.cc b/dw/textblock_linebreaking.cc index 7af2d75c..110def85 100644 --- a/dw/textblock_linebreaking.cc +++ b/dw/textblock_linebreaking.cc @@ -546,82 +546,9 @@ void Textblock::wordWrap (int wordIndex, bool wrapAll) bool lineAdded; do { - PRINTF (" searching from %d to %d\n", firstIndex, searchUntil); - - int breakPos = -1; - for (int i = firstIndex; i <= searchUntil; i++) { - Word *w = words->getRef(i); - - //printf (" %d (of %d): ", i, words->size ()); - //printWord (w); - //printf ("\n"); - - if (breakPos == -1 || - w->badnessAndPenalty.compareTo - (penaltyIndex, - &words->getRef(breakPos)->badnessAndPenalty) <= 0) - // "<=" instead of "<" in the next lines tends to result in - // more words per line -- theoretically. Practically, the - // case "==" will never occur. - breakPos = i; - } - - PRINTF (" breakPos = %d\n", breakPos); - - if (wrapAll && searchUntil == words->size () - 1) { - // Since no break and no space is added, the last word - // will have a penalty of inf. Actually, it should be - // less, since it is the last word. However, since more - // words may follow, the penalty is not changesd, but - // here, the search is corrected (maybe only - // temporary). - - // (Notice that it was once (temporally) set to -inf, - // not 0, but this will make e.g. test/table-1.html not - // work.) - Word *lastWord = words->getRef (searchUntil); - BadnessAndPenalty correctedBap = lastWord->badnessAndPenalty; - correctedBap.setPenalty (0); - if (correctedBap.compareTo - (penaltyIndex, - &words->getRef(breakPos)->badnessAndPenalty) <= 0) { - breakPos = searchUntil; - PRINTF (" corrected: breakPos = %d\n", breakPos); - } - } - - int hyphenatedWord = -1; - Word *wordBreak = words->getRef(breakPos); - PRINTF ("[%p] line (broken at word %d): ", this, breakPos); - //word1->badnessAndPenalty.print (); - PRINTF ("\n"); - - if (wordBreak->badnessAndPenalty.lineTight ()) { - // Sometimes, it is not the last word, which must be - // hyphenated, but some word before. Here, we search - // for the first word which can be hyphenated, *and* - // makes the line too tight. - - for (int i = breakPos; i >= firstIndex; i--) { - Word *word1 = words->getRef (i); - if (word1->badnessAndPenalty.lineTight () && - (word1->flags & Word::CAN_BE_HYPHENATED) && - word1->style->x_lang[0] && - word1->content.type == core::Content::TEXT && - Hyphenator::isHyphenationCandidate (word1->content.text)) - hyphenatedWord = i; - } - } - - if (wordBreak->badnessAndPenalty.lineLoose () && - breakPos + 1 < words->size ()) { - Word *word2 = words->getRef(breakPos + 1); - if ((word2->flags & Word::CAN_BE_HYPHENATED) && - word2->style->x_lang[0] && - word2->content.type == core::Content::TEXT && - Hyphenator::isHyphenationCandidate (word2->content.text)) - hyphenatedWord = breakPos + 1; - } + int breakPos = + searchMinBap (firstIndex, searchUntil, penaltyIndex, wrapAll); + int hyphenatedWord = considerHyphenation (firstIndex, breakPos); PRINTF ("[%p] breakPos = %d, hyphenatedWord = %d\n", this, breakPos, hyphenatedWord); @@ -686,6 +613,104 @@ void Textblock::wordWrap (int wordIndex, bool wrapAll) } } +int Textblock::searchMinBap (int firstWord, int lastWord, int penaltyIndex, + bool correctAtEnd) +{ + PRINTF (" searching from %d to %d\n", firstWord, lastWord); + + int pos = -1; + + for (int i = firstWord; i <= lastWord; i++) { + Word *w = words->getRef(i); + + //printf (" %d (of %d): ", i, words->size ()); + //printWord (w); + //printf ("\n"); + + if (pos == -1 || + w->badnessAndPenalty.compareTo (penaltyIndex, + &words->getRef(pos) + ->badnessAndPenalty) <= 0) + // "<=" instead of "<" in the next lines tends to result in + // more words per line -- theoretically. Practically, the + // case "==" will never occur. + pos = i; + } + + PRINTF (" found at %d\n", pos); + + if (correctAtEnd && lastWord == words->size () - 1) { + // Since no break and no space is added, the last word will have + // a penalty of inf. Actually, it should be less, since it is + // the last word. However, since more words may follow, the + // penalty is not changed, but here, the search is corrected + // (maybe only temporary). + + // (Notice that it was once (temporally) set to -inf, not 0, but + // this will make e.g. test/table-1.html not work.) + Word *w = words->getRef (lastWord); + BadnessAndPenalty correctedBap = w->badnessAndPenalty; + correctedBap.setPenalty (0); + if (correctedBap.compareTo(penaltyIndex, + &words->getRef(pos)->badnessAndPenalty) <= 0) { + pos = lastWord; + PRINTF (" corrected => %d\n", pos); + } + } + + return pos; +} + + +/** + * Suggest a word to hyphenate, when breaking at breakPos is + * planned. Return a word index or -1, when hyphenation makes no + * sense. + */ +int Textblock::considerHyphenation (int firstIndex, int breakPos) +{ + int hyphenatedWord = -1; + + Word *wordBreak = words->getRef(breakPos); + PRINTF ("[%p] line (broken at word %d): ", this, breakPos); + //wordBreak->badnessAndPenalty.print (); + PRINTF ("\n"); + + // A tight line: maybe, after hyphenation, some parts of the last + // word of this line can be put into the next line. + if (wordBreak->badnessAndPenalty.lineTight ()) { + // Sometimes, it is not the last word, which must be hyphenated, + // but some word before. Here, we search for the first word + // which can be hyphenated, *and* makes the line too tight. + for (int i = breakPos; i >= firstIndex; i--) { + Word *word1 = words->getRef (i); + if (word1->badnessAndPenalty.lineTight () && + isHyphenationCandidate (word1)) + hyphenatedWord = i; + } + } + + // A loose line: maybe, after hyphenation, some parts of the first + // word of the next line can be put into this line. + if (wordBreak->badnessAndPenalty.lineLoose () && + breakPos + 1 < words->size ()) { + Word *word2 = words->getRef(breakPos + 1); + if (isHyphenationCandidate (word2)) + hyphenatedWord = breakPos + 1; + } + + return hyphenatedWord; +} + +bool Textblock::isHyphenationCandidate (Word *word) +{ + return (word->flags & Word::CAN_BE_HYPHENATED) && + word->style->x_lang[0] && + word->content.type == core::Content::TEXT && + Hyphenator::isHyphenationCandidate (word->content.text); +} + + /** * Counter part to wordWrap(), but for extremes, not size calculation. */ |