aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Geerken <devnull@localhost>2015-06-08 22:18:41 +0200
committerSebastian Geerken <devnull@localhost>2015-06-08 22:18:41 +0200
commit7c8f69de8bc95c6078ee5fc0b63d263a80f31b44 (patch)
treeb495c1320496cd5ff67c56b6a07d5a79c218455b
parent826577556fa8b8eedcf1620b4104115d83dbce0b (diff)
SRDOP: Positions relative to multiple references; design now considers handling conflicts.
-rw-r--r--devdoc/dw-size-request-pos.doc85
-rw-r--r--dw/bullet.cc6
-rw-r--r--dw/bullet.hh6
-rw-r--r--dw/image.cc6
-rw-r--r--dw/image.hh6
-rw-r--r--dw/ooffloatsmgr.cc13
-rw-r--r--dw/ooffloatsmgr.hh4
-rw-r--r--dw/oofpositionedmgr.cc12
-rw-r--r--dw/oofpositionedmgr.hh5
-rw-r--r--dw/outofflowmgr.hh9
-rw-r--r--dw/ruler.cc6
-rw-r--r--dw/ruler.hh6
-rw-r--r--dw/table.cc6
-rw-r--r--dw/table.hh6
-rw-r--r--dw/textblock.cc170
-rw-r--r--dw/textblock.hh23
-rw-r--r--dw/textblock_linebreaking.cc51
-rw-r--r--dw/ui.cc5
-rw-r--r--dw/ui.hh6
-rw-r--r--dw/widget.cc53
-rw-r--r--dw/widget.hh44
-rw-r--r--test/dw_simple_container.cc6
-rw-r--r--test/dw_simple_container.hh6
23 files changed, 363 insertions, 177 deletions
diff --git a/devdoc/dw-size-request-pos.doc b/devdoc/dw-size-request-pos.doc
index dc497d00..32cc3089 100644
--- a/devdoc/dw-size-request-pos.doc
+++ b/devdoc/dw-size-request-pos.doc
@@ -6,6 +6,10 @@
dw-widget-sizes, \ref dw-grows, and **Size requisitions depending on
positions** (this document). </div>
+<div style="border: 2px solid #ff4040; margin: 1em 0;
+ padding: 0.5em 1em; background-color: #fff0f0"><b>Info:</b>
+ May not be up to date, needs a review.</div>
+
Motivation
==========
@@ -23,32 +27,57 @@ General Idea
A widget size may depend on the position relative to an anchestor
widget. If a widget wants to get the size of a child widget, it should
-1. call the new method dw::core::Widget::sizeRequestReference,
- which returns NULL, when the child's size does not depend on the
- position, or a widget relative to which the child's position must
- be calculated;
-2. call dw::core::Widget::sizeRequest with the position relative to
- this widget.
+1. call the new methods dw::core::Widget::numSizeRequestReferences and
+ dw::core::Widget::sizeRequestReference, which return all widgets
+ relative to which the child's position must be calculated;
+2. call dw::core::Widget::sizeRequest with the positions relative to
+ these widgets.
-The position passed to dw::core::Widget::sizeRequest must be the
-position at which this child will be allocated.
+All positions passed to dw::core::Widget::sizeRequest must costitute
+the position at which this child will be allocated.
There are situations where the parent widget is unable to determine
-this position before the size is known. An example: a textblock widget
-cannot determine the position of an inline widget (like an image, or
-an inline block) before the line is finished; on the other hand,
-finishing the line depends on knowing the sizes of the inline widgets.
-
-This may result in a conflict, when the size of an inline widgets
-depends on the position. Fortunately, this is not the case in dillo:
-the only widget whose size depends on the position is dw::Textblock
-(the size will depend on the position within its floats container); but
-an inline blocks constitute its own floats container, so that there is
-no dependance on a position within another widget.
-
-Generally, this case should be handled by providing a fallback
-strategy. (TODO: How does this look like? The widget is forced to
-calculate its size independant of the position?)
+these positions before the size is known. An example: a textblock
+widget cannot determine the positions of an inline widget (like an
+image, or an inline block) before the line is finished; on the other
+hand, finishing the line depends on knowing the sizes of the inline
+widgets.
+
+This may result in a conflict, when the size of an inline widget
+depends on positions. Generally, the only widget whose size depends on
+positions is dw::Textblock (the size will depend on the positions
+within its oof container, see \ref dw-out-of-flow), so this conflict
+occurs with inline blocks.
+
+This conflict is handled in different ways:
+
+1. Fortunately, this case is irrelevat for floats: an inline blocks
+ constitute its own floats container, so that there is no dependance
+ on a position within another widget.
+
+2. For positioned elements, this case is relevant, since an inline
+ block is in most cases not a container for positioned element. In
+ this case, a generator will call the methods
+ dw::oof::OutOfFlowMgr::tellIncompletePosition1 and
+ dw::oof::OutOfFlowMgr::tellIncompletePosition2, instead of
+ dw::oof::OutOfFlowMgr::tellPosition and
+ dw::oof::OutOfFlowMgr::tellPosition2, respectively. (Since this
+ case is irrelevant for floats,
+ dw::oof::OOFFloatsMgr::tellIncompletePosition1 and
+ dw::oof::OOFFloatsMgr::tellIncompletePosition2 are not implemented but
+ simply abort.)
+
+(This is not (yet) considered for borders: borders are only relevant
+for floats, but conflicts do not occur for floats.)
+
+
+Extremes
+--------
+Extremes may depend on the position in an analogue way, see:
+
+- dw::core::Widget::numGetExtremesReferences,
+- dw::core::Widget::getExtremesReference, and
+- dw::core::Widget::getExtremes.
Resizing
--------
@@ -102,4 +131,14 @@ Plan
6. Implement step 3 for positioned elements (affects only
dw::oof:OOFPositionedMgr). *INCOMPLETE.*
+
+Issues
+======
+
+- Since the signature of dw::core::Widget::sizeRequestImpl changes
+ quite often during the development of *size requisitions depending
+ on positions*, a simpler option dw::core::Widget::sizeRequestSimpl
+ has been added. May be removed again, after the design is stable.
+
+
*/
diff --git a/dw/bullet.cc b/dw/bullet.cc
index f3ce7a3b..98feb556 100644
--- a/dw/bullet.cc
+++ b/dw/bullet.cc
@@ -35,16 +35,14 @@ Bullet::~Bullet ()
DBG_OBJ_DELETE ();
}
-void Bullet::sizeRequestImpl (core::Requisition *requisition, bool posDefined,
- int x, int y)
+void Bullet::sizeRequestSimpl (core::Requisition *requisition)
{
requisition->width = lout::misc::max (getStyle()->font->xHeight * 4 / 5, 1);
requisition->ascent = lout::misc::max (getStyle()->font->xHeight, 1);
requisition->descent = 0;
}
-void Bullet::getExtremesImpl (core::Extremes *extremes, bool posDefined, int x,
- int y)
+void Bullet::getExtremesSimpl (core::Extremes *extremes)
{
extremes->minWidth = extremes->maxWidth = extremes->adjustmentWidth =
extremes->minWidthIntrinsic = extremes->maxWidthIntrinsic =
diff --git a/dw/bullet.hh b/dw/bullet.hh
index 76ea2553..ac94738e 100644
--- a/dw/bullet.hh
+++ b/dw/bullet.hh
@@ -14,10 +14,8 @@ namespace dw {
class Bullet: public core::Widget
{
protected:
- void sizeRequestImpl (core::Requisition *requisition, bool posDefined, int x,
- int y);
- void getExtremesImpl (core::Extremes *extremes, bool posDefined, int x,
- int y);
+ void sizeRequestSimpl (core::Requisition *requisition);
+ void getExtremesSimpl (core::Extremes *extremes);
void containerSizeChangedForChildren ();
void draw (core::View *view, core::Rectangle *area,
core::DrawingContext *context);
diff --git a/dw/image.cc b/dw/image.cc
index 77d87a61..519b82bb 100644
--- a/dw/image.cc
+++ b/dw/image.cc
@@ -172,8 +172,7 @@ Image::~Image()
DBG_OBJ_DELETE ();
}
-void Image::sizeRequestImpl (core::Requisition *requisition, bool posDefined,
- int x, int y)
+void Image::sizeRequestSimpl (core::Requisition *requisition)
{
DBG_OBJ_ENTER0 ("resize", 0, "sizeRequestImpl");
@@ -238,8 +237,7 @@ void Image::sizeRequestImpl (core::Requisition *requisition, bool posDefined,
DBG_OBJ_LEAVE ();
}
-void Image::getExtremesImpl (core::Extremes *extremes, bool posDefined, int x,
- int y)
+void Image::getExtremesSimpl (core::Extremes *extremes)
{
int contentWidth;
if (buffer)
diff --git a/dw/image.hh b/dw/image.hh
index 1de315bd..ae47f307 100644
--- a/dw/image.hh
+++ b/dw/image.hh
@@ -130,10 +130,8 @@ private:
bool isMap;
protected:
- void sizeRequestImpl (core::Requisition *requisition, bool posDefined, int x,
- int y);
- void getExtremesImpl (core::Extremes *extremes, bool posDefined, int x,
- int y);
+ void sizeRequestSimpl (core::Requisition *requisition);
+ void getExtremesSimpl (core::Extremes *extremes);
void sizeAllocateImpl (core::Allocation *allocation);
void containerSizeChangedForChildren ();
diff --git a/dw/ooffloatsmgr.cc b/dw/ooffloatsmgr.cc
index 10e72bae..e804138c 100644
--- a/dw/ooffloatsmgr.cc
+++ b/dw/ooffloatsmgr.cc
@@ -1608,6 +1608,19 @@ void OOFFloatsMgr::tellPosition1 (Widget *widget, int x, int y)
void OOFFloatsMgr::tellPosition2 (Widget *widget, int x, int y)
{
+ // Nothing to do.
+}
+
+void OOFFloatsMgr::tellIncompletePosition1 (Widget *generator, Widget *widget,
+ int x, int y)
+{
+ assertNotReached ();
+}
+
+void OOFFloatsMgr::tellIncompletePosition2 (Widget *generator, Widget *widget,
+ int x, int y)
+{
+ assertNotReached ();
}
bool OOFFloatsMgr::collidesV (Float *vloat, Float *other, SFVType type,
diff --git a/dw/ooffloatsmgr.hh b/dw/ooffloatsmgr.hh
index 1a66e2ff..c30ac172 100644
--- a/dw/ooffloatsmgr.hh
+++ b/dw/ooffloatsmgr.hh
@@ -360,6 +360,10 @@ public:
void tellPosition1 (core::Widget *widget, int x, int y);
void tellPosition2 (core::Widget *widget, int x, int y);
+ void tellIncompletePosition1 (core::Widget *generator, core::Widget *widget,
+ int x, int y);
+ void tellIncompletePosition2 (core::Widget *generator, core::Widget *widget,
+ int x, int y);
void getSize (core::Requisition *cbReq, int *oofWidth, int *oofHeight);
bool containerMustAdjustExtraSpace ();
diff --git a/dw/oofpositionedmgr.cc b/dw/oofpositionedmgr.cc
index 28852258..1ab7e06e 100644
--- a/dw/oofpositionedmgr.cc
+++ b/dw/oofpositionedmgr.cc
@@ -270,6 +270,18 @@ void OOFPositionedMgr::tellPosition2 (Widget *widget, int x, int y)
DBG_OBJ_LEAVE ();
}
+void OOFPositionedMgr::tellIncompletePosition1 (Widget *generator,
+ Widget *widget, int x, int y)
+{
+ // Nothing to do.
+}
+
+void OOFPositionedMgr::tellIncompletePosition2 (Widget *generator,
+ Widget *widget, int x, int y)
+{
+ // TODO
+}
+
bool OOFPositionedMgr::containerMustAdjustExtraSpace ()
{
return true;
diff --git a/dw/oofpositionedmgr.hh b/dw/oofpositionedmgr.hh
index 4edf11e8..09706235 100644
--- a/dw/oofpositionedmgr.hh
+++ b/dw/oofpositionedmgr.hh
@@ -101,6 +101,11 @@ public:
void tellPosition1 (core::Widget *widget, int x, int y);
void tellPosition2 (core::Widget *widget, int x, int y);
+ void tellIncompletePosition1 (core::Widget *generator, core::Widget *widget,
+ int x, int y);
+ void tellIncompletePosition2 (core::Widget *generator, core::Widget *widget,
+ int x, int y);
+
bool containerMustAdjustExtraSpace ();
diff --git a/dw/outofflowmgr.hh b/dw/outofflowmgr.hh
index 6dff2055..88ec349d 100644
--- a/dw/outofflowmgr.hh
+++ b/dw/outofflowmgr.hh
@@ -55,7 +55,14 @@ public:
* tellPosition2. Coordinates are relative to the *container*.
*/
virtual void tellPosition2 (core::Widget *widget, int x, int y) = 0;
-
+
+ virtual void tellIncompletePosition1 (core::Widget *generator,
+ core::Widget *widget, int x, int y)
+ = 0;
+ virtual void tellIncompletePosition2 (core::Widget *generator,
+ core::Widget *widget, int x, int y)
+ = 0;
+
virtual void getSize (core::Requisition *containerReq, int *oofWidth,
int *oofHeight) = 0;
virtual bool containerMustAdjustExtraSpace ()= 0;
diff --git a/dw/ruler.cc b/dw/ruler.cc
index 6b3d9bd1..bff43479 100644
--- a/dw/ruler.cc
+++ b/dw/ruler.cc
@@ -39,16 +39,14 @@ Ruler::~Ruler ()
DBG_OBJ_DELETE ();
}
-void Ruler::sizeRequestImpl (core::Requisition *requisition, bool posDefined,
- int x, int y)
+void Ruler::sizeRequestSimpl (core::Requisition *requisition)
{
requisition->width = lout::misc::max (getAvailWidth (true), boxDiffWidth ());
requisition->ascent = boxOffsetY ();
requisition->descent = boxRestHeight ();
}
-void Ruler::getExtremesImpl (core::Extremes *extremes, bool posDefined, int x,
- int y)
+void Ruler::getExtremesSimpl (core::Extremes *extremes)
{
extremes->minWidth = extremes->maxWidth = boxDiffWidth ();
extremes->minWidthIntrinsic = extremes->minWidth;
diff --git a/dw/ruler.hh b/dw/ruler.hh
index abbabe4c..74323d95 100644
--- a/dw/ruler.hh
+++ b/dw/ruler.hh
@@ -20,10 +20,8 @@ namespace dw {
class Ruler: public RegardingBorder
{
protected:
- void sizeRequestImpl (core::Requisition *requisition, bool posDefined, int x,
- int y);
- void getExtremesImpl (core::Extremes *extremes, bool posDefined, int x,
- int y);
+ void sizeRequestSimpl (core::Requisition *requisition);
+ void getExtremesSimpl (core::Extremes *extremes);
void containerSizeChangedForChildren ();
bool usesAvailWidth ();
void draw (core::View *view, core::Rectangle *area,
diff --git a/dw/table.cc b/dw/table.cc
index e8c8f2d1..4c953e62 100644
--- a/dw/table.cc
+++ b/dw/table.cc
@@ -103,8 +103,7 @@ Table::~Table()
DBG_OBJ_DELETE ();
}
-void Table::sizeRequestImpl (core::Requisition *requisition, bool posDefined,
- int x, int y)
+void Table::sizeRequestSimpl (core::Requisition *requisition)
{
DBG_OBJ_ENTER0 ("resize", 0, "sizeRequestImpl");
@@ -130,8 +129,7 @@ void Table::sizeRequestImpl (core::Requisition *requisition, bool posDefined,
DBG_OBJ_LEAVE ();
}
-void Table::getExtremesImpl (core::Extremes *extremes, bool posDefined, int x,
- int y)
+void Table::getExtremesSimpl (core::Extremes *extremes)
{
DBG_OBJ_ENTER0 ("resize", 0, "getExtremesImpl");
diff --git a/dw/table.hh b/dw/table.hh
index 0f164c90..3729da71 100644
--- a/dw/table.hh
+++ b/dw/table.hh
@@ -461,10 +461,8 @@ private:
}
protected:
- void sizeRequestImpl (core::Requisition *requisition, bool posDefined, int x,
- int y);
- void getExtremesImpl (core::Extremes *extremes, bool posDefined, int x,
- int y);
+ void sizeRequestSimpl (core::Requisition *requisition);
+ void getExtremesSimpl (core::Extremes *extremes);
void sizeAllocateImpl (core::Allocation *allocation);
void resizeDrawImpl ();
diff --git a/dw/textblock.cc b/dw/textblock.cc
index 6102f21e..262554c6 100644
--- a/dw/textblock.cc
+++ b/dw/textblock.cc
@@ -217,8 +217,11 @@ 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);
+
+ sizeRequestNumPos = 0;
+ sizeRequestReferences = NULL;
+ sizeRequestX = sizeRequestY = NULL;
+ DBG_OBJ_SET_BOOL ("sizeRequestNumPos", sizeRequestNumPos);
/*
* The initial sizes of lines and words should not be
@@ -285,6 +288,13 @@ Textblock::~Textblock ()
delete words;
delete anchors;
+ if (sizeRequestReferences)
+ delete[] sizeRequestReferences;
+ if (sizeRequestX)
+ delete[] sizeRequestX;
+ if (sizeRequestY)
+ delete[] sizeRequestY;
+
/* Make sure we don't own widgets anymore. Necessary before call of
parent class destructor. (???) */
words = NULL;
@@ -297,24 +307,32 @@ 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,
- bool posDefined, int x, int y)
+void Textblock::sizeRequestImpl (core::Requisition *requisition, int numPos,
+ Widget **references, 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;
+ if (sizeRequestReferences)
+ delete[] sizeRequestReferences;
+ if (sizeRequestX)
+ delete[] sizeRequestX;
+ if (sizeRequestY)
+ delete[] sizeRequestY;
+
+ sizeRequestNumPos = numPos;
+ DBG_OBJ_SET_BOOL ("sizeRequestNumPos", sizeRequestNumPos);
+
+ sizeRequestReferences = new Widget*[numPos];
+ sizeRequestX = new int[numPos];
+ sizeRequestY = new int[numPos];
+ for (int i = 0; i < numPos; i++) {
+ sizeRequestReferences[i] = references[i];
+ sizeRequestX[i] = x[i];
+ sizeRequestY[i] = y[i];
+ DBG_OBJ_ARRSET_PTR ("sizeRequestReferences", i, sizeRequestReferences[i]);
+ DBG_OBJ_ARRSET_NUM ("sizeRequestX", i, sizeRequestX[i]);
+ DBG_OBJ_ARRSET_NUM ("sizeRequestY", i, sizeRequestY[i]);
}
- 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) {
@@ -399,14 +417,14 @@ void Textblock::sizeRequestImpl (core::Requisition *requisition,
DBG_OBJ_LEAVE ();
}
-core::Widget *Textblock::sizeRequestReference ()
+int Textblock::numSizeRequestReferences ()
{
- return needsPositionForSize() ? oofContainer[OOFM_FLOATS] : NULL;
+ return 0;
}
-bool Textblock::needsPositionForSize ()
+core::Widget *Textblock::sizeRequestReference (int index)
{
- return oofContainer[OOFM_FLOATS] != this;
+ return NULL;
}
int Textblock::calcVerticalBorder (int widgetPadding, int widgetBorder,
@@ -446,8 +464,7 @@ void Textblock::getWordExtremes (Word *word, core::Extremes *extremes)
word->size.width;
}
-void Textblock::getExtremesImpl (core::Extremes *extremes, bool posDefined,
- int x, int y)
+void Textblock::getExtremesSimpl (core::Extremes *extremes)
{
DBG_OBJ_ENTER0 ("resize", 0, "getExtremesImpl");
@@ -1160,9 +1177,9 @@ core::Iterator *Textblock::iterator (core::Content::Type mask, bool atEnd)
/*
* Draw the decorations on a word.
*/
-void Textblock::decorateText(core::View *view, core::style::Style *style,
- core::style::Color::Shading shading,
- int x, int yBase, int width)
+void Textblock::decorateText (core::View *view, core::style::Style *style,
+ core::style::Color::Shading shading,
+ int x, int yBase, int width)
{
int y, height;
@@ -2256,52 +2273,89 @@ bool Textblock::calcSizeOfWidgetInFlow (int wordIndex, Widget *widget,
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
+ if ((wordIndex == 0 ||
+ words->getRef(wordIndex - 1)->content.type == core::Content::BREAK) &&
+ (widget->getStyle()->display == core::style::DISPLAY_BLOCK ||
+ widget->getStyle()->display == core::style::DISPLAY_LIST_ITEM ||
+ widget->getStyle()->display == core::style::DISPLAY_TABLE)) {
+ // pass positions
+ int lastWord = lines->empty () ? -1 : lines->getLastRef()->lastWord;
+ assert (wordIndex > lastWord);
+
+ int xRel = boxOffsetX () + leftInnerPadding
+ (lines->size () == 0 ? line1OffsetEff : 0);
int lastMargin, yLine = yOffsetOfLineToBeCreated (&lastMargin);
- int y = yRef + yLine - lastMargin
+ int yRel = yLine - lastMargin
+ max (lastMargin, widget->getStyle()->margin.top);
-
- widget->sizeRequest (size, true, x, y);
+ int numPos = 0;
+ int numChildReferences = widget->numSizeRequestReferences ();
+ Widget **references = new Widget*[numChildReferences];
+ int *x = new int[numChildReferences];
+ int *y = new int[numChildReferences];
+
+ for (int i = 0; i < numChildReferences; i++) {
+ Widget *childReference = widget->sizeRequestReference (i);
+ if (childReference == this) {
+ references[numPos] = childReference;
+ x[numPos] = xRel;
+ y[numPos] = yRel;
+ numPos++;
+ } else {
+ for (int j = 0; j < sizeRequestNumPos; j++) {
+ if (childReference == sizeRequestReferences[j]) {
+ references[numPos] = childReference;
+ x[numPos] = sizeRequestX[j] + xRel;
+ y[numPos] = sizeRequestY[j] + yRel;
+ numPos++;
+ }
+ }
+ }
+ }
+
+ widget->sizeRequest (size, numPos, references, x, y);
+
+ delete references;
+ delete x;
+ delete y;
+
result = true;
+ } else {
+ // do not pass positions (inline elements etc)
+ widget->sizeRequest (size);
+ result = false;
}
DBG_OBJ_LEAVE_VAL ("%s", boolToStr (result));
return result;
}
+bool Textblock::findSizeRequestReference (Widget *reference, int *xRef,
+ int *yRef)
+{
+ if (reference == this) {
+ if (xRef)
+ *xRef = 0;
+ if (yRef)
+ *yRef = 0;
+ return true;
+ } else {
+ for (int i = 0; i < sizeRequestNumPos; i++) {
+ if (reference == sizeRequestReferences[i]) {
+ if (xRef)
+ *xRef = sizeRequestX[i];
+ if (yRef)
+ *yRef = sizeRequestY[i];
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
+
/**
* Add a word (without hyphens) to the page structure.
*/
diff --git a/dw/textblock.hh b/dw/textblock.hh
index 907ab4b4..3decda6d 100644
--- a/dw/textblock.hh
+++ b/dw/textblock.hh
@@ -576,10 +576,11 @@ protected:
int redrawY;
int lastWordDrawn;
- bool sizeRequestPosDefined;
- int sizeRequestX, sizeRequestY;
+ int sizeRequestNumPos;
+ Widget **sizeRequestReferences;
+ int *sizeRequestX, *sizeRequestY;
- /* This value is (currently) set by setAscent(). */
+ /* This value is currently) set by setAscent(). */
int lineBreakWidth;
int wrapRefLines, wrapRefParagraphs; /* 0-based. Important: Both
@@ -618,7 +619,6 @@ protected:
int hoverLink; /* The link under the mouse pointer */
void queueDrawRange (int index1, int index2);
- bool needsPositionForSize ();
int calcVerticalBorder (int widgetPadding, int widgetBorder,
int widgetMargin, int lineBorderTotal,
int lineMarginTotal);
@@ -682,6 +682,11 @@ protected:
core::Requisition *size, bool isStart, bool isEnd);
bool calcSizeOfWidgetInFlow (int wordIndex, Widget *widget,
core::Requisition *size);
+ bool findSizeRequestReference (Widget *reference, int *xRef = NULL,
+ int *yRef = NULL);
+ bool findSizeRequestReference (int oofmIndex, int *xRef = NULL,
+ int *yRef = NULL)
+ { return findSizeRequestReference (oofContainer[oofmIndex], xRef, yRef); }
/**
* Of nested text blocks, only the most inner one must regard the
@@ -815,11 +820,11 @@ protected:
Widget *getWidgetAtPointLevel (int x, int y, int level,
core::GettingWidgetAtPointContext *context);
- void sizeRequestImpl (core::Requisition *requisition, bool posDefined, int x,
- int y);
- Widget *sizeRequestReference ();
- void getExtremesImpl (core::Extremes *extremes, bool posDefined, int x,
- int y);
+ void sizeRequestImpl (core::Requisition *requisition, int numPos,
+ Widget **references, int *x, int *y);
+ int numSizeRequestReferences ();
+ Widget *sizeRequestReference (int index);
+ void getExtremesSimpl (core::Extremes *extremes);
void sizeAllocateImpl (core::Allocation *allocation);
void calcExtraSpaceImpl ();
diff --git a/dw/textblock_linebreaking.cc b/dw/textblock_linebreaking.cc
index 31fcb833..03933830 100644
--- a/dw/textblock_linebreaking.cc
+++ b/dw/textblock_linebreaking.cc
@@ -463,16 +463,19 @@ Textblock::Line *Textblock::addLine (int firstWord, int lastWord,
if (word->content.type == core::Content::WIDGET_OOF_REF) {
Widget *widget = word->content.widget;
- oof::OutOfFlowMgr *oofm =
- searchOutOfFlowMgr (getWidgetOOFIndex (widget));
+ int oofmIndex = getWidgetOOFIndex (widget);
+ oof::OutOfFlowMgr *oofm = searchOutOfFlowMgr (oofmIndex);
// See also Textblock::sizeAllocate, and notes there about
// vertical alignment. Calculating the vertical position
// should probably be centralized.
if (oofm) {
- assert (sizeRequestPosDefined);
- oofm->tellPosition2 (widget, sizeRequestX + xWidget,
- sizeRequestY + yLine + (line->borderAscent
- - word->size.ascent));
+ int xRel = xWidget;
+ int yRel = yLine + (line->borderAscent - word->size.ascent);
+ int xRef, yRef;
+ if (findSizeRequestReference (oofmIndex, &xRef, &yRef))
+ oofm->tellPosition2 (widget, xRef + xRel, yRef + yRel);
+ else
+ oofm->tellIncompletePosition2 (widget, this, xRel, yRel);
}
}
@@ -757,12 +760,14 @@ int Textblock::wrapWordInFlow (int wordIndex, bool wrapAll)
lastFloatPos = newFloatPos;
Widget *widget = words->getRef(lastFloatPos)->content.widget;
- oof::OutOfFlowMgr *oofm =
- searchOutOfFlowMgr (getWidgetOOFIndex (widget));
+ int oofmIndex = getWidgetOOFIndex (widget);
+ oof::OutOfFlowMgr *oofm = searchOutOfFlowMgr (oofmIndex);
if (oofm && oofm->mayAffectBordersAtAll ()) {
- assert (sizeRequestPosDefined);
- oofm->tellPosition1 (widget, sizeRequestX + boxOffsetX (),
- sizeRequestY + yNewLine);
+ int xRel = boxOffsetX (), yRel = yNewLine, xRef, yRef;
+ if (findSizeRequestReference (oofmIndex, &xRef, &yRef))
+ oofm->tellPosition1 (widget, xRef + xRel, yRef + yRel);
+ else
+ oofm->tellIncompletePosition1 (widget, this, xRel, yRel);
}
balanceBreakPosAndHeight (wordIndex, firstIndex, &searchUntil,
@@ -852,16 +857,19 @@ int Textblock::wrapWordOofRef (int wordIndex, bool wrapAll)
// Floats, which affect either border, are handled in wrapWordInFlow; this
// is rather for positioned elements (but only for completeness:
// tellPosition1 is not implemented for positioned elements).
- oof::OutOfFlowMgr *oofm = searchOutOfFlowMgr (getWidgetOOFIndex (widget));
+ int oofmIndex = getWidgetOOFIndex (widget);
+ oof::OutOfFlowMgr *oofm = searchOutOfFlowMgr (oofmIndex);
DBG_OBJ_MSGF ("construct.word", 1, "parentRef = %d, oofm = %p",
widget->parentRef, oofm);
if (oofm && !oofm->mayAffectBordersAtAll ()) {
// TODO Again, "x" is not correct (see above).
- assert (sizeRequestPosDefined);
- oofm->tellPosition1 (widget, sizeRequestX + boxOffsetX (),
- sizeRequestY + yNewLine);
+ int xRel = boxOffsetX (), yRel = yNewLine, xRef, yRef;
+ if (findSizeRequestReference (oofmIndex, &xRef, &yRef))
+ oofm->tellPosition1 (widget, xRef + xRel, yRef + yRel);
+ else
+ oofm->tellIncompletePosition1 (widget, this, xRel, yRel);
}
-
+
DBG_OBJ_LEAVE ();
return 0; // Words list not changed.
@@ -2014,19 +2022,19 @@ void Textblock::calcBorders (int lastOofRef, int height)
bool oofmDefined = false;
for (int i = 0; i < NUM_OOFM && !oofmDefined; i++)
- if (searchOutOfFlowMgr(i))
+ if (findSizeRequestReference (i))
oofmDefined = true;
if (oofmDefined) {
int firstWordOfLine =
lines->size() > 0 ? lines->getLastRef()->lastWord + 1 : 0;
int effOofRef = misc::max (lastOofRef, firstWordOfLine - 1);
- assert (sizeRequestPosDefined);
- int y = sizeRequestY + yOffsetOfLineToBeCreated ();
+ int yRel = yOffsetOfLineToBeCreated (), yRef;
for (int i = 0; i < NUM_OOFM; i++) {
- oof::OutOfFlowMgr *oofm = searchOutOfFlowMgr(i);
- if (oofm) {
+ oof::OutOfFlowMgr *oofm;
+ if ((oofm = searchOutOfFlowMgr (i)) &&
+ findSizeRequestReference (i, NULL, &yRef)) {
// Consider the example:
//
// <div>
@@ -2059,6 +2067,7 @@ void Textblock::calcBorders (int lastOofRef, int height)
// than the first word of the new line, so a solution is to use
// the maximum of both.
+ int y = yRef + yRel;
bool thisHasLeft, thisHasRight;
thisHasLeft = oofm->hasFloatLeft (this, y, height, this, effOofRef);
diff --git a/dw/ui.cc b/dw/ui.cc
index 0a749c9b..c95160a4 100644
--- a/dw/ui.cc
+++ b/dw/ui.cc
@@ -48,13 +48,12 @@ Embed::~Embed()
DBG_OBJ_DELETE ();
}
-void Embed::sizeRequestImpl (Requisition *requisition, bool posDefined, int x,
- int y)
+void Embed::sizeRequestSimpl (Requisition *requisition)
{
resource->sizeRequest (requisition);
}
-void Embed::getExtremesImpl (Extremes *extremes, bool posDefined, int x, int y)
+void Embed::getExtremesSimpl (Extremes *extremes)
{
resource->getExtremes (extremes);
correctExtremes (extremes, false);
diff --git a/dw/ui.hh b/dw/ui.hh
index 25033ca8..62ffe3a6 100644
--- a/dw/ui.hh
+++ b/dw/ui.hh
@@ -228,10 +228,8 @@ private:
Resource *resource;
protected:
- void sizeRequestImpl (Requisition *requisition, bool posDefined, int x,
- int y);
- void getExtremesImpl (Extremes *extremes, bool posDefined, int x,
- int y);
+ void sizeRequestSimpl (Requisition *requisition);
+ void getExtremesSimpl (Extremes *extremes);
void sizeAllocateImpl (Allocation *allocation);
int getAvailWidthOfChild (Widget *child, bool forceValue);
diff --git a/dw/widget.cc b/dw/widget.cc
index 18555fa4..b3d47efb 100644
--- a/dw/widget.cc
+++ b/dw/widget.cc
@@ -567,8 +567,8 @@ bool Widget::usesAvailHeight ()
* \brief This method is a wrapper for Widget::sizeRequestImpl(); it calls
* the latter only when needed.
*/
-void Widget::sizeRequest (Requisition *requisition, bool posDefined, int x,
- int y)
+void Widget::sizeRequest (Requisition *requisition, int numPos,
+ Widget **references, int *x, int *y)
{
assert (!queueResizeEntered ());
@@ -588,7 +588,7 @@ void Widget::sizeRequest (Requisition *requisition, bool posDefined, int x,
if (needsResize ()) {
calcExtraSpace ();
/** \todo Check requisition == &(this->requisition) and do what? */
- sizeRequestImpl (requisition, posDefined, x, y);
+ sizeRequestImpl (requisition, numPos, references, x, y);
this->requisition = *requisition;
unsetFlags (NEEDS_RESIZE);
@@ -988,7 +988,8 @@ int Widget::calcHeight (style::Length cssValue, bool usePercentage,
/**
* \brief Wrapper for Widget::getExtremesImpl().
*/
-void Widget::getExtremes (Extremes *extremes, bool posDefined, int x, int y)
+void Widget::getExtremes (Extremes *extremes, int numPos, Widget **references,
+ int *x, int *y)
{
assert (!queueResizeEntered ());
@@ -1011,7 +1012,7 @@ void Widget::getExtremes (Extremes *extremes, bool posDefined, int x, int y)
// For backward compatibility (part 1/2):
extremes->minWidthIntrinsic = extremes->maxWidthIntrinsic = -1;
- getExtremesImpl (extremes, posDefined, x, y);
+ getExtremesImpl (extremes, numPos, references, x, y);
// For backward compatibility (part 2/2):
if (extremes->minWidthIntrinsic == -1)
@@ -1054,13 +1055,25 @@ void Widget::calcExtraSpace ()
DBG_OBJ_SET_NUM ("extraSpace.right", extraSpace.right);
}
-Widget *Widget::sizeRequestReference ()
+int Widget::numSizeRequestReferences ()
{
+ return 0;
+}
+
+Widget *Widget::sizeRequestReference (int index)
+{
+ misc::assertNotReached ();
return NULL;
}
-Widget *Widget::getExtremesReference ()
+int Widget::numGetExtremesReferences ()
{
+ return 0;
+}
+
+Widget *Widget::getExtremesReference (int index)
+{
+ misc::assertNotReached ();
return NULL;
}
@@ -1543,6 +1556,32 @@ void Widget::getPaddingArea (int *xPad, int *yPad, int *widthPad,
*heightPad -= style->borderWidth.top + style->borderWidth.bottom;
}
+void Widget::sizeRequestImpl (Requisition *requisition, int numPos,
+ Widget **references, int *x, int *y)
+{
+ // Use the simple variant.
+ sizeRequestSimpl (requisition);
+}
+
+void Widget::sizeRequestSimpl (Requisition *requisition)
+{
+ // Either variant should be implemented.
+ misc::assertNotReached ();
+}
+
+void Widget::getExtremesImpl (Extremes *extremes, int numPos,
+ Widget **references, int *x, int *y)
+{
+ // Use the simple variant.
+ getExtremesSimpl (extremes);
+}
+
+void Widget::getExtremesSimpl (Extremes *extremes)
+{
+ // Either variant should be implemented.
+ misc::assertNotReached ();
+}
+
void Widget::sizeAllocateImpl (Allocation *allocation)
{
}
diff --git a/dw/widget.hh b/dw/widget.hh
index ed7eae2b..5db9aa33 100644
--- a/dw/widget.hh
+++ b/dw/widget.hh
@@ -280,14 +280,26 @@ protected:
/**
* \brief See \ref dw-widget-sizes.
*/
- virtual void sizeRequestImpl (Requisition *requisition, bool posDefined,
- int x, int y) = 0;
-
+ virtual void sizeRequestImpl (Requisition *requisition, int numPos,
+ Widget **references, int *x, int *y);
+
+ /**
+ * \brief Simple variant, to be implemented by widgets with sizes
+ * not depending on positions.
+ */
+ virtual void sizeRequestSimpl (Requisition *requisition);
+
/**
* \brief See \ref dw-widget-sizes.
*/
- virtual void getExtremesImpl (Extremes *extremes, bool posDefined, int x,
- int y) = 0;
+ virtual void getExtremesImpl (Extremes *extremes, int numPos,
+ Widget **references, int *x, int *y);
+
+ /**
+ * \brief Simple variant, to be implemented by widgets with
+ * extremes not depending on positions.
+ */
+ virtual void getExtremesSimpl (Extremes *extremes);
virtual void calcExtraSpaceImpl ();
@@ -444,21 +456,31 @@ public:
inline int boxRestHeight ()
{ return extraSpace.bottom + getStyle()->boxRestHeight (); }
inline int boxDiffHeight () { return boxOffsetY () + boxRestHeight (); }
+
+ /**
+ * \brief See \ref dw-widget-sizes (or \ref dw-size-request-pos).
+ */
+ virtual int numSizeRequestReferences ();
+
+ /**
+ * \brief See \ref dw-widget-sizes (or \ref dw-size-request-pos).
+ */
+ virtual Widget *sizeRequestReference (int index);
/**
* \brief See \ref dw-widget-sizes (or \ref dw-size-request-pos).
*/
- virtual Widget *sizeRequestReference ();
+ virtual int numGetExtremesReferences ();
/**
* \brief See \ref dw-widget-sizes (or \ref dw-size-request-pos).
*/
- virtual Widget *getExtremesReference ();
+ virtual Widget *getExtremesReference (int index);
- void sizeRequest (Requisition *requisition, bool posDefined = false,
- int x = 0, int y = 0);
- void getExtremes (Extremes *extremes, bool posDefined = false, int x = 0,
- int y = 0);
+ void sizeRequest (Requisition *requisition, int numPos = 0,
+ Widget **references = NULL, int *x = NULL, int *y = NULL);
+ void getExtremes (Extremes *extremes, int numPos = 0,
+ Widget **references = NULL, int *x = NULL, int *y = NULL);
void sizeAllocate (Allocation *allocation);
void calcExtraSpace ();
diff --git a/test/dw_simple_container.cc b/test/dw_simple_container.cc
index 26d030a3..923642b1 100644
--- a/test/dw_simple_container.cc
+++ b/test/dw_simple_container.cc
@@ -160,8 +160,7 @@ SimpleContainer::~SimpleContainer ()
delete child;
}
-void SimpleContainer::sizeRequestImpl (Requisition *requisition,
- bool posDefined, int x, int y)
+void SimpleContainer::sizeRequestSimpl (Requisition *requisition)
{
Requisition childReq;
if (child)
@@ -177,8 +176,7 @@ void SimpleContainer::sizeRequestImpl (Requisition *requisition,
}
-void SimpleContainer::getExtremesImpl (Extremes *extremes, bool posDefined,
- int x, int y)
+void SimpleContainer::getExtremesSimpl (Extremes *extremes)
{
Extremes childExtr;
if (child)
diff --git a/test/dw_simple_container.hh b/test/dw_simple_container.hh
index 10c4b712..bd40b41e 100644
--- a/test/dw_simple_container.hh
+++ b/test/dw_simple_container.hh
@@ -34,10 +34,8 @@ private:
Widget *child;
protected:
- void sizeRequestImpl (core::Requisition *requisition, bool posDefined, int x,
- int y);
- void getExtremesImpl (core::Extremes *extremes, bool posDefined, int x,
- int y);
+ void sizeRequestSimpl (core::Requisition *requisition);
+ void getExtremesSimpl (core::Extremes *extremes);
void sizeAllocateImpl (core::Allocation *allocation);
public: