aboutsummaryrefslogtreecommitdiff
path: root/dw/textblock.cc
diff options
context:
space:
mode:
Diffstat (limited to 'dw/textblock.cc')
-rw-r--r--dw/textblock.cc316
1 files changed, 47 insertions, 269 deletions
diff --git a/dw/textblock.cc b/dw/textblock.cc
index 27c14561..3e06b4ab 100644
--- a/dw/textblock.cc
+++ b/dw/textblock.cc
@@ -70,7 +70,7 @@ Textblock::Textblock (bool limitTextWidth)
nonTemporaryLines = 0;
words = new misc::NotSoSimpleVector <Word> (1);
anchors = new misc::SimpleVector <Anchor> (1);
- leftFloatSide = rightFloatSide = NULL;
+ outOfFlowMgr = NULL;
//DBG_OBJ_SET_NUM(this, "num_lines", num_lines);
@@ -124,10 +124,8 @@ Textblock::~Textblock ()
delete words;
delete anchors;
- if(leftFloatSide)
- delete leftFloatSide;
- if(rightFloatSide)
- delete rightFloatSide;
+ if(outOfFlowMgr)
+ delete outOfFlowMgr;
/* Make sure we don't own widgets anymore. Necessary before call of
parent class destructor. (???) */
@@ -439,10 +437,8 @@ void Textblock::sizeAllocateImpl (core::Allocation *allocation)
}
}
- if(leftFloatSide)
- leftFloatSide->sizeAllocate(allocation);
- if(rightFloatSide)
- rightFloatSide->sizeAllocate(allocation);
+ if(outOfFlowMgr)
+ outOfFlowMgr->sizeAllocate(allocation);
for (int i = 0; i < anchors->size(); i++) {
Anchor *anchor = anchors->getRef(i);
@@ -474,16 +470,29 @@ void Textblock::resizeDrawImpl ()
void Textblock::markSizeChange (int ref)
{
- markChange (ref);
+ printf ("markSizeChange (%d)\n", ref);
+
+ if (OutOfFlowMgr::isRefOutOfFlow (ref)) {
+ assert (outOfFlowMgr != NULL);
+ outOfFlowMgr->markSizeChange (ref);
+ } else
+ markChange (ref);
}
void Textblock::markExtremesChange (int ref)
{
- markChange (ref);
+ printf ("markExtremesChange (%d)\n", ref);
+
+ if (OutOfFlowMgr::isRefOutOfFlow (ref)) {
+ assert (outOfFlowMgr != NULL);
+ outOfFlowMgr->markExtremesChange (ref);
+ } else
+ markChange (ref);
}
/*
- * Implementation for both mark_size_change and mark_extremes_change.
+ * Implementation for both markSizeChange and markExtremesChange.
+ * Only used for normal flow.
*/
void Textblock::markChange (int ref)
{
@@ -495,43 +504,24 @@ void Textblock::markChange (int ref)
added to a line. In the latter case, nothing has to be done
now, but addLine(...) will do everything necessary. */
- int refEquiv = (ref == 0) ? 1 | (dw::core::style::FLOAT_NONE << 1) : ref;
-
- if (refEquiv != -1 && (refEquiv & 1)) {
- switch((refEquiv >> 1) & 3)
- {
- case dw::core::style::FLOAT_NONE:
- if (wrapRef == -1)
- wrapRef = refEquiv >> 3;
- else
- wrapRef = misc::min (wrapRef, refEquiv >> 3);
- //DBG_OBJ_SET_NUM (page, "wrap_ref", page->wrap_ref);
- printf("wrapRef = %d\n", wrapRef);
- break;
-
- case dw::core::style::FLOAT_LEFT:
- leftFloatSide->queueResize(refEquiv);
- break;
-
- case dw::core::style::FLOAT_RIGHT:
- rightFloatSide->queueResize(refEquiv);
- break;
- }
- }
+ if (wrapRef == -1)
+ wrapRef = OutOfFlowMgr::getLineNoFromRef (ref);
+ else
+ wrapRef = misc::min (wrapRef, OutOfFlowMgr::getLineNoFromRef (ref));
PRINTF (" ... => %d\n", wrapRef);
}
void Textblock::notifySetAsTopLevel()
{
- containingBox = this;
+ containingBlock = this;
}
void Textblock::notifySetParent()
{
// Search for containing Box. It can be assumed that this widget has a
// parent, otherwise, notifySetAsToplevel would have been called.
- containingBox = NULL;
+ containingBlock = NULL;
Textblock *topmostTextblock = this;
for(Widget *widget = getParent(); widget != NULL;
@@ -541,19 +531,19 @@ void Textblock::notifySetParent()
topmostTextblock = (Textblock*)widget;
}
- for(Widget *widget = getParent(); containingBox == NULL;
+ for(Widget *widget = getParent(); containingBlock == NULL;
widget = widget->getParent())
{
if(widget->getParent() == NULL)
// No other widget left.
- containingBox = topmostTextblock;
+ containingBlock = topmostTextblock;
else if(widget->instanceOf(Textblock::CLASS_ID))
{
if(// this widget is a table cell
widget->getParent()->instanceOf(Table::CLASS_ID) ||
// this widget is a float
widget->getStyle()->vloat != dw::core::style::FLOAT_NONE)
- containingBox = (Textblock*)widget;
+ containingBlock = (Textblock*)widget;
}
}
}
@@ -1352,10 +1342,8 @@ void Textblock::draw (core::View *view, core::Rectangle *area)
drawLine (line, view, area);
}
- if(leftFloatSide)
- leftFloatSide->draw(view, area);
- if(rightFloatSide)
- rightFloatSide->draw(view, area);
+ if(outOfFlowMgr)
+ outOfFlowMgr->draw(view, area);
}
/**
@@ -1662,6 +1650,21 @@ void Textblock::addWidget (core::Widget *widget, core::style::Style *style)
// "Assigning parent_ref = %d to added word %d, "
// "in page with %d word(s)\n",
// lines->size () - 1, words->size() - 1, words->size());
+
+ // TODO Floats:
+ /*
+ Word *word;
+
+ widget->setStyle (style);
+ containingBlock->addFloatIntoContainer(widget, this);
+
+ word = addWord (0, 0, 0, false, style);
+ word->content.type = core::Content::FLOAT_REF;
+ word->content.breakSpace = 0;
+ word->content.widget = widget;
+ word->style = style;
+ wordWrap (words->size () - 1, false);
+ */
}
/**
@@ -1892,23 +1895,6 @@ void Textblock::addLinebreak (core::style::Style *style)
wordWrap (words->size () - 1, false);
}
-/** \todo This MUST be commented! */
-void Textblock::addFloatIntoGenerator (core::Widget *widget, core::style::Style *style)
-{
- Word *word;
-
- widget->setStyle (style);
- containingBox->addFloatIntoContainer(widget, this);
-
- word = addWord (0, 0, 0, false, style);
- word->content.type = core::Content::FLOAT_REF;
- word->content.breakSpace = 0;
- word->content.widget = widget;
- word->style = style;
- wordWrap (words->size () - 1, false);
-}
-
-
/**
* \brief Search recursively through widget.
*
@@ -2055,214 +2041,6 @@ void Textblock::changeWordStyle (int from, int to, core::style::Style *style,
// ----------------------------------------------------------------------
-/** \todo This MUST be commented! */
-void Textblock::addFloatIntoContainer(Widget *widget,
- Textblock *floatGenerator)
-{
- FloatSide *floatSide = NULL;
-
- switch(widget->getStyle()->vloat)
- {
- case dw::core::style::FLOAT_LEFT:
- if(leftFloatSide == NULL)
- leftFloatSide = new LeftFloatSide(this);
- floatSide = leftFloatSide;
- break;
-
- case dw::core::style::FLOAT_RIGHT:
- if(rightFloatSide == NULL)
- rightFloatSide = new RightFloatSide(this);
- floatSide = rightFloatSide;
- break;
-
- default:
- //TODO lout::misc::fail("invalid value %d for float to be added", widget->getStyle()->vloat);
- break;
- }
-
- // ABC
- widget->parentRef = 1 | (widget->getStyle()->vloat << 1) | (floatSide->size() << 3);
- widget->parentRef = 0;
- printf("parentRef = %d\n", widget->parentRef);
- widget->setParent(this);
-
- floatSide->addFloat(widget, floatGenerator);
-}
-
-void Textblock::handleFloatInContainer(Widget *widget, int lineNo,
- int y, int lineWidth, int lineHeight)
-{
- FloatSide *floatSide = NULL;
-
- switch(widget->getStyle()->vloat)
- {
- case dw::core::style::FLOAT_LEFT:
- floatSide = leftFloatSide;
- break;
-
- case dw::core::style::FLOAT_RIGHT:
- floatSide = rightFloatSide;
- break;
-
- default:
- //TODO lout::misc::fail("invalid value %d for float to be handled", widget->getStyle()->vloat);
- break;
- }
-
- floatSide->handleFloat(widget, lineNo, y, lineWidth, lineHeight);
-}
-
-Textblock::FloatSide::FloatSide(Textblock *floatContainer)
-{
- this->floatContainer = floatContainer;
- floats = new container::typed::Vector<Float>(1, false);
- floatsByWidget =
- new container::typed::HashTable<object::TypedPointer<dw::core::Widget>, Float>(true, true);
-}
-
-Textblock::FloatSide::~FloatSide()
-{
- delete floats;
- delete floatsByWidget;
-}
-
-void Textblock::FloatSide::addFloat(Widget *widget, Textblock *floatGenerator)
-{
- Float *vloat = new Float();
- vloat->floatGenerator = floatGenerator;
- vloat->widget = widget;
- floats->put(vloat);
- object::TypedPointer<Widget> *pointer = new object::TypedPointer<Widget>(widget);
- floatsByWidget->put(pointer, vloat);
-}
-
-void Textblock::FloatSide::handleFloat(Widget *widget, int lineNo,
- int y, int lineWidth, int lineHeight)
-{
- /** \todo lineHeight may change afterwards */
- object::TypedPointer<Widget> pointer(widget);
- Float *vloat = floatsByWidget->get(&pointer);
-
- printf("searching %s in %s\n", pointer.toString(), floatsByWidget->toString());
-
- dw::core::Requisition requisition;
- widget->sizeRequest(&requisition);
-
- int effY;
- /** \todo Check for another float. Futhermore: what, if the float does not fit
- * into a line at all? */
- if(requisition.width > vloat->floatGenerator->availWidth - lineWidth)
- effY = y + lineHeight;
- else
- effY = y;
-
- vloat->lineNo = lineNo;
- vloat->y = effY;
- vloat->width = requisition.width;
- vloat->ascent = requisition.ascent;
- vloat->descent = requisition.descent;
-}
-
-int Textblock::FloatSide::calcBorder(int y, Textblock *viewdFrom)
-{
- Float *vloat = findFloat(y);
- if(vloat) {
- int fromContainer = calcBorderFromContainer(vloat);
- int fromThisViewedFrom = fromContainer - calcBorderDiff(viewdFrom);
- //printf("fromThisViewedFrom = %d\n", fromThisViewedFrom);
- return misc::max(fromThisViewedFrom, 0);
- } else
- return 0;
-}
-
-Textblock::FloatSide::Float *Textblock::FloatSide::findFloat(int y)
-{
- for(int i = 0; i < floats->size(); i++)
- {
- Float *vloat = floats->get(i);
- if(y >= vloat->y && y < vloat->y + vloat->ascent + vloat->descent)
- return vloat;
- }
-
- return NULL;
-}
-
-void Textblock::FloatSide::draw (core::View *view, core::Rectangle *area)
-{
- for(int i = 0; i < floats->size(); i++)
- {
- Float *vloat = floats->get(i);
- core::Rectangle childArea;
- if (vloat->widget->intersects (area, &childArea))
- vloat->widget->draw (view, &childArea);
- }
-}
-
-void Textblock::FloatSide::queueResize(int ref)
-{
- // TODO Float *vloat = floats->get(ref >> 3);
- // TODO vloat->floatGenerator->queueResize(false, 1 | (dw::core::style::FLOAT_NONE << 1) | (vloat->lineNo << 3), true);
-}
-
-int Textblock::LeftFloatSide::calcBorderFromContainer(Textblock::FloatSide::Float *vloat)
-{
- return vloat->width + floatContainer->getStyle()->boxOffsetX() +
- vloat->floatGenerator->getStyle()->boxOffsetX();
-}
-
-int Textblock::LeftFloatSide::calcBorderDiff(Textblock *child)
-{
- return child->getStyle()->boxOffsetX();
-}
-
-void Textblock::LeftFloatSide::sizeAllocate(core::Allocation *containingBoxAllocation)
-{
- for(int i = 0; i < floats->size(); i++)
- {
- Float *vloat = floats->get(i);
- core::Allocation childAllocation;
- childAllocation.x =
- containingBoxAllocation->x + floatContainer->getStyle()->boxOffsetX() +
- vloat->floatGenerator->getStyle()->boxOffsetX();
- childAllocation.y = containingBoxAllocation->y + vloat->y;
- childAllocation.width = vloat->width;
- childAllocation.ascent = vloat->ascent;
- childAllocation.descent = vloat->descent;
- vloat->widget->sizeAllocate(&childAllocation);
- }
-}
-
-int Textblock::RightFloatSide::calcBorderFromContainer(Textblock::FloatSide::Float *vloat)
-{
- return vloat->width + floatContainer->getStyle()->boxRestWidth() +
- vloat->floatGenerator->getStyle()->boxRestWidth();
-}
-
-int Textblock::RightFloatSide::calcBorderDiff(Textblock *child)
-{
- return child->getStyle()->boxRestWidth();
-}
-
-void Textblock::RightFloatSide::sizeAllocate(core::Allocation *containingBoxAllocation)
-{
- for(int i = 0; i < floats->size(); i++)
- {
- Float *vloat = floats->get(i);
- core::Allocation childAllocation;
- childAllocation.x =
- containingBoxAllocation->x + containingBoxAllocation->width -
- floatContainer->getStyle()->boxRestWidth() - vloat->width -
- vloat->floatGenerator->getStyle()->boxRestWidth();
- childAllocation.y = containingBoxAllocation->y + vloat->y;
- childAllocation.width = vloat->width;
- childAllocation.ascent = vloat->ascent;
- childAllocation.descent = vloat->descent;
- vloat->widget->sizeAllocate(&childAllocation);
- }
-}
-
-// ----------------------------------------------------------------------
-
Textblock::TextblockIterator::TextblockIterator (Textblock *textblock,
core::Content::Type mask,
bool atEnd):