diff options
-rw-r--r-- | ChangeLog | 1 | ||||
-rw-r--r-- | dw/textblock.cc | 262 | ||||
-rw-r--r-- | dw/textblock.hh | 110 | ||||
-rw-r--r-- | dw/textblock_iterator.cc | 2 | ||||
-rw-r--r-- | dw/textblock_linebreaking.cc | 111 | ||||
-rw-r--r-- | src/cache.c | 3 | ||||
-rw-r--r-- | src/domain.c | 4 |
7 files changed, 270 insertions, 223 deletions
@@ -30,6 +30,7 @@ dillo-3.1 [not released yet] - New dillorc options 'adjust_min_width' and 'adjust_table_min_width'. - Make building of test/ files more robust. - Fix Makefile to pick up LIBJPEG_CPPFLAGS. + - Work on collapsing spaces: more cases supported. Patches: Sebastian Geerken +- Image buffer/cache improvements. Patch: Jorge Arellano Cid diff --git a/dw/textblock.cc b/dw/textblock.cc index ae4c6cb4..92d7f662 100644 --- a/dw/textblock.cc +++ b/dw/textblock.cc @@ -83,7 +83,7 @@ void Textblock::WordImgRenderer::getBgArea (int *x, int *y, int *width, *x = textblock->allocation.x + this->xWordWidget; *y = textblock->lineYOffsetCanvas (line); *width = textblock->words->getRef(wordNo)->size.width; - *height = line->boxAscent + line->boxDescent; + *height = line->borderAscent + line->borderDescent; } void Textblock::WordImgRenderer::getRefArea (int *xRef, int *yRef, @@ -330,40 +330,40 @@ void Textblock::sizeRequestImpl (core::Requisition *requisition) showMissingLines (); if (lines->size () > 0) { - Line *lastLine = lines->getRef (lines->size () - 1); - requisition->width = lastLine->maxLineWidth; - - DBG_OBJ_MSGF ("resize", 1, "lines[%d]->maxLineWidth = %d", - lines->size () - 1, lastLine->maxLineWidth); - - DBG_OBJ_MSGF ("resize", 1, "lines[0]->boxAscent = %d", - lines->getRef(0)->boxAscent); - DBG_OBJ_MSGF ("resize", 1, "lines[%d]->top = %d", - lines->size () - 1, lastLine->top); - DBG_OBJ_MSGF ("resize", 1, "lines[%d]->boxAscent = %d", - lines->size () - 1, lastLine->boxAscent); - DBG_OBJ_MSGF ("resize", 1, "lines[%d]->boxDescent = %d", - lines->size () - 1, lastLine->boxDescent); - - /* Note: the breakSpace of the last line is ignored, so breaks - at the end of a textblock are not visible. */ - requisition->ascent = lines->getRef(0)->boxAscent; - requisition->descent = lastLine->top - + lastLine->boxAscent + lastLine->boxDescent - - lines->getRef(0)->boxAscent; + Line *firstLine = lines->getRef(0), *lastLine = lines->getLastRef (); + + // Note: the breakSpace of the last line is ignored, so breaks + // at the end of a textblock are not visible. + + requisition->width = + lastLine->maxLineWidth + leftInnerPadding + boxDiffWidth (); + + // Also regard collapsing of this widget top margin and the top + // margin of the first line box: + requisition->ascent = calcVerticalBorder (getStyle()->padding.top, + getStyle()->borderWidth.top, + getStyle()->margin.top + + extraSpace.top, + firstLine->borderAscent, + firstLine->marginAscent); + + // And here, regard collapsing of this widget bottom margin and the + // bottom margin of the last line box: + requisition->descent = + // (BTW, this line: + lastLine->top - firstLine->borderAscent + lastLine->borderAscent + + // ... is 0 for a block with one line, so special handling + // for this case is not necessary.) + calcVerticalBorder (getStyle()->padding.bottom, + getStyle()->borderWidth.bottom, + getStyle()->margin.bottom + extraSpace.bottom, + lastLine->borderDescent, lastLine->marginDescent); } else { - requisition->width = 0; // before: lastLineWidth; - requisition->ascent = 0; - requisition->descent = 0; + requisition->width = leftInnerPadding + boxDiffWidth (); + requisition->ascent = boxOffsetY (); + requisition->descent = boxRestHeight ();; } - DBG_OBJ_MSGF ("resize", 1, "left inner padding = %d, boxDiffWidth = %d", - leftInnerPadding, boxDiffWidth ()); - - requisition->width += leftInnerPadding + boxDiffWidth (); - requisition->ascent += boxOffsetY (); - requisition->descent += boxRestHeight (); - if (mustBeWidenedToAvailWidth ()) { DBG_OBJ_MSGF ("resize", 1, "before considering lineBreakWidth (= %d): %d * (%d + %d)", @@ -401,6 +401,30 @@ void Textblock::sizeRequestImpl (core::Requisition *requisition) DBG_OBJ_LEAVE (); } +int Textblock::calcVerticalBorder (int widgetPadding, int widgetBorder, + int widgetMargin, int lineBorderTotal, + int lineMarginTotal) +{ + DBG_OBJ_ENTER ("resize", 0, "calcVerticalBorder", "%d, %d, %d, %d, %d", + widgetPadding, widgetBorder, widgetMargin, lineBorderTotal, + lineMarginTotal); + + int result; + + if (widgetPadding == 0 && widgetBorder == 0) { + if (lineMarginTotal - lineBorderTotal >= widgetMargin) + result = lineMarginTotal; + else + result = widgetMargin + lineBorderTotal; + } else + result = lineMarginTotal + widgetPadding + widgetBorder + widgetMargin; + + DBG_OBJ_MSGF ("resize", 0, "=> %d", result); + DBG_OBJ_LEAVE (); + + return result; +} + /** * Get the extremes of a word within a textblock. */ @@ -524,8 +548,13 @@ void Textblock::sizeAllocateImpl (core::Allocation *allocation) misc::max (allocation->ascent, // Reconstruct the initial size; see // Textblock::sizeRequestImpl. - (lines->size () > 0 ? lines->getRef(0)->boxAscent : 0) - + boxOffsetY ()); + (lines->size () > 0 ? + calcVerticalBorder (getStyle()->padding.top, + getStyle()->borderWidth.top, + getStyle()->margin.top + extraSpace.top, + lines->getRef(0)->borderAscent, + lines->getRef(0)->marginAscent) : + boxOffsetY ())); childBaseAllocation.descent = allocation->ascent + allocation->descent - childBaseAllocation.ascent; @@ -593,22 +622,18 @@ void Textblock::sizeAllocateImpl (core::Allocation *allocation) /* Commented lines break the n2 and n3 test cases at * http://www.dillo.org/test/img/ */ childAllocation.y = lineYOffsetCanvas (line) - + (line->boxAscent - word->size.ascent) - - word->content.widget->getStyle()->margin.top; + + (line->borderAscent - word->size.ascent); DBG_OBJ_MSGF ("resize", 1, - "childAllocation.y = %d + (%d - %d) - %d = %d", + "childAllocation.y = %d + (%d - %d) = %d", lineYOffsetCanvas (line), - line->boxAscent, word->size.ascent, - word->content.widget->getStyle()->margin.top, + line->borderAscent, word->size.ascent, childAllocation.y); childAllocation.width = word->size.width; - childAllocation.ascent = word->size.ascent - + word->content.widget->getStyle()->margin.top; - childAllocation.descent = word->size.descent - + word->content.widget->getStyle()->margin.bottom; - + childAllocation.ascent = word->size.ascent; + childAllocation.descent = word->size.descent; + oldChildAllocation = word->content.widget->getAllocation(); if (childAllocation.x != oldChildAllocation->x || @@ -972,8 +997,8 @@ bool Textblock::sendSelectionEvent (core::SelectionState::EventType eventType, } else { Line *lastLine = lines->getRef (lines->size () - 1); int yFirst = lineYOffsetCanvasI (0); - int yLast = lineYOffsetCanvas (lastLine) + lastLine->boxAscent + - lastLine->boxDescent; + int yLast = lineYOffsetCanvas (lastLine) + lastLine->borderAscent + + lastLine->borderDescent; if (event->yCanvas < yFirst) { // Above the first line: take the first word. wordIndex = 0; @@ -986,8 +1011,8 @@ bool Textblock::sendSelectionEvent (core::SelectionState::EventType eventType, lines->getRef (findLineIndexWhenAllocated (event->yWidget)); // Pointer within the break space? - if (event->yWidget > - (lineYOffsetWidget (line) + line->boxAscent + line->boxDescent)) { + if (event->yWidget > (lineYOffsetWidget (line) + + line->borderAscent + line->borderDescent)) { // Choose this break. wordIndex = line->lastWord; charPos = core::SelectionState::END_OF_WORD; @@ -1008,7 +1033,8 @@ bool Textblock::sendSelectionEvent (core::SelectionState::EventType eventType, if (event->xWidget >= wordStartX && event->xWidget < nextWordStartX) { // We have found the word. - int yWidgetBase = lineYOffsetWidget (line) + line->boxAscent; + int yWidgetBase = + lineYOffsetWidget (line) + line->borderAscent; if (event->xWidget >= nextWordStartX - word->effSpace) { charPos = core::SelectionState::END_OF_WORD; @@ -1114,26 +1140,6 @@ core::Iterator *Textblock::iterator (core::Content::Type mask, bool atEnd) return new TextblockIterator (this, mask, atEnd); } -/** - * Calculate the size of a widget within the page. - */ -void Textblock::calcWidgetSize (core::Widget *widget, core::Requisition *size) -{ - DBG_OBJ_ENTER ("resize", 0, "calcWidgetSize", "%p, ...", widget); - - widget->sizeRequest (size); - - // Ascent and descent in words do not contain margins. - // TODO: Re-evaluate (GROWS)! - core::style::Style *wstyle = widget->getStyle(); - size->ascent -= wstyle->margin.top; - size->descent -= wstyle->margin.bottom; - - DBG_OBJ_MSGF ("resize", 1, "result: %d * (%d + %d)", - size->width, size->ascent, size->descent); - DBG_OBJ_LEAVE (); -} - /* * Draw the decorations on a word. */ @@ -1247,8 +1253,8 @@ void Textblock::drawWord (Line *line, int wordIndex1, int wordIndex2, for (int i = wordIndex1; i <= wordIndex2; i++) w += words->getRef(i)->size.width; w += words->getRef(wordIndex2)->hyphenWidth; - drawBox (view, style, area, xWidget, yWidgetBase - line->boxAscent, - w, line->boxAscent + line->boxDescent, false); + drawBox (view, style, area, xWidget, yWidgetBase - line->borderAscent, + w, line->borderAscent + line->borderDescent, false); } if (wordIndex1 == wordIndex2 && !drawHyphen) { @@ -1447,7 +1453,7 @@ void Textblock::drawLine (Line *line, core::View *view, core::Rectangle *area) area->x, area->y, area->width, area->height); int xWidget = line->textOffset; - int yWidgetBase = lineYOffsetWidget (line) + line->boxAscent; + int yWidgetBase = lineYOffsetWidget (line) + line->borderAscent; DBG_OBJ_MSGF ("draw", 1, "line from %d to %d (%d words), at (%d, %d)", line->firstWord, line->lastWord, words->size (), @@ -1498,8 +1504,8 @@ void Textblock::drawLine (Line *line, core::View *view, core::Rectangle *area) if (word->spaceStyle->hasBackground ()) drawBox (view, word->spaceStyle, area, xWidget + wordSize, - yWidgetBase - line->boxAscent, word->effSpace, - line->boxAscent + line->boxDescent, false); + yWidgetBase - line->borderAscent, word->effSpace, + line->borderAscent + line->borderDescent, false); drawSpace(wordIndex, view, area, xWidget + wordSize, yWidgetBase); } @@ -1527,7 +1533,13 @@ int Textblock::findLineIndexWhenNotAllocated (int y) if (lines->size() == 0) return -1; else - return findLineIndex (y, lines->getRef(0)->boxAscent + boxOffsetY()); + return + findLineIndex (y, calcVerticalBorder (getStyle()->padding.top, + getStyle()->borderWidth.top, + getStyle()->margin.top + + extraSpace.top, + lines->getRef(0)->borderAscent, + lines->getRef(0)->marginAscent)); } int Textblock::findLineIndexWhenAllocated (int y) @@ -1640,8 +1652,8 @@ Textblock::Word *Textblock::findWord (int x, int y, bool *inSpace) if ((lineIndex = findLineIndexWhenAllocated (y)) >= lines->size ()) return NULL; line = lines->getRef (lineIndex); - yWidgetBase = lineYOffsetWidget (line) + line->boxAscent; - if (yWidgetBase + line->boxDescent <= y) + yWidgetBase = lineYOffsetWidget (line) + line->borderAscent; + if (yWidgetBase + line->borderDescent <= y) return NULL; xCursor = line->textOffset; @@ -2304,7 +2316,7 @@ void Textblock::addWidget (core::Widget *widget, core::style::Style *style) } core::Requisition size; - calcWidgetSize (widget, &size); + widget->sizeRequest (&size); Word *word = addWord (size.width, size.ascent, size.descent, 0, style); word->content.type = core::Content::WIDGET_IN_FLOW; word->content.widget = widget; @@ -2581,7 +2593,7 @@ void Textblock::addParbreak (int space, core::style::Style *style) misc::max (word->content.breakSpace, space); lastLine->breakSpace = misc::max (word->content.breakSpace, - lastLine->marginDescent - lastLine->boxDescent, + lastLine->marginDescent - lastLine->borderDescent, lastLine->breakSpace); return; } @@ -2810,7 +2822,7 @@ void Textblock::changeLinkColor (int link, int newColor) } if (changed) queueDrawArea (0, lineYOffsetWidget(line), allocation.width, - line->boxAscent + line->boxDescent); + line->borderAscent + line->borderDescent); } } @@ -2837,9 +2849,9 @@ void Textblock::queueDrawRange (int index1, int index2) if (line1idx >= 0 && line2idx >= 0) { Line *line1 = lines->getRef (line1idx), *line2 = lines->getRef (line2idx); - int y = lineYOffsetWidget (line1) + line1->boxAscent - + int y = lineYOffsetWidget (line1) + line1->borderAscent - line1->contentAscent; - int h = lineYOffsetWidget (line2) + line2->boxAscent + + int h = lineYOffsetWidget (line2) + line2->borderAscent + line2->contentDescent - y; queueDrawArea (0, y, allocation.width, h); @@ -3082,71 +3094,41 @@ Textblock *Textblock::getTextblockForLine (int firstWord, int lastWord) /** * Includes margin, border, and padding. */ -int Textblock::yOffsetOfPossiblyMissingLine (int lineNo) +int Textblock::yOffsetOfLineToBeCreated () { - DBG_OBJ_ENTER ("line.yoffset", 0, "yOffsetOfPossiblyMissingLine", - "%d <i>of %d</i>", lineNo, lines->size()); - - int result; - - if (lineNo == 0) { - result = boxOffsetY(); - DBG_OBJ_MSGF ("line.yoffset", 1, "first line: %d", result); - } else { - Line *prevLine = lines->getRef (lineNo - 1); - result = boxOffsetY() + prevLine->top + prevLine->boxAscent + - prevLine->boxDescent + prevLine->breakSpace; - DBG_OBJ_MSGF ("line.yoffset", 1, - "other line: %d + %d + (%d + %d) + %d = %d", - boxOffsetY(), prevLine->top, prevLine->boxAscent, - prevLine->boxDescent, prevLine->breakSpace, result); - } + // This method does not return an exact result: the position of the + // new line, which does not yet exist, cannot be calculated, since + // the top margin of the new line (which collapses either with the + // top margin of the textblock widget, or the bottom margin of the + // last line) must be taken into account. However, this method is + // only called for positioning floats; here, a slight incorrectness + // does not cause real harm. - DBG_OBJ_LEAVE (); + // (Similar applies to the line *height*, which calculated in an + // iterative way; see wrapWordInFlow. Using the same approach for + // the *position* is possible, but not worth the increased + // complexity.) - return result; -} - -int Textblock::heightOfPossiblyMissingLine (int lineNo) -{ - DBG_OBJ_ENTER ("line.height", 0, "heightOfPossiblyMissingLine", - "%d <i>of %d</i>", lineNo, lines->size()); + DBG_OBJ_ENTER0 ("line.yoffset", 0, "yOffsetOfLineToBeCreated"); int result; - if (lineNo < lines->size()) { - // An existing line. - - Line *line = lines->getRef (lineNo); - - // This is sometimes called within addLine, so that the - // condition above is true, but line->boxAscent and - // line->boxDescent are not set appropriately. We have to - // accumulate the heights then. - - if (line->finished) { - DBG_OBJ_MSGF ("line.height", 1, - "exists and is finished; height = %d + %d = %d", - line->boxAscent, line->boxDescent, - line->boxAscent + line->boxDescent); - result = line->boxAscent + line->boxDescent; - } else { - DBG_OBJ_MSG ("line.height", 1, "exist but is not finished"); - result = misc::max (1, newLineAscent + newLineDescent); - } - } else if (lineNo == lines->size()) { - // The line to be constructed: some words exist, but not the - // line. Accumulate the word heights. - - // Old comment: Furthermore, this is in some cases incomplete: - // see doc/dw-out-of-flow.doc. -- Still the case? - - DBG_OBJ_MSG ("line.height", 1, "does not exist"); - result = misc::max (1, newLineAscent + newLineDescent); - } else - result = 1; + if (lines->size () == 0) { + result = calcVerticalBorder (getStyle()->padding.top, + getStyle()->borderWidth.top + extraSpace.top, + getStyle()->margin.top, 0, 0); + DBG_OBJ_MSGF ("line.yoffset", 1, "first line: ... = %d", result); + } else { + Line *firstLine = lines->getRef (0), *lastLine = lines->getLastRef (); + result = calcVerticalBorder (getStyle()->padding.top, + getStyle()->borderWidth.top, + getStyle()->margin.top + extraSpace.top, + firstLine->borderAscent, + firstLine->marginAscent) + - firstLine->borderAscent + lastLine->top + lastLine->totalHeight (0); + DBG_OBJ_MSGF ("line.yoffset", 1, "other line: ... = %d", result); + } - DBG_OBJ_MSGF ("line.height", 0, "result = %d", result); DBG_OBJ_LEAVE (); return result; diff --git a/dw/textblock.hh b/dw/textblock.hh index 19140492..74ef6525 100644 --- a/dw/textblock.hh +++ b/dw/textblock.hh @@ -37,6 +37,11 @@ namespace dw { * * <h3>Collapsing Spaces</h3> * + * <div style="border: 2px solid #ffff00; margin-top: 0.5em; + * margin-bottom: 0.5em; padding: 0.5em 1em; background-color: + * #ffffe0"><b>Info:</b> Collapsing spaces are deprecated, in favor of + * collapsing margins (see below).</div> + * * The idea behind this is that every paragraph has a specific vertical * space around and that they are combined to one space, according to * rules stated below. A paragraph consists either of the lines between @@ -87,10 +92,11 @@ namespace dw { * <h3>Collapsing Margins</h3> * * Collapsing margins, as defined in the CSS2 specification, are, - * supported in addition to collapsing spaces. Also, spaces and margins - * collapse themselves. I.e., the space between two paragraphs is the - * maximum of the space calculated as described in "Collapsing Spaces" - * and the space calculated according to the rules for collapsing margins. + * supported in addition to collapsing spaces. Also, spaces and + * margins collapse themselves. I. e., the space between two + * paragraphs is the maximum of the space calculated as described in + * "Collapsing Spaces" and the space calculated according to the rules + * for collapsing margins. * * (This is an intermediate hybrid state, collapsing spaces are used in * the current version of dillo, while I implemented collapsing margins @@ -98,6 +104,44 @@ namespace dw { * a pure CSS-based dillo, collapsing spaces will not be needed anymore, and * may be removed for simplicity.) * + * Currently implemented cases: + * + * - The top margin of of the textblock widget and the top margin of + * the first line box (based on widgets in the first line) collapse. + * + * - The bottom margin of of the textblock widget and the bottom + * margin of the last line box collapse. + * + * - The bottom margin of a line box and the top margin of the + * following line collapse. Here, the break space is regarded, too. + * + * Open issues: + * + * - Only the value of Style::margin is regarded, not the result of + * the collapsing itself. For the widgets A, B (child of A), and C + * (child of B), the effective margin of A is the maximum of the + * *style* margins of A and B, while the effective margin of B (the + * collapsed margin of B and C) is ignored here. This could be + * solved by introducing an additional "effective" ("calculated", + * "collapsed") margin as an attribute of Widget. + * + * - For similar reasons, backgrounds to not work exactly. Usage of + * Widget::extraSpace should fix this, but it is only fully working + * in the GROWS branch (<http://flpsed.org/hgweb/dillo_grows>). + * + * - Do margins of inline blocks and tables collapse? Check CSS + * spec. (They do currently; if not, ignoring them is simple.) + * + * - Lines which only contain a BREAK should be skipped for collapsing + * margins, or at least all three should collapse: the previous + * margin, the break, and the following margin. (Compare this with + * the CSS spec.) + * + * - Related to this: adding breaks should be revised. + * Textblock::addLinebreak and Textblock::addParbreak work quite + * differently, and Textblock::addParbreak seems much to complex for + * our needs, even when spaces of lines are kept. + * * * <h3>Some Internals</h3> * @@ -326,20 +370,36 @@ protected: int top; /* "top" is always relative to the top of the first line, i.e. page->lines[0].top is always 0. */ - int boxAscent; /* Maximum of all ascents of the words - in this line. This is the actual - ascent of the line. */ - int boxDescent; /* Maximum of all decents of the words - in this line. This is the actual - descent of the line. */ - int contentAscent; /* ??? */ - int contentDescent; /* ??? */ + int marginAscent; /* Maximum of all total ascents + (including margin: hence the name) + of the words in this line. */ + int marginDescent; /* Maximum of all total decents + (including margin: hence the name) + of the words in this line. */ + int borderAscent; /* Maximum of all ascents minus margin + (but including padding and border: + hence the name) of the words in + this line. */ + int borderDescent; /* Maximum of all descents minus margin + (but including padding and border: + hence the name) of the words in + this line. */ + int contentAscent; /* ??? (depricated?) */ + int contentDescent; /* ??? (depricated?) */ int breakSpace; /* Space between this line and the next one. */ - int textOffset; /* ??? */ + int textOffset; /* ??? (to be documented) */ - /* This is similar to descent, but includes the bottom margins of the - * widgets within this line. */ - int marginDescent; + /** + * \brief Returns the difference between two vertical lines + * positions: height of this line plus space below this + * line. The margin of the next line (marginAscent - + * borderAscent) must be passed seperately. + */ + inline int totalHeight (int marginNextLine) + { return borderAscent + borderDescent + // Collapsing of the margins of adjacent lines is done here: + + lout::misc::max (marginDescent - borderDescent, marginNextLine, + breakSpace); } /* Maximum of all line widths, including this line. Does not * include the last space, but the last hyphen width. Please @@ -348,11 +408,6 @@ protected: * last line, not this line.*/ int maxLineWidth; - /* Set to false at the beginning of addLine(), and to true at - * the end. Should be checked by some methods which are called - * by addLine(). */ - bool finished; - /* The word index of the last OOF reference (most importantly: * float) whic is positioned before this line, or -1, if there * is no OOF reference positioned before. @@ -558,11 +613,13 @@ protected: int hoverLink; /* The link under the mouse pointer */ void queueDrawRange (int index1, int index2); + int calcVerticalBorder (int widgetPadding, int widgetBorder, + int widgetMargin, int lineBorderTotal, + int lineMarginTotal); void getWordExtremes (Word *word, core::Extremes *extremes); void justifyLine (Line *line, int diff); Line *addLine (int firstWord, int lastWord, int newLastOofPos, bool temporary, int minHeight); - void calcWidgetSize (core::Widget *widget, core::Requisition *size); void rewrap (); void fillParagraphs (); void initNewLine (); @@ -633,7 +690,7 @@ protected: inline int _lineYOffsetWidgetAllocation (Line *line, core::Allocation *allocation) { - return line->top + (allocation->ascent - lines->getRef(0)->boxAscent); + return line->top + (allocation->ascent - lines->getRef(0)->borderAscent); } inline int lineYOffsetWidget (Line *line) @@ -646,7 +703,7 @@ protected: * outside of lineYOffsetCanvas. */ inline int _lineYOffsetCanvasAllocation (Line *line, - core::Allocation *allocation) + core::Allocation *allocation) { return allocation->y + _lineYOffsetWidgetAllocation (line, allocation); } @@ -656,7 +713,7 @@ protected: */ inline int lineYOffsetCanvas (Line *line) { - return _lineYOffsetCanvasAllocation(line, &childBaseAllocation); + return _lineYOffsetCanvasAllocation (line, &childBaseAllocation); } inline int lineYOffsetWidgetI (int lineIndex) @@ -697,8 +754,7 @@ protected: Textblock *getTextblockForLine (int firstWord, int lastWord); void printBorderChangedErrorAndAbort (int y, Widget *vloat, int wrapLineIndex); - int yOffsetOfPossiblyMissingLine (int lineNo); - int heightOfPossiblyMissingLine (int lineNo); + int yOffsetOfLineToBeCreated (); bool sendSelectionEvent (core::SelectionState::EventType eventType, core::MousePositionEvent *event); diff --git a/dw/textblock_iterator.cc b/dw/textblock_iterator.cc index a0eb1bf4..8da692d6 100644 --- a/dw/textblock_iterator.cc +++ b/dw/textblock_iterator.cc @@ -208,7 +208,7 @@ void Textblock::TextblockIterator::getAllocation (int start, int end, && word->content.text[start] == 0); } - allocation->y = textblock->lineYOffsetCanvas (line) + line->boxAscent - + allocation->y = textblock->lineYOffsetCanvas (line) + line->borderAscent - word->size.ascent; allocation->width = word->size.width; diff --git a/dw/textblock_linebreaking.cc b/dw/textblock_linebreaking.cc index 77cf46be..f9ec1ecd 100644 --- a/dw/textblock_linebreaking.cc +++ b/dw/textblock_linebreaking.cc @@ -400,11 +400,11 @@ Textblock::Line *Textblock::addLine (int firstWord, int lastWord, DBG_OBJ_ARRATTRSET_NUM ("lines", lineIndex, "firstWord", line->firstWord); DBG_OBJ_ARRATTRSET_NUM ("lines", lineIndex, "lastWord", line->lastWord); - line->boxAscent = line->contentAscent = 0; - line->boxDescent = line->contentDescent = 0; + line->borderAscent = line->contentAscent = 0; + line->borderDescent = line->contentDescent = 0; + line->marginAscent = 0; line->marginDescent = 0; line->breakSpace = 0; - line->finished = false; bool regardBorder = mustBorderBeRegarded (line); line->leftOffset = misc::max (regardBorder ? newLineLeftBorder : 0, @@ -430,13 +430,10 @@ Textblock::Line *Textblock::addLine (int firstWord, int lastWord, if (lines->size () == 1) { // first line - line->top = 0; line->maxLineWidth = lineWidth; line->lastOofRefPositionedBeforeThisLine = -1; } 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->lastOofRefPositionedBeforeThisLine = prevLine->lastOofRefPositionedBeforeThisLine; @@ -449,14 +446,31 @@ Textblock::Line *Textblock::addLine (int firstWord, int lastWord, for(int i = line->firstWord; i <= line->lastWord; i++) accumulateWordForLine (lineIndex, i); + if (lines->size () == 1) + line->top = 0; + else { + // See comment in Line::totalHeight for collapsing of the + // margins of adjacent lines. + Line *prevLine = lines->getRef (lines->size () - 2); + line->top = prevLine->top + + prevLine->totalHeight (line->marginAscent - line->borderAscent); + } + // Especially empty lines (possible when there are floats) have // zero height, which may cause endless loops. For this reasons, // the height should be positive (assuming the caller passed // minHeight > 0). - line->boxAscent = misc::max (line->boxAscent, minHeight); - - DBG_OBJ_ARRATTRSET_NUM ("lines", lineIndex, "boxAscent", line->boxAscent); - DBG_OBJ_ARRATTRSET_NUM ("lines", lineIndex, "boxDescent", line->boxDescent); + line->borderAscent = misc::max (line->borderAscent, minHeight); + line->marginAscent = misc::max (line->marginAscent, minHeight); + + DBG_OBJ_ARRATTRSET_NUM ("lines", lineIndex, "borderAscent", + line->borderAscent); + DBG_OBJ_ARRATTRSET_NUM ("lines", lineIndex, "borderDescent", + line->borderDescent); + DBG_OBJ_ARRATTRSET_NUM ("lines", lineIndex, "marginAscent", + line->marginAscent); + DBG_OBJ_ARRATTRSET_NUM ("lines", lineIndex, "marginDescent", + line->marginDescent); DBG_OBJ_ARRATTRSET_NUM ("lines", lineIndex, "contentAscent", line->contentAscent); DBG_OBJ_ARRATTRSET_NUM ("lines", lineIndex, "contentDescent", @@ -481,7 +495,6 @@ Textblock::Line *Textblock::addLine (int firstWord, int lastWord, xWidget += word->size.width + word->effSpace; } - line->finished = true; line->lastOofRefPositionedBeforeThisLine = misc::max (line->lastOofRefPositionedBeforeThisLine, newLastOofPos); DBG_OBJ_SET_NUM ("lastLine.lastOofRefPositionedBeforeThisLine", @@ -715,7 +728,7 @@ int Textblock::wrapWordInFlow (int wordIndex, bool wrapAll) &breakPos); bool floatHandled; - int yNewLine = yOffsetOfPossiblyMissingLine (lines->size ()); + int yNewLine = yOffsetOfLineToBeCreated (); do { DBG_OBJ_MSG ("construct.word", 1, "<i>floatHandled loop cycle</i>"); @@ -847,7 +860,7 @@ int Textblock::wrapWordOofRef (int wordIndex, bool wrapAll) Word *word = words->getRef (wordIndex); Widget *widget = word->content.widget; - int yNewLine = yOffsetOfPossiblyMissingLine (lines->size ()); + int yNewLine = yOffsetOfLineToBeCreated (); // Floats, which affect either border, are handled in wrapWordInFlow; this // is rather for positioned elements. @@ -1487,19 +1500,13 @@ void Textblock::moveWordIndices (int wordIndex, int num, int *addIndex1) void Textblock::accumulateWordForLine (int lineIndex, int wordIndex) { + DBG_OBJ_ENTER ("construct.line", 1, "accumulateWordForLine", "%d, %d", + lineIndex, wordIndex); + DBG_MSG_WORD ("construct.line", 2, "<i>word:</i> ", wordIndex, ""); + Line *line = lines->getRef (lineIndex); Word *word = words->getRef (wordIndex); - PRINTF ("[%p] ACCUMULATE_WORD_FOR_LINE (%d, %d): %d + %d / %d + %d\n", - this, lineIndex, wordIndex, line->boxAscent, line->boxDescent, - word->size.ascent, word->size.descent); - //printf (" "); - //printWord (word); - //printf ("\n"); - - line->boxAscent = misc::max (line->boxAscent, word->size.ascent); - line->boxDescent = misc::max (line->boxDescent, word->size.descent); - int len = word->style->font->ascent; if (word->style->valign == core::style::VALIGN_SUPER) len += len / 2; @@ -1510,41 +1517,41 @@ void Textblock::accumulateWordForLine (int lineIndex, int wordIndex) len += word->style->font->ascent / 3; line->contentDescent = misc::max (line->contentDescent, len); - if (word->content.type == core::Content::WIDGET_IN_FLOW) { - int collapseMarginTop = 0; - - line->marginDescent = - misc::max (line->marginDescent, - word->size.descent + - word->content.widget->getStyle()->margin.bottom); - - if (lines->size () == 1 && - word->content.widget->isBlockLevel () && - getStyle ()->borderWidth.top == 0 && - getStyle ()->padding.top == 0) { - // collapse top margins of parent element and its first child - // see: http://www.w3.org/TR/CSS21/box.html#collapsing-margins - collapseMarginTop = getStyle ()->margin.top; - } + int borderAscent, borderDescent, marginAscent, marginDescent; - line->boxAscent = - misc::max (line->boxAscent, - word->size.ascent, - word->size.ascent - + word->content.widget->getStyle()->margin.top - - collapseMarginTop); + DBG_OBJ_MSGF ("construct.line", 2, "size.ascent = %d, size.descent = %d", + word->size.ascent, word->size.descent); + + if (word->content.type == core::Content::WIDGET_IN_FLOW) { + // TODO Consider extraSpace? + marginAscent = word->size.ascent; + marginDescent = word->size.descent; + borderAscent = + marginAscent - word->content.widget->getStyle()->margin.top; + borderDescent = + marginDescent - word->content.widget->getStyle()->margin.bottom; word->content.widget->parentRef = makeParentRefInFlow (lineIndex); } else { - line->marginDescent = - misc::max (line->marginDescent, line->boxDescent); + borderAscent = marginAscent = word->size.ascent; + borderDescent = marginDescent = word->size.descent; if (word->content.type == core::Content::BREAK) line->breakSpace = - misc::max (word->content.breakSpace, - line->marginDescent - line->boxDescent, - line->breakSpace); + misc::max (word->content.breakSpace, line->breakSpace); } + + DBG_OBJ_MSGF ("construct.line", 2, + "borderAscent = %d, borderDescent = %d, marginAscent = %d, " + "marginDescent = %d", + borderAscent, borderDescent, marginAscent, marginDescent); + + line->borderAscent = misc::max (line->borderAscent, borderAscent); + line->borderDescent = misc::max (line->borderDescent, borderDescent); + line->marginAscent = misc::max (line->marginAscent, marginAscent); + line->marginDescent = misc::max (line->marginDescent, marginDescent); + + DBG_OBJ_LEAVE (); } void Textblock::accumulateWordData (int wordIndex) @@ -1850,7 +1857,7 @@ void Textblock::rewrap () Word *word = words->getRef (i); if (word->content.type == core::Content::WIDGET_IN_FLOW) - calcWidgetSize (word->content.widget, &word->size); + word->content.widget->sizeRequest (&word->size); wordWrap (i, false); @@ -1965,7 +1972,7 @@ void Textblock::calcBorders (int lastOofRef, int height) int firstWordOfLine = lines->size() > 0 ? lines->getLastRef()->lastWord + 1 : 0; int effOofRef = misc::max (lastOofRef, firstWordOfLine - 1); - int y = yOffsetOfPossiblyMissingLine (lines->size ()); + int y = yOffsetOfLineToBeCreated (); for (int i = 0; i < NUM_OOFM; i++) { oof::OutOfFlowMgr *oofm = searchOutOfFlowMgr(i); diff --git a/src/cache.c b/src/cache.c index 1100b718..17ddbc25 100644 --- a/src/cache.c +++ b/src/cache.c @@ -870,7 +870,8 @@ static void Cache_finish_msg(CacheEntry_t *entry) if (eol) { char *status_line = dStrndup(entry->Header->str, eol - entry->Header->str); - MSG_HTTP("Body was empty. Server sent status: %s\n", status_line); + MSG_HTTP("Body of %s was empty. Server sent status: %s\n", + URL_STR_(entry->Url), status_line); dFree(status_line); } } diff --git a/src/domain.c b/src/domain.c index ea5c4948..8bff39de 100644 --- a/src/domain.c +++ b/src/domain.c @@ -129,7 +129,7 @@ bool_t a_Domain_permit(const DilloUrl *source, const DilloUrl *dest) ret = source_host[0] == '\0' || !dStrAsciiCasecmp(URL_SCHEME(dest), "data"); if (ret == FALSE) - MSG("Domain: DENIED from %s to %s.\n", source_host, URL_STR(dest)); + MSG("Domain: DENIED %s -> %s.\n", source_host, URL_STR(dest)); return ret; } @@ -151,7 +151,7 @@ bool_t a_Domain_permit(const DilloUrl *source, const DilloUrl *dest) if (ret == FALSE) { const char *src = source_host[0] ? source_host : URL_STR(source); - MSG("Domain: DENIED from %s to %s.\n", src, dest_host); + MSG("Domain: DENIED %s -> %s.\n", src, dest_host); } return ret; } |