diff -r b4985c1d5926 -r 21fb516a67f6 dw/textblock.cc --- a/dw/textblock.cc Thu Jun 18 18:28:23 2009 +0000 +++ b/dw/textblock.cc Sat Jun 20 01:53:54 2009 +0000 @@ -43,6 +43,7 @@ Textblock::Textblock (bool limitTextWidt mustQueueResize = false; redrawY = 0; lastWordDrawn = 0; + currNowrapStart = -1; /* * The initial sizes of lines and words should not be @@ -186,7 +187,6 @@ void Textblock::getExtremesImpl (core::E Word *word; int wordIndex, lineIndex; int parMin, parMax; - bool nowrap; //DBG_MSG (widget, "extremes", 0, "Dw_page_get_extremes"); //DBG_MSG_START (widget); @@ -198,10 +198,6 @@ void Textblock::getExtremesImpl (core::E } else if (wrapRef == -1) { /* no rewrap necessary -> values in lines are up to date */ line = lines->getRef (lines->size () - 1); - /* Historical note: The former distinction between lines with and without - * words[first_word]->nowrap set is no longer necessary, since - * Dw_page_real_word_wrap sets max_word_min to the correct value in any - * case. */ extremes->minWidth = line->maxWordMin; extremes->maxWidth = misc::max (line->maxParMax, lastLineParMax); //DBG_MSG (widget, "extremes", 0, "simple case"); @@ -233,12 +229,10 @@ void Textblock::getExtremesImpl (core::E //DBG_MSG_START (widget); line = lines->getRef (lineIndex); - nowrap = - words->getRef(line->firstWord)->style->whiteSpace - != core::style::WHITE_SPACE_NORMAL; - - //DEBUG_MSG (DEBUG_SIZE_LEVEL, " line %d (of %d), nowrap = %d\n", - // lineIndex, page->num_lines, nowrap); + Word *prevWord = NULL; + + //DEBUG_MSG (DEBUG_SIZE_LEVEL, " line %d (of %d)\n", + // lineIndex, page->num_lines); for (wordIndex = line->firstWord; wordIndex < line->lastWord; wordIndex++) { @@ -252,13 +246,34 @@ void Textblock::getExtremesImpl (core::E // " (next plus %d)\n", page->line1_offset); } - if (nowrap) { - parMin += prevWordSpace + wordExtremes.minWidth; - //DBG_MSGF (widget, "extremes", 0, "parMin = %d", parMin); - } else { - if (extremes->minWidth < wordExtremes.minWidth) - extremes->minWidth = wordExtremes.minWidth; + if (word->style->whiteSpace != core::style::WHITE_SPACE_NORMAL && + (prevWord == NULL || + prevWord->style->whiteSpace==core::style::WHITE_SPACE_NORMAL|| + prevWord->spaceStyle->whiteSpace == + core::style::WHITE_SPACE_NORMAL)) { + /* Start of unwrappable text. Let's figure out its width now. */ + int i = wordIndex; + Word *w = word; + + while (1) { + if (w->spaceStyle->whiteSpace != + core::style::WHITE_SPACE_NORMAL) { + wordExtremes.minWidth += w->effSpace; + if (i < line->lastWord - 1) { + w = words->getRef(++i); + + if (w->style->whiteSpace != + core::style::WHITE_SPACE_NORMAL) { + wordExtremes.minWidth += w->size.width; + continue; + } + } + } + break; + } } + if (extremes->minWidth < wordExtremes.minWidth) + extremes->minWidth = wordExtremes.minWidth; _MSG("parMax = %d, wordMaxWidth=%d, prevWordSpace=%d\n", parMax, wordExtremes.maxWidth, prevWordSpace); @@ -271,6 +286,7 @@ void Textblock::getExtremesImpl (core::E // " word %s: maxWidth = %d\n", // a_Dw_content_text (&word->content), // word_extremes.maxWidth); + prevWord = word; } if ((line->lastWord > line->firstWord && @@ -286,17 +302,6 @@ void Textblock::getExtremesImpl (core::E if (extremes->maxWidth < parMax) extremes->maxWidth = parMax; - - if (nowrap) { - //DBG_MSGF (widget, "extremes", 0, "parMin = %d", parMin); - if (extremes->minWidth < parMin) - extremes->minWidth = parMin; - - //DEBUG_MSG (DEBUG_SIZE_LEVEL + 2, - // " parMin = %d, after word %d (%s)\n", - // parMin, line->last_word - 1, - // a_Dw_content_text (&word->content)); - } prevWordSpace = 0; parMin = 0; @@ -857,7 +862,7 @@ void Textblock::wordWrap(int wordIndex) { Line *lastLine; Word *word, *prevWord; - int availWidth, lastSpace, leftOffset; + int availWidth, lastSpace, leftOffset, spanWidth = 0; bool newLine = false, newPar = false; core::Extremes wordExtremes; @@ -874,6 +879,21 @@ void Textblock::wordWrap(int wordIndex) word = words->getRef (wordIndex); + if (wordIndex == currNowrapStart) { + for (int i = wordIndex; i < words->size(); i++) { + Word *w = words->getRef(i); + if (w->content.type == core::Content::BREAK) + break; + if (w->style->whiteSpace != core::style::WHITE_SPACE_NORMAL) + spanWidth += w->size.width; + else + break; + if (w->spaceStyle->whiteSpace != core::style::WHITE_SPACE_NORMAL) + spanWidth += w->effSpace; + else + break; + } + } if (lines->size () == 0) { //DBG_MSG (page, "wrap", 0, "first line"); newLine = true; @@ -883,8 +903,8 @@ void Textblock::wordWrap(int wordIndex) lastLine = lines->getRef (lines->size () - 1); if (lines->size () > 0) { - prevWord = words->getRef (wordIndex - 1); - if (prevWord->content.type == core::Content::BREAK) { + prevWord = wordIndex > 0 ? words->getRef (wordIndex - 1) : NULL; + if (prevWord && prevWord->content.type == core::Content::BREAK) { //DBG_MSG (page, "wrap", 0, "after a break"); /* previous word is a break */ newLine = true; @@ -893,8 +913,10 @@ void Textblock::wordWrap(int wordIndex) != core::style::WHITE_SPACE_NORMAL) { //DBG_MSGF (page, "wrap", 0, "no wrap (white_space = %d)", // word->style->white_space); - newLine = false; - newPar = false; + newLine = wordIndex == currNowrapStart && + wordIndex > lastLine->firstWord && + (lastLineWidth + prevWord->origSpace + spanWidth > + availWidth); } else { if (lastLine->firstWord != wordIndex) { /* Does new word fit into the last line? */ @@ -997,9 +1019,7 @@ void Textblock::wordWrap(int wordIndex) lastLine->parMin += wordExtremes.minWidth + lastSpace; /* This may also increase the accumulated minimum word width. */ lastLine->maxWordMin = - misc::max (lastLine->maxWordMin, lastLine->parMin); - /* NOTE: Most code relies on that all values of nowrap are equal for all - * words within one line. */ + misc::max (lastLine->maxWordMin, spanWidth); } else /* Simple case. */ lastLine->maxWordMin = @@ -1125,7 +1145,7 @@ void Textblock::rewrap () void Textblock::rewrap () { int i, wordIndex; - Word *word; + Word *word, *prevWord; Line *lastLine; if (wrapRef == -1) @@ -1167,13 +1187,30 @@ void Textblock::rewrap () wordIndex = 0; } - - for (; wordIndex < words->size (); wordIndex++) { + prevWord = (wordIndex > 0) ? words->getRef (wordIndex - 1) : NULL; + + int savedNowrapStart = currNowrapStart; + int end = currNowrapStart != -1 ? currNowrapStart : words->size (); + + for (; wordIndex < end; wordIndex++) { word = words->getRef (wordIndex); if (word->content.type == core::Content::WIDGET) calcWidgetSize (word->content.widget, &word->size); + + if (word->style->whiteSpace == core::style::WHITE_SPACE_NORMAL) { + currNowrapStart = -1; + } else if (prevWord == NULL || + prevWord->style->whiteSpace==core::style::WHITE_SPACE_NORMAL|| + prevWord->spaceStyle->whiteSpace == + core::style::WHITE_SPACE_NORMAL || + prevWord->content.type == core::Content::BREAK) { + currNowrapStart = wordIndex; + } wordWrap (wordIndex); + + if (word->spaceStyle->whiteSpace == core::style::WHITE_SPACE_NORMAL) + currNowrapStart = -1; if (word->content.type == core::Content::WIDGET) { word->content.widget->parentRef = lines->size () - 1; @@ -1193,10 +1230,11 @@ void Textblock::rewrap () Dw_page_line_total_y_offset (page, &page->lines[page->num_lines - 1])); */ - } - + prevWord = word; + } /* Next time, the page will not have to be rewrapped. */ wrapRef = -1; + currNowrapStart = savedNowrapStart; //DBG_MSG_END (page); } @@ -1611,6 +1649,22 @@ void Textblock::calcTextSize (const char size->ascent += (size->ascent / 2); } +/* + * At the end of a complete block of nowrap text (terminated by EOF, a break, + * or WHITE_SPACE_NORMAL), send it through the wrapping code. + */ +void Textblock::addNowrapWords() +{ + int wordIndex = words->size() - 1; + + for (int i = currNowrapStart; i <= wordIndex; i++) { + wordWrap(i); + Word *w = words->getRef(i); + if (w->content.type == core::Content::WIDGET) + w->content.widget->parentRef = lines->size () - 1; + } + currNowrapStart = -1; +} /** * Add a word to the page structure. Stashes the argument pointer in @@ -1629,7 +1683,16 @@ void Textblock::addText (const char *tex //DBG_OBJ_ARRSET_STR (page, "words.%d.content.text", page->num_words - 1, // word->content.text); - wordWrap (words->size () - 1); + if (currNowrapStart == -1) { + int wordIndex = words->size() - 1; + + if (word->style->whiteSpace == core::style::WHITE_SPACE_NORMAL) + wordWrap (wordIndex); + else + currNowrapStart = wordIndex; + } else if (word->style->whiteSpace == core::style::WHITE_SPACE_NORMAL) { + addNowrapWords(); + } } /** @@ -1658,8 +1721,18 @@ void Textblock::addWidget (core::Widget //DBG_OBJ_ARRSET_PTR (page, "words.%d.content.widget", page->num_words - 1, // word->content.widget); - wordWrap (words->size () - 1); - word->content.widget->parentRef = lines->size () - 1; + if (currNowrapStart == -1) { + int wordIndex = words->size() - 1;; + + if (word->style->whiteSpace == core::style::WHITE_SPACE_NORMAL) { + wordWrap (wordIndex); + word->content.widget->parentRef = lines->size () - 1; + } else { + currNowrapStart = wordIndex; + } + } else if (word->style->whiteSpace == core::style::WHITE_SPACE_NORMAL) { + addNowrapWords(); + } //DBG_OBJ_SET_NUM (word->content.widget, "parent_ref", // word->content.widget->parent_ref); @@ -1704,7 +1777,17 @@ bool Textblock::addAnchor (const char *n word = addWord (0, 0, 0, style); word->content.type = core::Content::ANCHOR; word->content.anchor = copy; - wordWrap (words->size () - 1); + + if (currNowrapStart == -1) { + int wordIndex = words->size() - 1; + + if (word->style->whiteSpace == core::style::WHITE_SPACE_NORMAL) + wordWrap (wordIndex); + else + currNowrapStart = wordIndex; + } else if (word->style->whiteSpace == core::style::WHITE_SPACE_NORMAL) { + addNowrapWords(); + } return true; } } @@ -1715,33 +1798,34 @@ bool Textblock::addAnchor (const char *n */ void Textblock::addSpace (core::style::Style *style) { - int nl, nw; + int nw; int space; - nl = lines->size () - 1; - if (nl >= 0) { - nw = words->size () - 1; - if (nw >= 0) { - /* TODO: remove this test case */ - //if (page->words[nw].orig_space != 0) { - // _MSG(" a_Dw_page_add_space:: already existing space!!!\n"); - //} - - space = style->font->spaceWidth; - words->getRef(nw)->origSpace = space; - words->getRef(nw)->effSpace = space; - words->getRef(nw)->content.space = true; - - //DBG_OBJ_ARRSET_NUM (page, "words.%d.orig_space", nw, - // page->words[nw].orig_space); - //DBG_OBJ_ARRSET_NUM (page, "words.%d.eff_space", nw, - // page->words[nw].eff_space); - //DBG_OBJ_ARRSET_NUM (page, "words.%d.content.space", nw, - // page->words[nw].content.space); - - words->getRef(nw)->spaceStyle->unref (); - words->getRef(nw)->spaceStyle = style; - style->ref (); + nw = words->size () - 1; + if (nw >= 0) { + /* TODO: remove this test case */ + //if (page->words[nw].orig_space != 0) { + // _MSG(" a_Dw_page_add_space:: already existing space!!!\n"); + //} + + space = style->font->spaceWidth; + words->getRef(nw)->origSpace = space; + words->getRef(nw)->effSpace = space; + words->getRef(nw)->content.space = true; + + //DBG_OBJ_ARRSET_NUM (page, "words.%d.orig_space", nw, + // page->words[nw].orig_space); + //DBG_OBJ_ARRSET_NUM (page, "words.%d.eff_space", nw, + // page->words[nw].eff_space); + //DBG_OBJ_ARRSET_NUM (page, "words.%d.content.space", nw, + // page->words[nw].content.space); + + words->getRef(nw)->spaceStyle->unref (); + words->getRef(nw)->spaceStyle = style; + style->ref (); + if (currNowrapStart != -1 && + style->whiteSpace == core::style::WHITE_SPACE_NORMAL) { + addNowrapWords(); } } } @@ -1757,6 +1841,9 @@ void Textblock::addParbreak (int space, Widget *widget; int lineno; + if (currNowrapStart != -1) { + addNowrapWords(); + } /* A break may not be the first word of a page, or directly after the bullet/number (which is the first word) in a list item. (See also comment in Dw_page_size_request.) */ @@ -1832,6 +1919,9 @@ void Textblock::addLinebreak (core::styl { Word *word; + if (currNowrapStart != -1) { + addNowrapWords(); + } if (words->size () == 0 || words->get(words->size () - 1).content.type == core::Content::BREAK) // An
in an empty line gets the height of the current font @@ -1918,8 +2008,11 @@ void Textblock::handOverBreak (core::sty * calls to p_Dw_widget_queue_resize. * */ -void Textblock::flush () -{ +void Textblock::flush (bool eof) +{ + if (eof && currNowrapStart != -1) { + addNowrapWords(); + } if (mustQueueResize) { queueResize (-1, true); mustQueueResize = false; diff -r b4985c1d5926 -r 21fb516a67f6 dw/textblock.hh --- a/dw/textblock.hh Thu Jun 18 18:28:23 2009 +0000 +++ b/dw/textblock.hh Sat Jun 20 01:53:54 2009 +0000 @@ -230,6 +230,7 @@ protected: int redrawY; int lastWordDrawn; + int currNowrapStart; /* These values are set by set_... */ int availWidth, availAscent, availDescent; @@ -262,6 +263,7 @@ protected: void addLine (int wordInd, bool newPar); void calcWidgetSize (core::Widget *widget, core::Requisition *size); void rewrap (); + void addNowrapWords(); void decorateText(core::View *view, core::style::Style *style, core::style::Color::Shading shading, int x, int yBase, int width); @@ -369,7 +371,7 @@ public: core::Iterator *iterator (core::Content::Type mask, bool atEnd); - void flush (); + void flush (bool eof); void addText (const char *text, core::style::Style *style); void addWidget (core::Widget *widget, core::style::Style *style); diff -r b4985c1d5926 -r 21fb516a67f6 src/html.cc --- a/src/html.cc Thu Jun 18 18:28:23 2009 +0000 +++ b/src/html.cc Sat Jun 20 01:53:54 2009 +0000 @@ -1220,7 +1220,7 @@ static void Html_eventually_pop_dw(Dillo if (html->dw != S_TOP(html)->textblock) { if (hand_over_break) HT2TB(html)->handOverBreak (html->styleEngine->style ()); - HT2TB(html)->flush (); + HT2TB(html)->flush (true); html->dw = S_TOP(html)->textblock; } } @@ -2635,7 +2635,7 @@ static void Html_tag_close_li(DilloHtml { html->InFlags &= ~IN_LI; html->WordAfterLI = false; - ((ListItem *)html->dw)->flush (); + ((ListItem *)html->dw)->flush (true); } /* @@ -3777,7 +3777,7 @@ static int Html_write_raw(DilloHtml *htm } }/*while*/ - textblock->flush (); + textblock->flush (Eof); return token_start; } diff -r b4985c1d5926 -r 21fb516a67f6 src/plain.cc --- a/src/plain.cc Thu Jun 18 18:28:23 2009 +0000 +++ b/src/plain.cc Sat Jun 20 01:53:54 2009 +0000 @@ -177,7 +177,7 @@ void DilloPlain::write(void *Buf, uint_t Start_Ofs += len; } - DW2TB(dw)->flush(); + DW2TB(dw)->flush(Eof); } /*