aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dw/textblock.cc155
-rw-r--r--dw/textblock.hh88
-rw-r--r--dw/textblock_linebreaking.cc205
-rw-r--r--test/table-h1.html37
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&shy;stücks&shy;ver&shy;kehrs&shy;ge&shy;neh&shy;mi&shy;gungs&shy;zu&shy;stän&shy;dig&shy;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>