diff options
-rw-r--r-- | dw/textblock.cc | 18 | ||||
-rw-r--r-- | dw/textblock.hh | 14 | ||||
-rw-r--r-- | dw/textblock_linebreaking.cc | 13 |
3 files changed, 31 insertions, 14 deletions
diff --git a/dw/textblock.cc b/dw/textblock.cc index ef8cd300..f9c7bc95 100644 --- a/dw/textblock.cc +++ b/dw/textblock.cc @@ -41,9 +41,10 @@ namespace dw { int Textblock::CLASS_ID = -1; Textblock::DivChar Textblock::divChars[NUM_DIV_CHARS] = { - { "\xc2\xad", true, false, PENALTY_HYPHEN, -1 }, - { "-", false, true, -1, PENALTY_HYPHEN }, - { "\xe2\x80\x94", false, true, PENALTY_EM_DASH_LEFT, PENALTY_EM_DASH_RIGHT } + { "\xc2\xad", true, false, true, PENALTY_HYPHEN, -1 }, + { "-", false, true, true, -1, PENALTY_HYPHEN }, + { "\xe2\x80\x94", false, true, false, + PENALTY_EM_DASH_LEFT, PENALTY_EM_DASH_RIGHT } }; int Textblock::penalties[PENALTY_NUM][2] = { @@ -1509,7 +1510,7 @@ void Textblock::addText (const char *text, size_t len, int partPenaltyIndex[numParts - 1]; int partStart[numParts], partEnd[numParts]; bool charRemoved[numParts - 1], canBeHyphenated[numParts + 1]; - bool permDivChar[numParts - 1]; + bool permDivChar[numParts - 1], unbreakableForMinWidth[numParts - 1]; canBeHyphenated[0] = canBeHyphenated[numParts] = true; partStart[0] = 0; partEnd[numParts - 1] = len; @@ -1535,6 +1536,8 @@ void Textblock::addText (const char *text, size_t len, partPenaltyIndex[n] = divChars[foundDiv].penaltyIndexLeft; charRemoved[n] = true; permDivChar[n] = false; + unbreakableForMinWidth[n] = + divChars[foundDiv].unbreakableForMinWidth; canBeHyphenated[n + 1] = divChars[foundDiv].canBeHyphenated; partEnd[n] = i; partStart[n + 1] = i + lDiv; @@ -1548,6 +1551,8 @@ void Textblock::addText (const char *text, size_t len, partPenaltyIndex[n] = divChars[foundDiv].penaltyIndexLeft; charRemoved[n] = false; permDivChar[n] = false; + unbreakableForMinWidth[n] = + divChars[foundDiv].unbreakableForMinWidth; canBeHyphenated[n + 1] = divChars[foundDiv].canBeHyphenated; partEnd[n] = i; partStart[n + 1] = i; @@ -1558,6 +1563,8 @@ void Textblock::addText (const char *text, size_t len, partPenaltyIndex[n] = divChars[foundDiv].penaltyIndexRight; charRemoved[n] = false; permDivChar[n] = true; + unbreakableForMinWidth[n] = + divChars[foundDiv].unbreakableForMinWidth; canBeHyphenated[n + 1] = divChars[foundDiv].canBeHyphenated; partEnd[n] = i + lDiv; partStart[n + 1] = i + lDiv; @@ -1638,8 +1645,11 @@ void Textblock::addText (const char *text, size_t len, if (permDivChar[i]) word->flags |= Word::PERM_DIV_CHAR; + if (unbreakableForMinWidth[i]) + word->flags |= Word::UNBREAKABLE_FOR_MIN_WIDTH; word->flags |= Word::DRAW_AS_ONE_TEXT; + accumulateWordData (words->size() - 1); } } diff --git a/dw/textblock.hh b/dw/textblock.hh index 778a98b1..5359a46d 100644 --- a/dw/textblock.hh +++ b/dw/textblock.hh @@ -223,7 +223,7 @@ private: typedef struct { const char *s; - bool charRemoved, canBeHyphenated; + bool charRemoved, canBeHyphenated, unbreakableForMinWidth; int penaltyIndexLeft, penaltyIndexRight; } DivChar; @@ -280,17 +280,21 @@ protected: enum { /** Can be hyphenated automatically. (Cleared after * hyphenation.) */ - CAN_BE_HYPHENATED = 1 << 0, + CAN_BE_HYPHENATED = 1 << 0, /** Must be drawn with a hyphen, when at the end of the line. */ - DIV_CHAR_AT_EOL = 1 << 1, + DIV_CHAR_AT_EOL = 1 << 1, /** Is or ends with a "division character", which is part of * the word. */ - PERM_DIV_CHAR = 1 << 2, + PERM_DIV_CHAR = 1 << 2, /** This word must be drawn, together with the following * word(s), by only one call of View::drawText(), to get * kerning, ligatures etc. right. The last of the words drawn * as one text does *not* have this flag set. */ - DRAW_AS_ONE_TEXT = 1 << 3 + DRAW_AS_ONE_TEXT = 1 << 3, + /* When calculating the minimal width (as part of extremes), + * do not consider this word as breakable. This flag is + * ignored when the line is actually broken. */ + UNBREAKABLE_FOR_MIN_WIDTH = 1 << 4, }; /* TODO: perhaps add a xLeft? */ diff --git a/dw/textblock_linebreaking.cc b/dw/textblock_linebreaking.cc index 47027194..a1682e19 100644 --- a/dw/textblock_linebreaking.cc +++ b/dw/textblock_linebreaking.cc @@ -217,15 +217,17 @@ void Textblock::printWord (Word *word) printf ("\"%s\"", word->content.text); break; case core::Content::WIDGET: - printf ("<widget: %p>\n", word->content.widget); + printf ("<widget: %p>", word->content.widget); break; case core::Content::BREAK: - printf ("<break>\n"); + printf ("<break>"); break; default: - printf ("<?>\n"); + printf ("<?>"); break; } + + printf (" (flags = %d)", word->flags); printf (" [%d / %d + %d - %d => %d + %d - %d] => ", word->size.width, word->origSpace, word->stretchability, @@ -422,7 +424,7 @@ void Textblock::accumulateWordExtremes (int firstWord, int lastWord, // Minimum: between two *possible* breaks (or at the end). // TODO This is redundant to getExtremesImpl(). - // TODO Again, index 1 is used for lineCanBeBroken(). See getExtremes(). + // TODO: Again, index 1 is used for lineCanBeBroken(). See getExtremes(). if (word->badnessAndPenalty.lineCanBeBroken (1) || atLastWord) { parMin += extremes.minWidth + word->hyphenWidth; *maxOfMinWidth = misc::max (*maxOfMinWidth, parMin); @@ -704,7 +706,8 @@ int Textblock::hyphenateWord (int wordIndex) 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); + w->flags |= (Word::DRAW_AS_ONE_TEXT | Word::DIV_CHAR_AT_EOL | + Word::UNBREAKABLE_FOR_MIN_WIDTH); PRINTF (" [%d] + hyphen\n", wordIndex + i); } else { |