diff options
author | Sebastian Geerken <devnull@localhost> | 2014-04-03 14:01:21 +0200 |
---|---|---|
committer | Sebastian Geerken <devnull@localhost> | 2014-04-03 14:01:21 +0200 |
commit | 560193e2a5fce15db3c272520220877a7ee61567 (patch) | |
tree | 21d12ca1a99a0059d37c72690965fc5b9f683bc4 | |
parent | 42b27295acd59a1f7c124bea4004c7b9b0116034 (diff) |
Some refactoring.
-rw-r--r-- | dw/textblock.hh | 7 | ||||
-rw-r--r-- | dw/textblock_linebreaking.cc | 132 |
2 files changed, 79 insertions, 60 deletions
diff --git a/dw/textblock.hh b/dw/textblock.hh index e4238ca1..af9bdcce 100644 --- a/dw/textblock.hh +++ b/dw/textblock.hh @@ -702,6 +702,13 @@ protected: void processWord (int wordIndex); virtual bool wordWrap (int wordIndex, bool wrapAll); bool wrapWordInFlow (int wordIndex, bool wrapAll); + void balanceBreakPosAndHeight (int wordIndex, int firstIndex, + int *searchUntil, bool tempNewLine, + int penaltyIndex, bool *thereWillBeMoreSpace, + bool wrapAll, bool *wordListChanged, + int *wordIndexEnd, int lastFloatPos, + bool regardBorder, int *height, + int *breakPos); int searchBreakPos (int wordIndex, int firstIndex, int *searchUntil, bool tempNewLine, int penaltyIndex, bool thereWillBeMoreSpace, bool wrapAll, diff --git a/dw/textblock_linebreaking.cc b/dw/textblock_linebreaking.cc index fda6debb..3b3a55e7 100644 --- a/dw/textblock_linebreaking.cc +++ b/dw/textblock_linebreaking.cc @@ -767,66 +767,12 @@ bool Textblock::wrapWordInFlow (int wordIndex, bool wrapAll) containingBlock->outOfFlowMgr->tellPosition (words->getRef(lastFloatPos)->content.widget, yNewLine); - // The height of this part of the line (until the new - // break position) may change with the break position, - // but the break position may depend on the height. We - // try to let these values converge. - // - // The height, as a function of the break position, is - // monotonically (but not strictly) increasing, since - // more words may make the line higher (but not - // flatter). The break position, as a function of the - // height, is, however, monotonically (but not - // strictly) *de*creasing, since flatter lines may fit - // easier between floats (although this is a rare - // case). So a convergence is not necessary. - // - // For this reason, we iterate only as long as the - // height does not increase again, and stop if it - // remains the same. As the minimum is 1, this approach - // will force the iteration to stop. - // - // (As a side effect, this will lead to a larger break - // position, and so place as much words as possible in - // the line.) - - bool firstRun = true; - while (true) { - calcBorders (lastFloatPos, height); - thereWillBeMoreSpace = regardBorder ? - newLineHasFloatLeft || newLineHasFloatRight : false; - - DBG_OBJ_MSGF ("construct.word", 2, - "thereWillBeMoreSpace = %s", - thereWillBeMoreSpace ? "true" : "false"); - - for(int i = firstIndex; i <= wordIndexEnd; i++) - accumulateWordData (i); - - int newBreakPos = - searchBreakPos (wordIndex, firstIndex, &searchUntil, - tempNewLine, penaltyIndex, - thereWillBeMoreSpace, wrapAll, - &wordListChanged, &wordIndexEnd); - int newHeight = calcLinePartHeight (firstIndex, newBreakPos); - - if (!firstRun && newHeight >= height) - // - newHeight > height: do not proceed, discard - // new values, which are less desirable than - // the old ones (see above). - // - newHeight == height: convergence, stop - // here. New values can be discarded, since - // they are the same. - // (Since *some* value are needed, the results - // from the first run are never discarded.) - break; - else { - height = newHeight; - breakPos = newBreakPos; - } - - firstRun = false; - } + balanceBreakPosAndHeight (wordIndex, firstIndex, &searchUntil, + tempNewLine, penaltyIndex, + &thereWillBeMoreSpace, wrapAll, + &wordListChanged, &wordIndexEnd, + lastFloatPos, regardBorder, &height, + &breakPos); } DBG_OBJ_MSG_END (); @@ -878,6 +824,72 @@ bool Textblock::wrapWordInFlow (int wordIndex, bool wrapAll) return wordListChanged; } +// *height must be initialized, but not *breakPos. +void Textblock::balanceBreakPosAndHeight (int wordIndex, int firstIndex, + int *searchUntil, bool tempNewLine, + int penaltyIndex, + bool *thereWillBeMoreSpace, + bool wrapAll, bool *wordListChanged, + int *wordIndexEnd, int lastFloatPos, + bool regardBorder, int *height, + int *breakPos) +{ + // The height of this part of the line (until the new break + // position) may change with the break position, but the break + // position may depend on the height. We try to let these values + // converge. + // + // The height, as a function of the break position, is + // monotonically (but not strictly) increasing, since more words + // may make the line higher (but not flatter). The break position, + // as a function of the height, is, however, monotonically (but not + // strictly) *de*creasing, since flatter lines may fit easier + // between floats (although this is a rare case). So a convergence + // is not necessary. + // + // For this reason, we iterate only as long as the height does not + // increase again, and stop if it remains the same. As the minimum + // is 1, this approach will force the iteration to stop. + // + // (As a side effect, this will lead to a larger break position, + // and so place as much words as possible in the line.) + + bool firstRun = true; + while (true) { + calcBorders (lastFloatPos, *height); + *thereWillBeMoreSpace = regardBorder ? + newLineHasFloatLeft || newLineHasFloatRight : false; + + DBG_OBJ_MSGF ("construct.word", 2, "thereWillBeMoreSpace = %s", + *thereWillBeMoreSpace ? "true" : "false"); + + for(int i = firstIndex; i <= *wordIndexEnd; i++) + accumulateWordData (i); + + int newBreakPos = + searchBreakPos (wordIndex, firstIndex, searchUntil, + tempNewLine, penaltyIndex, + thereWillBeMoreSpace, wrapAll, + wordListChanged, wordIndexEnd); + int newHeight = calcLinePartHeight (firstIndex, newBreakPos); + + if (!firstRun && newHeight >= *height) + // - newHeight > height: do not proceed, discard new values, + // which are less desirable than the old ones (see above). + // - newHeight == height: convergence, stop here. New values + // can be discarded, since they are the same. + // (Since *some* value are needed, the results from the first + // run are never discarded.) + break; + else { + *height = newHeight; + *breakPos = newBreakPos; + } + + firstRun = false; + } +} + int Textblock::searchBreakPos (int wordIndex, int firstIndex, int *searchUntil, bool tempNewLine, int penaltyIndex, bool thereWillBeMoreSpace, bool wrapAll, |