diff options
author | Sebastian Geerken <devnull@localhost> | 2014-09-12 20:28:56 +0200 |
---|---|---|
committer | Sebastian Geerken <devnull@localhost> | 2014-09-12 20:28:56 +0200 |
commit | ae2d990af432ea56375936e5ec9872fe0503d61f (patch) | |
tree | 0b5bf1d9fbce4481ae3fc49b86b6362ae071a12f /dw | |
parent | f9f3fcc4b5f72de36d6cb231baeaf21a3b615704 (diff) |
Table gets OOF aware, part 1. Warning: crashes!
Diffstat (limited to 'dw')
-rw-r--r-- | dw/oofawarewidget.cc | 81 | ||||
-rw-r--r-- | dw/oofawarewidget.hh | 58 | ||||
-rw-r--r-- | dw/oofpositionedmgr.cc | 2 | ||||
-rw-r--r-- | dw/outofflowmgr.hh | 3 | ||||
-rw-r--r-- | dw/table.cc | 14 | ||||
-rw-r--r-- | dw/table.hh | 4 | ||||
-rw-r--r-- | dw/textblock.cc | 81 | ||||
-rw-r--r-- | dw/textblock.hh | 32 |
8 files changed, 173 insertions, 102 deletions
diff --git a/dw/oofawarewidget.cc b/dw/oofawarewidget.cc index 5747b78e..a71b3f0d 100644 --- a/dw/oofawarewidget.cc +++ b/dw/oofawarewidget.cc @@ -45,6 +45,17 @@ OOFAwareWidget::OOFAwareWidget () OOFAwareWidget::~OOFAwareWidget () { + for (int i = 0; i < NUM_OOFM; i++) { + if(outOfFlowMgr[i]) { + // I feel more comfortable by letting the OOF aware widget delete + // these widgets, instead of doing this in ~OutOfFlowMgr. + for (int j = 0; j < outOfFlowMgr[i]->getNumWidgets (); j++) + delete outOfFlowMgr[i]->getWidget (j); + + delete outOfFlowMgr[i]; + } + } + DBG_OBJ_DELETE (); } @@ -132,8 +143,7 @@ void OOFAwareWidget::notifySetParent () oofContainer[oofmIndex] = (OOFAwareWidget*)widget; } - DBG_OBJ_ARRSET_PTR ("containingBlock", oofmIndex, - containingBlock[oofmIndex]); + DBG_OBJ_ARRSET_PTR ("oofContainer", oofmIndex, oofContainer[oofmIndex]); assert (oofContainer[oofmIndex] != NULL); } @@ -163,6 +173,46 @@ void OOFAwareWidget::initOutOfFlowMgrs () } } +void OOFAwareWidget::correctRequisitionByOOF (Requisition *requisition) +{ + for (int i = 0; i < NUM_OOFM; i++) { + if (outOfFlowMgr[i]) { + int oofWidth, oofHeight; + DBG_OBJ_MSGF ("resize", 1, + "before considering widgets by OOFM #%d: %d * (%d + %d)", + i, requisition->width, requisition->ascent, + requisition->descent); + + outOfFlowMgr[i]->getSize (requisition, &oofWidth, &oofHeight); + + if (oofWidth > requisition->width) + requisition->width = oofWidth; + if (oofHeight > requisition->ascent + requisition->descent) + requisition->descent = oofHeight - requisition->ascent; + } + } +} + +void OOFAwareWidget::correctExtremesByOOF (Extremes *extremes) +{ + for (int i = 0; i < NUM_OOFM; i++) { + if (outOfFlowMgr[i]) { + int oofMinWidth, oofMaxWidth; + outOfFlowMgr[i]->getExtremes (extremes, &oofMinWidth, &oofMaxWidth); + + DBG_OBJ_MSGF ("resize", 1, "OOFM (#%d) correction: %d / %d", + i, oofMinWidth, oofMaxWidth); + + extremes->minWidth = max (extremes->minWidth, oofMinWidth); + extremes->minWidthIntrinsic = max (extremes->minWidthIntrinsic, + oofMinWidth); + extremes->maxWidth = max (extremes->maxWidth, oofMaxWidth); + extremes->maxWidthIntrinsic = max (extremes->maxWidthIntrinsic, + oofMinWidth); + } + } +} + void OOFAwareWidget::sizeAllocateStart (core::Allocation *allocation) { @@ -178,6 +228,33 @@ void OOFAwareWidget::sizeAllocateEnd () oofContainer[i]->outOfFlowMgr[i]->sizeAllocateEnd (this); } +void OOFAwareWidget::containerSizeChangedForChildrenOOF () +{ + for (int i = 0; i < NUM_OOFM; i++) + if (outOfFlowMgr[i]) + outOfFlowMgr[i]->containerSizeChangedForChildren (); +} + +void OOFAwareWidget::drawOOF (View *view, Rectangle *area) +{ + for (int i = 0; i < NUM_OOFM; i++) + if(outOfFlowMgr[i]) + outOfFlowMgr[i]->draw(view, area); +} + +Widget *OOFAwareWidget::getWidgetOOFAtPoint (int x, int y, int level) +{ + for (int i = 0; i < NUM_OOFM; i++) { + Widget *oofWidget = + outOfFlowMgr[i] ? + outOfFlowMgr[i]->getWidgetAtPoint (x, y, level) : NULL; + if (oofWidget) + return oofWidget; + } + + return NULL; +} + void OOFAwareWidget::borderChanged (int y, Widget *vloat) { assertNotReached (); diff --git a/dw/oofawarewidget.hh b/dw/oofawarewidget.hh index 7121f9ea..9421bae0 100644 --- a/dw/oofawarewidget.hh +++ b/dw/oofawarewidget.hh @@ -14,6 +14,26 @@ namespace oof { * * (Perhaps it should be diffenciated between the two roles, container * and generator, but this would make multiple inheritance necessary.) + * + * A sub class should at least take care to call these methods at the + * respective points: + * + * - dw::oof::OOFAwareWidget::correctRequisitionByOOF (from + * dw::core::Widget::getExtremesImpl) + * - dw::oof::OOFAwareWidget::correctExtremesByOOF (from + * dw::core::Widget::sizeRequestImpl) + * - dw::oof::OOFAwareWidget::sizeAllocateStart + * - dw::oof::OOFAwareWidget::sizeAllocateEnd (latter two from + * dw::core::Widget::sizeAllocateImpl) + * - dw::oof::OOFAwareWidget::containerSizeChangedForChildrenOOF + * (from dw::core::Widget::containerSizeChangedForChildren) + * - dw::oof::OOFAwareWidget::drawOOF (from dw::core::Widget::draw) + * - dw::oof::OOFAwareWidget::getWidgetOOFAtPoint (from + * dw::core::Widget::getWidgetAtPoint) + * + * See dw::Textblock on how this is done best. For both generators and + * containers of floats (which is only implemented by dw::Textblock) + * it gets a bit more complicated. */ class OOFAwareWidget: public core::Widget { @@ -22,6 +42,39 @@ protected: enum { PARENT_REF_OOFM_BITS = 2, PARENT_REF_OOFM_MASK = (1 << PARENT_REF_OOFM_BITS) - 1 }; + inline bool isParentRefOOF (int parentRef) + { return parentRef != -1 && (parentRef & PARENT_REF_OOFM_MASK); } + + inline int makeParentRefInFlow (int inFlowSubRef) + { return (inFlowSubRef << PARENT_REF_OOFM_BITS); } + inline int getParentRefInFlowSubRef (int parentRef) + { assert (!isParentRefOOF (parentRef)); + return parentRef >> PARENT_REF_OOFM_BITS; } + + inline int makeParentRefOOF (int oofmIndex, int oofmSubRef) + { return (oofmSubRef << PARENT_REF_OOFM_BITS) | (oofmIndex + 1); } + inline int getParentRefOOFSubRef (int parentRef) + { assert (isParentRefOOF (parentRef)); + return parentRef >> PARENT_REF_OOFM_BITS; } + inline int getParentRefOOFIndex (int parentRef) + { assert (isParentRefOOF (parentRef)); + return (parentRef & PARENT_REF_OOFM_MASK) - 1; } + inline oof::OutOfFlowMgr *getParentRefOutOfFlowMgr (int parentRef) + { return outOfFlowMgr[getParentRefOOFIndex (parentRef)]; } + + inline bool isWidgetOOF (Widget *widget) + { return isParentRefOOF (widget->parentRef); } + + inline int getWidgetInFlowSubRef (Widget *widget) + { return getParentRefInFlowSubRef (widget->parentRef); } + + inline int getWidgetOOFSubRef (Widget *widget) + { return getParentRefOOFSubRef (widget->parentRef); } + inline int getWidgetOOFIndex (Widget *widget) + { return getParentRefOOFIndex (widget->parentRef); } + inline oof::OutOfFlowMgr *getWidgetOutOfFlowMgr (Widget *widget) + { return getParentRefOutOfFlowMgr (widget->parentRef); } + OOFAwareWidget *oofContainer[NUM_OOFM]; OutOfFlowMgr *outOfFlowMgr[NUM_OOFM]; @@ -43,8 +96,13 @@ protected: { return widget->getStyle()->position == core::style::POSITION_RELATIVE; } void initOutOfFlowMgrs (); + void correctRequisitionByOOF (core::Requisition *requisition); + void correctExtremesByOOF (core::Extremes *extremes); void sizeAllocateStart (core::Allocation *allocation); void sizeAllocateEnd (); + void containerSizeChangedForChildrenOOF (); + void drawOOF (core::View *view, core::Rectangle *area); + core::Widget *getWidgetOOFAtPoint (int x, int y, int level); void notifySetAsTopLevel(); void notifySetParent(); diff --git a/dw/oofpositionedmgr.cc b/dw/oofpositionedmgr.cc index e314e641..709a5b91 100644 --- a/dw/oofpositionedmgr.cc +++ b/dw/oofpositionedmgr.cc @@ -181,7 +181,7 @@ void OOFPositionedMgr::addWidgetInFlow (OOFAwareWidget *widget, { } -int OOFPositionedMgr::addWidgetOOF (Widget *widget, OOFAwareWidget *generater, +int OOFPositionedMgr::addWidgetOOF (Widget *widget, OOFAwareWidget *generator, int externalIndex) { DBG_OBJ_ENTER ("construct.oofm", 0, "addWidgetOOF", "%p, %p, %d", diff --git a/dw/outofflowmgr.hh b/dw/outofflowmgr.hh index 0245803c..405db354 100644 --- a/dw/outofflowmgr.hh +++ b/dw/outofflowmgr.hh @@ -5,6 +5,9 @@ namespace dw { +/** + * \brief Out Of Flow. See \ref dw-out-of-flow. + */ namespace oof { class OOFAwareWidget; diff --git a/dw/table.cc b/dw/table.cc index 746856c7..a59c0120 100644 --- a/dw/table.cc +++ b/dw/table.cc @@ -124,6 +124,9 @@ void Table::sizeRequestImpl (core::Requisition *requisition) correctRequisition (requisition, core::splitHeightPreserveDescent); + // For the order, see similar reasoning for dw::Textblock. + correctRequisitionByOOF (requisition); + DBG_OBJ_LEAVE (); } @@ -152,6 +155,9 @@ void Table::getExtremesImpl (core::Extremes *extremes) correctExtremes (extremes); + // For the order, see similar reasoning for dw::Textblock. + correctExtremesByOOF (extremes); + DBG_OBJ_LEAVE (); } @@ -161,6 +167,8 @@ void Table::sizeAllocateImpl (core::Allocation *allocation) allocation->x, allocation->y, allocation->width, allocation->ascent, allocation->descent); + sizeAllocateStart (allocation); + calcCellSizes (true); /** @@ -201,6 +209,8 @@ void Table::sizeAllocateImpl (core::Allocation *allocation) x += colWidths->get (col) + getStyle()->hBorderSpacing; } + sizeAllocateEnd (); + DBG_OBJ_LEAVE (); } @@ -306,6 +316,8 @@ void Table::containerSizeChangedForChildren () } } + containerSizeChangedForChildrenOOF (); + DBG_OBJ_LEAVE (); } @@ -371,6 +383,8 @@ void Table::draw (core::View *view, core::Rectangle *area) child->draw (view, &childArea); } } + + drawOOF (view, area); } void Table::removeChild (Widget *child) diff --git a/dw/table.hh b/dw/table.hh index a8823ca0..dffec1be 100644 --- a/dw/table.hh +++ b/dw/table.hh @@ -1,7 +1,7 @@ #ifndef __DW_TABLE_HH__ #define __DW_TABLE_HH__ -#include "core.hh" +#include "oofawarewidget.hh" #include "alignedtablecell.hh" #include "../lout/misc.hh" @@ -319,7 +319,7 @@ namespace dw { * Here, \em foo-bar refers to the attribute \em bar of the tag \em foo foo. * Look at the HTML parser for more details. */ -class Table: public core::Widget +class Table: public oof::OOFAwareWidget { private: struct Child diff --git a/dw/textblock.cc b/dw/textblock.cc index 64f5fc23..2706fba4 100644 --- a/dw/textblock.cc +++ b/dw/textblock.cc @@ -300,18 +300,6 @@ Textblock::~Textblock () delete words; delete anchors; - for (int i = 0; i < NUM_OOFM; i++) { - if(outOfFlowMgr[i]) { - // I feel more comfortable by letting the textblock delete these - // widgets, instead of doing this in ~OutOfFlowMgr. - - for (int j = 0; j < outOfFlowMgr[i]->getNumWidgets (); j++) - delete outOfFlowMgr[i]->getWidget (j); - - delete outOfFlowMgr[i]; - } - } - /* Make sure we don't own widgets anymore. Necessary before call of parent class destructor. (???) */ words = NULL; @@ -404,22 +392,7 @@ void Textblock::sizeRequestImpl (core::Requisition *requisition) // Is this really what we want? An alternative could be that // OutOfFlowMgr::getSize honours CSS attributes an corrected sizes. - for (int i = 0; i < NUM_OOFM; i++) { - if (outOfFlowMgr[i]) { - int oofWidth, oofHeight; - DBG_OBJ_MSGF ("resize", 1, - "before considering widgets by OOFM #%d: %d * (%d + %d)", - i, requisition->width, requisition->ascent, - requisition->descent); - - outOfFlowMgr[i]->getSize (requisition, &oofWidth, &oofHeight); - - if (oofWidth > requisition->width) - requisition->width = oofWidth; - if (oofHeight > requisition->ascent + requisition->descent) - requisition->descent = oofHeight - requisition->ascent; - } - } + correctRequisitionByOOF (requisition); DBG_OBJ_MSGF ("resize", 1, "final: %d * (%d + %d)", requisition->width, requisition->ascent, requisition->descent); @@ -500,22 +473,7 @@ void Textblock::getExtremesImpl (core::Extremes *extremes) extremes->minWidth, extremes->minWidthIntrinsic, extremes->maxWidth, extremes->maxWidthIntrinsic); - for (int i = 0; i < NUM_OOFM; i++) { - if (outOfFlowMgr[i]) { - int oofMinWidth, oofMaxWidth; - outOfFlowMgr[i]->getExtremes (extremes, &oofMinWidth, &oofMaxWidth); - - DBG_OBJ_MSGF ("resize", 1, "OOFM (#%d) correction: %d / %d", - i, oofMinWidth, oofMaxWidth); - - extremes->minWidth = misc::max (extremes->minWidth, oofMinWidth); - extremes->minWidthIntrinsic = - misc::max (extremes->minWidthIntrinsic, oofMinWidth); - extremes->maxWidth = misc::max (extremes->maxWidth, oofMaxWidth); - extremes->maxWidthIntrinsic = - misc::max (extremes->maxWidthIntrinsic, oofMinWidth); - } - } + correctExtremesByOOF (extremes); DBG_OBJ_MSGF ("resize", 0, "finally, after considering OOFM: %d (%d) / %d (%d)", @@ -770,9 +728,7 @@ void Textblock::containerSizeChangedForChildren () word->content.widget->containerSizeChanged (); } - for (int i = 0; i < NUM_OOFM; i++) - if (outOfFlowMgr[i]) - outOfFlowMgr[i]->containerSizeChangedForChildren (); + containerSizeChangedForChildrenOOF (); DBG_OBJ_LEAVE (); } @@ -782,7 +738,7 @@ bool Textblock::affectsSizeChangeContainerChild (Widget *child) DBG_OBJ_ENTER ("resize", 0, "Textblock/affectsSizeChangeContainerChild", "%p", child); - // See Textblock::getAvailWidthForChild() and Textblock::oofSizeChanged(): + // See Textblock::getAvailWidthOfChild() and Textblock::oofSizeChanged(): // Extremes changes affect the size of the child, too: bool ret; if (!mustBeWidenedToAvailWidth () && @@ -836,9 +792,10 @@ void Textblock::markSizeChange (int ref) now, but addLine(...) will do everything necessary. */ if (ref != -1) { if (wrapRefLines == -1) - wrapRefLines = getParentRefLineNo (ref); + wrapRefLines = getParentRefInFlowSubRef (ref); else - wrapRefLines = misc::min (wrapRefLines, getParentRefLineNo (ref)); + wrapRefLines = misc::min (wrapRefLines, + getParentRefInFlowSubRef (ref)); } DBG_OBJ_SET_NUM ("wrapRefLines", wrapRefLines); @@ -869,10 +826,10 @@ void Textblock::markExtremesChange (int ref) now, but addLine(...) will do everything necessary. */ if (ref != -1) { if (wrapRefParagraphs == -1) - wrapRefParagraphs = getParentRefLineNo (ref); + wrapRefParagraphs = getParentRefInFlowSubRef (ref); else wrapRefParagraphs = - misc::min (wrapRefParagraphs, getParentRefLineNo (ref)); + misc::min (wrapRefParagraphs, getParentRefInFlowSubRef (ref)); } DBG_OBJ_SET_NUM ("wrapRefParagraphs", wrapRefParagraphs); @@ -1703,9 +1660,7 @@ void Textblock::draw (core::View *view, core::Rectangle *area) drawLine (line, view, area); } - for (int i = 0; i < NUM_OOFM; i++) - if(outOfFlowMgr[i]) - outOfFlowMgr[i]->draw(view, area); + drawOOF (view, area); DBG_OBJ_LEAVE (); } @@ -2550,7 +2505,7 @@ void Textblock::addParbreak (int space, core::style::Style *style) if (!isfirst) { /* The text block we searched for has been found. */ Word *word2; - int lineno = getWidgetLineNo (widget); + int lineno = getWidgetInFlowSubRef (widget); if (lineno > 0 && (word2 = @@ -2664,7 +2619,7 @@ void Textblock::breakAdded () * This is an optimized version of the general * dw::core::Widget::getWidgetAtPoint method. */ -core::Widget *Textblock::getWidgetAtPoint(int x, int y, int level) +core::Widget *Textblock::getWidgetAtPoint (int x, int y, int level) { //printf ("%*s-> examining the %s %p (%d, %d, %d x (%d + %d))\n", // 3 * level, "", getClassName (), this, allocation.x, allocation.y, @@ -2683,13 +2638,9 @@ core::Widget *Textblock::getWidgetAtPoint(int x, int y, int level) // First, search for widgets out of flow, notably floats, since // there are cases where they overlap child textblocks. Should // later be refined using z-index. - for (int i = 0; i < NUM_OOFM; i++) { - Widget *oofWidget = - outOfFlowMgr[i] ? - outOfFlowMgr[i]->getWidgetAtPoint (x, y, level) : NULL; - if (oofWidget) - return oofWidget; - } + Widget *oofWidget = getWidgetOOFAtPoint (x, y, level); + if (oofWidget) + return oofWidget; lineIndex = findLineIndexWhenAllocated (y - allocation.y); @@ -3012,7 +2963,7 @@ void Textblock::oofSizeChanged (bool extremesChanged) extremesChanged ? "true" : "false"); queueResize (-1, extremesChanged); - // See Textblock::getAvailWidthForChild(): Extremes changes may become also + // See Textblock::getAvailWidthOfChild(): Extremes changes may become also // relevant for the children, under certain conditions: if (extremesChanged && !mustBeWidenedToAvailWidth ()) containerSizeChanged (); diff --git a/dw/textblock.hh b/dw/textblock.hh index dc496550..82b62b2a 100644 --- a/dw/textblock.hh +++ b/dw/textblock.hh @@ -246,38 +246,6 @@ private: static const char *hyphenDrawChar; protected: - inline bool isParentRefOOF (int parentRef) - { return parentRef != -1 && (parentRef & PARENT_REF_OOFM_MASK); } - - inline int makeParentRefInFlow (int lineNo) - { return (lineNo << PARENT_REF_OOFM_BITS); } - inline int getParentRefLineNo (int parentRef) - { assert (!isParentRefOOF (parentRef)); - return parentRef >> PARENT_REF_OOFM_BITS; } - - inline int makeParentRefOOF (int oofmIndex, int oofmSubRef) - { return (oofmSubRef << PARENT_REF_OOFM_BITS) | (oofmIndex + 1); } - inline int getParentRefOOFSubRef (int parentRef) - { assert (isParentRefOOF (parentRef)); - return parentRef >> PARENT_REF_OOFM_BITS; } - inline int getParentRefOOFIndex (int parentRef) - { assert (isParentRefOOF (parentRef)); - return (parentRef & PARENT_REF_OOFM_MASK) - 1; } - inline oof::OutOfFlowMgr *getParentRefOutOfFlowMgr (int parentRef) - { return outOfFlowMgr[getParentRefOOFIndex (parentRef)]; } - - inline bool isWidgetOOF (Widget *widget) - { return isParentRefOOF (widget->parentRef); } - - inline int getWidgetLineNo (Widget *widget) - { return getParentRefLineNo (widget->parentRef); } - - inline int getWidgetOOFSubRef (Widget *widget) - { return getParentRefOOFSubRef (widget->parentRef); } - inline int getWidgetOOFIndex (Widget *widget) - { return getParentRefOOFIndex (widget->parentRef); } - inline oof::OutOfFlowMgr *getWidgetOutOfFlowMgr (Widget *widget) - { return getParentRefOutOfFlowMgr (widget->parentRef); } /** * \brief Implementation used for words. |