diff options
-rw-r--r-- | dw/textblock.cc | 15 | ||||
-rw-r--r-- | dw/textblock.hh | 20 | ||||
-rw-r--r-- | dw/textblock_linebreaking.cc | 73 |
3 files changed, 43 insertions, 65 deletions
diff --git a/dw/textblock.cc b/dw/textblock.cc index f6e1ad9c..2edc172c 100644 --- a/dw/textblock.cc +++ b/dw/textblock.cc @@ -1322,7 +1322,7 @@ void Textblock::fillWord (Word *word, int width, int ascent, int descent, word->origSpace = word->effSpace = word->stretchability = word->shrinkability = 0; word->hyphenWidth = 0; - word->badnessAndPenalty.setBothPenaltiesProhibitBreak (); + word->badnessAndPenalty.setPenalty (PENALTY_PROHIBIT_BREAK); word->content.space = false; word->flags = canBeHyphenated ? Word::CAN_BE_HYPHENATED : 0; @@ -1597,9 +1597,8 @@ void Textblock::addText (const char *text, size_t len, Word *word = words->getLastRef(); word->badnessAndPenalty - .setPenalty (0, penalties[partPenaltyIndex[i]][0]); - word->badnessAndPenalty - .setPenalty (1, penalties[partPenaltyIndex[i]][1]); + .setPenalties (penalties[partPenaltyIndex[i]][0], + penalties[partPenaltyIndex[i]][1]); if (signRemoved[i]) { // Currently, only soft hyphens (UTF-8: "\xc2\xad") can @@ -1820,12 +1819,12 @@ void Textblock::setBreakOption (Word *word, core::style::Style *style) case core::style::WHITE_SPACE_NORMAL: case core::style::WHITE_SPACE_PRE_LINE: case core::style::WHITE_SPACE_PRE_WRAP: - word->badnessAndPenalty.setBothPenalties (0); + word->badnessAndPenalty.setPenalty (0); break; case core::style::WHITE_SPACE_PRE: case core::style::WHITE_SPACE_NOWRAP: - word->badnessAndPenalty.setBothPenaltiesProhibitBreak (); + word->badnessAndPenalty.setPenalty (PENALTY_PROHIBIT_BREAK); break; } } @@ -1903,7 +1902,7 @@ void Textblock::addParbreak (int space, core::style::Style *style) word = addWord (0, 0, 0, false, style); word->content.type = core::Content::BREAK; - word->badnessAndPenalty.setBothPenaltiesForceBreak (); + word->badnessAndPenalty.setPenalty (PENALTY_FORCE_BREAK); word->content.breakSpace = space; wordWrap (words->size () - 1, false); } @@ -1926,7 +1925,7 @@ void Textblock::addLinebreak (core::style::Style *style) word = addWord (0, 0, 0, false, style); word->content.type = core::Content::BREAK; - word->badnessAndPenalty.setBothPenaltiesForceBreak (); + word->badnessAndPenalty.setPenalty (PENALTY_FORCE_BREAK); word->content.breakSpace = 0; wordWrap (words->size () - 1, false); } diff --git a/dw/textblock.hh b/dw/textblock.hh index b3bb6e98..6ccde9b9 100644 --- a/dw/textblock.hh +++ b/dw/textblock.hh @@ -152,12 +152,17 @@ private: * badness is not well defined, so fiddling with the penalties is a * bit difficult. */ + + enum { + PENALTY_FORCE_BREAK = INT_MIN, + PENALTY_PROHIBIT_BREAK = INT_MAX + }; + class BadnessAndPenalty { private: enum { NOT_STRETCHABLE, QUITE_LOOSE, BADNESS_VALUE, TOO_TIGHT } badnessState; - enum { FORCE_BREAK, PROHIBIT_BREAK, PENALTY_VALUE } penaltyState[2]; int ratio; // ratio is only defined when badness is defined int badness, penalty[2]; @@ -191,22 +196,15 @@ private: // etc. works. }; + void setSinglePenalty (int index, int penalty); int badnessValue (int infLevel); int penaltyValue (int index, int infLevel); public: void calcBadness (int totalWidth, int idealWidth, int totalStretchability, int totalShrinkability); - void setPenalty (int index, int penalty); - inline void setBothPenalties (int penalty) { - setPenalty (0, penalty); setPenalty (1, penalty); } - - void setPenaltyProhibitBreak (int index); - void setPenaltyForceBreak (int index); - inline void setBothPenaltiesProhibitBreak () { - setPenaltyProhibitBreak (0); setPenaltyProhibitBreak (1); } - inline void setBothPenaltiesForceBreak () { - setPenaltyForceBreak (0); setPenaltyForceBreak (1); } + inline void setPenalty (int penalty) { setPenalties (penalty, penalty); } + void setPenalties (int penalty1, int penalty2); bool lineLoose (); bool lineTight (); diff --git a/dw/textblock_linebreaking.cc b/dw/textblock_linebreaking.cc index bac23cb9..e2130b00 100644 --- a/dw/textblock_linebreaking.cc +++ b/dw/textblock_linebreaking.cc @@ -33,20 +33,12 @@ int Textblock::BadnessAndPenalty::badnessValue (int infLevel) int Textblock::BadnessAndPenalty::penaltyValue (int index, int infLevel) { - switch (penaltyState[index]) { - case FORCE_BREAK: + if (penalty[index] == INT_MIN) return infLevel == INF_PENALTIES ? -1 : 0; - - case PROHIBIT_BREAK: + else if (penalty[index] == INT_MAX) return infLevel == INF_PENALTIES ? 1 : 0; - - case PENALTY_VALUE: + else return infLevel == INF_VALUE ? penalty[index] : 0; - } - - // compiler happiness - lout::misc::assertNotReached (); - return 0; } void Textblock::BadnessAndPenalty::calcBadness (int totalWidth, int idealWidth, @@ -108,14 +100,21 @@ void Textblock::BadnessAndPenalty::calcBadness (int totalWidth, int idealWidth, * fitting line has a badness of 0. (ii) A line, where all spaces * are extended by exactly the stretchability, as well as a line, where * all spaces are reduced by the shrinkability, have a badness of 1. + * + * (TODO plural: penalties, not penalty. Correct above comment) */ -void Textblock::BadnessAndPenalty::setPenalty (int index, int penalty) +void Textblock::BadnessAndPenalty::setPenalties (int penalty1, int penalty2) { - if (penalty == INT_MAX) - setPenaltyProhibitBreak (index); - else if (penalty == INT_MIN) - setPenaltyForceBreak (index); - else { + // TODO Check here some cases, e.g. both or no penalty INT_MIN. + setSinglePenalty(0, penalty1); + setSinglePenalty(1, penalty1); +} + +void Textblock::BadnessAndPenalty::setSinglePenalty (int index, int penalty) +{ + if (penalty == INT_MAX || penalty == INT_MIN) + this->penalty[index] = penalty; + else // This factor consists of: (i) 100^3, since in calcBadness(), the // ratio is multiplied with 100 (again, to use integer numbers for // fractional numbers), and the badness (which has to be compared @@ -123,18 +122,6 @@ void Textblock::BadnessAndPenalty::setPenalty (int index, int penalty) // 100, of course, since 100 times the penalty is passed to this // method. this->penalty[index] = penalty * (100 * 100 * 100 / 100); - penaltyState[index] = PENALTY_VALUE; - } -} - -void Textblock::BadnessAndPenalty::setPenaltyProhibitBreak (int index) -{ - penaltyState[index] = PROHIBIT_BREAK; -} - -void Textblock::BadnessAndPenalty::setPenaltyForceBreak (int index) -{ - penaltyState[index] = FORCE_BREAK; } bool Textblock::BadnessAndPenalty::lineLoose () @@ -158,12 +145,12 @@ bool Textblock::BadnessAndPenalty::lineTooTight () bool Textblock::BadnessAndPenalty::lineMustBeBroken (int penaltyIndex) { - return penaltyState[penaltyIndex] == FORCE_BREAK; + return penalty[penaltyIndex] == PENALTY_FORCE_BREAK; } bool Textblock::BadnessAndPenalty::lineCanBeBroken (int penaltyIndex) { - return penaltyState[penaltyIndex] != PROHIBIT_BREAK; + return penalty[penaltyIndex] != PENALTY_PROHIBIT_BREAK; } int Textblock::BadnessAndPenalty::compareTo (int penaltyIndex, @@ -210,19 +197,13 @@ void Textblock::BadnessAndPenalty::print () printf ("("); for (int i = 0; i < 2; i++) { - switch (penaltyState[i]) { - case FORCE_BREAK: + if (penalty[i] == INT_MIN) printf ("-inf"); - break; - - case PROHIBIT_BREAK: + else if (penalty[i] == INT_MAX) printf ("inf"); - break; - - case PENALTY_VALUE: + else printf ("%d", penalty[i]); - break; - } + if (i == 0) printf (", "); } @@ -573,7 +554,7 @@ void Textblock::wordWrap (int wordIndex, bool wrapAll) // work.) Word *lastWord = words->getRef (searchUntil); BadnessAndPenalty correctedBap = lastWord->badnessAndPenalty; - correctedBap.setBothPenalties (0); + correctedBap.setPenalty (0); if (correctedBap.compareTo (penaltyIndex, &words->getRef(breakPos)->badnessAndPenalty) <= 0) { @@ -589,7 +570,7 @@ void Textblock::wordWrap (int wordIndex, bool wrapAll) PRINTF ("\n"); if (word1->badnessAndPenalty.lineTight () && - word1->flags && Word::CAN_BE_HYPHENATED && + (word1->flags & Word::CAN_BE_HYPHENATED) && word1->style->x_lang[0] && word1->content.type == core::Content::TEXT && Hyphenator::isHyphenationCandidate (word1->content.text)) @@ -598,7 +579,7 @@ void Textblock::wordWrap (int wordIndex, bool wrapAll) if (word1->badnessAndPenalty.lineLoose () && breakPos + 1 < words->size ()) { Word *word2 = words->getRef(breakPos + 1); - if (word2->flags && Word::CAN_BE_HYPHENATED && + if ((word2->flags & Word::CAN_BE_HYPHENATED) && word2->style->x_lang[0] && word2->content.type == core::Content::TEXT && Hyphenator::isHyphenationCandidate (word2->content.text)) @@ -719,8 +700,8 @@ int Textblock::hyphenateWord (int wordIndex) // Note: there are numBreaks + 1 word parts. if (i < numBreaks) { // TODO There should be a method fillHyphen. - w->badnessAndPenalty.setPenalty (0, penalties[PENALTY_HYPHEN][0]); - w->badnessAndPenalty.setPenalty (1, penalties[PENALTY_HYPHEN][1]); + w->badnessAndPenalty.setPenalties (penalties[PENALTY_HYPHEN][0], + penalties[PENALTY_HYPHEN][1]); w->hyphenWidth = layout->textWidth (origWord.style->font, "\xc2\xad", 2); w->flags |= (Word::DRAW_AS_ONE_TEXT | Word::DIV_CHAR_AT_EOL); |