aboutsummaryrefslogtreecommitdiff
path: root/dw
diff options
context:
space:
mode:
Diffstat (limited to 'dw')
-rw-r--r--dw/iterator.cc57
-rw-r--r--dw/iterator.hh24
-rw-r--r--dw/oofawarewidget.cc119
-rw-r--r--dw/oofawarewidget.hh16
-rw-r--r--dw/ooffloatsmgr.cc31
-rw-r--r--dw/ooffloatsmgr.hh4
-rw-r--r--dw/oofpositionedmgr.cc22
-rw-r--r--dw/oofpositionedmgr.hh7
-rw-r--r--dw/outofflowmgr.hh2
-rw-r--r--dw/stackingcontextmgr.cc26
-rw-r--r--dw/stackingcontextmgr.hh12
-rw-r--r--dw/table.cc28
-rw-r--r--dw/table.hh2
-rw-r--r--dw/textblock.cc75
-rw-r--r--dw/textblock.hh7
-rw-r--r--dw/widget.cc66
-rw-r--r--dw/widget.hh4
17 files changed, 388 insertions, 114 deletions
diff --git a/dw/iterator.cc b/dw/iterator.cc
index dbb779f6..92a028d0 100644
--- a/dw/iterator.cc
+++ b/dw/iterator.cc
@@ -898,5 +898,62 @@ void CharIterator::unhighlight (CharIterator *it1, CharIterator *it2,
}
}
+// ---------------------------
+// StackingIteratorStack
+// ---------------------------
+
+StackingIteratorStack::StackingIteratorStack ()
+{
+ vector = new lout::container::untyped::Vector (1, true);
+ topPos = -1;
+}
+
+StackingIteratorStack::~StackingIteratorStack ()
+{
+ delete vector;
+}
+
+void StackingIteratorStack::intoStringBuffer(lout::misc::StringBuffer *sb)
+{
+ sb->append ("[ ");
+
+ for (int i = 0; i < vector->size (); i++) {
+ if (i != 0)
+ sb->append (" ");
+ if (i == topPos)
+ sb->append ("<b>");
+ vector->get(i)->intoStringBuffer (sb);
+ if (i == topPos)
+ sb->append ("</b>");
+ }
+
+ sb->append (" ]");
+}
+
+void StackingIteratorStack::push (lout::object::Object *object)
+{
+ assert (atRealTop ());
+ vector->put (object);
+ topPos++;
+}
+
+void StackingIteratorStack::pop ()
+{
+ assert (atRealTop ());
+ vector->remove (vector->size () - 1);
+ topPos--;
+}
+
+void StackingIteratorStack::forward ()
+{
+ assert (!atRealTop ());
+ topPos++;
+}
+
+void StackingIteratorStack::backward ()
+{
+ topPos--;
+}
+
} // namespace core
} // namespace dw
diff --git a/dw/iterator.hh b/dw/iterator.hh
index 9460adc4..773cf303 100644
--- a/dw/iterator.hh
+++ b/dw/iterator.hh
@@ -263,6 +263,30 @@ public:
hpos, vpos); }
};
+/**
+ * \brief Some completely different kind of iterator: ...
+ */
+class StackingIteratorStack
+{
+private:
+ lout::container::untyped::Vector *vector;
+ int topPos;
+
+public:
+ StackingIteratorStack ();
+ ~StackingIteratorStack ();
+
+ void intoStringBuffer(lout::misc::StringBuffer *sb);
+
+ inline bool atRealTop () { return topPos == vector->size () - 1; }
+ inline lout::object::Object *getTop () { return vector->get (topPos); }
+
+ void push (lout::object::Object *object);
+ void pop ();
+ void forward ();
+ void backward ();
+};
+
} // namespace core
} // namespace dw
diff --git a/dw/oofawarewidget.cc b/dw/oofawarewidget.cc
index f26591ce..e7efc204 100644
--- a/dw/oofawarewidget.cc
+++ b/dw/oofawarewidget.cc
@@ -26,7 +26,6 @@ using namespace dw;
using namespace dw::core;
using namespace dw::core::style;
using namespace lout::object;
-using namespace lout::container::untyped;
using namespace lout::misc;
namespace dw {
@@ -48,6 +47,17 @@ const char *OOFAwareWidget::OOFStackIterator::majorLevelText (int majorLevel)
}
}
+void OOFAwareWidget::OOFStackIterator::intoStringBuffer(StringBuffer *sb)
+{
+ sb->append ("(");
+ sb->append (majorLevelText (majorLevel));
+ sb->append (", ");
+ sb->appendInt (minorLevel);
+ sb->append (", ");
+ sb->appendInt (index);
+ sb->append (")");
+}
+
int OOFAwareWidget::CLASS_ID = -1;
OOFAwareWidget::OOFAwareWidget ()
@@ -83,6 +93,20 @@ void OOFAwareWidget::notifySetAsTopLevel ()
= oofContainer[OOFM_FIXED] = this;
}
+bool OOFAwareWidget::getOOFMIndex (Widget *widget)
+{
+ if (testWidgetFloat (widget))
+ return OOFM_FLOATS;
+ else if (testWidgetAbsolutelyPositioned (widget))
+ return OOFM_ABSOLUTE;
+ else if (testWidgetFixedlyPositioned (widget))
+ return OOFM_FIXED;
+ else {
+ lout::misc::assertNotReached ();
+ return -1;
+ }
+}
+
bool OOFAwareWidget::isOOFContainer (Widget *widget, int oofmIndex)
{
// TODO The methods isPossibleContainer() and isPossibleContainerParent()
@@ -270,18 +294,75 @@ void OOFAwareWidget::containerSizeChangedForChildrenOOF ()
outOfFlowMgr[i]->containerSizeChangedForChildren ();
}
-Widget *OOFAwareWidget::draw (View *view, Rectangle *area, Stack *iterator)
+bool OOFAwareWidget::doesWidgetOOFInterruptDrawing (Widget *widget,
+ OOFAwareWidget *generator,
+ OOFAwareWidget *container)
+{
+ DBG_OBJ_ENTER_O ("draw", 0, (void*)NULL, "doesWidgetOOFInterruptDrawing",
+ "%p, %p, %p", widget, generator, container);
+
+ int cl = container->stackingContextWidget->getLevel (),
+ gl = generator->stackingContextWidget->getLevel ();
+
+ DBG_OBJ_MSGF_O ("draw", 1, (void*)NULL, "%d < %d => %s",
+ cl, gl, cl < gl ? "true" : "false");
+
+ DBG_OBJ_LEAVE_O ((void*)NULL);
+ return cl < gl;
+}
+
+bool OOFAwareWidget::doesWidgetOOFInterruptDrawing (Widget *widget)
+{
+ DBG_OBJ_ENTER ("draw", 0, "doesWidgetOOFInterruptDrawing", "%p", widget);
+
+ // This is the generator of the widget.
+ int oofmIndex = getOOFMIndex (widget);
+ DBG_OBJ_MSGF ("draw", 1, "oofmIndex = %d", oofmIndex);
+
+ bool b =
+ doesWidgetOOFInterruptDrawing (widget, this, oofContainer[oofmIndex]);
+ DBG_OBJ_MSGF ("draw", 1, "=> %s", b ? "true" : "false");
+
+ DBG_OBJ_LEAVE ();
+ return b;
+}
+
+Widget *OOFAwareWidget::draw (View *view, Rectangle *area,
+ StackingIteratorStack *iteratorStack)
{
DBG_OBJ_ENTER ("draw", 0, "draw", "%d, %d, %d * %d",
area->x, area->y, area->width, area->height);
- OOFStackIterator *osi = (OOFStackIterator*)iterator->getTop ();
+ OOFStackIterator *osi = (OOFStackIterator*)iteratorStack->getTop ();
Widget *retWidget = NULL;
while (retWidget == NULL && osi->majorLevel < OOFStackIterator::END) {
- retWidget = drawLevel (view, area, iterator, osi->majorLevel);
+ retWidget = drawLevel (view, area, iteratorStack, osi->majorLevel);
+
+ if (retWidget) {
+ if (retWidget->getParent () == this) {
+ DBG_OBJ_MSGF ("draw", 1, "interrupted at %p, drawing seperately",
+ retWidget);
+ DBG_IF_RTFL {
+ StringBuffer sb;
+ iteratorStack->intoStringBuffer (&sb);
+ DBG_OBJ_MSGF ("draw", 2, "iteratorStack: %s", sb.getChars ());
+ }
- if (retWidget == NULL) {
+ core::Rectangle retWidgetArea;
+ if (retWidget->intersects (area, &retWidgetArea)) {
+ // Similar to Widget::drawToplevel. Nested
+ // interruptions are not allowed.
+ StackingIteratorStack iteratorStack2;
+ Widget *retWidget2 =
+ retWidget->drawTotal (view, &retWidgetArea, &iteratorStack2);
+ assert (retWidget2 == NULL);
+ }
+
+ retWidget = NULL; // Continue with the current state of "iterator".
+ DBG_OBJ_MSG ("draw", 1, "done with interruption");
+ }
+ } else {
osi->majorLevel++;
osi->minorLevel = osi->index = 0;
}
@@ -293,7 +374,8 @@ Widget *OOFAwareWidget::draw (View *view, Rectangle *area, Stack *iterator)
return retWidget;
}
-Widget *OOFAwareWidget::drawLevel (View *view, Rectangle *area, Stack *iterator,
+Widget *OOFAwareWidget::drawLevel (View *view, Rectangle *area,
+ StackingIteratorStack *iteratorStack,
int majorLevel)
{
DBG_OBJ_ENTER ("draw", 0, "OOFAwareWidget/drawLevel",
@@ -313,9 +395,9 @@ Widget *OOFAwareWidget::drawLevel (View *view, Rectangle *area, Stack *iterator,
case OOFStackIterator::SC_BOTTOM:
if (stackingContextMgr) {
- OOFStackIterator *osi = (OOFStackIterator*)iterator->getTop ();
+ OOFStackIterator *osi = (OOFStackIterator*)iteratorStack->getTop ();
retWidget =
- stackingContextMgr->drawBottom (view, area, iterator,
+ stackingContextMgr->drawBottom (view, area, iteratorStack,
&osi->minorLevel, &osi->index);
}
break;
@@ -329,14 +411,14 @@ Widget *OOFAwareWidget::drawLevel (View *view, Rectangle *area, Stack *iterator,
break;
case OOFStackIterator::OOF_CONT:
- retWidget = drawOOF (view, area, iterator);
+ retWidget = drawOOF (view, area, iteratorStack);
break;
case OOFStackIterator::SC_TOP:
if (stackingContextMgr) {
- OOFStackIterator *osi = (OOFStackIterator*)iterator->getTop ();
+ OOFStackIterator *osi = (OOFStackIterator*)iteratorStack->getTop ();
retWidget =
- stackingContextMgr->drawTop (view, area, iterator,
+ stackingContextMgr->drawTop (view, area, iteratorStack,
&osi->minorLevel, &osi->index);
}
break;
@@ -351,19 +433,22 @@ Widget *OOFAwareWidget::drawLevel (View *view, Rectangle *area, Stack *iterator,
}
Widget *OOFAwareWidget::drawOOF (View *view, Rectangle *area,
- lout::container::untyped::Stack *iterator)
+ StackingIteratorStack *iteratorStack)
{
- OOFStackIterator *osi = (OOFStackIterator*)iterator->getTop ();
+ OOFStackIterator *osi = (OOFStackIterator*)iteratorStack->getTop ();
assert (osi->majorLevel == OOFStackIterator::OOF_CONT);
Widget *retWidget = NULL;
- for (; retWidget == NULL && osi->minorLevel < NUM_OOFM; osi->minorLevel++) {
+ while (retWidget == NULL && osi->minorLevel < NUM_OOFM) {
if(outOfFlowMgr[osi->minorLevel])
- retWidget = outOfFlowMgr[osi->minorLevel]->draw (view, area, iterator,
- &(osi->index));
- if (retWidget == NULL)
+ retWidget =
+ outOfFlowMgr[osi->minorLevel]->draw (view, area, iteratorStack,
+ &(osi->index));
+ if (retWidget == NULL) {
+ osi->minorLevel++;
osi->index = 0;
+ }
}
return retWidget;
diff --git a/dw/oofawarewidget.hh b/dw/oofawarewidget.hh
index bef075a3..362069dc 100644
--- a/dw/oofawarewidget.hh
+++ b/dw/oofawarewidget.hh
@@ -111,6 +111,8 @@ protected:
END } ;
int majorLevel, minorLevel, index;
+ void intoStringBuffer(lout::misc::StringBuffer *sb);
+
static const char *majorLevelText (int majorLevel4);
};
@@ -171,6 +173,8 @@ protected:
static inline bool testWidgetRelativelyPositioned (Widget *widget)
{ return widget->getStyle()->position == core::style::POSITION_RELATIVE; }
+ static bool getOOFMIndex (Widget *widget);
+
void initOutOfFlowMgrs ();
void correctRequisitionByOOF (core::Requisition *requisition,
void (*splitHeightFun) (int, int*, int*));
@@ -178,11 +182,12 @@ protected:
void sizeAllocateStart (core::Allocation *allocation);
void sizeAllocateEnd ();
void containerSizeChangedForChildrenOOF ();
+
virtual Widget *drawLevel (core::View *view, core::Rectangle *area,
- lout::container::untyped::Stack *iterator,
+ core::StackingIteratorStack *iteratorStack,
int majorLevel);
Widget *drawOOF (core::View *view, core::Rectangle *area,
- lout::container::untyped::Stack *iterator);
+ core::StackingIteratorStack *iteratorStack);
Widget *getWidgetOOFAtPoint (int x, int y);
static bool isOOFContainer (Widget *widget, int oofmIndex);
@@ -203,8 +208,13 @@ public:
OOFAwareWidget ();
~OOFAwareWidget ();
+ static bool doesWidgetOOFInterruptDrawing (Widget *widget,
+ OOFAwareWidget *generator,
+ OOFAwareWidget *container);
+ bool doesWidgetOOFInterruptDrawing (Widget *widget);
+
Widget *draw (core::View *view, core::Rectangle *area,
- lout::container::untyped::Stack *iterator);
+ core::StackingIteratorStack *iteratorStack);
lout::object::Object *stackingIterator (bool atEnd);
virtual void borderChanged (int y, core::Widget *vloat);
diff --git a/dw/ooffloatsmgr.cc b/dw/ooffloatsmgr.cc
index f6f488f2..5373d84c 100644
--- a/dw/ooffloatsmgr.cc
+++ b/dw/ooffloatsmgr.cc
@@ -1278,8 +1278,7 @@ int OOFFloatsMgr::calcFloatX (Float *vloat, Side side, int gbX, int gbWidth,
}
Widget *OOFFloatsMgr::draw (View *view, Rectangle *area,
- lout::container::untyped::Stack *iterator,
- int *index)
+ StackingIteratorStack *iteratorStack, int *index)
{
DBG_OBJ_ENTER ("draw", 0, "draw", "(%d, %d, %d * %d), [%d]",
area->x, area->y, area->width, area->height, *index);
@@ -1287,10 +1286,11 @@ Widget *OOFFloatsMgr::draw (View *view, Rectangle *area,
Widget *retWidget = NULL;
if (*index < leftFloatsCB->size ())
- retWidget = drawFloats (leftFloatsCB, view, area, iterator, index, 0);
+ retWidget =
+ drawFloats (leftFloatsCB, view, area, iteratorStack, index, 0);
if (retWidget == NULL)
- retWidget = drawFloats (rightFloatsCB, view, area, iterator, index,
+ retWidget = drawFloats (rightFloatsCB, view, area, iteratorStack, index,
leftFloatsCB->size ());
DBG_OBJ_MSGF ("draw", 1, "=> %p", retWidget);
@@ -1300,7 +1300,7 @@ Widget *OOFFloatsMgr::draw (View *view, Rectangle *area,
Widget *OOFFloatsMgr::drawFloats (SortedFloatsVector *list, View *view,
Rectangle *area,
- lout::container::untyped::Stack *iterator,
+ StackingIteratorStack *iteratorStack,
int *index, int startIndex)
{
// This could be improved, since the list is sorted: search the
@@ -1309,12 +1309,21 @@ Widget *OOFFloatsMgr::drawFloats (SortedFloatsVector *list, View *view,
Widget *retWidget = NULL;
- for (; retWidget == NULL && *index - startIndex < list->size(); (*index)++) {
- Widget *childWidget = list->get(*index - startIndex)->getWidget ();
- Rectangle childArea;
- if (!StackingContextMgr::handledByStackingContextMgr (childWidget) &&
- childWidget->intersects (area, &childArea))
- retWidget = childWidget->drawTotal (view, &childArea, iterator);
+ while (retWidget == NULL && *index - startIndex < list->size()) {
+ Float *vloat = list->get(*index - startIndex);
+ Widget *childWidget = vloat->getWidget ();
+
+ if (!OOFAwareWidget:: doesWidgetOOFInterruptDrawing
+ (childWidget, vloat->generatingBlock, container)) {
+ Rectangle childArea;
+ if (!StackingContextMgr::handledByStackingContextMgr (childWidget) &&
+ childWidget->intersects (area, &childArea))
+ retWidget =
+ childWidget->drawTotal (view, &childArea, iteratorStack);
+ }
+
+ if (retWidget == NULL)
+ (*index)++;
}
return retWidget;
diff --git a/dw/ooffloatsmgr.hh b/dw/ooffloatsmgr.hh
index e90a72be..f7f994d7 100644
--- a/dw/ooffloatsmgr.hh
+++ b/dw/ooffloatsmgr.hh
@@ -286,7 +286,7 @@ private:
core::Widget *drawFloats (SortedFloatsVector *list, core::View *view,
core::Rectangle *area,
- lout::container::untyped::Stack *iterator,
+ core::StackingIteratorStack *iteratorStack,
int *index, int startIndex);
core::Widget *getFloatWidgetAtPoint (SortedFloatsVector *list, int x, int y);
@@ -343,7 +343,7 @@ public:
void sizeAllocateEnd (OOFAwareWidget *caller);
void containerSizeChangedForChildren ();
core::Widget *draw (core::View *view, core::Rectangle *area,
- lout::container::untyped::Stack *iterator, int *index);
+ core::StackingIteratorStack *iteratorStack, int *index);
void markSizeChange (int ref);
void markExtremesChange (int ref);
diff --git a/dw/oofpositionedmgr.cc b/dw/oofpositionedmgr.cc
index 07bc45aa..c0c31417 100644
--- a/dw/oofpositionedmgr.cc
+++ b/dw/oofpositionedmgr.cc
@@ -169,7 +169,7 @@ bool OOFPositionedMgr::haveExtremesChanged ()
Widget *OOFPositionedMgr::draw (View *view, Rectangle *area,
- lout::container::untyped::Stack *iterator,
+ StackingIteratorStack *iteratorStack,
int *index)
{
DBG_OBJ_ENTER ("draw", 0, "draw", "(%d, %d, %d * %d), [%d]",
@@ -177,12 +177,20 @@ Widget *OOFPositionedMgr::draw (View *view, Rectangle *area,
Widget *retWidget = NULL;
- for (; retWidget == NULL && *index < children->size(); (*index)++) {
- Widget *childWidget = children->get(*index)->widget;
- Rectangle childArea;
- if (!StackingContextMgr::handledByStackingContextMgr (childWidget) &&
- childWidget->intersects (area, &childArea))
- retWidget = childWidget->drawTotal (view, &childArea, iterator);
+ while (retWidget == NULL && *index < children->size()) {
+ Child *child = children->get(*index);
+
+ if (!OOFAwareWidget:: doesWidgetOOFInterruptDrawing
+ (child->widget, child->generator, container)) {
+ Rectangle childArea;
+ if (!StackingContextMgr::handledByStackingContextMgr (child->widget) &&
+ child->widget->intersects (area, &childArea))
+ retWidget =
+ child->widget->drawTotal (view, &childArea, iteratorStack);
+ }
+
+ if (retWidget == NULL)
+ (*index)++;
}
DBG_OBJ_MSGF ("draw", 1, "=> %p", retWidget);
diff --git a/dw/oofpositionedmgr.hh b/dw/oofpositionedmgr.hh
index c7f55262..819c4558 100644
--- a/dw/oofpositionedmgr.hh
+++ b/dw/oofpositionedmgr.hh
@@ -13,10 +13,11 @@ protected:
class Child: public lout::object::Object
{
public:
- core::Widget *widget, *generator;
+ core::Widget *widget;
+ OOFAwareWidget *generator;
int x, y;
- inline Child (core::Widget *widget, core::Widget *generator)
+ inline Child (core::Widget *widget, OOFAwareWidget *generator)
{ this->widget = widget; this->generator = generator; x = y = 0; }
};
@@ -65,7 +66,7 @@ public:
void sizeAllocateEnd (OOFAwareWidget *caller);
void containerSizeChangedForChildren ();
core::Widget *draw (core::View *view, core::Rectangle *area,
- lout::container::untyped::Stack *iterator, int *index);
+ core::StackingIteratorStack *iteratorStack, int *index);
void markSizeChange (int ref);
void markExtremesChange (int ref);
diff --git a/dw/outofflowmgr.hh b/dw/outofflowmgr.hh
index 5b74e513..15a94081 100644
--- a/dw/outofflowmgr.hh
+++ b/dw/outofflowmgr.hh
@@ -26,7 +26,7 @@ public:
virtual void sizeAllocateEnd (OOFAwareWidget *caller) = 0;
virtual void containerSizeChangedForChildren () = 0;
virtual core::Widget *draw (core::View *view, core::Rectangle *area,
- lout::container::untyped::Stack *iterator,
+ core::StackingIteratorStack *iteratorStack,
int *index) = 0;
virtual void markSizeChange (int ref) = 0;
diff --git a/dw/stackingcontextmgr.cc b/dw/stackingcontextmgr.cc
index c104f5ee..70b4dd75 100644
--- a/dw/stackingcontextmgr.cc
+++ b/dw/stackingcontextmgr.cc
@@ -61,34 +61,33 @@ void StackingContextMgr::addChildSCWidget (Widget *widget)
}
Widget *StackingContextMgr::drawBottom (View *view, Rectangle *area,
- lout::container::untyped::Stack
- *iterator,
+ StackingIteratorStack *iteratorStack,
int *zIndexOffset, int *index)
{
DBG_OBJ_ENTER ("draw", 0, "drawBottom", "(%d, %d, %d * %d), [%d], [%d]",
area->x, area->y, area->width, area->height, *zIndexOffset,
*index);
Widget *retWidget =
- draw (view, area, iterator, index, INT_MIN, -1, zIndexOffset);
+ draw (view, area, iteratorStack, index, INT_MIN, -1, zIndexOffset);
DBG_OBJ_LEAVE ();
return retWidget;
}
Widget *StackingContextMgr::drawTop (View *view, Rectangle *area,
- lout::container::untyped::Stack *iterator,
+ StackingIteratorStack *iteratorStack,
int *zIndexOffset, int *index)
{
DBG_OBJ_ENTER ("draw", 0, "drawTop", "(%d, %d, %d * %d), [%d], [%d]",
area->x, area->y, area->width, area->height, *zIndexOffset,
*index);
Widget *retWidget =
- draw (view, area, iterator, index, 0, INT_MAX, zIndexOffset);
+ draw (view, area, iteratorStack, index, 0, INT_MAX, zIndexOffset);
DBG_OBJ_LEAVE ();
return retWidget;
}
Widget *StackingContextMgr::draw (View *view, Rectangle *area,
- lout::container::untyped::Stack *iterator,
+ StackingIteratorStack *iteratorStack,
int *zIndexOffset, int startZIndex,
int endZIndex, int *index)
{
@@ -102,24 +101,27 @@ Widget *StackingContextMgr::draw (View *view, Rectangle *area,
Widget *retWidget = NULL;
int startZIndexEff = max (minZIndex, startZIndex),
endZIndexEff = min (maxZIndex, endZIndex);
- for (; retWidget == NULL && *zIndexOffset + startZIndexEff <= endZIndexEff;
- (*zIndexOffset)++) {
+ while (retWidget == NULL && *zIndexOffset + startZIndexEff <= endZIndexEff) {
DBG_OBJ_MSGF ("draw", 1, "drawing zIndex = %d + %d",
*zIndexOffset, startZIndexEff);
DBG_OBJ_MSG_START ();
- // TODO This is wrong.
- for (; retWidget == NULL && *index < childSCWidgets->size ();
- (*index)++) {
+ while (retWidget == NULL && *index < childSCWidgets->size ()) {
Widget *child = childSCWidgets->get (*index);
DBG_OBJ_MSGF ("draw", 2, "widget %p has zIndex = %d",
child, child->getStyle()->zIndex);
Rectangle childArea;
if (child->getStyle()->zIndex == *zIndexOffset + startZIndexEff &&
child->intersects (area, &childArea))
- retWidget = child->drawTotal (view, &childArea, iterator);
+ retWidget = child->drawTotal (view, &childArea, iteratorStack);
+
+ if (retWidget == NULL)
+ (*index)++;
}
+ if (retWidget == NULL)
+ (*zIndexOffset)++;
+
DBG_OBJ_MSG_END ();
}
diff --git a/dw/stackingcontextmgr.hh b/dw/stackingcontextmgr.hh
index 7f86c22c..10a929cf 100644
--- a/dw/stackingcontextmgr.hh
+++ b/dw/stackingcontextmgr.hh
@@ -24,8 +24,8 @@ private:
int minZIndex, maxZIndex;
Widget *draw (View *view, Rectangle *area,
- lout::container::untyped::Stack *iterator,
- int *zIndexOffset, int startZIndex, int endZIndex, int *index);
+ StackingIteratorStack *iteratorStack, int *zIndexOffset,
+ int startZIndex, int endZIndex, int *index);
Widget *getWidgetAtPoint (int x, int y, int startZIndex, int endZIndex);
public:
@@ -48,11 +48,11 @@ public:
void addChildSCWidget (Widget *widget);
Widget *drawBottom (View *view, Rectangle *area,
- lout::container::untyped::Stack *iterator,
- int *zIndexOffset, int *index);
+ StackingIteratorStack *iteratorStack, int *zIndexOffset,
+ int *index);
Widget *drawTop (View *view, Rectangle *area,
- lout::container::untyped::Stack *iterator,
- int *zIndexOffset, int *index);
+ StackingIteratorStack *iteratorStack, int *zIndexOffset,
+ int *index);
Widget *getTopWidgetAtPoint (int x, int y);
Widget *getBottomWidgetAtPoint (int x, int y);
diff --git a/dw/table.cc b/dw/table.cc
index f9858ddd..3e53ec58 100644
--- a/dw/table.cc
+++ b/dw/table.cc
@@ -357,7 +357,7 @@ bool Table::isBlockLevel ()
}
core::Widget *Table::drawLevel (core::View *view, core::Rectangle *area,
- lout::container::untyped::Stack *iterator,
+ core::StackingIteratorStack *iteratorStack,
int majorLevel)
{
DBG_OBJ_ENTER ("draw", 0, "Table/drawLevel", "(%d, %d, %d * %d), %s",
@@ -386,19 +386,29 @@ core::Widget *Table::drawLevel (core::View *view, core::Rectangle *area,
switch (majorLevel) {
case OOFStackIterator::IN_FLOW:
- for (int i = 0; retWidget == NULL && i < children->size (); i++) {
- if (childDefined (i)) {
- Widget *child = children->get(i)->cell.widget;
- core::Rectangle childArea;
- if (!core::StackingContextMgr::handledByStackingContextMgr (child)
- && child->intersects (area, &childArea))
- retWidget = child->drawTotal (view, &childArea, iterator);
+ {
+ OOFStackIterator *osi = (OOFStackIterator*)iteratorStack->getTop ();
+
+ while (retWidget == NULL && osi->index < children->size ()) {
+ if (childDefined (osi->index)) {
+ Widget *child = children->get(osi->index)->cell.widget;
+ core::Rectangle childArea;
+ if (!core::StackingContextMgr::handledByStackingContextMgr
+ (child)
+ && child->intersects (area, &childArea))
+ retWidget =
+ child->drawTotal (view, &childArea, iteratorStack);
+ }
+
+ if (retWidget == NULL)
+ osi->index++;
}
}
break;
default:
- retWidget = OOFAwareWidget::drawLevel (view, area, iterator, majorLevel);
+ retWidget =
+ OOFAwareWidget::drawLevel (view, area, iteratorStack, majorLevel);
break;
}
diff --git a/dw/table.hh b/dw/table.hh
index 502b1332..c6f23259 100644
--- a/dw/table.hh
+++ b/dw/table.hh
@@ -472,7 +472,7 @@ protected:
bool isBlockLevel ();
Widget *drawLevel (core::View *view, core::Rectangle *area,
- lout::container::untyped::Stack *iterator,
+ core::StackingIteratorStack *iteratorStack,
int majorLevel);
//bool buttonPressImpl (core::EventButton *event);
diff --git a/dw/textblock.cc b/dw/textblock.cc
index 4b915f2e..9ededeff 100644
--- a/dw/textblock.cc
+++ b/dw/textblock.cc
@@ -1449,12 +1449,12 @@ void Textblock::drawSpace(int wordIndex, core::View *view,
*/
core::Widget *Textblock::drawLine (Line *line, core::View *view,
core::Rectangle *area,
- lout::container::untyped::Stack *iterator)
+ core::StackingIteratorStack *iteratorStack)
{
DBG_OBJ_ENTER ("draw", 0, "drawLine", "..., %d, %d, %d * %d",
area->x, area->y, area->width, area->height);
- OOFStackIterator *osi = (OOFStackIterator*)iterator->getTop ();
+ OOFStackIterator *osi = (OOFStackIterator*)iteratorStack->getTop ();
Widget *retWidget = NULL;
@@ -1470,9 +1470,8 @@ core::Widget *Textblock::drawLine (Line *line, core::View *view,
if (osi->index < line->firstWord)
osi->index = line->firstWord;
- for (; retWidget == NULL && osi->index <= line->lastWord
- && xWidget < area->x + area->width;
- osi->index++) {
+ while (retWidget == NULL && osi->index <= line->lastWord
+ && xWidget < area->x + area->width) {
Word *word = words->getRef (osi->index);
int wordSize = word->size.width;
@@ -1487,7 +1486,8 @@ core::Widget *Textblock::drawLine (Line *line, core::View *view,
if (!core::StackingContextMgr::handledByStackingContextMgr
(child) &&
child->intersects (area, &childArea))
- retWidget = child->drawTotal (view, &childArea, iterator);
+ retWidget =
+ child->drawTotal (view, &childArea, iteratorStack);
} else {
int wordIndex2 = osi->index;
while (wordIndex2 < line->lastWord &&
@@ -1522,6 +1522,9 @@ core::Widget *Textblock::drawLine (Line *line, core::View *view,
}
}
xWidget += wordSize + word->effSpace;
+
+ if (retWidget == NULL)
+ osi->index++;
}
DBG_OBJ_MSGF ("draw", 1, "=> %p", retWidget);
@@ -1695,7 +1698,7 @@ Textblock::Word *Textblock::findWord (int x, int y, bool *inSpace)
}
core::Widget *Textblock::drawLevel (core::View *view, core::Rectangle *area,
- lout::container::untyped::Stack *iterator,
+ core::StackingIteratorStack *iteratorStack,
int majorLevel)
{
DBG_OBJ_ENTER ("draw", 0, "Textblock/drawLevel", "(%d, %d, %d * %d), %s",
@@ -1714,16 +1717,17 @@ core::Widget *Textblock::drawLevel (core::View *view, core::Rectangle *area,
break;
DBG_OBJ_MSGF ("draw", 0, "line %d (of %d)", lineIndex, lines->size ());
- retWidget = drawLine (line, view, area, iterator);
+ retWidget = drawLine (line, view, area, iteratorStack);
}
break;
case OOFStackIterator::OOF_REF:
- // TODO
+ retWidget = drawOOFReferences (view, area, iteratorStack);
break;
default:
- retWidget = OOFAwareWidget::drawLevel (view, area, iterator, majorLevel);
+ retWidget =
+ OOFAwareWidget::drawLevel (view, area, iteratorStack, majorLevel);
break;
}
@@ -1732,6 +1736,45 @@ core::Widget *Textblock::drawLevel (core::View *view, core::Rectangle *area,
return retWidget;
}
+core::Widget *Textblock::drawOOFReferences (core::View *view,
+ core::Rectangle *area,
+ core::StackingIteratorStack
+ *iteratorStack)
+{
+ DBG_OBJ_ENTER ("draw", 0, "Textblock/drawOOFReferences", "%d, %d, %d * %d",
+ area->x, area->y, area->width, area->height);
+
+ // TODO Inefficient. Store Widgets OOF references in seperate list?
+
+ OOFStackIterator *osi = (OOFStackIterator*)iteratorStack->getTop ();
+ assert (osi->majorLevel == OOFStackIterator::OOF_REF);
+
+ Widget *retWidget = NULL;
+
+ while (retWidget == NULL && osi->minorLevel < NUM_OOFM) {
+ while (retWidget == NULL && osi->index < words->size ()) {
+ Word *word = words->getRef (osi->index);
+ if (word->content.type == core::Content::WIDGET_OOF_REF &&
+ getOOFMIndex (word->content.widget) == osi->minorLevel &&
+ doesWidgetOOFInterruptDrawing (word->content.widget))
+ retWidget = word->content.widget;
+
+ // The index is increased in any case: the iterator must
+ // point to the next element.
+ osi->index++;
+ }
+
+ if (retWidget == NULL) {
+ osi->minorLevel++;
+ osi->index = 0;
+ }
+ }
+
+ DBG_OBJ_MSGF ("draw", 1, "=> %p", retWidget);
+ DBG_OBJ_LEAVE ();
+ return retWidget;
+}
+
/**
* Add a new word (text, widget etc.) to a page.
*/
@@ -2291,18 +2334,10 @@ void Textblock::addWidget (core::Widget *widget, core::style::Style *style)
initOutOfFlowMgrs ();
if (testWidgetOutOfFlow (widget)) {
- int oofmIndex = -1;
- if (testWidgetFloat (widget))
- oofmIndex = OOFM_FLOATS;
- else if (testWidgetAbsolutelyPositioned (widget))
- oofmIndex = OOFM_ABSOLUTE;
- else if (testWidgetFixedlyPositioned (widget))
- oofmIndex = OOFM_FIXED;
- else
- lout::misc::assertNotReached ();
-
+ int oofmIndex = getOOFMIndex (widget);
widget->setParent (oofContainer[oofmIndex]);
widget->setGenerator (this);
+
int oofmSubRef =
searchOutOfFlowMgr(oofmIndex)->addWidgetOOF (widget, this,
words->size ());
diff --git a/dw/textblock.hh b/dw/textblock.hh
index c9f86fa5..4a5681e6 100644
--- a/dw/textblock.hh
+++ b/dw/textblock.hh
@@ -643,7 +643,10 @@ protected:
void drawSpace (int wordIndex, core::View *view, core::Rectangle *area,
int xWidget, int yWidgetBase);
Widget *drawLine (Line *line, core::View *view, core::Rectangle *area,
- lout::container::untyped::Stack *iterator);
+ core::StackingIteratorStack *iteratorStack);
+ Widget *drawOOFReferences (core::View *view, core::Rectangle *area,
+ core::StackingIteratorStack *iteratorStack);
+
int findLineIndex (int y);
int findLineIndexWhenNotAllocated (int y);
int findLineIndexWhenAllocated (int y);
@@ -799,7 +802,7 @@ protected:
void calcTextOffset (int lineIndex, int totalWidth);
Widget *drawLevel (core::View *view, core::Rectangle *area,
- lout::container::untyped::Stack *iterator,
+ core::StackingIteratorStack *iteratorStack,
int majorLevel);
void sizeRequestImpl (core::Requisition *requisition);
diff --git a/dw/widget.cc b/dw/widget.cc
index cf955dec..e312ee6f 100644
--- a/dw/widget.cc
+++ b/dw/widget.cc
@@ -188,7 +188,7 @@ void Widget::draw (View *view, Rectangle *area)
/** Area is given in widget coordinates. */
Widget *Widget::draw (View *view, Rectangle *area,
- lout::container::untyped::Stack *iterator)
+ StackingIteratorStack *iteratorStack)
{
// Suitable for widgets without children.
draw (view, area);
@@ -196,34 +196,64 @@ Widget *Widget::draw (View *view, Rectangle *area,
}
Widget *Widget::drawTotal (View *view, Rectangle *area,
- lout::container::untyped::Stack *iterator)
+ StackingIteratorStack *iteratorStack)
{
DBG_OBJ_ENTER ("draw", 0, "drawTotal", "%d, %d, %d * %d",
area->x, area->y, area->width, area->height);
- Object *si = stackingIterator (false);
- if (si) {
- iterator->push (si);
- DBG_OBJ_MSGF ("draw", 1, "pushing on iterator; now %d element(s)",
- iterator->size ());
+ DBG_IF_RTFL {
+ misc::StringBuffer sb;
+ iteratorStack->intoStringBuffer (&sb);
+ DBG_OBJ_MSGF ("draw", 2, "initial iteratorStack: %s", sb.getChars ());
+ }
+
+ Object *si = NULL;
+
+ if (iteratorStack->atRealTop ()) {
+ si = stackingIterator (false);
+ if (si) {
+ iteratorStack->push (si);
+ }
} else
- DBG_OBJ_MSGF ("draw", 1, "nothing on iterator; %d element(s)",
- iterator->size ());
-
+ iteratorStack->forward ();
- Widget *retWidget = draw (view, area, iterator);
+ DBG_IF_RTFL {
+ misc::StringBuffer sb;
+ iteratorStack->intoStringBuffer (&sb);
+ DBG_OBJ_MSGF ("draw", 2, "iteratorStack before drawing: %s",
+ sb.getChars ());
+ }
+
+ Widget *retWidget = draw (view, area, iteratorStack);
+ DBG_OBJ_MSGF ("draw", 1, "=> %p", retWidget);
+
+ DBG_IF_RTFL {
+ misc::StringBuffer sb;
+ iteratorStack->intoStringBuffer (&sb);
+ DBG_OBJ_MSGF ("draw", 2, "iteratorStack after drawing: %s",
+ sb.getChars ());
+ }
// A return value other than NULL indicates a widget with a complex
// drawing process, for which stackIterator() must return something
// non-NULL, so that the interrupted drawing process can be
- // continued.
+ // continued. (TODO: Not quite correct when forward() was called
+ // instead of push().)
+
+ // assert (retWidget == NULL || si != NULL);
- assert (retWidget == NULL || si != NULL);
+ if (retWidget == NULL) {
+ if (si)
+ iteratorStack->pop ();
+ } else
+ iteratorStack->backward ();
- if (retWidget == NULL && si != NULL)
- iterator->pop ();
+ DBG_IF_RTFL {
+ misc::StringBuffer sb;
+ iteratorStack->intoStringBuffer (&sb);
+ DBG_OBJ_MSGF ("draw", 2, "final iteratorStack: %s", sb.getChars ());
+ }
- DBG_OBJ_MSGF ("draw", 1, "=> %p", retWidget);
DBG_OBJ_LEAVE ();
return retWidget;
}
@@ -232,8 +262,8 @@ void Widget::drawToplevel (View *view, Rectangle *area)
{
assert (parent == NULL);
- lout::container::untyped::Stack iterator (true);
- Widget *retWidget = drawTotal (view, area, &iterator);
+ StackingIteratorStack iteratorStack;
+ Widget *retWidget = drawTotal (view, area, &iteratorStack);
// Everything should be finished at this point.
assert (retWidget == NULL);
diff --git a/dw/widget.hh b/dw/widget.hh
index d44454bc..a4a84cac 100644
--- a/dw/widget.hh
+++ b/dw/widget.hh
@@ -471,9 +471,9 @@ public:
bool intersects (Rectangle *area, Rectangle *intersection);
virtual Widget *draw (View *view, Rectangle *area,
- lout::container::untyped::Stack *iterator);
+ StackingIteratorStack *iteratorStack);
Widget *drawTotal (View *view, Rectangle *area,
- lout::container::untyped::Stack *iterator);
+ StackingIteratorStack *iteratorStack);
void drawToplevel (View *view, Rectangle *area);
bool buttonPress (EventButton *event);