aboutsummaryrefslogtreecommitdiff
path: root/dw
diff options
context:
space:
mode:
authorSebastian Geerken <devnull@localhost>2014-10-19 00:29:52 +0200
committerSebastian Geerken <devnull@localhost>2014-10-19 00:29:52 +0200
commit356751ca1ee7df3819dfcfcece24cfbdb37fba7c (patch)
tree8cffd8d8235aab30ef267695b8b6bf2bfa191e53 /dw
parent021d425fea3bdc727328ccbe24f508453a4ada36 (diff)
Changes in drawing process: is now interruptable. (Some errors left.)
Diffstat (limited to 'dw')
-rw-r--r--dw/layout.cc2
-rw-r--r--dw/oofawarewidget.cc138
-rw-r--r--dw/oofawarewidget.hh22
-rw-r--r--dw/ooffloatsmgr.cc37
-rw-r--r--dw/ooffloatsmgr.hh9
-rw-r--r--dw/oofpositionedmgr.cc18
-rw-r--r--dw/oofpositionedmgr.hh3
-rw-r--r--dw/outofflowmgr.hh4
-rw-r--r--dw/stackingcontextmgr.cc39
-rw-r--r--dw/stackingcontextmgr.hh12
-rw-r--r--dw/table.cc43
-rw-r--r--dw/table.hh4
-rw-r--r--dw/textblock.cc91
-rw-r--r--dw/textblock.hh9
-rw-r--r--dw/widget.cc65
-rw-r--r--dw/widget.hh17
16 files changed, 407 insertions, 106 deletions
diff --git a/dw/layout.cc b/dw/layout.cc
index 60cea8e0..43c27dd8 100644
--- a/dw/layout.cc
+++ b/dw/layout.cc
@@ -704,7 +704,7 @@ void Layout::draw (View *view, Rectangle *area)
widgetDrawArea.width = intersection.width;
widgetDrawArea.height = intersection.height;
- topLevel->draw (view, &widgetDrawArea);
+ topLevel->drawToplevel (view, &widgetDrawArea);
view->finishDrawing (&intersection);
}
diff --git a/dw/oofawarewidget.cc b/dw/oofawarewidget.cc
index 3ffdef5d..e3a1f55e 100644
--- a/dw/oofawarewidget.cc
+++ b/dw/oofawarewidget.cc
@@ -24,12 +24,30 @@
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 {
namespace oof {
+const char *OOFAwareWidget::OOFStackIterator::majorLevelText (int majorLevel)
+{
+ switch (majorLevel) {
+ case START: return "START";
+ case BACKGROUND: return "BACKGROUND";
+ case SC_BOTTOM: return "SC_BOTTOM";
+ case IN_FLOW: return "IN_FLOW";
+ case OOF_REF: return "OOF_REF";
+ case OOF_CONT: return "OOF_CONT";
+ case SC_TOP: return "SC_TOP";
+ case END: return "END";
+ default: return "???";
+ }
+}
+
int OOFAwareWidget::CLASS_ID = -1;
OOFAwareWidget::OOFAwareWidget ()
@@ -59,7 +77,7 @@ OOFAwareWidget::~OOFAwareWidget ()
DBG_OBJ_DELETE ();
}
-void OOFAwareWidget::notifySetAsTopLevel()
+void OOFAwareWidget::notifySetAsTopLevel ()
{
oofContainer[OOFM_FLOATS] = oofContainer[OOFM_ABSOLUTE]
= oofContainer[OOFM_FIXED] = this;
@@ -90,10 +108,10 @@ bool OOFAwareWidget::isOOFContainer (Widget *widget, int oofmIndex)
((OOFAwareWidget*)widget->getParent())
->isPossibleContainerParent (OOFM_FLOATS)) ||
// Inline blocks are containing blocks, too.
- widget->getStyle()->display == core::style::DISPLAY_INLINE_BLOCK ||
+ widget->getStyle()->display == DISPLAY_INLINE_BLOCK ||
// Same for blocks with 'overview' set to another value than
// (the default value) 'visible'.
- widget->getStyle()->overflow != core::style::OVERFLOW_VISIBLE ||
+ widget->getStyle()->overflow != OVERFLOW_VISIBLE ||
// Finally, "out of flow" in a narrower sense: floats;
// absolutely and fixedly positioned elements; furthermore,
// relatively positioned elements must already be
@@ -229,7 +247,7 @@ void OOFAwareWidget::correctExtremesByOOF (Extremes *extremes)
}
}
-void OOFAwareWidget::sizeAllocateStart (core::Allocation *allocation)
+void OOFAwareWidget::sizeAllocateStart (Allocation *allocation)
{
for (int i = 0; i < NUM_OOFM; i++)
@@ -251,11 +269,101 @@ void OOFAwareWidget::containerSizeChangedForChildrenOOF ()
outOfFlowMgr[i]->containerSizeChangedForChildren ();
}
-void OOFAwareWidget::drawOOF (View *view, Rectangle *area)
+Widget *OOFAwareWidget::draw (View *view, Rectangle *area, Stack *iterator)
{
- for (int i = 0; i < NUM_OOFM; i++)
- if(outOfFlowMgr[i])
- outOfFlowMgr[i]->draw(view, area);
+ DBG_OBJ_ENTER ("draw", 0, "draw", "%d, %d, %d * %d",
+ area->x, area->y, area->width, area->height);
+
+ OOFStackIterator *osi = (OOFStackIterator*)iterator->getTop ();
+ Widget *retWidget = NULL;
+
+ while (retWidget == NULL && osi->majorLevel < OOFStackIterator::END) {
+ retWidget = drawLevel (view, area, iterator, osi->majorLevel);
+
+ if (retWidget == NULL) {
+ osi->majorLevel++;
+ osi->minorLevel = osi->index = 0;
+ }
+ }
+
+
+ DBG_OBJ_MSGF ("draw", 1, "=> %p", retWidget);
+ DBG_OBJ_LEAVE ();
+ return retWidget;
+}
+
+Widget *OOFAwareWidget::drawLevel (View *view, Rectangle *area, Stack *iterator,
+ int majorLevel)
+{
+ DBG_OBJ_ENTER ("draw", 0, "OOFAwareWidget/drawLevel",
+ "(%d, %d, %d * %d), %s",
+ area->x, area->y, area->width, area->height,
+ OOFStackIterator::majorLevelText (majorLevel));
+
+ Widget *retWidget = NULL;
+
+ switch (majorLevel) {
+ case OOFStackIterator::START:
+ break;
+
+ case OOFStackIterator::BACKGROUND:
+ drawWidgetBox (view, area, false);
+ break;
+
+ case OOFStackIterator::SC_BOTTOM:
+ if (stackingContextMgr) {
+ OOFStackIterator *osi = (OOFStackIterator*)iterator->getTop ();
+ retWidget = stackingContextMgr->drawBottom (view, area, iterator,
+ &osi->index);
+ }
+ break;
+
+ case OOFStackIterator::IN_FLOW:
+ // Should be implemented in the sub class.
+ break;
+
+ case OOFStackIterator::OOF_REF:
+ // Should be implemented in the sub class (when references are hold).
+ break;
+
+ case OOFStackIterator::OOF_CONT:
+ retWidget = drawOOF (view, area, iterator);
+ break;
+
+ case OOFStackIterator::SC_TOP:
+ if (stackingContextMgr) {
+ OOFStackIterator *osi = (OOFStackIterator*)iterator->getTop ();
+ retWidget = stackingContextMgr->drawTop (view, area, iterator,
+ &osi->index);
+ }
+ break;
+
+ case OOFStackIterator::END:
+ break;
+ }
+
+ DBG_OBJ_MSGF ("draw", 1, "=> %p", retWidget);
+ DBG_OBJ_LEAVE ();
+ return retWidget;
+}
+
+Widget *OOFAwareWidget::drawOOF (View *view, Rectangle *area,
+ lout::container::untyped::Stack *iterator)
+{
+ OOFStackIterator *osi = (OOFStackIterator*)iterator->getTop ();
+ assert (osi->majorLevel == OOFStackIterator::OOF_CONT);
+
+ Widget *retWidget = NULL;
+
+ for (; retWidget == NULL && osi->minorLevel < NUM_OOFM; osi->minorLevel++) {
+ if(outOfFlowMgr[osi->minorLevel])
+ retWidget = outOfFlowMgr[osi->minorLevel]->draw (view, area, iterator,
+ &(osi->index));
+ if (retWidget == NULL)
+ osi->index = 0;
+ }
+
+ return retWidget;
}
Widget *OOFAwareWidget::getWidgetOOFAtPoint (int x, int y)
@@ -302,7 +410,7 @@ void OOFAwareWidget::removeChild (Widget *child)
assert (isWidgetOOF (child));
}
-core::Widget *OOFAwareWidget::getWidgetAtPoint (int x, int y)
+Widget *OOFAwareWidget::getWidgetAtPoint (int x, int y)
{
if (x >= allocation.x &&
y >= allocation.y &&
@@ -321,7 +429,7 @@ core::Widget *OOFAwareWidget::getWidgetAtPoint (int x, int y)
return oofWidget;
Widget *childAtPoint = NULL;
- Iterator *it =
+ core::Iterator *it =
iterator ((Content::Type)
(Content::WIDGET_IN_FLOW | Content::WIDGET_OOF_CONT),
false);
@@ -350,6 +458,16 @@ core::Widget *OOFAwareWidget::getWidgetAtPoint (int x, int y)
return NULL;
}
+
+Object *OOFAwareWidget::stackingIterator (bool atEnd)
+{
+ OOFStackIterator *osi = new OOFStackIterator ();
+ // TODO Consider atEnd.
+ osi->majorLevel = OOFStackIterator::BACKGROUND;
+ osi->minorLevel = osi->index = 0;
+ return osi;
+}
+
void OOFAwareWidget::borderChanged (int y, Widget *vloat)
{
assertNotReached ();
diff --git a/dw/oofawarewidget.hh b/dw/oofawarewidget.hh
index d2d5ef85..5525c301 100644
--- a/dw/oofawarewidget.hh
+++ b/dw/oofawarewidget.hh
@@ -105,6 +105,16 @@ protected:
void print ();
};
+ class OOFStackIterator: public lout::object::Object
+ {
+ public:
+ enum { START, BACKGROUND, SC_BOTTOM, IN_FLOW, OOF_REF, OOF_CONT, SC_TOP,
+ END } ;
+ int majorLevel, minorLevel, index;
+
+ static const char *majorLevelText (int majorLevel4);
+ };
+
inline bool isParentRefOOF (int parentRef)
{ return parentRef != -1 && (parentRef & PARENT_REF_OOFM_MASK); }
@@ -169,8 +179,12 @@ protected:
void sizeAllocateStart (core::Allocation *allocation);
void sizeAllocateEnd ();
void containerSizeChangedForChildrenOOF ();
- void drawOOF (core::View *view, core::Rectangle *area);
- core::Widget *getWidgetOOFAtPoint (int x, int y);
+ virtual Widget *drawLevel (core::View *view, core::Rectangle *area,
+ lout::container::untyped::Stack *iterator,
+ int majorLevel);
+ Widget *drawOOF (core::View *view, core::Rectangle *area,
+ lout::container::untyped::Stack *iterator);
+ Widget *getWidgetOOFAtPoint (int x, int y);
static bool isOOFContainer (Widget *widget, int oofmIndex);
@@ -190,6 +204,10 @@ public:
OOFAwareWidget ();
~OOFAwareWidget ();
+ Widget *draw (core::View *view, core::Rectangle *area,
+ lout::container::untyped::Stack *iterator);
+ lout::object::Object *stackingIterator (bool atEnd);
+
virtual void borderChanged (int y, core::Widget *vloat);
virtual void clearPositionChanged ();
virtual void oofSizeChanged (bool extremesChanged);
diff --git a/dw/ooffloatsmgr.cc b/dw/ooffloatsmgr.cc
index eeca4681..f6f488f2 100644
--- a/dw/ooffloatsmgr.cc
+++ b/dw/ooffloatsmgr.cc
@@ -1277,30 +1277,47 @@ int OOFFloatsMgr::calcFloatX (Float *vloat, Side side, int gbX, int gbWidth,
return x;
}
-void OOFFloatsMgr::draw (View *view, Rectangle *area)
+Widget *OOFFloatsMgr::draw (View *view, Rectangle *area,
+ lout::container::untyped::Stack *iterator,
+ int *index)
{
- DBG_OBJ_ENTER ("draw", 0, "draw", "%d, %d, %d * %d",
- area->x, area->y, area->width, area->height);
+ DBG_OBJ_ENTER ("draw", 0, "draw", "(%d, %d, %d * %d), [%d]",
+ area->x, area->y, area->width, area->height, *index);
- drawFloats (leftFloatsCB, view, area);
- drawFloats (rightFloatsCB, view, area);
+ Widget *retWidget = NULL;
+ if (*index < leftFloatsCB->size ())
+ retWidget = drawFloats (leftFloatsCB, view, area, iterator, index, 0);
+
+ if (retWidget == NULL)
+ retWidget = drawFloats (rightFloatsCB, view, area, iterator, index,
+ leftFloatsCB->size ());
+
+ DBG_OBJ_MSGF ("draw", 1, "=> %p", retWidget);
DBG_OBJ_LEAVE ();
+ return retWidget;
}
-void OOFFloatsMgr::drawFloats (SortedFloatsVector *list, View *view,
- Rectangle *area)
+Widget *OOFFloatsMgr::drawFloats (SortedFloatsVector *list, View *view,
+ Rectangle *area,
+ lout::container::untyped::Stack *iterator,
+ int *index, int startIndex)
{
// This could be improved, since the list is sorted: search the
// first float fitting into the area, and iterate until one is
// found below the area.
- for (int i = 0; i < list->size(); i++) {
- Widget *childWidget = list->get(i)->getWidget ();
+
+ 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))
- childWidget->draw (view, &childArea);
+ retWidget = childWidget->drawTotal (view, &childArea, iterator);
}
+
+ return retWidget;
}
void OOFFloatsMgr::addWidgetInFlow (OOFAwareWidget *textblock,
diff --git a/dw/ooffloatsmgr.hh b/dw/ooffloatsmgr.hh
index 274e5d3c..e90a72be 100644
--- a/dw/ooffloatsmgr.hh
+++ b/dw/ooffloatsmgr.hh
@@ -284,8 +284,10 @@ private:
bool doFloatsExceedCB (Side side);
bool haveExtremesChanged (Side side);
- void drawFloats (SortedFloatsVector *list, core::View *view,
- core::Rectangle *area);
+ core::Widget *drawFloats (SortedFloatsVector *list, core::View *view,
+ core::Rectangle *area,
+ lout::container::untyped::Stack *iterator,
+ int *index, int startIndex);
core::Widget *getFloatWidgetAtPoint (SortedFloatsVector *list, int x, int y);
bool collidesV (Float *vloat, Float *other, SFVType type, int *yReal);
@@ -340,7 +342,8 @@ public:
core::Allocation *allocation);
void sizeAllocateEnd (OOFAwareWidget *caller);
void containerSizeChangedForChildren ();
- void draw (core::View *view, core::Rectangle *area);
+ core::Widget *draw (core::View *view, core::Rectangle *area,
+ lout::container::untyped::Stack *iterator, int *index);
void markSizeChange (int ref);
void markExtremesChange (int ref);
diff --git a/dw/oofpositionedmgr.cc b/dw/oofpositionedmgr.cc
index 449ea322..07bc45aa 100644
--- a/dw/oofpositionedmgr.cc
+++ b/dw/oofpositionedmgr.cc
@@ -168,20 +168,26 @@ bool OOFPositionedMgr::haveExtremesChanged ()
}
-void OOFPositionedMgr::draw (View *view, Rectangle *area)
+Widget *OOFPositionedMgr::draw (View *view, Rectangle *area,
+ lout::container::untyped::Stack *iterator,
+ int *index)
{
- DBG_OBJ_ENTER ("draw", 0, "draw", "%d, %d, %d * %d",
- area->x, area->y, area->width, area->height);
+ DBG_OBJ_ENTER ("draw", 0, "draw", "(%d, %d, %d * %d), [%d]",
+ area->x, area->y, area->width, area->height, *index);
- for (int i = 0; i < children->size(); i++) {
- Widget *childWidget = children->get(i)->widget;
+ 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))
- childWidget->draw (view, &childArea);
+ retWidget = childWidget->drawTotal (view, &childArea, iterator);
}
+ DBG_OBJ_MSGF ("draw", 1, "=> %p", retWidget);
DBG_OBJ_LEAVE ();
+ return retWidget;
}
void OOFPositionedMgr::addWidgetInFlow (OOFAwareWidget *widget,
diff --git a/dw/oofpositionedmgr.hh b/dw/oofpositionedmgr.hh
index 40f3af43..c7f55262 100644
--- a/dw/oofpositionedmgr.hh
+++ b/dw/oofpositionedmgr.hh
@@ -64,7 +64,8 @@ public:
core::Allocation *allocation);
void sizeAllocateEnd (OOFAwareWidget *caller);
void containerSizeChangedForChildren ();
- void draw (core::View *view, core::Rectangle *area);
+ core::Widget *draw (core::View *view, core::Rectangle *area,
+ lout::container::untyped::Stack *iterator, int *index);
void markSizeChange (int ref);
void markExtremesChange (int ref);
diff --git a/dw/outofflowmgr.hh b/dw/outofflowmgr.hh
index b5f50c56..5b74e513 100644
--- a/dw/outofflowmgr.hh
+++ b/dw/outofflowmgr.hh
@@ -25,7 +25,9 @@ public:
core::Allocation *allocation) = 0;
virtual void sizeAllocateEnd (OOFAwareWidget *caller) = 0;
virtual void containerSizeChangedForChildren () = 0;
- virtual void draw (core::View *view, core::Rectangle *area) = 0;
+ virtual core::Widget *draw (core::View *view, core::Rectangle *area,
+ lout::container::untyped::Stack *iterator,
+ int *index) = 0;
virtual void markSizeChange (int ref) = 0;
virtual void markExtremesChange (int ref) = 0;
diff --git a/dw/stackingcontextmgr.cc b/dw/stackingcontextmgr.cc
index 373756e2..c7b5f783 100644
--- a/dw/stackingcontextmgr.cc
+++ b/dw/stackingcontextmgr.cc
@@ -60,48 +60,67 @@ void StackingContextMgr::addChildSCWidget (Widget *widget)
DBG_OBJ_ARRSET_PTR ("childSCWidgets", childSCWidgets->size() - 1, widget);
}
-void StackingContextMgr::drawBottom (View *view, Rectangle *area)
+Widget *StackingContextMgr::drawBottom (View *view, Rectangle *area,
+ lout::container::untyped::Stack
+ *iterator,
+ int *index)
{
DBG_OBJ_ENTER ("draw", 0, "drawBottom", "%d, %d, %d * %d",
area->x, area->y, area->width, area->height);
- draw (view, area, INT_MIN, -1);
+ Widget *retWidget = draw (view, area, iterator, index, INT_MIN, -1);
DBG_OBJ_LEAVE ();
+ return retWidget;
}
-void StackingContextMgr::drawTop (View *view, Rectangle *area)
+Widget *StackingContextMgr::drawTop (View *view, Rectangle *area,
+ lout::container::untyped::Stack *iterator,
+ int *index)
{
DBG_OBJ_ENTER ("draw", 0, "drawTop", "%d, %d, %d * %d",
area->x, area->y, area->width, area->height);
- draw (view, area, 0, INT_MAX);
+ Widget *retWidget = draw (view, area, iterator, index, 0, INT_MAX);
DBG_OBJ_LEAVE ();
+ return retWidget;
}
-void StackingContextMgr::draw (View *view, Rectangle *area, int startZIndex,
- int endZIndex)
+Widget *StackingContextMgr::draw (View *view, Rectangle *area,
+ lout::container::untyped::Stack *iterator,
+ int *index, int startZIndex, int endZIndex)
{
DBG_OBJ_ENTER ("draw", 0, "draw", "[%d, %d, %d * %d], %d, %d",
area->x, area->y, area->width, area->height, startZIndex,
endZIndex);
+ DBG_OBJ_MSGF ("draw", 1, "initially: index = %d (of %d)",
+ *index, childSCWidgets->size ());
+
+ Widget *retWidget = NULL;
for (int zIndex = max (minZIndex, startZIndex);
- zIndex <= min (maxZIndex, endZIndex); zIndex++) {
+ retWidget == NULL && zIndex <= min (maxZIndex, endZIndex);
+ zIndex++) {
DBG_OBJ_MSGF ("draw", 1, "drawing zIndex = %d", zIndex);
DBG_OBJ_MSG_START ();
- for (int i = 0; i < childSCWidgets->size (); i++) {
- Widget *child = childSCWidgets->get (i);
+ // TODO This is wrong.
+ for (; retWidget == NULL && *index < childSCWidgets->size ();
+ (*index)++) {
+ 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 == zIndex &&
child->intersects (area, &childArea))
- child->draw (view, &childArea);
+ retWidget = child->drawTotal (view, &childArea, iterator);
}
DBG_OBJ_MSG_END ();
}
+ DBG_OBJ_MSGF ("draw", 1, "finally: index = %d (of %d)",
+ *index, childSCWidgets->size ());
+ DBG_OBJ_MSGF ("draw", 1, "=> %p", retWidget);
DBG_OBJ_LEAVE ();
+ return retWidget;
}
Widget *StackingContextMgr::getTopWidgetAtPoint (int x, int y)
diff --git a/dw/stackingcontextmgr.hh b/dw/stackingcontextmgr.hh
index 5c6a0d2f..e7254d7f 100644
--- a/dw/stackingcontextmgr.hh
+++ b/dw/stackingcontextmgr.hh
@@ -23,7 +23,9 @@ private:
lout::container::typed::Vector<Widget> *childSCWidgets;
int minZIndex, maxZIndex;
- void draw (View *view, Rectangle *area, int startZIndex, int endZIndex);
+ Widget *draw (View *view, Rectangle *area,
+ lout::container::untyped::Stack *iterator,
+ int *index, int startZIndex, int endZIndex);
Widget *getWidgetAtPoint (int x, int y, int startZIndex, int endZIndex);
public:
@@ -45,8 +47,12 @@ public:
void addChildSCWidget (Widget *widget);
- void drawBottom (View *view, Rectangle *area);
- void drawTop (View *view, Rectangle *area);
+ Widget *drawBottom (View *view, Rectangle *area,
+ lout::container::untyped::Stack *iterator,
+ int *index);
+ Widget *drawTop (View *view, Rectangle *area,
+ lout::container::untyped::Stack *iterator,
+ 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 5e4083ff..f9858ddd 100644
--- a/dw/table.cc
+++ b/dw/table.cc
@@ -356,21 +356,24 @@ bool Table::isBlockLevel ()
return true;
}
-void Table::draw (core::View *view, core::Rectangle *area)
+core::Widget *Table::drawLevel (core::View *view, core::Rectangle *area,
+ lout::container::untyped::Stack *iterator,
+ int majorLevel)
{
- DBG_OBJ_ENTER ("draw", 0, "draw", "%d, %d, %d * %d",
- area->x, area->y, area->width, area->height);
+ DBG_OBJ_ENTER ("draw", 0, "Table/drawLevel", "(%d, %d, %d * %d), %s",
+ area->x, area->y, area->width, area->height,
+ OOFStackIterator::majorLevelText (majorLevel));
- // Can be optimized, by iterating on the lines in area.
- drawWidgetBox (view, area, false);
+ Widget *retWidget = NULL;
#if 0
+ // This old code belongs perhaps to the background. Check when reactivated.
int offx = getStyle()->boxOffsetX () + getStyle()->hBorderSpacing;
int offy = getStyle()->boxOffsetY () + getStyle()->vBorderSpacing;
int width = getContentWidth ();
-
+
// This part seems unnecessary. It also segfaulted sometimes when
- // cumHeight size was less than numRows. --jcid
+ // cumHeight size was less than numRows. --jcid
for (int row = 0; row < numRows; row++) {
if (rowStyle->get (row))
drawBox (view, rowStyle->get (row), area,
@@ -381,19 +384,27 @@ void Table::draw (core::View *view, core::Rectangle *area)
}
#endif
- for (int i = 0; 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))
- child->draw (view, &childArea);
+ 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);
+ }
}
- }
+ break;
- drawOOF (view, area);
+ default:
+ retWidget = OOFAwareWidget::drawLevel (view, area, iterator, majorLevel);
+ break;
+ }
+ DBG_OBJ_MSGF ("draw", 1, "=> %p", retWidget);
DBG_OBJ_LEAVE ();
+ return retWidget;
}
void Table::removeChild (Widget *child)
diff --git a/dw/table.hh b/dw/table.hh
index 560a2cb7..502b1332 100644
--- a/dw/table.hh
+++ b/dw/table.hh
@@ -471,7 +471,9 @@ protected:
bool isBlockLevel ();
- void draw (core::View *view, core::Rectangle *area);
+ Widget *drawLevel (core::View *view, core::Rectangle *area,
+ lout::container::untyped::Stack *iterator,
+ int majorLevel);
//bool buttonPressImpl (core::EventButton *event);
//bool buttonReleaseImpl (core::EventButton *event);
diff --git a/dw/textblock.cc b/dw/textblock.cc
index 92d7f662..4b915f2e 100644
--- a/dw/textblock.cc
+++ b/dw/textblock.cc
@@ -1447,10 +1447,16 @@ 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)
+core::Widget *Textblock::drawLine (Line *line, core::View *view,
+ core::Rectangle *area,
+ lout::container::untyped::Stack *iterator)
{
DBG_OBJ_ENTER ("draw", 0, "drawLine", "..., %d, %d, %d * %d",
area->x, area->y, area->width, area->height);
+
+ OOFStackIterator *osi = (OOFStackIterator*)iterator->getTop ();
+
+ Widget *retWidget = NULL;
int xWidget = line->textOffset;
int yWidgetBase = lineYOffsetWidget (line) + line->borderAscent;
@@ -1461,10 +1467,13 @@ void Textblock::drawLine (Line *line, core::View *view, core::Rectangle *area)
DBG_MSG_WORD ("draw", 1, "<i>line starts with: </i>", line->firstWord, "");
DBG_MSG_WORD ("draw", 1, "<i>line ends with: </i>", line->lastWord, "");
- for (int wordIndex = line->firstWord;
- wordIndex <= line->lastWord && xWidget < area->x + area->width;
- wordIndex++) {
- Word *word = words->getRef(wordIndex);
+ if (osi->index < line->firstWord)
+ osi->index = line->firstWord;
+
+ for (; retWidget == NULL && osi->index <= line->lastWord
+ && xWidget < area->x + area->width;
+ osi->index++) {
+ Word *word = words->getRef (osi->index);
int wordSize = word->size.width;
if (xWidget + wordSize + word->hyphenWidth + word->effSpace >= area->x) {
@@ -1478,36 +1487,36 @@ void Textblock::drawLine (Line *line, core::View *view, core::Rectangle *area)
if (!core::StackingContextMgr::handledByStackingContextMgr
(child) &&
child->intersects (area, &childArea))
- child->draw (view, &childArea);
+ retWidget = child->drawTotal (view, &childArea, iterator);
} else {
- int wordIndex2 = wordIndex;
+ int wordIndex2 = osi->index;
while (wordIndex2 < line->lastWord &&
(words->getRef(wordIndex2)->flags
& Word::DRAW_AS_ONE_TEXT) &&
word->style == words->getRef(wordIndex2 + 1)->style)
wordIndex2++;
- drawWord(line, wordIndex, wordIndex2, view, area,
+ drawWord(line, osi->index, wordIndex2, view, area,
xWidget, yWidgetBase);
wordSize = 0;
- for (int i = wordIndex; i <= wordIndex2; i++)
+ for (int i = osi->index; i <= wordIndex2; i++)
wordSize += words->getRef(i)->size.width;
- wordIndex = wordIndex2;
- word = words->getRef(wordIndex);
+ osi->index = wordIndex2;
+ word = words->getRef (osi->index);
}
}
- if (word->effSpace > 0 && wordIndex < line->lastWord &&
- words->getRef(wordIndex + 1)->content.type !=
+ if (word->effSpace > 0 && osi->index < line->lastWord &&
+ words->getRef(osi->index + 1)->content.type !=
core::Content::BREAK) {
if (word->spaceStyle->hasBackground ())
drawBox (view, word->spaceStyle, area,
xWidget + wordSize,
yWidgetBase - line->borderAscent, word->effSpace,
line->borderAscent + line->borderDescent, false);
- drawSpace(wordIndex, view, area, xWidget + wordSize,
- yWidgetBase);
+ drawSpace (osi->index, view, area, xWidget + wordSize,
+ yWidgetBase);
}
}
@@ -1515,7 +1524,9 @@ void Textblock::drawLine (Line *line, core::View *view, core::Rectangle *area)
xWidget += wordSize + word->effSpace;
}
+ DBG_OBJ_MSGF ("draw", 1, "=> %p", retWidget);
DBG_OBJ_LEAVE ();
+ return retWidget;
}
/**
@@ -1683,36 +1694,42 @@ Textblock::Word *Textblock::findWord (int x, int y, bool *inSpace)
return NULL;
}
-void Textblock::draw (core::View *view, core::Rectangle *area)
+core::Widget *Textblock::drawLevel (core::View *view, core::Rectangle *area,
+ lout::container::untyped::Stack *iterator,
+ int majorLevel)
{
- DBG_OBJ_ENTER ("draw", 0, "draw", "%d, %d, %d * %d",
- area->x, area->y, area->width, area->height);
+ DBG_OBJ_ENTER ("draw", 0, "Textblock/drawLevel", "(%d, %d, %d * %d), %s",
+ area->x, area->y, area->width, area->height,
+ OOFStackIterator::majorLevelText (majorLevel));
- int lineIndex;
- Line *line;
+ Widget *retWidget = NULL;
- drawWidgetBox (view, area, false);
-
- if (stackingContextMgr)
- stackingContextMgr->drawBottom (view, area);
-
- lineIndex = findLineIndexWhenAllocated (area->y);
+ switch (majorLevel) {
+ case OOFStackIterator::IN_FLOW:
+ // Osi->index (word index) is regarded in drawLine.
+ for (int lineIndex = findLineIndexWhenAllocated (area->y);
+ retWidget == NULL && lineIndex < lines->size (); lineIndex++) {
+ Line *line = lines->getRef (lineIndex);
+ if (lineYOffsetWidget (line) >= area->y + area->height)
+ break;
+
+ DBG_OBJ_MSGF ("draw", 0, "line %d (of %d)", lineIndex, lines->size ());
+ retWidget = drawLine (line, view, area, iterator);
+ }
+ break;
- for (; lineIndex < lines->size (); lineIndex++) {
- line = lines->getRef (lineIndex);
- if (lineYOffsetWidget (line) >= area->y + area->height)
- break;
+ case OOFStackIterator::OOF_REF:
+ // TODO
+ break;
- DBG_OBJ_MSGF ("draw", 0, "line %d (of %d)", lineIndex, lines->size ());
- drawLine (line, view, area);
+ default:
+ retWidget = OOFAwareWidget::drawLevel (view, area, iterator, majorLevel);
+ break;
}
- drawOOF (view, area);
-
- if (stackingContextMgr)
- stackingContextMgr->drawTop (view, area);
-
+ DBG_OBJ_MSGF ("draw", 1, "=> %p", retWidget);
DBG_OBJ_LEAVE ();
+ return retWidget;
}
/**
diff --git a/dw/textblock.hh b/dw/textblock.hh
index 74ef6525..c9f86fa5 100644
--- a/dw/textblock.hh
+++ b/dw/textblock.hh
@@ -642,7 +642,8 @@ protected:
core::Rectangle *area, int xWidget, int yWidgetBase);
void drawSpace (int wordIndex, core::View *view, core::Rectangle *area,
int xWidget, int yWidgetBase);
- void drawLine (Line *line, core::View *view, core::Rectangle *area);
+ Widget *drawLine (Line *line, core::View *view, core::Rectangle *area,
+ lout::container::untyped::Stack *iterator);
int findLineIndex (int y);
int findLineIndexWhenNotAllocated (int y);
int findLineIndexWhenAllocated (int y);
@@ -797,6 +798,10 @@ protected:
void alignLine (int lineIndex);
void calcTextOffset (int lineIndex, int totalWidth);
+ Widget *drawLevel (core::View *view, core::Rectangle *area,
+ lout::container::untyped::Stack *iterator,
+ int majorLevel);
+
void sizeRequestImpl (core::Requisition *requisition);
void getExtremesImpl (core::Extremes *extremes);
void sizeAllocateImpl (core::Allocation *allocation);
@@ -816,8 +821,6 @@ protected:
bool isBlockLevel ();
- void draw (core::View *view, core::Rectangle *area);
-
bool buttonPressImpl (core::EventButton *event);
bool buttonReleaseImpl (core::EventButton *event);
bool motionNotifyImpl (core::EventMotion *event);
diff --git a/dw/widget.cc b/dw/widget.cc
index be103756..cf955dec 100644
--- a/dw/widget.cc
+++ b/dw/widget.cc
@@ -179,6 +179,66 @@ bool Widget::intersects (Rectangle *area, Rectangle *intersection)
return r;
}
+/** Area is given in widget coordinates. */
+void Widget::draw (View *view, Rectangle *area)
+{
+ DBG_OBJ_MSG ("draw", 0, "<b>Widget::draw not implemented</b>");
+ misc::assertNotReached ();
+}
+
+/** Area is given in widget coordinates. */
+Widget *Widget::draw (View *view, Rectangle *area,
+ lout::container::untyped::Stack *iterator)
+{
+ // Suitable for widgets without children.
+ draw (view, area);
+ return NULL;
+}
+
+Widget *Widget::drawTotal (View *view, Rectangle *area,
+ lout::container::untyped::Stack *iterator)
+{
+ 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 ());
+ } else
+ DBG_OBJ_MSGF ("draw", 1, "nothing on iterator; %d element(s)",
+ iterator->size ());
+
+
+ Widget *retWidget = draw (view, area, iterator);
+
+ // 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.
+
+ assert (retWidget == NULL || si != NULL);
+
+ if (retWidget == NULL && si != NULL)
+ iterator->pop ();
+
+ DBG_OBJ_MSGF ("draw", 1, "=> %p", retWidget);
+ DBG_OBJ_LEAVE ();
+ return retWidget;
+}
+
+void Widget::drawToplevel (View *view, Rectangle *area)
+{
+ assert (parent == NULL);
+
+ lout::container::untyped::Stack iterator (true);
+ Widget *retWidget = drawTotal (view, area, &iterator);
+
+ // Everything should be finished at this point.
+ assert (retWidget == NULL);
+}
+
void Widget::setParent (Widget *parent)
{
this->parent = parent;
@@ -1835,6 +1895,11 @@ void Widget::leaveNotifyImpl (EventCrossing *)
tooltip->onLeave();
}
+lout::object::Object *Widget::stackingIterator (bool atEnd)
+{
+ return NULL;
+}
+
void Widget::removeChild (Widget *child)
{
// Should be implemented.
diff --git a/dw/widget.hh b/dw/widget.hh
index 4ad397ee..d44454bc 100644
--- a/dw/widget.hh
+++ b/dw/widget.hh
@@ -277,6 +277,8 @@ protected:
inline void queueResize (int ref, bool extremesChanged)
{ queueResize (ref, extremesChanged, false); }
+ virtual void draw (View *view, Rectangle *area);
+
/**
* \brief See \ref dw-widget-sizes.
*/
@@ -468,8 +470,11 @@ public:
bool intersects (Rectangle *area, Rectangle *intersection);
- /** Area is given in widget coordinates. */
- virtual void draw (View *view, Rectangle *area) = 0;
+ virtual Widget *draw (View *view, Rectangle *area,
+ lout::container::untyped::Stack *iterator);
+ Widget *drawTotal (View *view, Rectangle *area,
+ lout::container::untyped::Stack *iterator);
+ void drawToplevel (View *view, Rectangle *area);
bool buttonPress (EventButton *event);
bool buttonRelease (EventButton *event);
@@ -523,6 +528,14 @@ public:
* dw::core::Iterator::prev in this case.
*/
virtual Iterator *iterator (Content::Type mask, bool atEnd) = 0;
+
+ /**
+ * \brief ...
+ *
+ * May return NULL.
+ */
+ virtual lout::object::Object *stackingIterator (bool atEnd);
+
virtual void removeChild (Widget *child);
};