aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Geerken <devnull@localhost>2012-11-14 21:59:03 +0100
committerSebastian Geerken <devnull@localhost>2012-11-14 21:59:03 +0100
commita940db1461814764bdcebf0a22a729a8a193b7f8 (patch)
treec06abfc78331a3e0fdfec0cd983b1700b23422a0
parent53e9245bcbaea2b7b4485369aa2289f1d102f26c (diff)
Removed penaltyState, replaced it with INT_MIN and INT_MAX. Also, fixed a bug related to hyphenation ("&&" instead of "&").
-rw-r--r--dw/textblock.cc15
-rw-r--r--dw/textblock.hh20
-rw-r--r--dw/textblock_linebreaking.cc73
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)&nbsp;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);