aboutsummaryrefslogtreecommitdiff
path: root/dw
diff options
context:
space:
mode:
authorSebastian Geerken <devnull@localhost>2015-01-30 19:27:16 +0100
committerSebastian Geerken <devnull@localhost>2015-01-30 19:27:16 +0100
commitb1e34672ecbe28c18462cd1b02ba0b2cfc7f772b (patch)
tree8812e9c6b89b4099129d00e8a123ea1f501943de /dw
parent76544475ea4a8578351a818068657a9bd6cd5a06 (diff)
Relative positions, part 1.
Diffstat (limited to 'dw')
-rw-r--r--dw/Makefile.am2
-rw-r--r--dw/oofawarewidget.cc49
-rw-r--r--dw/oofawarewidget.hh14
-rw-r--r--dw/ooffloatsmgr.cc9
-rw-r--r--dw/ooffloatsmgr.hh1
-rw-r--r--dw/oofpositionedmgr.cc18
-rw-r--r--dw/oofpositionedmgr.hh8
-rw-r--r--dw/oofposrelmgr.cc96
-rw-r--r--dw/oofposrelmgr.hh32
-rw-r--r--dw/outofflowmgr.hh2
-rw-r--r--dw/textblock.cc27
-rw-r--r--dw/textblock.hh9
-rw-r--r--dw/textblock_linebreaking.cc16
13 files changed, 251 insertions, 32 deletions
diff --git a/dw/Makefile.am b/dw/Makefile.am
index ba0c7539..0f743114 100644
--- a/dw/Makefile.am
+++ b/dw/Makefile.am
@@ -82,6 +82,8 @@ libDw_widgets_a_SOURCES = \
oofposfixedmgr.hh \
oofpositionedmgr.cc \
oofpositionedmgr.hh \
+ oofposrelmgr.cc \
+ oofposrelmgr.hh \
outofflowmgr.cc \
outofflowmgr.hh \
regardingborder.cc \
diff --git a/dw/oofawarewidget.cc b/dw/oofawarewidget.cc
index 4f7f4bc8..3e51600f 100644
--- a/dw/oofawarewidget.cc
+++ b/dw/oofawarewidget.cc
@@ -20,6 +20,7 @@
#include "oofawarewidget.hh"
#include "ooffloatsmgr.hh"
#include "oofposabsmgr.hh"
+#include "oofposrelmgr.hh"
#include "oofposfixedmgr.hh"
using namespace dw;
@@ -34,7 +35,7 @@ namespace dw {
namespace oof {
const char *OOFAwareWidget::OOFM_NAME[NUM_OOFM] = {
- "FLOATS", "ABSOLUTE", "FIXED"
+ "FLOATS", "ABSOLUTE", "RELATIVE", "FIXED"
};
int OOFAwareWidget::CLASS_ID = -1;
@@ -90,18 +91,37 @@ void OOFAwareWidget::notifySetAsTopLevel ()
}
}
-bool OOFAwareWidget::getOOFMIndex (Widget *widget)
+int OOFAwareWidget::getOOFMIndex (Widget *widget)
{
+ DBG_OBJ_ENTER_O ("construct", 0, NULL, "getOOFMIndex", "%p", widget);
+ DBG_OBJ_MSGF_O ("construct", 1, NULL, "position = %s, float = %s",
+ widget->getStyle()->position
+ == style::POSITION_STATIC ? "static" :
+ (widget->getStyle()->position
+ == style::POSITION_RELATIVE ? "relative" :
+ (widget->getStyle()->position
+ == style::POSITION_ABSOLUTE ? "absolute" :
+ (widget->getStyle()->position
+ == style::POSITION_FIXED ? "fixed" : "???"))),
+ widget->getStyle()->vloat == style::FLOAT_NONE ? "none" :
+ (widget->getStyle()->vloat == style::FLOAT_LEFT ? "left" :
+ (widget->getStyle()->vloat == style::FLOAT_RIGHT ?
+ "right" : "???")));
+
+ int index = -1;
if (testWidgetFloat (widget))
- return OOFM_FLOATS;
+ index = OOFM_FLOATS;
else if (testWidgetAbsolutelyPositioned (widget))
- return OOFM_ABSOLUTE;
+ index = OOFM_ABSOLUTE;
+ else if (testWidgetRelativelyPositioned (widget))
+ index = OOFM_RELATIVE;
else if (testWidgetFixedlyPositioned (widget))
- return OOFM_FIXED;
- else {
+ index = OOFM_FIXED;
+ else
lout::misc::assertNotReached ();
- return -1;
- }
+
+ DBG_OBJ_LEAVE_VAL_O (NULL, "%d (%s)", index, OOFM_NAME[index]);
+ return index;
}
bool OOFAwareWidget::isOOFContainer (Widget *widget, int oofmIndex)
@@ -141,6 +161,7 @@ bool OOFAwareWidget::isOOFContainer (Widget *widget, int oofmIndex)
// process" in "dw-stacking-context.doc".
testWidgetOutOfFlow (widget)));
+ case OOFM_RELATIVE: // TODO Correct?
case OOFM_ABSOLUTE:
// We use the toplevel widget as container, i. e. parent widget.
// See also OOFPosAbsMgr::isReference for the definition of the
@@ -203,6 +224,13 @@ void OOFAwareWidget::initOutOfFlowMgrs ()
oofContainer[OOFM_ABSOLUTE]->outOfFlowMgr[OOFM_ABSOLUTE]);
}
+ if (oofContainer[OOFM_RELATIVE]->outOfFlowMgr[OOFM_RELATIVE] == NULL) {
+ oofContainer[OOFM_RELATIVE]->outOfFlowMgr[OOFM_RELATIVE] =
+ new OOFPosRelMgr (oofContainer[OOFM_RELATIVE]);
+ DBG_OBJ_ASSOC (oofContainer[OOFM_RELATIVE],
+ oofContainer[OOFM_RELATIVE]->outOfFlowMgr[OOFM_RELATIVE]);
+ }
+
if (oofContainer[OOFM_FIXED]->outOfFlowMgr[OOFM_FIXED] == NULL) {
oofContainer[OOFM_FIXED]->outOfFlowMgr[OOFM_FIXED] =
new OOFPosFixedMgr (oofContainer[OOFM_FIXED]);
@@ -526,6 +554,11 @@ void OOFAwareWidget::borderChanged (int y, Widget *vloat)
assertNotReached ();
}
+void OOFAwareWidget::widgetRefSizeChanged (int externalIndex)
+{
+ assertNotReached ();
+}
+
void OOFAwareWidget::clearPositionChanged ()
{
assertNotReached ();
diff --git a/dw/oofawarewidget.hh b/dw/oofawarewidget.hh
index 3d78d69a..249dfe9a 100644
--- a/dw/oofawarewidget.hh
+++ b/dw/oofawarewidget.hh
@@ -67,9 +67,9 @@ namespace oof {
class OOFAwareWidget: public core::Widget
{
protected:
- enum { OOFM_FLOATS, OOFM_ABSOLUTE, OOFM_FIXED, NUM_OOFM };
+ enum { OOFM_FLOATS, OOFM_ABSOLUTE, OOFM_RELATIVE, OOFM_FIXED, NUM_OOFM };
static const char *OOFM_NAME[NUM_OOFM];
- enum { PARENT_REF_OOFM_BITS = 2,
+ enum { PARENT_REF_OOFM_BITS = 3,
PARENT_REF_OOFM_MASK = (1 << PARENT_REF_OOFM_BITS) - 1 };
class OOFAwareWidgetIterator: public core::Iterator
@@ -147,7 +147,7 @@ protected:
{ return oofContainer[oofmIndex] ?
oofContainer[oofmIndex]->outOfFlowMgr[oofmIndex] : NULL; }
- static bool getOOFMIndex (Widget *widget);
+ static int getOOFMIndex (Widget *widget);
void initOutOfFlowMgrs ();
void correctRequisitionByOOF (core::Requisition *requisition,
@@ -209,9 +209,12 @@ public:
testStyleFixedlyPositioned (style); }
static inline bool testStyleOutOfFlow (core::style::Style *style)
- { return testStyleFloat (style) || testStyleAbsolutelyPositioned (style)
+ { // Second part is equivalent to testStylePositioned(), but we still keep
+ // the two seperately.
+ return testStyleFloat (style) || testStyleAbsolutelyPositioned (style)
+ || testStyleRelativelyPositioned (style)
|| testStyleFixedlyPositioned (style); }
-
+
static inline bool testWidgetFloat (Widget *widget)
{ return testStyleFloat (widget->getStyle ()); }
@@ -235,6 +238,7 @@ public:
virtual bool mustBeWidenedToAvailWidth ();
virtual void borderChanged (int y, core::Widget *vloat);
+ virtual void widgetRefSizeChanged (int externalIndex);
virtual void clearPositionChanged ();
virtual void oofSizeChanged (bool extremesChanged);
virtual int getLineBreakWidth (); // Should perhaps be renamed.
diff --git a/dw/ooffloatsmgr.cc b/dw/ooffloatsmgr.cc
index 5b6c8755..c509af8d 100644
--- a/dw/ooffloatsmgr.cc
+++ b/dw/ooffloatsmgr.cc
@@ -1421,6 +1421,11 @@ int OOFFloatsMgr::addWidgetOOF (Widget *widget, OOFAwareWidget *generatingBlock,
return subRef;
}
+void OOFFloatsMgr::calcWidgetRefSize (Widget *widget, Requisition *size)
+{
+ size->width = size->ascent = size->descent = 0;
+}
+
void OOFFloatsMgr::moveExternalIndices (OOFAwareWidget *generatingBlock,
int oldStartIndex, int diff)
{
@@ -1434,8 +1439,8 @@ void OOFFloatsMgr::moveExternalIndices (SortedFloatsVector *list,
{
// Could be faster with binary search, but the GB (not CB!) lists
// should be rather small.
- for (int i = 0; i < list->size(); i++) {
- Float *vloat = list->get(i);
+ for (int i = 0; i < list->size (); i++) {
+ Float *vloat = list->get (i);
if (vloat->externalIndex >= oldStartIndex) {
vloat->externalIndex += diff;
DBG_OBJ_SET_NUM_O (vloat->getWidget (), "<Float>.externalIndex",
diff --git a/dw/ooffloatsmgr.hh b/dw/ooffloatsmgr.hh
index 430f383f..94a67fea 100644
--- a/dw/ooffloatsmgr.hh
+++ b/dw/ooffloatsmgr.hh
@@ -354,6 +354,7 @@ public:
int externalIndex);
int addWidgetOOF (core::Widget *widget, OOFAwareWidget *generatingBlock,
int externalIndex);
+ void calcWidgetRefSize (core::Widget *widget,core::Requisition *size);
void moveExternalIndices (OOFAwareWidget *generatingBlock, int oldStartIndex,
int diff);
diff --git a/dw/oofpositionedmgr.cc b/dw/oofpositionedmgr.cc
index 9a248cf5..270e8c84 100644
--- a/dw/oofpositionedmgr.cc
+++ b/dw/oofpositionedmgr.cc
@@ -254,7 +254,7 @@ int OOFPositionedMgr::addWidgetOOF (Widget *widget, OOFAwareWidget *generator,
if (reference == NULL)
reference = container;
- Child *child = new Child (widget, generator, reference);
+ Child *child = new Child (widget, generator, reference, externalIndex);
children->put (child);
childrenByWidget->put (new TypedPointer<Widget> (widget), child);
@@ -264,15 +264,29 @@ int OOFPositionedMgr::addWidgetOOF (Widget *widget, OOFAwareWidget *generator,
DBG_OBJ_SET_PTR_O (widget, "<Positioned>.generator", generator);
DBG_OBJ_SET_PTR_O (widget, "<Positioned>.reference", reference);
+ DBG_OBJ_SET_NUM_O (widget, "<Positioned>.externalIndex", externalIndex);
DBG_OBJ_MSGF ("construct.oofm", 1, "=> %d", subRef);
DBG_OBJ_LEAVE ();
return subRef;
}
+void OOFPositionedMgr::calcWidgetRefSize (Widget *widget, Requisition *size)
+{
+ size->width = size->ascent = size->descent = 0;
+}
+
void OOFPositionedMgr::moveExternalIndices (OOFAwareWidget *generator,
int oldStartIndex, int diff)
{
+ for (int i = 0; i < children->size (); i++) {
+ Child *child = children->get (i);
+ if (child->externalIndex >= oldStartIndex) {
+ child->externalIndex += diff;
+ DBG_OBJ_SET_NUM_O (child->widget, "<Positioned>.externalIndex",
+ child->externalIndex);
+ }
+ }
}
void OOFPositionedMgr::markSizeChange (int ref)
@@ -630,7 +644,7 @@ void OOFPositionedMgr::calcPosAndSizeChildOfChild (Child *child, int refWidth,
// *xPtr and *yPtr refer to reference area; caller must adjust them.
DBG_OBJ_ENTER ("resize.oofm", 0, "calcPosAndSizeChildOfChild",
- "%p, %d, %d, ...", child, refWidth, refHeight);
+ "[%p], %d, %d, ...", child->widget, refWidth, refHeight);
// TODO (i) Consider {min|max}-{width|heigt}. (ii) Height is always
// apportioned to descent (ascent is preserved), which makes sense
diff --git a/dw/oofpositionedmgr.hh b/dw/oofpositionedmgr.hh
index 9b99f3cd..9fa80cf5 100644
--- a/dw/oofpositionedmgr.hh
+++ b/dw/oofpositionedmgr.hh
@@ -15,12 +15,13 @@ protected:
public:
core::Widget *widget, *reference;
OOFAwareWidget *generator;
- int x, y;
+ int externalIndex, x, y;
inline Child (core::Widget *widget, OOFAwareWidget *generator,
- core::Widget *reference)
+ core::Widget *reference, int externalIndex)
{ this->widget = widget; this->generator = generator;
- this->reference = reference; x = y = 0; }
+ this->reference = reference; this->externalIndex = externalIndex;
+ x = y = 0; }
};
virtual bool isReference (core::Widget *widget) = 0;
@@ -98,6 +99,7 @@ public:
int externalIndex);
int addWidgetOOF (core::Widget *widget, OOFAwareWidget *generator,
int externalIndex);
+ void calcWidgetRefSize (core::Widget *widget, core::Requisition *size);
void moveExternalIndices (OOFAwareWidget *generator, int oldStartIndex,
int diff);
diff --git a/dw/oofposrelmgr.cc b/dw/oofposrelmgr.cc
new file mode 100644
index 00000000..ecb47ba4
--- /dev/null
+++ b/dw/oofposrelmgr.cc
@@ -0,0 +1,96 @@
+/*
+ * Dillo Widget
+ *
+ * Copyright 2015 Sebastian Geerken <sgeerken@dillo.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "oofposrelmgr.hh"
+#include "oofawarewidget.hh"
+
+namespace dw {
+
+namespace oof {
+
+OOFPosRelMgr::OOFPosRelMgr (OOFAwareWidget *container) :
+ OOFPositionedMgr (container)
+{
+ DBG_OBJ_CREATE ("dw::OOFPosRelMgr");
+}
+
+OOFPosRelMgr::~OOFPosRelMgr ()
+{
+ DBG_OBJ_DELETE ();
+}
+
+
+void OOFPosRelMgr::markSizeChange (int ref)
+{
+ DBG_OBJ_ENTER ("resize.oofm", 0, "markSizeChange", "%d", ref);
+ Child *child = children->get(ref);
+ DBG_OBJ_MSGF ("resize.oofm", 1, "generator = %p, externalIndex = %d",
+ child->generator, child->externalIndex);
+ child->generator->widgetRefSizeChanged (child->externalIndex);
+ DBG_OBJ_LEAVE ();
+}
+
+void OOFPosRelMgr::markExtremesChange (int ref)
+{
+}
+
+void OOFPosRelMgr::calcWidgetRefSize (core::Widget *widget,
+ core::Requisition *size)
+{
+ DBG_OBJ_ENTER ("resize.oofm", 0, "calcWidgetRefSize", "%p", widget);
+ widget->sizeRequest (size);
+ DBG_OBJ_LEAVE_VAL ("%d * (%d + %d)",
+ size->width, size->ascent, size->descent);
+}
+
+bool OOFPosRelMgr::isReference (core::Widget *widget)
+{
+ // TODO Remove soon. This implementation will imply reference = container.
+ return false;
+}
+
+// TODO: Check all containerBox* implementations.
+
+int OOFPosRelMgr::containerBoxOffsetX ()
+{
+ return container->getParent () ?
+ container->boxOffsetX () - container->getStyle()->padding.left : 0;
+}
+
+int OOFPosRelMgr::containerBoxOffsetY ()
+{
+ return container->getParent () ?
+ container->boxOffsetY () - container->getStyle()->padding.top : 0;
+}
+
+int OOFPosRelMgr::containerBoxRestWidth ()
+{
+ return container->getParent () ?
+ container->boxRestWidth () - container->getStyle()->padding.right : 0;
+}
+
+int OOFPosRelMgr::containerBoxRestHeight ()
+{
+ return container->getParent () ?
+ container->boxRestHeight () - container->getStyle()->padding.bottom : 0;
+}
+
+} // namespace oof
+
+} // namespace dw
diff --git a/dw/oofposrelmgr.hh b/dw/oofposrelmgr.hh
new file mode 100644
index 00000000..6f712a84
--- /dev/null
+++ b/dw/oofposrelmgr.hh
@@ -0,0 +1,32 @@
+#ifndef __DW_OOFPOSRELMGR_HH__
+#define __DW_OOFPOSRELMGR_HH__
+
+#include "oofpositionedmgr.hh"
+
+namespace dw {
+
+namespace oof {
+
+class OOFPosRelMgr: public OOFPositionedMgr
+{
+protected:
+ bool isReference (core::Widget *widget);
+ int containerBoxOffsetX ();
+ int containerBoxOffsetY ();
+ int containerBoxRestWidth ();
+ int containerBoxRestHeight ();
+
+public:
+ OOFPosRelMgr (OOFAwareWidget *container);
+ ~OOFPosRelMgr ();
+
+ void markSizeChange (int ref);
+ void markExtremesChange (int ref);
+ void calcWidgetRefSize (core::Widget *widget, core::Requisition *size);
+};
+
+} // namespace oof
+
+} // namespace dw
+
+#endif // __DW_OOFPOSRELMGR_HH__
diff --git a/dw/outofflowmgr.hh b/dw/outofflowmgr.hh
index 0ca19ee6..1632499e 100644
--- a/dw/outofflowmgr.hh
+++ b/dw/outofflowmgr.hh
@@ -38,6 +38,8 @@ public:
OOFAwareWidget *parent, int externalIndex) = 0;
virtual int addWidgetOOF (core::Widget *widget, OOFAwareWidget *generator,
int externalIndex) = 0;
+ virtual void calcWidgetRefSize (core::Widget *widget,
+ core::Requisition *size) = 0;
virtual void moveExternalIndices (OOFAwareWidget *generator,
int oldStartIndex, int diff) = 0;
diff --git a/dw/textblock.cc b/dw/textblock.cc
index 40eb4014..ab5c44e8 100644
--- a/dw/textblock.cc
+++ b/dw/textblock.cc
@@ -735,7 +735,7 @@ void Textblock::calcExtraSpaceImpl ()
int clearPosition = 0;
for (int i = 0; i < NUM_OOFM; i++)
- if (searchOutOfFlowMgr(i))
+ if (searchOutOfFlowMgr (i))
clearPosition =
misc::max (clearPosition,
searchOutOfFlowMgr(i)->getClearPosition (this));
@@ -2309,20 +2309,22 @@ void Textblock::addWidget (core::Widget *widget, core::style::Style *style)
if (testWidgetOutOfFlow (widget)) {
int oofmIndex = getOOFMIndex (widget);
+ DBG_OBJ_MSGF ("construct.word", 1, "ouf of flow: oofmIndex = %d (%s)",
+ oofmIndex, OOFM_NAME[oofmIndex]);
+
widget->setParent (oofContainer[oofmIndex]);
widget->setGenerator (this);
- int oofmSubRef =
- searchOutOfFlowMgr(oofmIndex)->addWidgetOOF (widget, this,
- words->size ());
+ oof::OutOfFlowMgr *oofm = searchOutOfFlowMgr (oofmIndex);
+ int oofmSubRef = oofm->addWidgetOOF (widget, this, words->size ());
widget->parentRef = makeParentRefOOF (oofmIndex, oofmSubRef);
- DBG_OBJ_MSGF ("construct.word", 1,
- "ouf of flow: oofmIndex = %d, oofmSubRef = %d => "
- "parentRef = %d",
- oofmIndex, oofmSubRef, widget->parentRef);
+ DBG_OBJ_MSGF ("construct.word", 1, "oofmSubRef = %d => parentRef = %d",
+ oofmSubRef, widget->parentRef);
- Word *word = addWord (0, 0, 0, 0, style);
+ core::Requisition size;
+ oofm->calcWidgetRefSize (widget, &size);
+ Word *word = addWord (size.width, size.ascent, size.descent, 0, style);
word->content.type = core::Content::WIDGET_OOF_REF;
word->content.widget = widget;
@@ -3055,6 +3057,13 @@ void Textblock::borderChanged (int y, Widget *vloat)
DBG_OBJ_LEAVE ();
}
+void Textblock::widgetRefSizeChanged (int externalIndex)
+{
+ int lineNo = findLineOfWord (externalIndex);
+ if (lineNo >= 0 && lineNo < lines->size ())
+ queueResize (makeParentRefInFlow (lineNo), true);
+}
+
void Textblock::clearPositionChanged ()
{
DBG_OBJ_ENTER0 ("resize", 0, "clearPositionChanged");
diff --git a/dw/textblock.hh b/dw/textblock.hh
index 5e626876..a7eeab47 100644
--- a/dw/textblock.hh
+++ b/dw/textblock.hh
@@ -857,6 +857,10 @@ public:
static void setPenaltyEmDashRight2 (int penaltyRightEmDash2);
static void setStretchabilityFactor (int stretchabilityFactor);
+ static inline bool mustAddBreaks (core::style::Style *style)
+ { return !testStyleOutOfFlow (style) ||
+ testStyleRelativelyPositioned (style); }
+
Textblock (bool limitTextWidth);
~Textblock ();
@@ -881,6 +885,7 @@ public:
bool mustBeWidenedToAvailWidth ();
void borderChanged (int y, core::Widget *vloat);
+ void widgetRefSizeChanged (int externalIndex);
void clearPositionChanged ();
void oofSizeChanged (bool extremesChanged);
int getLineBreakWidth ();
@@ -888,7 +893,7 @@ public:
bool isPossibleContainerParent (int oofmIndex);
};
-#define DBG_SET_WORD_PENALTY(n, i, is) \
+#define DBG_SET_WORD_PENALTY(n, i, is) \
D_STMT_START { \
if (words->getRef(n)->badnessAndPenalty.getPenalty (i) == INT_MIN) \
DBG_OBJ_ARRATTRSET_SYM ("words", n, "penalty." is, "-inf"); \
@@ -897,7 +902,7 @@ public:
else \
DBG_OBJ_ARRATTRSET_NUM ("words", n, "penalty." is, \
words->getRef(n)->badnessAndPenalty \
- .getPenalty (i)); \
+ .getPenalty (i)); \
} D_STMT_END
#define DBG_SET_WORD(n) \
diff --git a/dw/textblock_linebreaking.cc b/dw/textblock_linebreaking.cc
index e9815d93..719389a6 100644
--- a/dw/textblock_linebreaking.cc
+++ b/dw/textblock_linebreaking.cc
@@ -1914,8 +1914,22 @@ void Textblock::rewrap ()
for (int i = firstWord; i < words->size (); i++) {
Word *word = words->getRef (i);
- if (word->content.type == core::Content::WIDGET_IN_FLOW)
+ switch (word->content.type) {
+ case core::Content::WIDGET_IN_FLOW:
word->content.widget->sizeRequest (&word->size);
+ break;
+
+ case core::Content::WIDGET_OOF_REF:
+ {
+ int oofmIndex = getOOFMIndex (word->content.widget);
+ oof::OutOfFlowMgr *oofm = searchOutOfFlowMgr (oofmIndex);
+ oofm->calcWidgetRefSize (word->content.widget, &(word->size));
+ }
+ break;
+
+ default:
+ break;
+ }
wordWrap (i, false);