diff options
author | Sebastian Geerken <devnull@localhost> | 2012-12-07 19:32:40 +0100 |
---|---|---|
committer | Sebastian Geerken <devnull@localhost> | 2012-12-07 19:32:40 +0100 |
commit | af5ba96e99d8ceeab04e5b046e600ca68a2aa50f (patch) | |
tree | 6196dc175c56b1d7c22c8ea2859f785cc01820f8 | |
parent | b674a18d7ee9871ce62456eff7e9483e29a21102 (diff) | |
parent | 93e2f307007acc8be297301e60796b21ee36e932 (diff) |
Merge experimental extremes calculation.
-rw-r--r-- | dw/textblock.cc | 155 | ||||
-rw-r--r-- | dw/textblock.hh | 88 | ||||
-rw-r--r-- | dw/textblock_linebreaking.cc | 205 | ||||
-rw-r--r-- | test/table-h1.html | 37 |
4 files changed, 281 insertions, 204 deletions
diff --git a/dw/textblock.cc b/dw/textblock.cc index 20ac7fa5..3f68cdcc 100644 --- a/dw/textblock.cc +++ b/dw/textblock.cc @@ -137,6 +137,7 @@ Textblock::Textblock (bool limitTextWidth) * is that high values decrease speed due to memory handling overhead!) * TODO: Some tests would be useful. */ + paragraphs = new misc::SimpleVector <Paragraph> (1); lines = new misc::SimpleVector <Line> (1); nonTemporaryLines = 0; words = new misc::NotSoSimpleVector <Word> (1); @@ -144,7 +145,7 @@ Textblock::Textblock (bool limitTextWidth) //DBG_OBJ_SET_NUM(this, "num_lines", num_lines); - wrapRef = -1; + wrapRefLines = wrapRefParagraphs = -1; //DBG_OBJ_SET_NUM(this, "last_line_width", last_line_width); //DBG_OBJ_SET_NUM(this, "last_line_par_min", last_line_par_min); @@ -190,6 +191,7 @@ Textblock::~Textblock () removeAnchor(anchor->name); } + delete paragraphs; delete lines; delete words; delete anchors; @@ -292,115 +294,23 @@ void Textblock::getExtremesImpl (core::Extremes *extremes) { PRINTF ("[%p] GET_EXTREMES: ...\n", this); - showMissingLines (); + fillParagraphs (); - if (lines->size () == 0) { + if (paragraphs->size () == 0) { /* empty page */ extremes->minWidth = 0; extremes->maxWidth = 0; - - PRINTF ("GET_EXTREMES: empty (but %d words)\n", words->size()); - } else if (wrapRef == -1) { - /* no rewrap necessary -> values in lines are up to date */ - Line *lastLine = lines->getRef (lines->size () - 1); - extremes->minWidth = lastLine->maxParMin; - Word *lastWord = words->getRef (lastLine->lastWord); - extremes->maxWidth = - misc::max (lastLine->maxParMax, - // parMax includes the last space, which we ignore here - lastLine->parMax - lastWord->origSpace - + lastWord->hyphenWidth); - - PRINTF ("GET_EXTREMES: no rewrap => %d, %d\n", - lastLine->maxParMin, lastLine->maxParMax); - } else { - int parMax; - /* Calculate the extremes, based on the values in the line from - where a rewrap is necessary. */ - - PRINTF ("GET_EXTREMES: complex case ...\n"); - - if (wrapRef == 0) { - extremes->minWidth = 0; - extremes->maxWidth = 0; - parMax = 0; - } else { - // Line [wrapRef - 1], not [wrapRef], because maxParMin and - // maxParMax include the respective values *in* any line - // (accumulated up to the *end*), but we start at line - // [wrapRef], so these are not needed. - - Line *line = lines->getRef (wrapRef - 1); - Word *lastWord = words->getRef (line->lastWord); - extremes->minWidth = line->maxParMin; - // consider also accumulated next value of maxParMax: parMax - extremes->maxWidth = - misc::max (line->maxParMax, - // parMax includes the last space, which we ignore here - line->parMax - lastWord->origSpace - + lastWord->hyphenWidth); - parMax = line->parMax; - } - - if (wrapRef < lines->size()) { - int parMin = 0; - - for (int wordIndex = lines->getRef(wrapRef)->firstWord; - wordIndex < words->size(); wordIndex++) { - Word *word = words->getRef (wordIndex); - bool atLastWord = wordIndex == words->size() - 1; - - //printf (" word: "); - //printWord (word); - //printf ("\n"); - - core::Extremes wordExtremes; - getWordExtremes (word, &wordExtremes); - if (wordIndex == 0) { - wordExtremes.minWidth += line1Offset; - wordExtremes.maxWidth += line1Offset; - } - - // Minimum: between two *possible* breaks (or at the end). - // TODO: Explain why index 1 is used in lineCanBeBroken(). - if (word->badnessAndPenalty.lineCanBeBroken (1) || atLastWord) { - parMin += wordExtremes.minWidth + word->hyphenWidth; - extremes->minWidth = misc::max (extremes->minWidth, parMin); - parMin = 0; - } else - // Shrinkability could be considered, but really does not play a - // role. - parMin += wordExtremes.minWidth + word->origSpace; - - // Maximum: between two *necessary* breaks (or at the end). - // TODO: lineMustBeBroken should be independent of the - // penalty index? - if (word->badnessAndPenalty.lineMustBeBroken (1) || atLastWord) { - parMax += wordExtremes.maxWidth + word->hyphenWidth; - extremes->maxWidth = misc::max (extremes->maxWidth, parMax); - parMax = 0; - } else - parMax += wordExtremes.maxWidth + word->origSpace; - - PRINTF (" => ... extremes = %d / %d, parMin = %d, parMax = %d\n", - extremes->minWidth, extremes->maxWidth, parMin, parMax); - } - } + } else { + Paragraph *lastPar = paragraphs->getLastRef (); + extremes->minWidth = lastPar->maxParMin; + extremes->maxWidth = lastPar->maxParMax; } int diff = innerPadding + getStyle()->boxDiffWidth (); extremes->minWidth += diff; extremes->maxWidth += diff; - //printf ("[%p] GET_EXTREMES, on textblock that ", this); - //if (words->size() == 0) - // printf ("is empty\n"); - //else { - // printf ("starts with:\n "); - // printWord (words->getRef(0)); - // printf ("\n"); - //} - //printf ("=> %d / %d\n", extremes->minWidth, extremes->maxWidth); + PRINTF ("=> %d / %d\n", extremes->minWidth, extremes->maxWidth); } @@ -537,20 +447,27 @@ void Textblock::resizeDrawImpl () void Textblock::markSizeChange (int ref) { - markChange (ref); -} + PRINTF ("[%p] MARK_SIZE_CHANGE (%d): %d => ...\n", this, ref, wrapRefLines); -void Textblock::markExtremesChange (int ref) -{ - markChange (ref); + /* By the way: ref == -1 may have two different causes: (i) flush() + calls "queueResize (-1, true)", when no rewrapping is necessary; + and (ii) a word may have parentRef == -1 , when it is not yet + added to a line. In the latter case, nothing has to be done + now, but addLine(...) will do everything necessary. */ + if (ref != -1) { + if (wrapRefLines == -1) + wrapRefLines = ref; + else + wrapRefLines = misc::min (wrapRefLines, ref); + } + + PRINTF (" ... => %d\n", wrapRefLine); } -/* - * Implementation for both mark_size_change and mark_extremes_change. - */ -void Textblock::markChange (int ref) +void Textblock::markExtremesChange (int ref) { - PRINTF ("[%p] MARK_CHANGE (%d): %d => ...\n", this, ref, wrapRef); + PRINTF ("[%p] MARK_EXTREMES_CHANGE (%d): %d => ...\n", + this, ref, wrapRefParagraphs); /* By the way: ref == -1 may have two different causes: (i) flush() calls "queueResize (-1, true)", when no rewrapping is necessary; @@ -558,13 +475,13 @@ void Textblock::markChange (int ref) added to a line. In the latter case, nothing has to be done now, but addLine(...) will do everything necessary. */ if (ref != -1) { - if (wrapRef == -1) - wrapRef = ref; + if (wrapRefParagraphs == -1) + wrapRefParagraphs = ref; else - wrapRef = misc::min (wrapRef, ref); + wrapRefParagraphs = misc::min (wrapRefParagraphs, ref); } - PRINTF (" ... => %d\n", wrapRef); + PRINTF (" ... => %d\n", wrapRefParagraphs); } void Textblock::setWidth (int width) @@ -1685,6 +1602,7 @@ void Textblock::addText (const char *text, size_t len, word->flags |= Word::DRAW_AS_ONE_TEXT; accumulateWordData (words->size() - 1); + correctLastWordExtremes (); } } } @@ -1739,7 +1657,7 @@ void Textblock::addText0 (const char *text, size_t len, bool canBeHyphenated, word->content.type = core::Content::TEXT; word->content.text = layout->textZone->strndup(text, len); - wordWrap (words->size () - 1, false); + processWord (words->size () - 1); } /** @@ -1770,7 +1688,7 @@ void Textblock::addWidget (core::Widget *widget, core::style::Style *style) //DBG_OBJ_ARRSET_PTR (page, "words.%d.content.widget", words->size() - 1, // word->content.widget); - wordWrap (words->size () - 1, false); + processWord (words->size () - 1); //DBG_OBJ_SET_NUM (word->content.widget, "parent_ref", // word->content.widget->parent_ref); @@ -1830,6 +1748,7 @@ void Textblock::addSpace (core::style::Style *style) if (wordIndex >= 0) { fillSpace (words->getRef(wordIndex), style); accumulateWordData (wordIndex); + correctLastWordExtremes (); } } @@ -1976,7 +1895,7 @@ void Textblock::addParbreak (int space, core::style::Style *style) word->content.type = core::Content::BREAK; word->badnessAndPenalty.setPenalty (PENALTY_FORCE_BREAK); word->content.breakSpace = space; - wordWrap (words->size () - 1, false); + processWord (words->size () - 1); } /* @@ -1999,7 +1918,7 @@ void Textblock::addLinebreak (core::style::Style *style) word->content.type = core::Content::BREAK; word->badnessAndPenalty.setPenalty (PENALTY_FORCE_BREAK); word->content.breakSpace = 0; - wordWrap (words->size () - 1, false); + processWord (words->size () - 1); } diff --git a/dw/textblock.hh b/dw/textblock.hh index 5e6bfa1c..5fea8ffc 100644 --- a/dw/textblock.hh +++ b/dw/textblock.hh @@ -96,9 +96,10 @@ namespace dw { * * <h3>Some Internals</h3> * - * There are 3 lists, dw::Textblock::words, dw::Textblock::lines, and - * dw::Textblock::anchors. The word list is quite static; only new words - * may be added. A word is either text, a widget, or a break. + * There are 4 lists, dw::Textblock::words, dw::Textblock::paragraphs, + * dw::Textblock::lines, and dw::Textblock::anchors. The word list is + * quite static; only new words may be added. A word is either text, a + * widget, or a break. * * Lines refer to the word list (first and last). They are completely * redundant, i.e., they can be rebuilt from the words. Lines can be @@ -106,6 +107,10 @@ namespace dw { * below). For the latter purpose, several values are accumulated in the * lines. See dw::Textblock::Line for details. * + * A recent change was the introduction of the paragraphs list, which + * works quite similar, is also redundant, but is used to calculate + * the extremes, not the size. + * * Anchors associate the anchor name with the index of the next word at * the point of the anchor. * @@ -232,6 +237,36 @@ private: static const char *hyphenDrawChar; protected: + struct Paragraph + { + int firstWord; /* first word's index in word vector */ + int lastWord; /* last word's index in word vector */ + + // TODO Adjust comments. Short note: maxParMin/maxParMax is + // is never smaller than parMin/parMax. + + /* + * General remark: all values include the last hyphen width, but + * not the last space; these values are, however corrected, when + * another word is added. + * + * Also, as opposed to lines, paragraphs are created with the + * first, not the last word, so these values change when new + * words are added. + */ + + int parMin; /* The sum of all word minima (plus spaces, + hyphen width etc.) of the last c */ + int parMax; /* The sum of all word maxima in this + * paragraph (plus spaces, hyphen width + * etc.). */ + + int maxParMin; /* Maximum of all paragraph minima, including + * this line. */ + int maxParMax; /* Maximum of all paragraph maxima (value of "parMax"), + * including this one. */ + }; + struct Line { int firstWord; /* first word's index in word vector */ @@ -246,35 +281,12 @@ protected: * widgets within this line. */ int marginDescent; - /* The following members contain accumulated values, from the - * top down to this line. Please notice a change: until - * recently, the values were accumulated up to the last line, - * not this line. - * - * Also, keep in mind that at the end of a line, the space of - * the last word is ignored, but instead, the hyphen width must - * be considered.*/ - - int maxLineWidth; /* Maximum of all line widths, including this - * line. Does not include the last space, but - * the last hyphen width. */ - int maxParMin; /* Maximum of all paragraph minima, including - * this line. */ - int maxParMax; /* Maximum of all paragraph maxima. This line - * is only included, if it is the last line of - * the paragraph (last word is a forced - * break); otherwise, it is the value of the - * last paragraph. For this reason, consider - * also parMax. */ - int parMax; /* The maximal total width down from the last - * paragraph start, to the *end* of this line. - * The space at the end of this line is - * included, but not the hyphen width (as - * opposed to the other values). So, in some - * cases, the space has to be subtracted and - * the hyphen width to be added, to compare it - * to maxParMax. (Search the code for - * occurances.) */ + /* Maximum of all line widths, including this line. Does not + * include the last space, but the last hyphen width. Please + * notice a change: until recently (before hyphenation and + * changed line breaking), the values were accumulated up to the + * last line, not this line.*/ + int maxLineWidth; }; struct Word @@ -336,6 +348,7 @@ protected: }; void printWordShort (Word *word); + void printWordWithFlags (Word *word); void printWord (Word *word); struct Anchor @@ -412,9 +425,10 @@ protected: /* These values are set by set_... */ int availWidth, availAscent, availDescent; - int wrapRef; /* [0 based] */ + int wrapRefLines, wrapRefParagraphs; /* [0 based] */ lout::misc::SimpleVector <Line> *lines; + lout::misc::SimpleVector <Paragraph> *paragraphs; int nonTemporaryLines; lout::misc::NotSoSimpleVector <Word> *words; lout::misc::SimpleVector <Anchor> *anchors; @@ -427,11 +441,11 @@ protected: void queueDrawRange (int index1, int index2); void getWordExtremes (Word *word, core::Extremes *extremes); - void markChange (int ref); void justifyLine (Line *line, int diff); Line *addLine (int firstWord, int lastWord, bool temporary); void calcWidgetSize (core::Widget *widget, core::Requisition *size); void rewrap (); + void fillParagraphs (); void showMissingLines (); void removeTemporaryLines (); @@ -540,10 +554,14 @@ protected: void accumulateWordExtremes (int firstWord, int lastWord, int *maxOfMinWidth, int *sumOfMaxWidth); + void processWord (int wordIndex); virtual void wordWrap (int wordIndex, bool wrapAll); + void handleWordExtremes (int wordIndex); + void correctLastWordExtremes (); + int hyphenateWord (int wordIndex); void accumulateWordForLine (int lineIndex, int wordIndex); - void accumulateWordData(int wordIndex); + void accumulateWordData (int wordIndex); int calcAvailWidth (int lineIndex); void initLine1Offset (int wordIndex); void alignLine (int lineIndex); diff --git a/dw/textblock_linebreaking.cc b/dw/textblock_linebreaking.cc index 3a719086..e33cfe62 100644 --- a/dw/textblock_linebreaking.cc +++ b/dw/textblock_linebreaking.cc @@ -227,11 +227,22 @@ void Textblock::printWordShort (Word *word) } } -void Textblock::printWord (Word *word) +void Textblock::printWordWithFlags (Word *word) { printWordShort (word); + printf (" (flags = %s:%s:%s:%s:%s)", + (word->flags & Word::CAN_BE_HYPHENATED) ? "h?" : "--", + (word->flags & Word::DIV_CHAR_AT_EOL) ? "de" : "--", + (word->flags & Word::PERM_DIV_CHAR) ? "dp" : "--", + (word->flags & Word::DRAW_AS_ONE_TEXT) ? "t1" : "--", + (word->flags & Word::UNBREAKABLE_FOR_MIN_WIDTH) ? "um" : "--"); + +} + +void Textblock::printWord (Word *word) +{ + printWordWithFlags (word); - printf (" (flags = %d)", word->flags); printf (" [%d / %d + %d - %d => %d + %d - %d] => ", word->size.width, word->origSpace, word->stretchability, word->shrinkability, word->totalWidth, word->totalStretchability, @@ -342,56 +353,18 @@ Textblock::Line *Textblock::addLine (int firstWord, int lastWord, Word *word = words->getRef (i); lineWidth += (word->effSpace - word->origSpace); } - - int lastMaxParMax; // maxParMax of the last line - + if (lines->size () == 1) { // first line line->top = 0; - line->maxLineWidth = lineWidth; - line->maxParMin = maxOfMinWidth; - line->parMax = sumOfMaxWidth; - - lastMaxParMax = 0; } else { Line *prevLine = lines->getRef (lines->size () - 2); - line->top = prevLine->top + prevLine->boxAscent + prevLine->boxDescent + prevLine->breakSpace; - line->maxLineWidth = misc::max (lineWidth, prevLine->maxLineWidth); - line->maxParMin = misc::max (maxOfMinWidth, prevLine->maxParMin); - - Word *lastWordOfPrevLine = words->getRef (prevLine->lastWord); - // TODO: lineMustBeBroken should be independent of the penalty - // index? Otherwise, examine the last line. - if (lastWordOfPrevLine->badnessAndPenalty.lineMustBeBroken (0)) - // This line starts a new paragraph. - line->parMax = sumOfMaxWidth; - else - // This line continues the paragraph from prevLine. - line->parMax = prevLine->parMax + sumOfMaxWidth; - - lastMaxParMax = prevLine->maxParMax; } - - // "maxParMax" is only set, when this line is the last line of the - // paragraph. - Word *lastWordOfThisLine = words->getRef (line->lastWord); - // TODO: lineMustBeBroken should be independent of the penalty - // index? Otherwise, examine the last line. - if (lastWordOfThisLine->badnessAndPenalty.lineMustBeBroken (0)) - // Paragraph ends here. - line->maxParMax = - misc::max (lastMaxParMax, - // parMax includes the last space, which we ignore here - line->parMax - lastWordOfThisLine->origSpace - + lastWordOfThisLine->hyphenWidth); - else - // Paragraph continues: simply copy the last value of "maxParMax". - line->maxParMax = lastMaxParMax; - + for(int i = line->firstWord; i <= line->lastWord; i++) accumulateWordForLine (lineIndex, i); @@ -406,11 +379,6 @@ Textblock::Line *Textblock::addLine (int firstWord, int lastWord, PRINTF (" line[%d].maxLineWidth = %d\n", lines->size () - 1, line->maxLineWidth); - PRINTF (" line[%d].maxParMin = %d\n", - lines->size () - 1, line->maxParMin); - PRINTF (" line[%d].maxParMax = %d\n", - lines->size () - 1, line->maxParMax); - PRINTF (" line[%d].parMax = %d\n", lines->size () - 1, line->parMax); mustQueueResize = true; @@ -462,6 +430,12 @@ void Textblock::accumulateWordExtremes (int firstWord, int lastWord, } } +void Textblock::processWord (int wordIndex) +{ + wordWrap (wordIndex, false); + handleWordExtremes (wordIndex); +} + /* * This method is called in two cases: (i) when a word is added * (ii) when a page has to be (partially) rewrapped. It does word wrap, @@ -666,6 +640,96 @@ void Textblock::wordWrap (int wordIndex, bool wrapAll) } } +/** + * Counter part to wordWrap(), but for extremes, not size calculation. + */ +void Textblock::handleWordExtremes (int wordIndex) +{ + // TODO Overall, clarify penalty index. + + Word *word = words->getRef (wordIndex); + core::Extremes wordExtremes; + getWordExtremes (word, &wordExtremes); + + //printf ("[%p] HANDLE_WORD_EXTREMES (%d):", this, wordIndex); + //printWordWithFlags (word); + //printf ("=> %d / %d\n", wordExtremes.minWidth, wordExtremes.maxWidth); + + if (wordIndex == 0) { + wordExtremes.minWidth += line1Offset; + wordExtremes.maxWidth += line1Offset; + } + + if (paragraphs->size() == 0 || + words->getRef(paragraphs->getLastRef()->lastWord) + ->badnessAndPenalty.lineMustBeBroken (1)) { + // Add a new paragraph. + Paragraph *prevPar = + paragraphs->size() == 0 ? NULL : paragraphs->getLastRef(); + paragraphs->increase (); + Paragraph *par = paragraphs->getLastRef(); + + par->firstWord = par->lastWord = wordIndex; + par->parMin = par->parMax = 0; + + if (prevPar) { + par->maxParMin = prevPar->maxParMin; + par->maxParMax = prevPar->maxParMax; + } else + par->maxParMin = par->maxParMax = 0; + } + + Paragraph *lastPar = paragraphs->getLastRef(); + + int corrDiffMin, corrDiffMax; + if (wordIndex - 1 >= lastPar->firstWord) { + Word *lastWord = words->getRef (wordIndex - 1); + if (lastWord->badnessAndPenalty.lineCanBeBroken (1) && + (lastWord->flags & Word::UNBREAKABLE_FOR_MIN_WIDTH) == 0) + corrDiffMin = 0; + else + corrDiffMin = lastWord->origSpace - lastWord->hyphenWidth; + + corrDiffMax = lastWord->origSpace - lastWord->hyphenWidth; + } else + corrDiffMin = corrDiffMax = 0; + + PRINTF (" (lastPar from %d to %d; corrDiffMin = %d, corDiffMax = %d)\n", + lastPar->firstWord, lastPar->lastWord, corrDiffMin, corrDiffMax); + + // Minimum: between two *possible* breaks. + // Shrinkability could be considered, but really does not play a role. + lastPar->parMin += wordExtremes.minWidth + word->hyphenWidth + corrDiffMin; + lastPar->maxParMin = misc::max (lastPar->maxParMin, lastPar->parMin); + if (word->badnessAndPenalty.lineCanBeBroken (1) && + (word->flags & Word::UNBREAKABLE_FOR_MIN_WIDTH) == 0) + lastPar->parMin = 0; + + // Maximum: between two *necessary* breaks. + lastPar->parMax += wordExtremes.maxWidth + word->hyphenWidth + corrDiffMax; + lastPar->maxParMax = misc::max (lastPar->maxParMax, lastPar->parMax); + + PRINTF (" => parMin = %d, parMax = %d\n", + lastPar->parMin, lastPar->parMax); + + lastPar->lastWord = wordIndex; +} + +/** + * Called when something changed for the last word (space, hyphens etc.). + */ +void Textblock::correctLastWordExtremes () +{ + if (paragraphs->size() > 0) { + if (words->getLastRef()->badnessAndPenalty.lineCanBeBroken (1)) { + paragraphs->getLastRef()->parMin = 0; + PRINTF (" => corrected; parMin = %d\n", + paragraphs->getLastRef()->parMin); + } + } +} + + int Textblock::hyphenateWord (int wordIndex) { Word *hyphenatedWord = words->getRef(wordIndex); @@ -965,14 +1029,14 @@ void Textblock::rewrap () { PRINTF ("[%p] REWRAP: wrapRef = %d\n", this, wrapRef); - if (wrapRef == -1) + if (wrapRefLines == -1) /* page does not have to be rewrapped */ return; /* All lines up from wrapRef will be rebuild from the word list, * the line list up from this position is rebuild. */ - lines->setSize (wrapRef); - nonTemporaryLines = misc::min (nonTemporaryLines, wrapRef); + lines->setSize (wrapRefLines); + nonTemporaryLines = misc::min (nonTemporaryLines, wrapRefLines); int firstWord; if (lines->size () > 0) @@ -999,7 +1063,46 @@ void Textblock::rewrap () } /* Next time, the page will not have to be rewrapped. */ - wrapRef = -1; + wrapRefLines = -1; +} + +/** + * Counter part to rewrap(), but for extremes, not size calculation. + */ +void Textblock::fillParagraphs () +{ + if (wrapRefParagraphs == -1) + return; + + // Notice that wrapRefParagraphs refers to the lines, not to the paragraphs. + int firstWordOfLine; + if (lines->size () > 0 && wrapRefParagraphs > 0) + firstWordOfLine = lines->getRef(wrapRefParagraphs - 1)->lastWord + 1; + else + firstWordOfLine = 0; + + // Binary search would be faster, but there should not be many paragraphs + // in a text block (so that binary search may be even slower). + int parNo = 0; + while (paragraphs->size() - 1 > parNo && + paragraphs->getRef(parNo)->lastWord <= firstWordOfLine) + parNo++; + + paragraphs->setSize (parNo); + + int firstWord; + if (paragraphs->size () > 0) + firstWord = paragraphs->getLastRef()->lastWord + 1; + else + firstWord = 0; + + PRINTF ("[%p] FILL_PARAGRAPHS: now %d paragraphs; starting from word %d\n", + this, parNo, firstWord); + + for (int i = firstWord; i < words->size (); i++) + handleWordExtremes (i); + + wrapRefParagraphs = -1; } void Textblock::showMissingLines () diff --git a/test/table-h1.html b/test/table-h1.html new file mode 100644 index 00000000..fb82c3ec --- /dev/null +++ b/test/table-h1.html @@ -0,0 +1,37 @@ +<table> +<tr> +<td lang="de">Grundstücksverkehrsgenehmigungszuständigkeit ABC +<td>Sed ut perspiciatis, unde omnis iste natus error sit voluptatem +accusantium doloremque laudantium, totam rem aperiam eaque ipsa, quae +ab illo inventore veritatis et quasi architecto beatae vitae dicta +sunt, explicabo. nemo enim ipsam voluptatem, quia voluptas sit, +aspernatur aut odit aut fugit, sed quia consequuntur magni dolores +eos, qui ratione voluptatem sequi nesciunt, neque porro quisquam est, +qui dolorem ipsum, quia dolor sit, amet, consectetur, adipisci velit, +sed quia non numquam eius modi tempora incidunt, ut labore et dolore +magnam aliquam quaerat voluptatem. ut enim ad minima veniam, quis +nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut +aliquid ex ea commodi consequatur? quis autem vel eum iure +reprehenderit, qui in ea voluptate velit esse, quam nihil molestiae +consequatur, vel illum, qui dolorem eum fugiat, quo voluptas nulla +pariatur? +</table> + +<table> +<tr> +<td>Grund­stücks­ver­kehrs­ge­neh­mi­gungs­zu­stän­dig­keit ABC +<td>Sed ut perspiciatis, unde omnis iste natus error sit voluptatem +accusantium doloremque laudantium, totam rem aperiam eaque ipsa, quae +ab illo inventore veritatis et quasi architecto beatae vitae dicta +sunt, explicabo. nemo enim ipsam voluptatem, quia voluptas sit, +aspernatur aut odit aut fugit, sed quia consequuntur magni dolores +eos, qui ratione voluptatem sequi nesciunt, neque porro quisquam est, +qui dolorem ipsum, quia dolor sit, amet, consectetur, adipisci velit, +sed quia non numquam eius modi tempora incidunt, ut labore et dolore +magnam aliquam quaerat voluptatem. ut enim ad minima veniam, quis +nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut +aliquid ex ea commodi consequatur? quis autem vel eum iure +reprehenderit, qui in ea voluptate velit esse, quam nihil molestiae +consequatur, vel illum, qui dolorem eum fugiat, quo voluptas nulla +pariatur? +</table> |