25#include "../lout/msg.h"
26#include "../lout/debug.hh"
27#include "../lout/misc.hh"
60 if (penalty[
index] == INT_MIN)
61 return infLevel == INF_PENALTIES ? -1 : 0;
62 else if (penalty[
index] == INT_MAX)
63 return infLevel == INF_PENALTIES ? 1 : 0;
65 return infLevel == INF_VALUE ? penalty[
index] : 0;
69 int totalStretchability,
70 int totalShrinkability)
73 this->totalWidth = totalWidth;
74 this->idealWidth = idealWidth;
75 this->totalStretchability = totalStretchability;
76 this->totalShrinkability = totalShrinkability;
81 if (totalWidth == idealWidth) {
82 badnessState = BADNESS_VALUE;
84 }
else if (totalWidth < idealWidth) {
85 if (totalStretchability == 0)
86 badnessState = NOT_STRETCHABLE;
88 ratio = 100 * (idealWidth - totalWidth) / totalStretchability;
90 badnessState = QUITE_LOOSE;
92 badnessState = BADNESS_VALUE;
97 if (totalShrinkability == 0)
98 badnessState = TOO_TIGHT;
101 ratio = 100 * (idealWidth - totalWidth) / totalShrinkability;
103 badnessState = TOO_TIGHT;
105 badnessState = BADNESS_VALUE;
133 setSinglePenalty(0, penalty1);
134 setSinglePenalty(1, penalty2);
139 if (penalty == INT_MAX || penalty == INT_MIN)
140 this->penalty[
index] = penalty;
148 this->penalty[
index] = penalty * (100 * 100 * 100 / 100);
154 badnessState == NOT_STRETCHABLE || badnessState == QUITE_LOOSE ||
155 (badnessState == BADNESS_VALUE &&
ratio > 0);
161 badnessState == TOO_TIGHT || (badnessState == BADNESS_VALUE &&
ratio < 0);
166 return badnessState == TOO_TIGHT;
183 for (
int l = INF_MAX; l >= 0; l--) {
184 int thisValue = badnessValue (l) + penaltyValue (penaltyIndex, l);
188 if (thisValue != otherValue)
189 return thisValue - otherValue;
197 switch (badnessState) {
198 case NOT_STRETCHABLE:
199 sb->
append (
"not stretchable");
207 sb->
append (
"quite loose (ratio = ");
230 for (
int i = 0; i < 2; i++) {
231 if (penalty[i] == INT_MIN)
233 else if (penalty[i] == INT_MAX)
251 DBG_OBJ_ENTER (
"construct.line", 0,
"justifyLine",
"..., %d", diff);
257 int spaceStretchabilitySum = 0;
261 if (spaceStretchabilitySum > 0) {
262 int spaceStretchabilityCum = 0;
263 int spaceDiffCum = 0;
268 spaceStretchabilityCum * diff / spaceStretchabilitySum
270 spaceDiffCum += spaceDiff;
272 DBG_OBJ_MSGF (
"construct.line", 1,
"%d (of %d): diff = %d",
273 i,
words->size (), spaceDiff);
278 }
else if (diff < 0) {
279 int spaceShrinkabilitySum = 0;
283 if (spaceShrinkabilitySum > 0) {
284 int spaceShrinkabilityCum = 0;
285 int spaceDiffCum = 0;
290 spaceShrinkabilityCum * diff / spaceShrinkabilitySum
292 spaceDiffCum += spaceDiff;
294 DBG_OBJ_MSGF (
"construct.line", 1,
"%d (of %d): diff = %d",
295 i,
words->size (), spaceDiff);
307 int newLastOofPos,
bool temporary,
310 DBG_OBJ_ENTER (
"construct.line", 0,
"addLine",
"%d, %d, %d, %s, %d",
311 firstWord, lastWord, newLastOofPos,
312 temporary ?
"true" :
"false", minHeight);
316 if (lastWord >= firstWord) {
317 DBG_MSG_WORD (
"construct.line", 1,
"<i>first word:</i> ", firstWord,
"");
318 DBG_MSG_WORD (
"construct.line", 1,
"<i>last word:</i> ", lastWord,
"");
320 Word *lastWordOfLine =
words->getRef(lastWord);
323 DBG_OBJ_MSGF (
"construct.line", 1,
"lineWidth (from last word): %d",
328 DBG_OBJ_MSGF (
"construct.line", 1,
"lineWidth (empty line): %d",
334 if (
lines->size () == 0) {
336 DBG_OBJ_MSGF (
"construct.line", 1,
"lineWidth (line1OffsetEff): %d",
350 DBG_OBJ_MSGF (
"construct.line", 1,
"nonTemporaryLines = %d",
353 int lineIndex =
lines->size () - 1;
376 "regardBorder = %s, newLineLeftBorder = %d, "
377 "newLineRightBorder = %d",
392 "lineWidth [corrected space (%d - %d) after word %d]: %d",
405 if (
lines->size () == 1) {
422 if (
lines->size () == 1)
459 for (
int i = firstWord; i <= lastWord; i++) {
500 DBG_OBJ_ENTER (
"construct.all", 0,
"processWord",
"%d", wordIndex);
501 DBG_MSG_WORD (
"construct.all", 1,
"<i>processed word:</i>", wordIndex,
"");
503 int diffWords =
wordWrap (wordIndex,
false);
520 "word list has become longer by %d", diffWords);
521 DBG_MSG_WORD (
"construct.all", 1,
"<i>processed word now:</i>",
526 firstWord =
paragraphs->getLastRef()->firstWord;
529 DBG_OBJ_MSG (
"construct.paragraph", 1,
"removing last paragraph");
533 int lastIndex = wordIndex + diffWords;
535 "processing words again from %d to %d",
536 firstWord, lastIndex);
542 for (
int i = firstWord; i <= lastIndex; i++)
561 wordIndex, wrapAll ?
"true" :
"false");
562 DBG_MSG_WORD (
"construct.word", 1,
"<i>wrapped word:</i> ", wordIndex,
"");
588 DBG_OBJ_ENTER (
"construct.word", 0,
"wrapWordInFlow",
"%d, %s",
589 wordIndex, wrapAll ?
"true" :
"false");
610 bool thereWillBeMoreSpace = regardBorder ?
614 "thereWillBeMoreSpace = %s ? %s || %s : false = %s",
615 regardBorder ?
"true" :
"false",
618 thereWillBeMoreSpace ?
"true" :
"false");
621 bool tempNewLine =
false;
623 lines->size() == 0 ? 0 :
lines->getLastRef()->lastWord + 1;
626 if (wordIndex < firstIndex)
630 else if (wrapAll && wordIndex >= firstIndex &&
631 wordIndex ==
words->size() -1) {
633 searchUntil = wordIndex;
635 DBG_OBJ_MSG (
"construct.word", 1,
"<b>new line:</b> last word");
636 }
else if (wordIndex >= firstIndex &&
639 word->badnessAndPenalty.lineMustBeBroken (penaltyIndex)) {
641 searchUntil = wordIndex;
642 DBG_OBJ_MSG (
"construct.word", 1,
"<b>new line:</b> forced break");
652 "possible line break between %d and %d?",
653 firstIndex, wordIndex - 1);
656 bool possibleLineBreak =
false;
657 for (
int i = firstIndex;
658 !(thereWillBeMoreSpace || possibleLineBreak)
659 && i <= wordIndex - 1;
661 DBG_OBJ_MSGF (
"construct.word", 2,
"examining word %d", i);
662 if (
words->getRef(i)->badnessAndPenalty
663 .lineCanBeBroken (penaltyIndex)) {
664 DBG_MSG_WORD (
"construct.word", 2,
"break possible for word:",
666 possibleLineBreak =
true;
672 possibleLineBreak ?
"true" :
"false");
674 DBG_OBJ_MSGF (
"construct.word", 1,
"word->... too tight: %s",
675 word->badnessAndPenalty.lineTooTight () ?
678 if ((thereWillBeMoreSpace || possibleLineBreak)
679 && word->badnessAndPenalty.lineTooTight ()) {
681 searchUntil = wordIndex - 1;
683 "<b>new line:</b> line too tight");
685 DBG_OBJ_MSG (
"construct.word", 1,
"no <b>new line</b>");
690 if(!newLine && !wrapAll) {
701 PRINTF (
"[%p] special case? newLine = %s, wrapAll = %s => "
702 "mustQueueResize = %s\n",
this, newLine ?
"true" :
"false",
708 int wordIndexEnd = wordIndex;
711 int lastFloatPos =
lines->size() > 0 ?
712 lines->getLastRef()->lastOofRefPositionedBeforeThisLine : -1;
713 DBG_OBJ_MSGF (
"construct.word", 2,
"lastFloatPos = %d", lastFloatPos);
716 tempNewLine, penaltyIndex,
true,
717 &thereWillBeMoreSpace, wrapAll,
718 &diffWords, &wordIndexEnd,
719 &lastFloatPos, regardBorder, &height,
726 DBG_OBJ_MSG (
"construct.word", 1,
"<i>floatHandled loop cycle</i>");
730 "breakPos = %d, height = %d, lastFloatPos = %d",
731 breakPos, height, lastFloatPos);
733 int startSearch =
max (firstIndex, lastFloatPos + 1);
734 int newFloatPos = -1;
737 DBG_OBJ_MSGF (
"construct.word", 2,
"searching from %d to %d",
738 startSearch, breakPos);
739 for (
int i = startSearch; newFloatPos == -1 && i <= breakPos; i++) {
742 for (
int j = 0; newFloatPos == -1 && j <
NUM_OOFM; j++) {
751 DBG_OBJ_MSGF (
"construct.word", 2,
"newFloatPos = %d", newFloatPos);
753 if (newFloatPos == -1)
754 floatHandled =
false;
763 lastFloatPos = newFloatPos;
766 words->getRef(lastFloatPos)->content.widgetReference->widget;
770 int xRel =
boxOffsetX (), yRel = yNewLine, xRef, yRef;
778 tempNewLine, penaltyIndex,
false,
779 &thereWillBeMoreSpace, wrapAll,
780 &diffWords, &wordIndexEnd,
781 &lastFloatPos, regardBorder, &height,
786 }
while (floatHandled);
789 if (firstIndex <= breakPos) {
792 DBG_OBJ_MSGF (
"construct.word", 1,
"%d <= %d => minHeight = %d",
793 firstIndex, breakPos, minHeight);
810 "%d < %d => minHeight = %d (l: %s (%d), r: %s (%d))",
811 firstIndex, breakPos, minHeight,
818 addLine (firstIndex, breakPos, lastFloatPos, tempNewLine, minHeight);
821 "accumulating again from %d to %d",
822 breakPos + 1, wordIndexEnd);
823 for(
int i = breakPos + 1; i <= wordIndexEnd; i++)
828 word =
words->getRef (wordIndex);
844 int firstWordWithoutLine;
845 if (
lines->size() == 0)
846 firstWordWithoutLine = 0;
848 firstWordWithoutLine =
lines->getLastRef()->lastWord + 1;
850 if (wordIndex >= firstWordWithoutLine) {
853 word->content.widget->parentRef);
864 DBG_OBJ_ENTER (
"construct.word", 0,
"wrapWordOofRef",
"%d, %s",
865 wordIndex, wrapAll ?
"true" :
"false");
876 DBG_OBJ_MSGF (
"construct.word", 1,
"parentRef = %d, oofm = %p",
877 widget->parentRef, oofm);
880 int xRel =
boxOffsetX (), yRel = yNewLine, xRef, yRef;
889 int firstWordWithoutLine;
890 if (
lines->size() == 0)
891 firstWordWithoutLine = 0;
893 firstWordWithoutLine =
lines->getLastRef()->lastWord + 1;
895 if (wordIndex >= firstWordWithoutLine) {
896 word->content.widgetReference->parentRef =
910 int *searchUntil,
bool tempNewLine,
912 bool borderIsCalculated,
913 bool *thereWillBeMoreSpace,
914 bool wrapAll,
int *diffWords,
915 int *wordIndexEnd,
int *lastFloatPos,
916 bool regardBorder,
int *height,
919 DBG_OBJ_ENTER (
"construct.word", 0,
"balanceBreakPosAndHeight",
920 "%d, %d. %d, %s, %d, %s, ..., %s, ..., %d, %s, %d, ...",
921 wordIndex, firstIndex, *searchUntil,
922 tempNewLine ?
"true" :
"false", penaltyIndex,
923 borderIsCalculated ?
"true" :
"false",
924 wrapAll ?
"true" :
"false", *lastFloatPos,
925 regardBorder ?
"true" :
"false", *height);
949 if (!(borderIsCalculated && runNo == 1)) {
952 *thereWillBeMoreSpace = regardBorder ?
955 for(
int i = firstIndex; i <= *wordIndexEnd; i++)
959 DBG_OBJ_MSGF (
"construct.word", 1,
"thereWillBeMoreSpace = %s",
960 *thereWillBeMoreSpace ?
"true" :
"false");
964 tempNewLine, penaltyIndex, *thereWillBeMoreSpace,
965 wrapAll, diffWords, wordIndexEnd, lastFloatPos);
969 "runNo = %d, newBreakPos = %d, newHeight = %d",
970 runNo, newBreakPos, newHeight);
973 "old: height = %d, breakPos undefined", *height);
976 "old: height = %d, breakPos = %d", *height, *breakPos);
980 && newHeight >= *height) {
981 if (newHeight == *height) {
984 DBG_OBJ_MSG (
"construct.word", 1,
"stopping, adopting new values");
985 *breakPos = newBreakPos;
990 "stopping, discarding new values");
993 DBG_OBJ_MSG (
"construct.word", 1,
"adopting new values, continuing");
995 *breakPos = newBreakPos;
1002 *searchUntil, *lastFloatPos, *height, *breakPos);
1007 bool tempNewLine,
int penaltyIndex,
1008 bool thereWillBeMoreSpace,
bool wrapAll,
1009 int *diffWords,
int *wordIndexEnd,
1013 "%d, %d. %d, %s, %d, %s, %s, ...",
1014 wordIndex, firstIndex, *searchUntil,
1015 tempNewLine ?
"true" :
"false", penaltyIndex,
1016 thereWillBeMoreSpace ?
"true" :
"false",
1017 wrapAll ?
"true" :
"false");
1019 DBG_MSG_WORD (
"construct.word", 1,
"<i>first word:</i> ", firstIndex,
"");
1025 DBG_OBJ_MSG (
"construct.word", 1,
"<i>searchBreakPos loop cycle</i>");
1028 if (firstIndex > *searchUntil) {
1031 assert (*searchUntil == firstIndex - 1);
1032 result = firstIndex - 1;
1034 }
else if (thereWillBeMoreSpace &&
1035 words->getRef(firstIndex)->badnessAndPenalty.lineTooTight ()) {
1040 words->getRef(firstIndex)->badnessAndPenalty.intoStringBuffer (&sb);
1042 "too tight: %s ... hyphenatedWord = %d",
1046 if (hyphenatedWord == -1) {
1047 DBG_OBJ_MSG (
"construct.word", 1,
"... => empty line");
1048 result = firstIndex - 1;
1052 "... => hyphenate word and try again");
1055 if (hyphenatedWord <= wordIndex)
1057 DBG_OBJ_MSGF (
"construct.word", 1,
"new searchUntil = %d",
1063 DBG_OBJ_MSG (
"construct.word", 1,
"non-empty line");
1067 thereWillBeMoreSpace, wrapAll);
1070 DBG_OBJ_MSGF (
"construct.word", 1,
"breakPos = %d", breakPos);
1071 DBG_MSG_WORD (
"construct.word", 1,
"<i>break at word:</i> ",
1073 DBG_OBJ_MSGF (
"construct.word", 1,
"hyphenatedWord = %d",
1075 if (hyphenatedWord != -1)
1077 "<i>hyphenate at word:</i> ",
1078 hyphenatedWord,
"");
1080 if(hyphenatedWord == -1) {
1089 DBG_OBJ_MSGF (
"construct.word", 1,
"old searchUntil = %d",
1093 if (hyphenatedWord <= wordIndex)
1095 DBG_OBJ_MSGF (
"construct.word", 1,
"new searchUntil = %d",
1099 if (hyphenatedWord <= wordIndex)
1103 "accumulating again from %d to %d",
1104 breakPos + 1, *wordIndexEnd);
1105 for(
int i = breakPos + 1; i <= *wordIndexEnd; i++)
1111 }
while(!lineAdded);
1119 bool thereWillBeMoreSpace,
bool correctAtEnd)
1121 DBG_OBJ_ENTER (
"construct.word", 0,
"searchMinBap",
"%d, %d, %d, %s, %s",
1122 firstWord, lastWord, penaltyIndex,
1123 thereWillBeMoreSpace ?
"true" :
"false",
1124 correctAtEnd ?
"true" :
"false");
1129 for (
int i = firstWord; i <= lastWord; i++) {
1135 DBG_OBJ_MSGF (
"construct.word", 2,
"%d (of %d): b+p: %s",
1137 DBG_MSG_WORD (
"construct.word", 2,
"(<i>i. e.:</i> ", i,
")");
1147 ->badnessAndPenalty) <= 0)
1152 DBG_OBJ_MSGF (
"construct.word", 1,
"found at %d", pos);
1154 if (correctAtEnd && lastWord ==
words->size () - 1) {
1170 DBG_OBJ_MSGF (
"construct.word", 1,
"corrected b+p: %s",
1174 if (correctedBap.
compareTo(penaltyIndex,
1175 &
words->getRef(pos)->badnessAndPenalty) <= 0) {
1177 DBG_OBJ_MSGF (
"construct.word", 1,
"corrected: %d", pos);
1192 int hyphenatedWord = -1;
1194 Word *wordBreak =
words->getRef(breakPos);
1205 for (
int i = breakPos; i >= firstIndex; i--) {
1216 breakPos + 1 <
words->size ()) {
1217 Word *word2 =
words->getRef(breakPos + 1);
1219 hyphenatedWord = breakPos + 1;
1222 return hyphenatedWord;
1237 int ascent = 0, descent = 0;
1239 for (
int i = firstWord; i <= lastWord; i++) {
1245 return max (ascent + descent, 1);
1255 DBG_OBJ_ENTER (
"construct.paragraph", 0,
"handleWordExtremes",
"%d",
1262 "<i>handled word:</i> ", wordIndex,
"");
1266 DBG_OBJ_MSGF (
"construct.paragraph", 1,
"extremes: %d (%d) / %d (%d)",
1270 if (wordIndex == 0) {
1279 ->badnessAndPenalty.lineMustBeBroken (1)) {
1314 int corrDiffMin, corrDiffMax;
1315 if (wordIndex - 1 >= lastPar->
firstWord) {
1316 Word *lastWord =
words->getRef (wordIndex - 1);
1325 corrDiffMin = corrDiffMax = 0;
1351 "maxParAdjustmentWidth",
1364 "parAdjustmentWidth",
1401 PRINTF (
" => corrected; parMin = %d\n",
1410 Word *hyphenatedWord =
words->getRef(wordIndex);
1411 char lang[3] = { hyphenatedWord->
style->
x_lang[0],
1414 PRINTF (
"[%p] considering to hyphenate word %d, '%s', in language '%s'\n",
1415 this, wordIndex,
words->getRef(wordIndex)->content.text, lang);
1421 if (numBreaks > 0) {
1422 Word origWord = *hyphenatedWord;
1426 origWord.
style, numBreaks, breakPos, wordSize);
1428 PRINTF (
"[%p] %d words ...\n",
this,
words->size ());
1429 words->insert (wordIndex, numBreaks);
1432 for (
int i = wordIndex + numBreaks; i <
words->size (); i++)
1436 for (
int i = 0; i < numBreaks; i++)
1438 PRINTF (
"[%p] ... => %d words\n",
this,
words->size ());
1443 for (
int i = 0; i <
anchors->size (); i++) {
1449 for (
int i = 0; i < numBreaks + 1; i++) {
1450 Word *w =
words->getRef (wordIndex + i);
1451 fillWord (wordIndex + i, wordSize[i].width, wordSize[i].ascent,
1452 wordSize[i].descent,
false, origWord.
style);
1457 int start = (i == 0 ? 0 : breakPos[i - 1]);
1458 int end = (i == numBreaks ?
1475 if (i < numBreaks) {
1499 for (
int i = 0; i < numBreaks + 1; i++)
1511 words->getRef(wordIndex)->flags &=
~Word::CAN_BE_HYPHENATED;
1519 DBG_OBJ_ENTER (
"construct.word", 0,
"moveWordIndices",
"%d, %d",
1526 for (
int i =
lines->size () - 1; i >= 0; i--) {
1532 "lines[%d]->lastOofRef = %d < %d => stop",
1537 "adding %d to lines[%d]->lastOofRef...: %d -> %d",
1557 if (addIndex1 && *addIndex1 >= wordIndex)
1565 DBG_OBJ_ENTER (
"construct.line", 1,
"accumulateWordForLine",
"%d, %d",
1566 lineIndex, wordIndex);
1567 DBG_MSG_WORD (
"construct.line", 2,
"<i>word:</i> ", wordIndex,
"");
1582 int borderAscent, borderDescent, marginAscent, marginDescent;
1584 DBG_OBJ_MSGF (
"construct.line", 2,
"size.ascent = %d, size.descent = %d",
1600 borderAscent = marginAscent = word->
size.
ascent;
1601 borderDescent = marginDescent = word->
size.
descent;
1613 "borderAscent = %d, borderDescent = %d, marginAscent = %d, "
1614 "marginDescent = %d",
1615 borderAscent, borderDescent, marginAscent, marginDescent);
1627 DBG_OBJ_ENTER (
"construct.word.accum", 1,
"accumulateWordData",
"%d",
1629 DBG_MSG_WORD (
"construct.word.accum", 1,
"<i>word:</i> ", wordIndex,
"");
1634 int lineIndex =
lines->size ();
1635 while (lineIndex > 0 && wordIndex <= lines->getRef(lineIndex - 1)->lastWord)
1638 int firstWordOfLine;
1640 firstWordOfLine = 0;
1642 firstWordOfLine =
lines->getRef(lineIndex - 1)->lastWord + 1;
1645 DBG_OBJ_MSGF (
"construct.word.accum", 2,
"lineIndex = %d", lineIndex);
1650 "(%s existing line %d starts with word %d; "
1651 "lineBreakWidth = %d)",
1652 lineIndex < lines->size () ?
"already" :
"not yet",
1655 if (wordIndex == firstWordOfLine) {
1664 "first word of line: words[%d].totalWidth = %d + %d = %d; "
1665 "maxAscent = %d, maxDescent = %d",
1669 Word *prevWord =
words->getRef (wordIndex - 1);
1682 "not first word of line: words[%d].totalWidth = %d + %d - "
1683 "%d + %d + %d = %d; maxAscent = max (%d, %d) = %d, "
1684 "maxDescent = max (%d, %d) = %d",
1692 int totalStretchability =
1694 int totalShrinkability =
1698 "totalStretchability = %d + ... = %d",
1701 "totalShrinkability = %d + ... = %d",
1705 totalStretchability,
1706 totalShrinkability);
1720 DBG_OBJ_ENTER (
"construct.word.width", 1,
"calcLineBreakWidth",
1721 "%d <i>of %d</i>", lineIndex,
lines->size());
1732 int leftBorder, rightBorder;
1737 leftBorder = rightBorder = 0;
1755 if (wordIndex == 0) {
1785 DBG_OBJ_ENTER (
"construct.line", 0,
"alignLine",
"%d", lineIndex);
1790 words->getRef(i)->effSpace =
words->getRef(i)->origSpace;
1793 int firstWordNotOofRef = line->
firstWord;
1794 while (firstWordNotOofRef <= line->lastWord &&
1795 words->getRef(firstWordNotOofRef)->content.type
1797 firstWordNotOofRef++;
1799 if (firstWordNotOofRef <= line->lastWord) {
1800 Word *firstWord =
words->getRef (firstWordNotOofRef);
1810 "first word has 'text-align: left'");
1816 "first word has 'text-align: string'");
1821 "first word has 'text-align: justify'");
1831 lineBreakWidth < lastWord->totalWidth)
1836 "first word has 'text-align: right'");
1841 "first word has 'text-align: center'");
1861 DBG_OBJ_ENTER (
"construct.line", 0,
"calcTextOffset",
"%d, %d",
1862 lineIndex, totalWidth);
1871 DBG_OBJ_MSGF (
"construct.line", 1,
"left: textOffset = %d",
1878 "right: textOffset = %d - %d - %d = %d",
1886 "center: textOffset = (%d + %d - %d - %d) /2 = %d",
1915 DBG_OBJ_MSG (
"construct.line", 0,
"does not have to be rewrapped");
1926 if (
lines->size () > 0) {
1928 firstWord = lastLine->
lastWord + 1;
1932 DBG_OBJ_MSGF (
"construct.line", 0,
"starting with word %d", firstWord);
1937 for (
int i = firstWord; i <
words->size (); i++) {
1993 int firstWordOfLine;
1998 firstWordOfLine =
lines->getRef(lineNo)->lastWord + 1;
2000 firstWordOfLine = 0;
2004 firstWordOfLine >
paragraphs->getLastRef()->firstWord)
2022 firstWord =
paragraphs->getLastRef()->lastWord + 1;
2026 DBG_OBJ_MSGF (
"resize", 1,
"firstWord = %d, words->size() = %d [before]",
2027 firstWord,
words->size ());
2029 for (
int i = firstWord; i <
words->size (); i++)
2046 lines->getLastRef()->lastOofRefPositionedBeforeThisLine : -1,
2059 DBG_OBJ_ENTER (
"construct.line", 0,
"calcBorders",
"%d, %d",
2060 lastOofRef, height);
2066 bool oofmDefined =
false;
2067 for (
int i = 0; i <
NUM_OOFM && !oofmDefined; i++)
2072 int firstWordOfLine =
2073 lines->size() > 0 ?
lines->getLastRef()->lastWord + 1 : 0;
2074 int effOofRef =
max (lastOofRef, firstWordOfLine - 1);
2077 for (
int i = 0; i <
NUM_OOFM; i++) {
2113 int y = yRef + yRel;
2114 bool thisHasLeft, thisHasRight;
2116 thisHasLeft = oofm->
hasFloatLeft (y, height,
this, effOofRef);
2118 thisHasRight = oofm->
hasFloatRight (y, height,
this, effOofRef);
2145 "OOFM #%d: %d * %d (%s) / %d * %d (%s), at %d (%d), "
2146 "until %d = max (%d, %d - 1)",
2151 y, height, effOofRef, lastOofRef, firstWordOfLine);
2174 bool tempWord =
words->size () > 0 &&
2176 int firstWordToWrap =
2177 lines->size () > 0 ?
lines->getLastRef()->lastWord + 1 : 0;
2180 "words->size() = %d, firstWordToWrap = %d, tempWord = %s",
2181 words->size (), firstWordToWrap, tempWord ?
"true" :
"false");
2188 for (
int i = firstWordToWrap; i <
words->size (); i++)
2195 if (
lines->getLastRef()->lastWord >
words->size () - 1)
2196 lines->getLastRef()->lastWord =
words->size () - 1;
2202 assert (
lines->size () == 0 ||
2203 lines->getLastRef()->lastWord ==
words->size () - 1);
2227 if (nonTemporaryLines < lines->size ()) {
2236 lines->size () > 0 ?
lines->getLastRef()->lastWord + 1 : 0;
2237 for (
int i = firstWord; i <
words->size (); i++)
2269 DBG_OBJ_ENTER (
"construct.word.accum", 0,
"getLineStretchability",
"%d",
2271 DBG_MSG_WORD (
"construct.word.accum", 1,
"<i>last word:</i> ",
2274 Word *lastWord =
words->getRef (lastWordIndex);
2279 DBG_OBJ_MSG (
"construct.word.accum", 1,
"justified => 0");
2284 "not justified => %d * (%d + %d) / 100 = %d",
static Hyphenator * getHyphenator(const char *language)
int * hyphenateWord(core::Platform *platform, const char *word, int *numBreaks)
Given a word, returns a list of the possible hyphenation points.
static bool isHyphenationCandidate(const char *word)
Simple test to avoid much costs.
int penaltyValue(int index, int infLevel)
enum dw::Textblock::BadnessAndPenalty::@29 badnessState
bool lineMustBeBroken(int penaltyIndex)
int compareTo(int penaltyIndex, BadnessAndPenalty *other)
bool lineCanBeBroken(int penaltyIndex)
void intoStringBuffer(lout::misc::StringBuffer *sb)
void setPenalty(int penalty)
void calcBadness(int totalWidth, int idealWidth, int totalStretchability, int totalShrinkability)
int badnessValue(int infLevel)
void setPenalties(int penalty1, int penalty2)
Sets the penalty, multiplied by 100.
void setSinglePenalty(int index, int penalty)
void setData(int xWordWidget, int lineNo)
int findParagraphOfWord(int wordIndex)
Find the paragraph of word wordIndex.
void calcTextSizes(const char *text, size_t textLen, core::style::Style *style, int numBreaks, int *breakPos, core::Requisition *wordSize)
void initLine1Offset(int wordIndex)
int searchBreakPos(int wordIndex, int firstIndex, int *searchUntil, bool tempNewLine, int penaltyIndex, bool thereWillBeMoreSpace, bool wrapAll, int *diffWords, int *wordIndexEnd, int *addIndex1=NULL)
void removeTemporaryLines()
int newLineLeftFloatHeight
void accumulateWordData(int wordIndex)
void getWordExtremes(Word *word, core::Extremes *extremes)
Get the extremes of a word within a textblock.
lout::misc::NotSoSimpleVector< Word > * words
int wrapWordOofRef(int wordIndex, bool wrapAll)
void handleWordExtremes(int wordIndex)
Counter part to wordWrap(), but for extremes, not size calculation.
int yOffsetOfLineCreated(Line *line)
Includes margin, border, and padding.
void correctLastWordExtremes()
Called when something changed for the last word (space, hyphens etc.).
virtual int wordWrap(int wordIndex, bool wrapAll)
int getLineStretchability(int lastWordIndex)
bool isHyphenationCandidate(Word *word)
void processWord(int wordIndex)
Line * addLine(int firstWord, int lastWord, int newLastOofPos, bool temporary, int minHeight)
int considerHyphenation(int firstIndex, int breakPos)
Suggest a word to hyphenate, when breaking at breakPos is planned.
bool calcSizeOfWidgetInFlow(int wordIndex, Widget *widget, core::Requisition *size)
Calculate the size of a widget, and return whether it has to be positioned at the top of the line.
int getGeneratorX(int oofmIndex)
Return position relative to container, not regarding margin/border/padding, Called by OOFFloatsMgr to...
bool newLineHasFloatRight
void fillParagraphs()
Counter part to rewrap(), but for extremes, not size calculation.
void calcBorders(int lastOofRef, int height)
void rewrap()
Rewrap the page from the line from which this is necessary.
static const char * hyphenDrawChar
The character which is used to draw a hyphen at the end of a line, either caused by automatic hyphena...
void cleanupWord(int wordNo)
void calcTextOffset(int lineIndex, int totalWidth)
void balanceBreakPosAndHeight(int wordIndex, int firstIndex, int *searchUntil, bool tempNewLine, int penaltyIndex, bool borderIsCalculated, bool *thereWillBeMoreSpace, bool wrapAll, int *diffWords, int *wordIndexEnd, int *lastFloatPos, bool regardBorder, int *height, int *breakPos)
void accumulateWordForLine(int lineIndex, int wordIndex)
bool isBreakAllowedInWord(Word *word)
int searchMinBap(int firstWord, int lastWordm, int penaltyIndex, bool thereWillBeMoreSpace, bool correctAtEnd)
int getLineShrinkability(int lastWordIndex)
lout::misc::SimpleVector< Anchor > * anchors
static int getSpaceStretchability(struct Word *word)
int yOffsetOfLineToBeCreated(int *lastMargin=NULL)
Includes margin, border, and padding.
static int stretchabilityFactor
...
bool mustBorderBeRegarded(Line *line)
Of nested text blocks, only the most inner one must regard the borders of floats.
bool findSizeRequestReference(Widget *reference, int *xRef=NULL, int *yRef=NULL)
void moveWordIndices(int wordIndex, int num, int *addIndex1=NULL)
int getGeneratorRest(int oofmIndex)
static int penalties[PENALTY_NUM][2]
The penalties for hyphens and other, multiplied by 100.
int hyphenateWord(int wordIndex, int *addIndex1=NULL)
int calcLineBreakWidth(int lineIndex)
void addText0(const char *text, size_t len, short flags, core::style::Style *style, core::Requisition *size)
Add a word (without hyphens) to the page structure.
int wrapWordInFlow(int wordIndex, bool wrapAll)
int newLineRightFloatHeight
void fillSpace(int wordNo, core::style::Style *style)
int calcLinePartHeight(int firstWord, int lastWord)
void alignLine(int lineIndex)
Align the line.
void fillWord(int wordNo, int width, int ascent, int descent, short flags, core::style::Style *style)
int calcPenaltyIndexForNewLine()
void initWord(int wordNo)
Basic initialization, which is neccessary before fillWord.
lout::misc::SimpleVector< Paragraph > * paragraphs
void justifyLine(Line *line, int diff)
static int getSpaceShrinkability(struct Word *word)
bool ignoreLine1OffsetSometimes
lout::misc::SimpleVector< Line > * lines
lout::misc::ZoneAllocator * textZone
int textWidth(style::Font *font, const char *text, int len)
Represents additional data for OOF containers.
virtual bool mayAffectBordersAtAll()=0
virtual bool hasFloatRight(int y, int h, OOFAwareWidget *lastGen, int lastExtIndex)=0
Return whether there is a float on the right side.
virtual bool hasFloatLeft(int y, int h, OOFAwareWidget *lastGen, int lastExtIndex)=0
Return whether there is a float on the left side.
virtual int getRightBorder(int y, int h, OOFAwareWidget *lastGen, int lastExtIndex)=0
Get the right border for the vertical position of y, for a height of h, based on floats; relative to ...
virtual int getLeftFloatHeight(int y, int h, OOFAwareWidget *lastGen, int lastExtIndex)=0
Assuming there is a float on the left side, return the rest height of it.
virtual void tellPosition1(core::Widget *widget, int x, int y)=0
Called before tellPosition2, see there for more.
virtual void tellIncompletePosition1(core::Widget *generator, core::Widget *widget, int x, int y)=0
virtual void tellIncompletePosition2(core::Widget *generator, core::Widget *widget, int x, int y)=0
virtual void calcWidgetRefSize(core::Widget *widget, core::Requisition *size)=0
virtual int getRightFloatHeight(int y, int h, OOFAwareWidget *lastGen, int lastExtIndex)=0
Assuming there is a float on the right side, return the rest height of it.
virtual void moveExternalIndices(OOFAwareWidget *generator, int oldStartIndex, int diff)=0
virtual void tellPosition2(core::Widget *widget, int x, int y)=0
Called after tellPosition1.
virtual int getLeftBorder(int y, int h, OOFAwareWidget *lastGen, int lastExtIndex)=0
Get the left border for the vertical position of y, for a height of h", based on floats; relative to ...
A class for fast concatenation of a large number of strings.
void append(const char *str)
Append a NUL-terminated string to the buffer, with copying.
const char * getChars()
Return a NUL-terminated strings containing all appended strings.
const char * strndup(const char *str, size_t t)
#define DBG_OBJ_ENTER0(aspect, prio, funname)
#define DBG_OBJ_SET_BOOL(var, val)
#define DBG_OBJ_MSG_END()
#define DBG_OBJ_MSGF(aspect, prio, fmt,...)
#define DBG_OBJ_SET_NUM(var, val)
#define DBG_OBJ_MSG(aspect, prio, msg)
#define DBG_OBJ_ENTER(aspect, prio, funname, fmt,...)
#define DBG_OBJ_MSG_START()
#define DBG_OBJ_ARRATTRSET_NUM(var, ind, attr, val)
#define DBG_OBJ_SET_NUM_O(obj, var, val)
#define DBG_OBJ_ARRATTRSET_SYM(var, ind, attr, val)
#define DBG_OBJ_LEAVE_VAL(fmt,...)
int multiplyWithPerLengthRounded(int x, Length l)
Like multiplyWithPerLength, but rounds to nearest integer instead of down.
bool isPerLength(Length l)
Returns true if l is a percentage.
int absLengthVal(Length l)
Returns the value of a length in pixels, as an integer.
Dw is in this namespace, or sub namespaces of this one.
Miscellaneous stuff, which does not fit anywhere else.
const char * boolToStr(bool b)
enum dw::Textblock::Line::@31 alignment
int lastOofRefPositionedBeforeThisLine
int totalHeight(int marginNextLine)
Returns the difference between two vertical lines positions: height of this line plus space below thi...
int maxParAdjustmentWidth
SpaceImgRenderer * spaceImgRenderer
core::style::Style * style
WordImgRenderer * wordImgRenderer
@ DIV_CHAR_AT_EOL
Must be drawn with a hyphen, when at the end of the line.
@ UNBREAKABLE_FOR_MIN_WIDTH
@ CAN_BE_HYPHENATED
Can be hyphenated automatically.
@ DRAW_AS_ONE_TEXT
This word must be drawn, together with the following word(s), by only one call of View::drawText(),...
BadnessAndPenalty badnessAndPenalty
int totalSpaceStretchability
core::style::Style * spaceStyle
int totalSpaceShrinkability
@ WIDGET_OOF_REF
reference to a widget out of flow (OOF); this widget (containing this content) is only the generator ...
@ WIDGET_IN_FLOW
widget in normal flow, so that this widget (containing this content) is both container (parent) and g...
WidgetReference * widgetReference
#define DBG_MSG_WORD(aspect, prio, prefix, n, suffix)
#define DBG_SET_WORD_SIZE(n)