summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dw/textblock.cc89
-rw-r--r--dw/textblock.hh15
-rw-r--r--lout/misc.hh4
3 files changed, 79 insertions, 29 deletions
diff --git a/dw/textblock.cc b/dw/textblock.cc
index 63928a35..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 {
@@ -216,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
@@ -300,6 +303,18 @@ void Textblock::sizeRequestImpl (core::Requisition *requisition,
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) {
@@ -611,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;
@@ -2245,22 +2252,53 @@ void Textblock::calcTextSizes (const char *text, size_t textLen,
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);
- return false;
+ result = false;
} else {
+ assert (getParent () == NULL || sizeRequestPosDefined);
assert
(wordIndex == 0 ||
words->getRef(wordIndex - 1)->content.type == core::Content::BREAK);
assert (reference == oofContainer[OOFM_FLOATS]);
- // TODO: x, y
- widget->sizeRequest (size, true, 0, 0);
+ // 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));
- return true;
+ 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;
}
/**
@@ -2279,7 +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::AT_TOP_OF_LINE) ? "at" : "--",
+ (flags & Word::TOPLEFT_OF_LINE) ? "00" : "--",
style, size->width, size->ascent, size->descent);
//printf("[%p] addText0 ('", this);
@@ -2364,7 +2402,7 @@ void Textblock::addWidget (core::Widget *widget, core::style::Style *style)
core::Requisition size;
short flags = calcSizeOfWidgetInFlow (words->size (), widget, &size) ?
- Word::AT_TOP_OF_LINE : 0;
+ Word::TOPLEFT_OF_LINE : 0;
Word *word =
addWord (size.width, size.ascent, size.descent, flags, style);
word->content.type = core::Content::WIDGET_IN_FLOW;
@@ -3171,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
@@ -3194,7 +3232,8 @@ int Textblock::yOffsetOfLineToBeCreated ()
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);
+ if (lastMargin)
+ *lastMargin = getStyle()->margin.top;
} else {
Line *firstLine = lines->getRef (0), *lastLine = lines->getLastRef ();
result = calcVerticalBorder (getStyle()->padding.top,
@@ -3203,10 +3242,14 @@ int Textblock::yOffsetOfLineToBeCreated ()
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;
}
diff --git a/dw/textblock.hh b/dw/textblock.hh
index e5ff87d5..6030ff63 100644
--- a/dw/textblock.hh
+++ b/dw/textblock.hh
@@ -451,11 +451,11 @@ protected:
* hyphenation) the last part of a "real" text word, this
* flag is set. Analogue to WORD_START. */
WORD_END = 1 << 6,
- /* This word is put at the top of the line. This is necessary
- * if the size of a child widget depends on the position,
- * which, on the other hand, cannot be determined before
- * the whole line is broken. */
- AT_TOP_OF_LINE = 1 << 7
+ /* This word is put at the top of the line, and at the
+ * left. This is necessary if the size of a child widget
+ * depends on the position, which, on the other hand, cannot
+ * be determined before the whole line is broken. */
+ TOPLEFT_OF_LINE = 1 << 7
};
/* TODO: perhaps add a xLeft? */
@@ -576,6 +576,9 @@ protected:
int redrawY;
int lastWordDrawn;
+ bool sizeRequestPosDefined;
+ int sizeRequestX, sizeRequestY;
+
/* This value is (currently) set by setAscent(). */
int lineBreakWidth;
@@ -762,7 +765,7 @@ protected:
int lastWord);
void printBorderChangedErrorAndAbort (int y, Widget *vloat,
int wrapLineIndex);
- int yOffsetOfLineToBeCreated ();
+ int yOffsetOfLineToBeCreated (int *lastMargin = NULL);
int yOffsetOfLineCreated (Line *line);
bool sendSelectionEvent (core::SelectionState::EventType eventType,
diff --git a/lout/misc.hh b/lout/misc.hh
index ac9e42e6..946ed821 100644
--- a/lout/misc.hh
+++ b/lout/misc.hh
@@ -120,6 +120,8 @@ public:
*/
inline int size() const { return this->num; }
+ inline bool empty() const { return size() == 0; }
+
inline T* getArray() const { return array; }
inline T* detachArray() {
@@ -380,6 +382,8 @@ public:
inline int size() const { return this->numMain + this->numExtra; }
+ inline bool empty() const { return size() == 0; }
+
inline void increase() { setSize(size() + 1); }
inline void setSize(int newSize)