diff options
Diffstat (limited to 'dw/textblock.cc')
-rw-r--r-- | dw/textblock.cc | 316 |
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): |