aboutsummaryrefslogtreecommitdiff
path: root/dw/textblock.cc
diff options
context:
space:
mode:
authorSebastian Geerken <devnull@localhost>2014-10-15 00:00:08 +0200
committerSebastian Geerken <devnull@localhost>2014-10-15 00:00:08 +0200
commit021d425fea3bdc727328ccbe24f508453a4ada36 (patch)
tree8a3e9c11bfb4672c79e9ef797daccca6ca4102fd /dw/textblock.cc
parent6c5f32b8ec8f9a01ca0ab6107779bfa2eda5299b (diff)
parent3143688e32d73fa788fd2d37e395753bae578e7d (diff)
Merge with main repo.
Diffstat (limited to 'dw/textblock.cc')
-rw-r--r--dw/textblock.cc262
1 files changed, 122 insertions, 140 deletions
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;