aboutsummaryrefslogtreecommitdiff
path: root/dw/textblock.cc
diff options
context:
space:
mode:
Diffstat (limited to 'dw/textblock.cc')
-rw-r--r--dw/textblock.cc763
1 files changed, 405 insertions, 358 deletions
diff --git a/dw/textblock.cc b/dw/textblock.cc
index 21de1991..788360b2 100644
--- a/dw/textblock.cc
+++ b/dw/textblock.cc
@@ -37,6 +37,7 @@ static dw::core::style::Tooltip *hoverTooltip = NULL;
using namespace lout;
+using namespace lout::misc;
using namespace lout::unicode;
namespace dw {
@@ -105,16 +106,6 @@ void Textblock::WordImgRenderer::draw (int x, int y, int width, int height)
}
-void Textblock::WordImgRenderer::print ()
-{
- printf ("%p: word #%d, ", this, wordNo);
- if (wordNo < textblock->words->size())
- textblock->printWordShort (textblock->words->getRef(wordNo));
- else
- printf ("<word %d does not exist>", wordNo);
- printf (", data set: %s", dataSet ? "yes" : "no");
-}
-
void Textblock::SpaceImgRenderer::getBgArea (int *x, int *y, int *width,
int *height)
{
@@ -128,16 +119,6 @@ core::style::Style *Textblock::SpaceImgRenderer::getStyle ()
return textblock->words->getRef(wordNo)->spaceStyle;
}
-void Textblock::SpaceImgRenderer::print ()
-{
- printf ("%p: word FOR SPACE #%d, ", this, wordNo);
- if (wordNo < textblock->words->size())
- textblock->printWordShort (textblock->words->getRef(wordNo));
- else
- printf ("<word %d does not exist>", wordNo);
- printf (", data set: %s", dataSet ? "yes" : "no");
-}
-
// ----------------------------------------------------------------------
Textblock::DivChar Textblock::divChars[NUM_DIV_CHARS] = {
@@ -227,7 +208,6 @@ Textblock::Textblock (bool limitTextWidth)
registerName ("dw::Textblock", &CLASS_ID);
setButtonSensitive(true);
- containingBlock = NULL;
hasListitemValue = false;
leftInnerPadding = 0;
line1Offset = 0;
@@ -237,7 +217,9 @@ Textblock::Textblock (bool limitTextWidth)
DBG_OBJ_SET_NUM ("redrawY", redrawY);
lastWordDrawn = -1;
DBG_OBJ_SET_NUM ("lastWordDrawn", lastWordDrawn);
-
+ sizeRequestPosDefined = false;
+ DBG_OBJ_SET_BOOL ("sizeRequestPosDefined", sizeRequestPosDefined);
+
/*
* The initial sizes of lines and words should not be
* too high, since this will waste much memory with tables
@@ -252,7 +234,6 @@ Textblock::Textblock (bool limitTextWidth)
nonTemporaryLines = 0;
words = new misc::NotSoSimpleVector <Word> (1);
anchors = new misc::SimpleVector <Anchor> (1);
- outOfFlowMgr = NULL;
wrapRefLines = wrapRefParagraphs = -1;
@@ -267,9 +248,6 @@ Textblock::Textblock (bool limitTextWidth)
lineBreakWidth = -1;
DBG_OBJ_SET_NUM ("lineBreakWidth", lineBreakWidth);
- verticalOffset = 0;
- DBG_OBJ_SET_NUM ("verticalOffset", verticalOffset);
-
this->limitTextWidth = limitTextWidth;
for (int layer = 0; layer < core::HIGHLIGHT_NUM_LAYERS; layer++) {
@@ -278,6 +256,11 @@ Textblock::Textblock (bool limitTextWidth)
hlStart[layer].nChar = 0;
hlEnd[layer].index = 0;
hlEnd[layer].nChar = 0;
+
+ DBG_OBJ_ARRATTRSET_NUM ("hlStart", layer, "index", hlStart[layer].index);
+ DBG_OBJ_ARRATTRSET_NUM ("hlStart", layer, "nChar", hlStart[layer].nChar);
+ DBG_OBJ_ARRATTRSET_NUM ("hlEnd", layer, "index", hlEnd[layer].index);
+ DBG_OBJ_ARRATTRSET_NUM ("hlEnd", layer, "nChar", hlEnd[layer].nChar);
}
initNewLine ();
@@ -285,8 +268,6 @@ Textblock::Textblock (bool limitTextWidth)
Textblock::~Textblock ()
{
- _MSG("Textblock::~Textblock\n");
-
/* make sure not to call a free'd tooltip (very fast overkill) */
hoverTooltip = NULL;
@@ -304,16 +285,6 @@ Textblock::~Textblock ()
delete words;
delete anchors;
- if(outOfFlowMgr) {
- // I feel more comfortable by letting the textblock delete these
- // widgets, instead of doing this in ~OutOfFlowMgr.
-
- for (int i = 0; i < outOfFlowMgr->getNumWidgets (); i++)
- delete outOfFlowMgr->getWidget (i);
-
- delete outOfFlowMgr;
- }
-
/* Make sure we don't own widgets anymore. Necessary before call of
parent class destructor. (???) */
words = NULL;
@@ -326,10 +297,25 @@ Textblock::~Textblock ()
* padding/border/margin. This can be used to align the first lines
* of several textblocks in a horizontal line.
*/
-void Textblock::sizeRequestImpl (core::Requisition *requisition)
+void Textblock::sizeRequestImpl (core::Requisition *requisition,
+ bool posDefined, int x, int y)
{
DBG_OBJ_ENTER0 ("resize", 0, "sizeRequestImpl");
+ assert (posDefined || !needsPositionForSize ());
+
+ sizeRequestPosDefined = true;
+ if (posDefined) {
+ sizeRequestX = x;
+ sizeRequestY = y;
+ } else {
+ sizeRequestX = 0;
+ sizeRequestY = 0;
+ }
+ DBG_OBJ_SET_BOOL ("sizeRequestPosDefined", sizeRequestPosDefined);
+ DBG_OBJ_SET_NUM ("sizeRequestX", sizeRequestX);
+ DBG_OBJ_SET_NUM ("sizeRequestY", sizeRequestY);
+
int newLineBreakWidth = getAvailWidth (true);
if (newLineBreakWidth != lineBreakWidth) {
lineBreakWidth = newLineBreakWidth;
@@ -347,14 +333,15 @@ void Textblock::sizeRequestImpl (core::Requisition *requisition)
// 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
- + getStyle()->boxDiffWidth ();
+ 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,
+ getStyle()->margin.top
+ + extraSpace.top,
firstLine->borderAscent,
firstLine->marginAscent);
@@ -367,16 +354,14 @@ void Textblock::sizeRequestImpl (core::Requisition *requisition)
// for this case is not necessary.)
calcVerticalBorder (getStyle()->padding.bottom,
getStyle()->borderWidth.bottom,
- getStyle()->margin.bottom,
+ getStyle()->margin.bottom + extraSpace.bottom,
lastLine->borderDescent, lastLine->marginDescent);
} else {
- requisition->width = leftInnerPadding + getStyle()->boxDiffWidth ();
- requisition->ascent = getStyle()->boxOffsetY ();
- requisition->descent = getStyle()->boxRestHeight ();;
+ requisition->width = leftInnerPadding + boxDiffWidth ();
+ requisition->ascent = boxOffsetY ();
+ requisition->descent = boxRestHeight ();
}
- requisition->ascent += verticalOffset;
-
if (mustBeWidenedToAvailWidth ()) {
DBG_OBJ_MSGF ("resize", 1,
"before considering lineBreakWidth (= %d): %d * (%d + %d)",
@@ -407,31 +392,23 @@ void Textblock::sizeRequestImpl (core::Requisition *requisition)
// Is this really what we want? An alternative could be that
// OutOfFlowMgr::getSize honours CSS attributes an corrected sizes.
- DBG_OBJ_MSGF ("resize", 1, "before considering OOF widgets: %d * (%d + %d)",
- requisition->width, requisition->ascent, requisition->descent);
-
- if (outOfFlowMgr) {
- int oofWidth, oofHeight;
- outOfFlowMgr->getSize (requisition, &oofWidth, &oofHeight);
-
- // Floats must be within the *content* area, not the *margin*
- // area (which is equivalent to the requisition /
- // allocation). For this reason, boxRestWidth() and
- // boxRestHeight() must be considered.
-
- if (oofWidth + boxRestWidth () > requisition->width)
- requisition->width = oofWidth + boxRestWidth ();
- if (oofHeight + boxRestHeight ()
- > requisition->ascent + requisition->descent)
- requisition->descent =
- oofHeight + boxRestHeight () - requisition->ascent;
- }
+ correctRequisitionByOOF (requisition, core::splitHeightPreserveAscent);
DBG_OBJ_MSGF ("resize", 1, "final: %d * (%d + %d)",
requisition->width, requisition->ascent, requisition->descent);
DBG_OBJ_LEAVE ();
}
+core::Widget *Textblock::sizeRequestReference ()
+{
+ return needsPositionForSize() ? oofContainer[OOFM_FLOATS] : NULL;
+}
+
+bool Textblock::needsPositionForSize ()
+{
+ return oofContainer[OOFM_FLOATS] != this;
+}
+
int Textblock::calcVerticalBorder (int widgetPadding, int widgetBorder,
int widgetMargin, int lineBorderTotal,
int lineMarginTotal)
@@ -515,7 +492,7 @@ void Textblock::getExtremesImpl (core::Extremes *extremes)
extremes->minWidth, extremes->minWidthIntrinsic,
extremes->maxWidth, extremes->maxWidthIntrinsic);
- int diff = leftInnerPadding + getStyle()->boxDiffWidth ();
+ int diff = leftInnerPadding + boxDiffWidth ();
extremes->minWidth += diff;
extremes->minWidthIntrinsic += diff;
extremes->maxWidth += diff;
@@ -534,22 +511,7 @@ void Textblock::getExtremesImpl (core::Extremes *extremes)
extremes->minWidth, extremes->minWidthIntrinsic,
extremes->maxWidth, extremes->maxWidthIntrinsic);
- if (outOfFlowMgr) {
- int oofMinWidth, oofMaxWidth;
- outOfFlowMgr->getExtremes (extremes, &oofMinWidth, &oofMaxWidth);
-
- DBG_OBJ_MSGF ("resize", 1, "OOFM correction: %d / %d",
- oofMinWidth, oofMaxWidth);
-
- extremes->minWidth = misc::max (extremes->minWidth, oofMinWidth);
- extremes->minWidthIntrinsic =
- misc::max (extremes->minWidthIntrinsic, oofMinWidth);
- extremes->maxWidth = misc::max (extremes->maxWidth, oofMaxWidth);
- extremes->maxWidthIntrinsic =
- misc::max (extremes->maxWidthIntrinsic, oofMinWidth);
- extremes->adjustmentWidth =
- misc::max (extremes->adjustmentWidth, oofMinWidth);
- }
+ correctExtremesByOOF (extremes);
DBG_OBJ_MSGF ("resize", 0,
"finally, after considering OOFM: %d (%d) / %d (%d)",
@@ -601,10 +563,10 @@ void Textblock::sizeAllocateImpl (core::Allocation *allocation)
(lines->size () > 0 ?
calcVerticalBorder (getStyle()->padding.top,
getStyle()->borderWidth.top,
- getStyle()->margin.top,
+ getStyle()->margin.top + extraSpace.top,
lines->getRef(0)->borderAscent,
lines->getRef(0)->marginAscent) :
- getStyle()->boxOffsetY ()) + verticalOffset);
+ boxOffsetY ()));
childBaseAllocation.descent =
allocation->ascent + allocation->descent - childBaseAllocation.ascent;
@@ -614,8 +576,7 @@ void Textblock::sizeAllocateImpl (core::Allocation *allocation)
DBG_OBJ_SET_NUM ("childBaseAllocation.ascent", childBaseAllocation.ascent);
DBG_OBJ_SET_NUM ("childBaseAllocation.descent", childBaseAllocation.descent);
- if (containingBlock->outOfFlowMgr)
- containingBlock->outOfFlowMgr->sizeAllocateStart (this, allocation);
+ sizeAllocateStart (allocation);
int lineIndex, wordIndex;
Line *line;
@@ -665,29 +626,21 @@ void Textblock::sizeAllocateImpl (core::Allocation *allocation)
"allocating widget in flow: line %d, word %d",
lineIndex, wordIndex);
- childAllocation.x = xCursor + childBaseAllocation.x;
-
- DBG_OBJ_MSGF ("resize", 1, "childAllocation.x = %d + %d = %d",
- xCursor, childBaseAllocation.x, childAllocation.x);
+ // TODO For word->flags & Word::TOPLEFT_OF_LINE, make
+ // allocation consistent with calcSizeOfWidgetInFlow():
+ childAllocation.x = xCursor + childBaseAllocation.x;
+
/** \todo Justification within the line is done here. */
-
/* align=top:
childAllocation.y = line->top + allocation->y;
*/
-
/* align=bottom (base line) */
/* Commented lines break the n2 and n3 test cases at
* http://www.dillo.org/test/img/ */
childAllocation.y = lineYOffsetCanvas (line)
+ (line->borderAscent - word->size.ascent);
- DBG_OBJ_MSGF ("resize", 1,
- "childAllocation.y = %d + (%d - %d) = %d",
- lineYOffsetCanvas (line),
- line->borderAscent, word->size.ascent,
- childAllocation.y);
-
childAllocation.width = word->size.width;
childAllocation.ascent = word->size.ascent;
childAllocation.descent = word->size.descent;
@@ -755,9 +708,8 @@ void Textblock::sizeAllocateImpl (core::Allocation *allocation)
DBG_OBJ_MSG_END ();
- if (containingBlock->outOfFlowMgr)
- containingBlock->outOfFlowMgr->sizeAllocateEnd (this);
-
+ sizeAllocateEnd ();
+
for (int i = 0; i < anchors->size(); i++) {
Anchor *anchor = anchors->getRef(i);
int y;
@@ -777,32 +729,52 @@ void Textblock::sizeAllocateImpl (core::Allocation *allocation)
DBG_OBJ_LEAVE ();
}
+void Textblock::calcExtraSpaceImpl ()
+{
+ OOFAwareWidget::calcExtraSpaceImpl ();
+
+ int clearPosition = 0;
+ for (int i = 0; i < NUM_OOFM; i++)
+ if (searchOutOfFlowMgr (i))
+ clearPosition =
+ misc::max (clearPosition,
+ searchOutOfFlowMgr(i)->getClearPosition (this));
+
+ extraSpace.top = misc::max (extraSpace.top, clearPosition);
+}
+
int Textblock::getAvailWidthOfChild (Widget *child, bool forceValue)
{
- DBG_OBJ_ENTER ("resize", 0, "Textblock/getAvailWidthOfChild", "%p, %s",
+ DBG_OBJ_ENTER ("resize", 0, "Textblock::getAvailWidthOfChild", "%p, %s",
child, forceValue ? "true" : "false");
int width;
- if (child->getStyle()->width == core::style::LENGTH_AUTO) {
- // No width specified: similar to standard implementation (see
- // there), but "leftInnerPadding" has to be considered, too.
- DBG_OBJ_MSG ("resize", 1, "no specification");
- if (forceValue)
- width = misc::max (getAvailWidth (true) - boxDiffWidth ()
- - leftInnerPadding,
- 0);
- else
- width = -1;
- } else
- width = Widget::getAvailWidthOfChild (child, forceValue);
-
- if (forceValue && this == child->getContainer () &&
- !mustBeWidenedToAvailWidth ()) {
- core::Extremes extremes;
- getExtremes (&extremes);
- if (width > extremes.maxWidth - boxDiffWidth () - leftInnerPadding)
- width = extremes.maxWidth - boxDiffWidth () - leftInnerPadding;
+ if (isWidgetOOF (child) && getWidgetOutOfFlowMgr(child) &&
+ getWidgetOutOfFlowMgr(child)->dealingWithSizeOfChild (child))
+ width =
+ getWidgetOutOfFlowMgr(child)->getAvailWidthOfChild (child,forceValue);
+ else {
+ if (child->getStyle()->width == core::style::LENGTH_AUTO) {
+ // No width specified: similar to standard implementation (see
+ // there), but "leftInnerPadding" has to be considered, too.
+ DBG_OBJ_MSG ("resize", 1, "no specification");
+ if (forceValue)
+ width = misc::max (getAvailWidth (true) - boxDiffWidth ()
+ - leftInnerPadding,
+ 0);
+ else
+ width = -1;
+ } else
+ width = Widget::getAvailWidthOfChild (child, forceValue);
+
+ if (forceValue && this == child->getContainer () &&
+ !mustBeWidenedToAvailWidth ()) {
+ core::Extremes extremes;
+ getExtremes (&extremes);
+ if (width > extremes.maxWidth - boxDiffWidth () - leftInnerPadding)
+ width = extremes.maxWidth - boxDiffWidth () - leftInnerPadding;
+ }
}
DBG_OBJ_MSGF ("resize", 1, "=> %d", width);
@@ -810,7 +782,15 @@ int Textblock::getAvailWidthOfChild (Widget *child, bool forceValue)
return width;
}
-
+int Textblock::getAvailHeightOfChild (core::Widget *child, bool forceValue)
+{
+ if (isWidgetOOF(child) && getWidgetOutOfFlowMgr(child) &&
+ getWidgetOutOfFlowMgr(child)->dealingWithSizeOfChild (child))
+ return getWidgetOutOfFlowMgr(child)->getAvailHeightOfChild (child,
+ forceValue);
+ else
+ return Widget::getAvailHeightOfChild (child, forceValue);
+}
void Textblock::containerSizeChangedForChildren ()
{
@@ -822,9 +802,8 @@ void Textblock::containerSizeChangedForChildren ()
word->content.widget->containerSizeChanged ();
}
- if (outOfFlowMgr)
- outOfFlowMgr->containerSizeChangedForChildren ();
-
+ containerSizeChangedForChildrenOOF ();
+
DBG_OBJ_LEAVE ();
}
@@ -833,7 +812,7 @@ bool Textblock::affectsSizeChangeContainerChild (Widget *child)
DBG_OBJ_ENTER ("resize", 0,
"Textblock/affectsSizeChangeContainerChild", "%p", child);
- // See Textblock::getAvailWidthForChild() and Textblock::oofSizeChanged():
+ // See Textblock::getAvailWidthOfChild() and Textblock::oofSizeChanged():
// Extremes changes affect the size of the child, too:
bool ret;
if (!mustBeWidenedToAvailWidth () &&
@@ -876,13 +855,10 @@ void Textblock::markSizeChange (int ref)
{
DBG_OBJ_ENTER ("resize", 0, "markSizeChange", "%d", ref);
- if (OutOfFlowMgr::isRefOutOfFlow (ref)) {
- assert (outOfFlowMgr != NULL);
- outOfFlowMgr->markSizeChange (ref);
- } else {
- PRINTF ("[%p] MARK_SIZE_CHANGE (%d): %d => ...\n",
- this, ref, wrapRefLines);
-
+ if (isParentRefOOF (ref))
+ getParentRefOutOfFlowMgr(ref)
+ ->markSizeChange (getParentRefOOFSubRef (ref));
+ else {
/* 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
@@ -890,10 +866,10 @@ void Textblock::markSizeChange (int ref)
now, but addLine(...) will do everything necessary. */
if (ref != -1) {
if (wrapRefLines == -1)
- wrapRefLines = OutOfFlowMgr::getLineNoFromRef (ref);
+ wrapRefLines = getParentRefInFlowSubRef (ref);
else
wrapRefLines = misc::min (wrapRefLines,
- OutOfFlowMgr::getLineNoFromRef (ref));
+ getParentRefInFlowSubRef (ref));
}
DBG_OBJ_SET_NUM ("wrapRefLines", wrapRefLines);
@@ -913,13 +889,10 @@ void Textblock::markExtremesChange (int ref)
{
DBG_OBJ_ENTER ("resize", 1, "markExtremesChange", "%d", ref);
- if (OutOfFlowMgr::isRefOutOfFlow (ref)) {
- assert (outOfFlowMgr != NULL);
- outOfFlowMgr->markExtremesChange (ref);
- } else {
- PRINTF ("[%p] MARK_EXTREMES_CHANGE (%d): %d => ...\n",
- this, ref, wrapRefParagraphs);
-
+ if (isParentRefOOF (ref))
+ getParentRefOutOfFlowMgr(ref)
+ ->markExtremesChange (getParentRefOOFSubRef (ref));
+ else {
/* 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
@@ -927,11 +900,10 @@ void Textblock::markExtremesChange (int ref)
now, but addLine(...) will do everything necessary. */
if (ref != -1) {
if (wrapRefParagraphs == -1)
- wrapRefParagraphs = OutOfFlowMgr::getLineNoFromRef (ref);
+ wrapRefParagraphs = getParentRefInFlowSubRef (ref);
else
wrapRefParagraphs =
- misc::min (wrapRefParagraphs,
- OutOfFlowMgr::getLineNoFromRef (ref));
+ misc::min (wrapRefParagraphs, getParentRefInFlowSubRef (ref));
}
DBG_OBJ_SET_NUM ("wrapRefParagraphs", wrapRefParagraphs);
@@ -940,61 +912,6 @@ void Textblock::markExtremesChange (int ref)
DBG_OBJ_LEAVE ();
}
-void Textblock::notifySetAsTopLevel()
-{
- PRINTF ("%p becomes toplevel\n", this);
- containingBlock = this;
- PRINTF ("-> %p is its own containing block\n", this);
-}
-
-bool Textblock::isContainingBlock (Widget *widget)
-{
- return
- // Of course, only textblocks are considered as containing
- // blocks.
- widget->instanceOf (Textblock::CLASS_ID) &&
- // The second condition: that this block is "out of flow", in a
- // wider sense.
- (// The toplevel widget is "out of flow", since there is no
- // parent, and so no context.
- widget->getParent() == NULL ||
- // A similar reasoning applies to a widget with another parent
- // than a textblock (typical example: a table cell (this is
- // also a text block) within a table widget).
- !widget->getParent()->instanceOf (Textblock::CLASS_ID) ||
- // Inline blocks are containing blocks, too.
- widget->getStyle()->display == core::style::DISPLAY_INLINE_BLOCK ||
- // Same for blocks with 'overview' set to another value than
- // (the default value) 'visible'.
- widget->getStyle()->overflow != core::style::OVERFLOW_VISIBLE ||
- // Finally, "out of flow" in a narrower sense: floats and
- // absolute positions.
- OutOfFlowMgr::isWidgetOutOfFlow (widget));
-}
-
-void Textblock::notifySetParent ()
-{
- PRINTF ("%p becomes a child of %p\n", this, getParent());
-
- // Search for containing Box.
- containingBlock = NULL;
-
- for (Widget *widget = this; widget != NULL && containingBlock == NULL;
- widget = widget->getParent())
- if (isContainingBlock (widget)) {
- containingBlock = (Textblock*)widget;
-
- if (containingBlock == this) {
- PRINTF ("-> %p is its own containing block\n", this);
- } else {
- PRINTF ("-> %p becomes containing block of %p\n",
- containingBlock, this);
- }
- }
-
- assert (containingBlock != NULL);
-}
-
bool Textblock::isBlockLevel ()
{
return true;
@@ -1084,6 +1001,8 @@ void Textblock::leaveNotifyImpl (core::EventCrossing *event)
bool Textblock::sendSelectionEvent (core::SelectionState::EventType eventType,
core::MousePositionEvent *event)
{
+ DBG_OBJ_ENTER0 ("events", 0, "sendSelectionEvent");
+
core::Iterator *it;
int wordIndex;
int charPos = 0, link = -1;
@@ -1213,11 +1132,17 @@ bool Textblock::sendSelectionEvent (core::SelectionState::EventType eventType,
}
}
}
-
- it = new TextblockIterator (this, core::Content::maskForSelection (true),
- false, wordIndex);
+
+ DBG_OBJ_MSGF ("events", 1, "wordIndex = %d", wordIndex);
+ DBG_MSG_WORD ("events", 1, "<i>this is:</i> ", wordIndex, "");
+
+ it = TextblockIterator::createWordIndexIterator
+ (this, core::Content::maskForSelection (true), wordIndex);
r = selectionHandleEvent (eventType, it, charPos, link, event);
it->unref ();
+
+ DBG_OBJ_MSGF ("events", 1, "=> %s", r ? "true" : "false");
+ DBG_OBJ_LEAVE ();
return r;
}
@@ -1538,24 +1463,29 @@ void Textblock::drawSpace(int wordIndex, core::View *view,
* - area is used always (ev. set it to event->area)
* - event is only used when is_expose
*/
-void Textblock::drawLine (Line *line, core::View *view, core::Rectangle *area)
+void Textblock::drawLine (Line *line, core::View *view, core::Rectangle *area,
+ core::DrawingContext *context)
{
- DBG_OBJ_ENTER ("draw", 0, "drawLine", "..., %d, %d, %d * %d",
+ DBG_OBJ_ENTER ("draw", 0, "drawLine", "..., [%d, %d, %d * %d]",
area->x, area->y, area->width, area->height);
-
+
int xWidget = line->textOffset;
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 (),
xWidget, yWidgetBase);
- DBG_MSG_WORD ("draw", 0, "<i>line starts with: </i>", line->firstWord, "");
- DBG_MSG_WORD ("draw", 0, "<i>line ends with: </i>", line->lastWord, "");
+ DBG_MSG_WORD ("draw", 1, "<i>line starts with: </i>", line->firstWord, "");
+ DBG_MSG_WORD ("draw", 1, "<i>line ends with: </i>", line->lastWord, "");
+
+ DBG_OBJ_MSG_START ();
for (int wordIndex = line->firstWord;
wordIndex <= line->lastWord && xWidget < area->x + area->width;
wordIndex++) {
- Word *word = words->getRef(wordIndex);
+ DBG_MSG_WORD ("draw", 2, "<i>drawing: </i>", wordIndex, "");
+
+ Word *word = words->getRef (wordIndex);
int wordSize = word->size.width;
if (xWidget + wordSize + word->hyphenWidth + word->effSpace >= area->x) {
@@ -1566,9 +1496,10 @@ void Textblock::drawLine (Line *line, core::View *view, core::Rectangle *area)
if (word->content.type == core::Content::WIDGET_IN_FLOW) {
core::Widget *child = word->content.widget;
core::Rectangle childArea;
-
- if (child->intersects (area, &childArea))
- child->draw (view, &childArea);
+ if (!core::StackingContextMgr::handledByStackingContextMgr
+ (child) &&
+ child->intersects (this, area, &childArea))
+ child->draw (view, &childArea, context);
} else {
int wordIndex2 = wordIndex;
while (wordIndex2 < line->lastWord &&
@@ -1596,8 +1527,8 @@ void Textblock::drawLine (Line *line, core::View *view, core::Rectangle *area)
xWidget + wordSize,
yWidgetBase - line->borderAscent, word->effSpace,
line->borderAscent + line->borderDescent, false);
- drawSpace(wordIndex, view, area, xWidget + wordSize,
- yWidgetBase);
+ drawSpace (wordIndex, view, area, xWidget + wordSize,
+ yWidgetBase);
}
}
@@ -1605,6 +1536,8 @@ void Textblock::drawLine (Line *line, core::View *view, core::Rectangle *area)
xWidget += wordSize + word->effSpace;
}
+ DBG_OBJ_MSG_END ();
+
DBG_OBJ_LEAVE ();
}
@@ -1626,7 +1559,8 @@ int Textblock::findLineIndexWhenNotAllocated (int y)
return
findLineIndex (y, calcVerticalBorder (getStyle()->padding.top,
getStyle()->borderWidth.top,
- getStyle()->margin.top,
+ getStyle()->margin.top
+ + extraSpace.top,
lines->getRef(0)->borderAscent,
lines->getRef(0)->marginAscent));
}
@@ -1772,38 +1706,45 @@ Textblock::Word *Textblock::findWord (int x, int y, bool *inSpace)
return NULL;
}
-void Textblock::draw (core::View *view, core::Rectangle *area)
+void Textblock::drawLevel (core::View *view, core::Rectangle *area,
+ int level, core::DrawingContext *context)
{
- DBG_OBJ_ENTER ("draw", 0, "draw", "%d, %d, %d * %d",
- area->x, area->y, area->width, area->height);
-
- int lineIndex;
- Line *line;
+ DBG_OBJ_ENTER ("draw", 0, "Textblock::drawLevel", "(%d, %d, %d * %d), %s",
+ area->x, area->y, area->width, area->height,
+ stackingLevelText (level));
- // Instead of drawWidgetBox, use drawBox to include verticalOffset.
- if (getParent() == NULL) {
- // The toplevel (parent == NULL) widget is a special case, which
- // we leave to drawWidgetBox; verticalOffset will here always 0.
- assert (verticalOffset == 0);
- drawWidgetBox (view, area, false);
- } else
- drawBox (view, getStyle(), area, 0, verticalOffset, allocation.width,
- getHeight() - verticalOffset, false);
+ switch (level) {
+ case SL_IN_FLOW:
+ for (int lineIndex = findLineIndexWhenAllocated (area->y);
+ lineIndex < lines->size (); lineIndex++) {
+ Line *line = lines->getRef (lineIndex);
+ if (lineYOffsetWidget (line) >= area->y + area->height)
+ break;
- lineIndex = findLineIndexWhenAllocated (area->y);
+ DBG_OBJ_MSGF ("draw", 0, "line %d (of %d)", lineIndex, lines->size ());
+ drawLine (line, view, area, context);
+ }
+ break;
- for (; lineIndex < lines->size (); lineIndex++) {
- line = lines->getRef (lineIndex);
- if (lineYOffsetWidget (line) >= area->y + area->height)
- break;
+ case SL_OOF_REF:
+ // TODO Inefficient. Perhaps store OOF references in seperate
+ // (much smaller!) list.
+ for (int oofmIndex = 0; oofmIndex < NUM_OOFM; oofmIndex++) {
+ for (int wordIndex = 0; wordIndex < words->size (); wordIndex++) {
+ Word *word = words->getRef (wordIndex);
+ if (word->content.type == core::Content::WIDGET_OOF_REF &&
+ getOOFMIndex (word->content.widget) == oofmIndex &&
+ doesWidgetOOFInterruptDrawing (word->content.widget))
+ word->content.widget->drawInterruption (view, area, context);
+ }
+ }
+ break;
- DBG_OBJ_MSGF ("draw", 0, "line %d (of %d)", lineIndex, lines->size ());
- drawLine (line, view, area);
+ default:
+ OOFAwareWidget::drawLevel (view, area, level, context);
+ break;
}
- if(outOfFlowMgr)
- outOfFlowMgr->draw(view, area);
-
DBG_OBJ_LEAVE ();
}
@@ -1914,6 +1855,7 @@ void Textblock::fillWord (int wordNo, int width, int ascent, int descent,
word->size.width = width;
word->size.ascent = ascent;
word->size.descent = descent;
+ DBG_SET_WORD_SIZE (wordNo);
word->origSpace = word->effSpace = 0;
word->hyphenWidth = 0;
word->badnessAndPenalty.setPenalty (PENALTY_PROHIBIT_BREAK);
@@ -2304,15 +2246,70 @@ void Textblock::calcTextSizes (const char *text, size_t textLen,
}
/**
+ * Calculate the size of a widget, and return whether it has to be
+ * positioned at the top of the line.
+ */
+bool Textblock::calcSizeOfWidgetInFlow (int wordIndex, Widget *widget,
+ core::Requisition *size)
+{
+ DBG_OBJ_ENTER ("resize", 0, "calcSizeOfWidgetInFlow", "%d, %p, ...",
+ wordIndex, widget);
+
+ int lastWord = lines->empty () ? -1 : lines->getLastRef()->lastWord;
+ assert (wordIndex > lastWord);
+ bool result;
+
+ Widget *reference = widget->sizeRequestReference ();
+
+ if (reference == NULL) {
+ widget->sizeRequest (size);
+ result = false;
+ } else {
+ assert (getParent () == NULL || sizeRequestPosDefined);
+ assert
+ (wordIndex == 0 ||
+ words->getRef(wordIndex - 1)->content.type == core::Content::BREAK);
+ assert (reference == oofContainer[OOFM_FLOATS]);
+
+ // The following assertion is always the case in dillo, and
+ // plausible (since floats are the reason why the size depends
+ // on the position); and it simplifies the calculation of x
+ // below.
+ assert (widget->instanceOf (RegardingBorder::CLASS_ID) &&
+ !isOOFContainer (widget, OOFM_FLOATS));
+
+ int xRef, yRef;
+ if (getParent () == NULL)
+ xRef = yRef = 0;
+ else {
+ xRef = sizeRequestX;
+ yRef = sizeRequestY;
+ }
+
+ int x = xRef + boxOffsetX () + leftInnerPadding
+ + (lines->size () == 0 ? line1OffsetEff : 0);
+ int lastMargin, yLine = yOffsetOfLineToBeCreated (&lastMargin);
+ int y = yRef + yLine - lastMargin
+ + max (lastMargin, widget->getStyle()->margin.top);
+
+ widget->sizeRequest (size, true, x, y);
+
+ result = true;
+ }
+
+ DBG_OBJ_LEAVE_VAL ("%s", boolToStr (result));
+ return result;
+}
+
+/**
* Add a word (without hyphens) to the page structure.
*/
void Textblock::addText0 (const char *text, size_t len, short flags,
core::style::Style *style, core::Requisition *size)
{
DBG_OBJ_ENTER ("construct.word", 0, "addText0",
- "..., %d, %s:%s:%s:%s:%s:%s:%s, %p, %d * (%d + %d)",
+ "..., %d, %s:%s:%s:%s:%s:%s:%s:%s, %p, %d * (%d + %d)",
(int)len,
- // Ugly copy&paste from printWordFlags:
(flags & Word::CAN_BE_HYPHENATED) ? "h?" : "--",
(flags & Word::DIV_CHAR_AT_EOL) ? "de" : "--",
(flags & Word::PERM_DIV_CHAR) ? "dp" : "--",
@@ -2320,6 +2317,7 @@ void Textblock::addText0 (const char *text, size_t len, short flags,
(flags & Word::UNBREAKABLE_FOR_MIN_WIDTH) ? "um" : "--",
(flags & Word::WORD_START) ? "st" : "--",
(flags & Word::WORD_END) ? "en" : "--",
+ (flags & Word::TOPLEFT_OF_LINE) ? "00" : "--",
style, size->width, size->ascent, size->descent);
//printf("[%p] addText0 ('", this);
@@ -2364,22 +2362,26 @@ void Textblock::addWidget (core::Widget *widget, core::style::Style *style)
widget->setStyle (style);
- PRINTF ("adding the %s %p to %p (word %d) ...\n",
- widget->getClassName(), widget, this, words->size());
-
- if (containingBlock->outOfFlowMgr == NULL) {
- containingBlock->outOfFlowMgr = new OutOfFlowMgr (containingBlock);
- DBG_OBJ_ASSOC (containingBlock, containingBlock->outOfFlowMgr);
- }
+ initOutOfFlowMgrs ();
- if (OutOfFlowMgr::isWidgetOutOfFlow (widget)) {
- PRINTF (" -> out of flow.\n");
+ if (testWidgetOutOfFlow (widget)) {
+ int oofmIndex = getOOFMIndex (widget);
+ DBG_OBJ_MSGF ("construct.word", 1, "ouf of flow: oofmIndex = %d (%s)",
+ oofmIndex, OOFM_NAME[oofmIndex]);
- widget->setParent (containingBlock);
+ widget->setParent (oofContainer[oofmIndex]);
widget->setGenerator (this);
- containingBlock->outOfFlowMgr->addWidgetOOF (widget, this,
- words->size ());
- Word *word = addWord (0, 0, 0, 0, style);
+
+ oof::OutOfFlowMgr *oofm = searchOutOfFlowMgr (oofmIndex);
+ int oofmSubRef = oofm->addWidgetOOF (widget, this, words->size ());
+ widget->parentRef = makeParentRefOOF (oofmIndex, oofmSubRef);
+
+ DBG_OBJ_MSGF ("construct.word", 1, "oofmSubRef = %d => parentRef = %d",
+ oofmSubRef, widget->parentRef);
+
+ core::Requisition size;
+ oofm->calcWidgetRefSize (widget, &size);
+ Word *word = addWord (size.width, size.ascent, size.descent, 0, style);
word->content.type = core::Content::WIDGET_OOF_REF;
word->content.widget = widget;
@@ -2387,18 +2389,22 @@ void Textblock::addWidget (core::Widget *widget, core::style::Style *style)
// problems with breaking near float definitions.)
setBreakOption (word, style, 0, 0, false);
} else {
- PRINTF (" -> within flow.\n");
+ DBG_OBJ_MSG ("construct.word", 1, "in flow");
widget->setParent (this);
// TODO Replace (perhaps) later "textblock" by "OOF aware widget".
- if (widget->instanceOf (Textblock::CLASS_ID))
- containingBlock->outOfFlowMgr->addWidgetInFlow ((Textblock*)widget,
- this, words->size ());
+ if (widget->instanceOf (Textblock::CLASS_ID)) {
+ for (int i = 0; i < NUM_OOFM; i++)
+ searchOutOfFlowMgr(i)->addWidgetInFlow ((Textblock*)widget, this,
+ words->size ());
+ }
core::Requisition size;
- widget->sizeRequest (&size);
- Word *word = addWord (size.width, size.ascent, size.descent, 0, style);
+ short flags = calcSizeOfWidgetInFlow (words->size (), widget, &size) ?
+ Word::TOPLEFT_OF_LINE : 0;
+ Word *word =
+ addWord (size.width, size.ascent, size.descent, flags, style);
word->content.type = core::Content::WIDGET_IN_FLOW;
word->content.widget = widget;
}
@@ -2632,7 +2638,7 @@ void Textblock::addParbreak (int space, core::style::Style *style)
for (Widget *widget = this;
widget->getParent() != NULL &&
widget->getParent()->instanceOf (Textblock::CLASS_ID) &&
- !OutOfFlowMgr::isRefOutOfFlow (widget->parentRef);
+ !isWidgetOOF (widget);
widget = widget->getParent ()) {
Textblock *textblock2 = (Textblock*)widget->getParent ();
int index = textblock2->hasListitemValue ? 1 : 0;
@@ -2643,7 +2649,7 @@ void Textblock::addParbreak (int space, core::style::Style *style)
if (!isfirst) {
/* The text block we searched for has been found. */
Word *word2;
- int lineno = OutOfFlowMgr::getLineNoFromRef (widget->parentRef);
+ int lineno = getWidgetInFlowSubRef (widget);
if (lineno > 0 &&
(word2 =
@@ -2652,8 +2658,7 @@ void Textblock::addParbreak (int space, core::style::Style *style)
word2->content.type == core::Content::BREAK) {
if (word2->content.breakSpace < space) {
word2->content.breakSpace = space;
- textblock2->queueResize
- (OutOfFlowMgr::createRefNormalFlow (lineno), false);
+ textblock2->queueResize (makeParentRefInFlow (lineno), false);
textblock2->mustQueueResize = false;
}
}
@@ -2752,63 +2757,66 @@ void Textblock::breakAdded ()
words->getRef(words->size () - 2)->effSpace = 0;
}
-/**
- * \brief Search recursively through widget.
- *
- * This is an optimized version of the general
- * dw::core::Widget::getWidgetAtPoint method.
- */
-core::Widget *Textblock::getWidgetAtPoint(int x, int y, int level)
-{
- //printf ("%*s-> examining the %s %p (%d, %d, %d x (%d + %d))\n",
- // 3 * level, "", getClassName (), this, allocation.x, allocation.y,
- // allocation.width, allocation.ascent, allocation.descent);
-
- int lineIndex, wordIndex;
- Line *line;
-
- if (x < allocation.x ||
- y < allocation.y ||
- x > allocation.x + allocation.width ||
- y > allocation.y + getHeight ()) {
- return NULL;
- }
-
- // First, search for widgets out of flow, notably floats, since
- // there are cases where they overlap child textblocks. Should
- // later be refined using z-index.
- Widget *oofWidget =
- outOfFlowMgr ? outOfFlowMgr->getWidgetAtPoint (x, y, level) : NULL;
- if (oofWidget)
- return oofWidget;
-
- lineIndex = findLineIndexWhenAllocated (y - allocation.y);
-
- if (lineIndex < 0 || lineIndex >= lines->size ()) {
- return this;
- }
-
- line = lines->getRef (lineIndex);
-
- for (wordIndex = line->firstWord; wordIndex <= line->lastWord;wordIndex++) {
- Word *word = words->getRef (wordIndex);
-
- if (word->content.type == core::Content::WIDGET_IN_FLOW) {
- core::Widget * childAtPoint;
- if (word->content.widget->wasAllocated ()) {
- childAtPoint = word->content.widget->getWidgetAtPoint (x, y,
- level + 1);
- if (childAtPoint) {
- return childAtPoint;
+core::Widget *Textblock::getWidgetAtPointLevel (int x, int y, int level,
+ core::GettingWidgetAtPointContext
+ *context)
+{
+ DBG_OBJ_ENTER ("events", 0, "Textblock::getWidgetAtPointLevel", "%d, %d, %s",
+ x, y, stackingLevelText (level));
+
+ Widget *widgetAtPoint = NULL;
+
+ switch (level) {
+ case SL_IN_FLOW:
+ {
+ int lineIndex = findLineIndexWhenAllocated (y - allocation.y);
+
+ if (lineIndex >= 0 && lineIndex < lines->size ()) {
+ Line *line = lines->getRef (lineIndex);
+
+ for (int wordIndex = line->lastWord;
+ widgetAtPoint == NULL && wordIndex >= line->firstWord;
+ wordIndex--) {
+ Word *word = words->getRef (wordIndex);
+ if (word->content.type == core::Content::WIDGET_IN_FLOW &&
+ !core::StackingContextMgr::handledByStackingContextMgr
+ (word->content.widget))
+ widgetAtPoint =
+ word->content.widget->getWidgetAtPoint (x, y, context);
}
}
}
+ break;
+
+ case SL_OOF_REF:
+ // TODO Inefficient. Perhaps store OOF references in seperate
+ // (much smaller!) list.
+ for (int oofmIndex = NUM_OOFM; widgetAtPoint == NULL && oofmIndex >= 0;
+ oofmIndex--) {
+ for (int wordIndex = words->size () - 1;
+ widgetAtPoint == NULL && wordIndex >= 0; wordIndex--) {
+ Word *word = words->getRef (wordIndex);
+ if (word->content.type == core::Content::WIDGET_OOF_REF &&
+ getOOFMIndex (word->content.widget) == oofmIndex &&
+ doesWidgetOOFInterruptDrawing (word->content.widget))
+ widgetAtPoint =
+ word->content.widget->getWidgetAtPointInterrupted (x, y,
+ context);
+ }
+ }
+ break;
+
+ default:
+ widgetAtPoint =
+ OOFAwareWidget::getWidgetAtPointLevel (x, y, level, context);
+ break;
}
- return this;
+ DBG_OBJ_MSGF ("events", 1, "=> %p", widgetAtPoint);
+ DBG_OBJ_LEAVE ();
+ return widgetAtPoint;
}
-
/**
* This function "hands" the last break of a page "over" to a parent
* page. This is used for "collapsing spaces".
@@ -2909,6 +2917,8 @@ void Textblock::changeWordStyle (int from, int to, core::style::Style *style,
void Textblock::queueDrawRange (int index1, int index2)
{
+ DBG_OBJ_ENTER ("draw", 0, "queueDrawRange", "%d, %d", index1, index2);
+
int from = misc::min (index1, index2);
int to = misc::max (index1, index2);
@@ -2930,18 +2940,6 @@ void Textblock::queueDrawRange (int index1, int index2)
queueDrawArea (0, y, allocation.width, h);
}
-}
-
-void Textblock::setVerticalOffset (int verticalOffset)
-{
- DBG_OBJ_ENTER ("resize", 0, "setVerticalOffset", "%d", verticalOffset);
-
- if (this->verticalOffset != verticalOffset) {
- this->verticalOffset = verticalOffset;
- DBG_OBJ_SET_NUM ("verticalOffset", verticalOffset);
- mustQueueResize = true;
- queueDraw (); // Could perhaps be optimized.
- }
DBG_OBJ_LEAVE ();
}
@@ -2951,18 +2949,24 @@ bool Textblock::mustBeWidenedToAvailWidth ()
DBG_OBJ_ENTER0 ("resize", 0, "mustBeWidenedToAvailWidth");
bool toplevel = getParent () == NULL,
block = getStyle()->display == core::style::DISPLAY_BLOCK,
- vloat = getStyle()->vloat != core::style::FLOAT_NONE,
- result = toplevel || (block && !vloat);
+ vloat = testWidgetFloat (this),
+ abspos = testWidgetAbsolutelyPositioned (this),
+ fixpos = testWidgetFixedlyPositioned (this),
+ // In detail, this depends on what the respective OOFM does
+ // with the child widget:
+ result = toplevel || (block && !(vloat || abspos || fixpos));
DBG_OBJ_MSGF ("resize", 0,
- "=> %s (toplevel: %s, block: %s, float: %s)",
+ "=> %s (toplevel: %s, block: %s, float: %s, abspos: %s, "
+ "fixpos: %s)",
result ? "true" : "false", toplevel ? "true" : "false",
- block ? "true" : "false", vloat ? "true" : "false");
+ block ? "true" : "false", vloat ? "true" : "false",
+ abspos ? "true" : "false", fixpos ? "true" : "false");
DBG_OBJ_LEAVE ();
return result;
}
/**
- * Called by dw::OutOfFlowMgr when the border has changed due to a
+ * Called by dw::OOFFloatsMgr when the border has changed due to a
* float (or some floats).
*
* "y", which given in widget coordinates, denotes the minimal
@@ -3091,7 +3095,7 @@ void Textblock::borderChanged (int y, Widget *vloat)
minWrapLineIndex, maxWrapLineIndex,
vloat->getGenerator() == this ? "yes" : "no");
- queueResize (OutOfFlowMgr::createRefNormalFlow (realWrapLineIndex), true);
+ queueResize (makeParentRefInFlow (realWrapLineIndex), true);
// Notice that the line no. realWrapLineIndex may not exist yet.
if (realWrapLineIndex == 0)
@@ -3112,6 +3116,13 @@ void Textblock::borderChanged (int y, Widget *vloat)
DBG_OBJ_LEAVE ();
}
+void Textblock::widgetRefSizeChanged (int externalIndex)
+{
+ int lineNo = findLineOfWord (externalIndex);
+ if (lineNo >= 0 && lineNo < lines->size ())
+ queueResize (makeParentRefInFlow (lineNo), true);
+}
+
void Textblock::clearPositionChanged ()
{
DBG_OBJ_ENTER0 ("resize", 0, "clearPositionChanged");
@@ -3127,7 +3138,7 @@ void Textblock::oofSizeChanged (bool extremesChanged)
extremesChanged ? "true" : "false");
queueResize (-1, extremesChanged);
- // See Textblock::getAvailWidthForChild(): Extremes changes may become also
+ // See Textblock::getAvailWidthOfChild(): Extremes changes may become also
// relevant for the children, under certain conditions:
if (extremesChanged && !mustBeWidenedToAvailWidth ())
containerSizeChanged ();
@@ -3135,6 +3146,21 @@ void Textblock::oofSizeChanged (bool extremesChanged)
DBG_OBJ_LEAVE ();
}
+int Textblock::getLineBreakWidth ()
+{
+ return lineBreakWidth;
+}
+
+bool Textblock::isPossibleContainer (int oofmIndex)
+{
+ return true;
+}
+
+bool Textblock::isPossibleContainerParent (int oofmIndex)
+{
+ return true;
+}
+
RegardingBorder *Textblock::getWidgetRegardingBorderForLine (Line *line)
{
return getWidgetRegardingBorderForLine (line->firstWord, line->lastWord);
@@ -3168,16 +3194,10 @@ RegardingBorder *Textblock::getWidgetRegardingBorderForLine (int firstWord,
if (word->content.type == core::Content::WIDGET_IN_FLOW) {
Widget *widget = word->content.widget;
if (widget->instanceOf (RegardingBorder::CLASS_ID) &&
- // Exclude some cases where a widget constitutes a new
- // container (see definition of float container in
- // Textblock::isContainingBlock).
- widget->getStyle()->display != core::style::DISPLAY_INLINE_BLOCK &&
- widget->getStyle()->overflow == core::style::OVERFLOW_VISIBLE)
+ // Exclude cases where a textblock constitutes a new floats
+ // container.
+ !isOOFContainer (widget, OOFM_FLOATS))
widgetRegardingBorder = (RegardingBorder*)widget;
-
- // (TODO: It would look nicer if there is one common place
- // for such definitions. Will be fixed in "dillo_grows", not
- // here.)
}
}
@@ -3189,7 +3209,7 @@ RegardingBorder *Textblock::getWidgetRegardingBorderForLine (int firstWord,
/**
* Includes margin, border, and padding.
*/
-int Textblock::yOffsetOfLineToBeCreated ()
+int Textblock::yOffsetOfLineToBeCreated (int *lastMargin)
{
// This method does not return an exact result: the position of the
// new line, which does not yet exist, cannot be calculated, since
@@ -3209,24 +3229,51 @@ int Textblock::yOffsetOfLineToBeCreated ()
int result;
if (lines->size () == 0) {
- result = verticalOffset + calcVerticalBorder (getStyle()->padding.top,
- getStyle()->borderWidth.top,
- getStyle()->margin.top,
- 0, 0);
- DBG_OBJ_MSGF ("line.yoffset", 1, "first line: ... = %d", result);
+ result = calcVerticalBorder (getStyle()->padding.top,
+ getStyle()->borderWidth.top + extraSpace.top,
+ getStyle()->margin.top, 0, 0);
+ if (lastMargin)
+ *lastMargin = getStyle()->margin.top;
} else {
Line *firstLine = lines->getRef (0), *lastLine = lines->getLastRef ();
- result = verticalOffset + calcVerticalBorder (getStyle()->padding.top,
- getStyle()->borderWidth.top,
- getStyle()->margin.top,
- firstLine->borderAscent,
- firstLine->marginAscent)
+ 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);
+ if (lastMargin)
+ *lastMargin = lastLine->marginDescent - lastLine->borderDescent;
}
- DBG_OBJ_LEAVE ();
+ if (lastMargin)
+ DBG_OBJ_LEAVE_VAL ("%d, %d", result, *lastMargin);
+ else
+ DBG_OBJ_LEAVE_VAL ("%d", result);
+
+ return result;
+}
+
+/**
+ * Includes margin, border, and padding. Can be used without allocation.
+ */
+int Textblock::yOffsetOfLineCreated (Line *line)
+{
+ // Similar applies (regarding exactness) as to yOffsetOfLineToBeCreated.
+
+ DBG_OBJ_ENTER0 ("line.yoffset", 0, "yOffsetOfLineToBeCreated");
+
+ int result;
+
+ Line *firstLine = lines->getRef (0);
+ result = calcVerticalBorder (getStyle()->padding.top,
+ getStyle()->borderWidth.top,
+ getStyle()->margin.top + extraSpace.top,
+ firstLine->borderAscent,
+ firstLine->marginAscent)
+ - firstLine->borderAscent + line->top;
+ DBG_OBJ_LEAVE_VAL ("%d", result);
return result;
}