aboutsummaryrefslogtreecommitdiff
path: root/dw
diff options
context:
space:
mode:
Diffstat (limited to 'dw')
-rw-r--r--dw/layout.cc1
-rw-r--r--dw/style.cc12
-rw-r--r--dw/style.hh17
-rw-r--r--dw/textblock.cc342
-rw-r--r--dw/textblock.hh95
-rw-r--r--dw/textblock_linebreaking.cc18
-rw-r--r--dw/types.hh3
-rw-r--r--dw/widget.cc21
-rw-r--r--dw/widget.hh3
9 files changed, 486 insertions, 26 deletions
diff --git a/dw/layout.cc b/dw/layout.cc
index 9dfd5e9b..d2610687 100644
--- a/dw/layout.cc
+++ b/dw/layout.cc
@@ -248,6 +248,7 @@ void Layout::addWidget (Widget *widget)
topLevel = widget;
widget->layout = this;
+ widget->notifySetAsTopLevel();
findtextState.setWidget (widget);
diff --git a/dw/style.cc b/dw/style.cc
index 2a1d4088..b0868c1f 100644
--- a/dw/style.cc
+++ b/dw/style.cc
@@ -17,8 +17,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-
-
#include <stdio.h>
#include <string.h>
#include <unistd.h>
@@ -49,6 +47,8 @@ void StyleAttrs::initValues ()
valign = VALIGN_BASELINE;
backgroundColor = NULL;
width = height = lineHeight = LENGTH_AUTO;
+ vloat = FLOAT_NONE;
+ clear = CLEAR_NONE;
textIndent = 0;
margin.setVal (0);
borderWidth.setVal (0);
@@ -75,6 +75,8 @@ void StyleAttrs::resetValues ()
valign = VALIGN_BASELINE;
textAlignChar = '.';
+ vloat = FLOAT_NONE; /** \todo Correct? Check specification. */
+ clear = CLEAR_NONE; /** \todo Correct? Check specification. */
backgroundColor = NULL;
width = LENGTH_AUTO;
height = LENGTH_AUTO;
@@ -120,6 +122,8 @@ bool StyleAttrs::equals (object::Object *other) {
valign == otherAttrs->valign &&
textAlignChar == otherAttrs->textAlignChar &&
textTransform == otherAttrs->textTransform &&
+ vloat == otherAttrs->vloat &&
+ clear == otherAttrs->clear &&
hBorderSpacing == otherAttrs->hBorderSpacing &&
vBorderSpacing == otherAttrs->vBorderSpacing &&
wordSpacing == otherAttrs->wordSpacing &&
@@ -160,6 +164,8 @@ int StyleAttrs::hashValue () {
valign +
textAlignChar +
textTransform +
+ vloat +
+ clear +
hBorderSpacing +
vBorderSpacing +
wordSpacing +
@@ -252,6 +258,8 @@ void Style::copyAttrs (StyleAttrs *attrs)
valign = attrs->valign;
textAlignChar = attrs->textAlignChar;
textTransform = attrs->textTransform;
+ vloat = attrs->vloat;
+ clear = attrs->clear;
hBorderSpacing = attrs->hBorderSpacing;
vBorderSpacing = attrs->vBorderSpacing;
wordSpacing = attrs->wordSpacing;
diff --git a/dw/style.hh b/dw/style.hh
index 2422bfa9..6b492793 100644
--- a/dw/style.hh
+++ b/dw/style.hh
@@ -281,7 +281,6 @@ enum ListStylePosition {
LIST_STYLE_POSITION_INSIDE,
LIST_STYLE_POSITION_OUTSIDE
};
-
enum ListStyleType {
LIST_STYLE_TYPE_DISC,
LIST_STYLE_TYPE_CIRCLE,
@@ -333,6 +332,19 @@ enum WhiteSpace {
WHITE_SPACE_PRE_LINE,
};
+enum FloatType {
+ FLOAT_NONE,
+ FLOAT_LEFT,
+ FLOAT_RIGHT
+};
+
+enum ClearType {
+ CLEAR_LEFT,
+ CLEAR_RIGHT,
+ CLEAR_BOTH,
+ CLEAR_NONE
+};
+
/**
* \brief Type for representing all lengths within dw::core::style.
*
@@ -450,6 +462,9 @@ public:
VAlignType valign;
char textAlignChar; /* In future, strings will be supported. */
TextTransform textTransform;
+
+ FloatType vloat; /* "float" is a keyword. */
+ ClearType clear;
int hBorderSpacing, vBorderSpacing, wordSpacing;
Length width, height, lineHeight, textIndent;
diff --git a/dw/textblock.cc b/dw/textblock.cc
index c66fac23..6aa75a13 100644
--- a/dw/textblock.cc
+++ b/dw/textblock.cc
@@ -19,17 +19,19 @@
#include "textblock.hh"
+#include "table.hh" // Yes, this is ugly. -- SG
#include "../lout/msg.h"
#include "../lout/misc.hh"
#include <stdio.h>
-#include <math.h>
+#include <math.h> // remove again?
+#include <limits.h>
/*
* Local variables
*/
- /* The tooltip under mouse pointer in current textblock. No ref. hold.
- * (having one per view looks not worth the extra clutter). */
+/* The tooltip under mouse pointer in current textblock. No ref. hold.
+ * (having one per view looks not worth the extra clutter). */
static dw::core::style::Tooltip *hoverTooltip = NULL;
@@ -68,6 +70,7 @@ Textblock::Textblock (bool limitTextWidth)
nonTemporaryLines = 0;
words = new misc::NotSoSimpleVector <Word> (1);
anchors = new misc::SimpleVector <Anchor> (1);
+ leftFloatSide = rightFloatSide = NULL;
//DBG_OBJ_SET_NUM(this, "num_lines", num_lines);
@@ -121,6 +124,11 @@ Textblock::~Textblock ()
delete words;
delete anchors;
+ if(leftFloatSide)
+ delete leftFloatSide;
+ if(rightFloatSide)
+ delete rightFloatSide;
+
/* Make sure we don't own widgets anymore. Necessary before call of
parent class destructor. (???) */
words = NULL;
@@ -244,7 +252,7 @@ void Textblock::getExtremesImpl (core::Extremes *extremes)
int parMax;
/* Calculate the extremes, based on the values in the line from
where a rewrap is necessary. */
-
+
PRINTF ("GET_EXTREMES: complex case ...\n");
if (wrapRef == 0) {
@@ -431,6 +439,11 @@ void Textblock::sizeAllocateImpl (core::Allocation *allocation)
}
}
+ if(leftFloatSide)
+ leftFloatSide->sizeAllocate(allocation);
+ if(rightFloatSide)
+ rightFloatSide->sizeAllocate(allocation);
+
for (int i = 0; i < anchors->size(); i++) {
Anchor *anchor = anchors->getRef(i);
int y;
@@ -481,16 +494,70 @@ void Textblock::markChange (int ref)
and (ii) a word may have parentRef == -1 , when it is not yet
added to a line. In the latter case, nothing has to be done
now, but addLine(...) will do everything neccessary. */
- if (ref != -1) {
- if (wrapRef == -1)
- wrapRef = ref;
- else
- wrapRef = misc::min (wrapRef, ref);
+
+ 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;
+ }
}
PRINTF (" ... => %d\n", wrapRef);
}
+void Textblock::notifySetAsTopLevel()
+{
+ containingBox = 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;
+ Textblock *topmostTextblock = this;
+
+ for(Widget *widget = getParent(); widget != NULL;
+ widget = widget->getParent())
+ {
+ if(widget->instanceOf(Textblock::CLASS_ID))
+ topmostTextblock = (Textblock*)widget;
+ }
+
+ for(Widget *widget = getParent(); containingBox == NULL;
+ widget = widget->getParent())
+ {
+ if(widget->getParent() == NULL)
+ // No other widget left.
+ containingBox = 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;
+ }
+ }
+}
+
void Textblock::setWidth (int width)
{
/* If limitTextWidth is set to YES, a queueResize() may also be
@@ -502,7 +569,11 @@ void Textblock::setWidth (int width)
// words->size());
availWidth = width;
+//<<<<<<< textblock.cc
+// queueResize (false, dw::core::style::FLOAT_NONE, false);
+//=======
queueResize (0, false);
+//>>>>>>> 1.24
mustQueueResize = false;
redrawY = 0;
}
@@ -517,7 +588,11 @@ void Textblock::setAscent (int ascent)
// words->size());
availAscent = ascent;
+//<<<<<<< textblock.cc
+// queueResize (false, dw::core::style::FLOAT_NONE, false);
+//=======
queueResize (0, false);
+//>>>>>>> 1.24
mustQueueResize = false;
}
}
@@ -531,7 +606,11 @@ void Textblock::setDescent (int descent)
// words->size());
availDescent = descent;
+//<<<<<<< textblock.cc
+// queueResize (false, dw::core::style::FLOAT_NONE, false);
+//=======
queueResize (0, false);
+//>>>>>>> 1.24
mustQueueResize = false;
}
}
@@ -1264,6 +1343,11 @@ 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);
}
/**
@@ -1560,6 +1644,9 @@ void Textblock::addWidget (core::Widget *widget, core::style::Style *style)
// word->content.widget);
wordWrap (words->size () - 1, false);
+ // ABC
+ word->content.widget->parentRef = 1 | (dw::core::style::FLOAT_NONE << 1) | ((lines->size () - 1) << 3);
+ printf("parentRef = %d\n", word->content.widget->parentRef);
//DBG_OBJ_SET_NUM (word->content.widget, "parent_ref",
// word->content.widget->parent_ref);
@@ -1728,8 +1815,8 @@ void Textblock::addParbreak (int space, core::style::Style *style)
if (!isfirst) {
/* The page we searched for has been found. */
Word *word2;
- int lineno = widget->parentRef;
-
+ // ABC
+ int lineno = widget->parentRef >> 3;
if (lineno > 0 &&
(word2 =
textblock2->words->getRef(textblock2->lines
@@ -1737,7 +1824,11 @@ void Textblock::addParbreak (int space, core::style::Style *style)
word2->content.type == core::Content::BREAK) {
if (word2->content.breakSpace < space) {
word2->content.breakSpace = space;
+//<<<<<<< textblock.cc
+// textblock2->queueResize (false, 1 | (dw::core::style::FLOAT_NONE << 1) | (lineno << 3), false);
+//=======
textblock2->queueResize (lineno, false);
+//>>>>>>> 1.24
textblock2->mustQueueResize = false;
}
}
@@ -1793,6 +1884,22 @@ 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.
@@ -1863,6 +1970,11 @@ void Textblock::handOverBreak (core::style::Style *style)
*/
void Textblock::flush ()
{
+//<<<<<<< textblock.cc
+// if (asap || mustQueueResize) {
+// printf("queueResize(%s, -1, true)\n", asap ? "true" : "false");
+// queueResize (asap, -1, true);
+//=======
PRINTF ("[%p] FLUSH => %s (parentRef = %d)\n",
this, mustQueueResize ? "true" : "false", parentRef);
@@ -1935,6 +2047,214 @@ 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):
diff --git a/dw/textblock.hh b/dw/textblock.hh
index 0c3c6870..8d8f91cc 100644
--- a/dw/textblock.hh
+++ b/dw/textblock.hh
@@ -18,10 +18,11 @@ namespace dw {
* of paragraphs.
*
* <div style="border: 2px solid #ffff00; margin-top: 0.5em;
- * margin-bottom: 0.5em; padding: 0.5em 1em;
- * background-color: #ffffe0"><b>Info:</b> The recent changes (line
- * breaking and hyphenation) have not yet been incorporated into this
- * documentation. See \ref dw-line-breaking.</div>
+ * margin-bottom: 0.5em; padding: 0.5em 1em; background-color:
+ * #ffffe0"><b>Info:</b> The recent changes (line breaking and
+ * hyphenation on one hand, floats on the other hand) have not yet
+ * been incorporated into this documentation. See \ref
+ * dw-line-breaking and \ref dw-special-textflow.</div>
*
* <h3>Signals</h3>
*
@@ -144,6 +145,11 @@ namespace dw {
class Textblock: public core::Widget
{
private:
+ // Hint: the following is somewhat chaotic, as a result of the merge
+ // of dillo_hyphen and dillo_floats
+
+ // Part 1 -- Line-Breaking and Hyphenation
+
/**
* This class encapsulates the badness/penalty calculation, and so
* (i) makes changes (hopefully) simpler, and (ii) hides the
@@ -207,6 +213,69 @@ private:
void print ();
};
+ // Part 2 -- Floats
+
+ Textblock *containingBox;
+
+ class FloatSide
+ {
+ protected:
+ class Float: public lout::object::Object
+ {
+ public:
+ Textblock *floatGenerator;
+ core::Widget *widget;
+ int lineNo, y, width, ascent, descent;
+ };
+
+ Textblock *floatContainer;
+ lout::container::typed::Vector<Float> *floats;
+ lout::container::typed::HashTable<lout::object::TypedPointer<dw::core::Widget>, Float> *floatsByWidget;
+
+ Float *findFloat(int y);
+
+ virtual int calcBorderFromContainer(Float *vloat) = 0;
+ virtual int calcBorderDiff(Textblock *child) = 0;
+
+ public:
+ FloatSide(Textblock *floatContainer);
+ virtual ~FloatSide();
+
+ inline int size() { return floats->size(); }
+ void addFloat(Widget *widget, Textblock *floatGenerator);
+ void handleFloat(Widget *widget, int lineNo, int y, int lineWidth, int lineHeight);
+ int calcBorder(int y, Textblock *viewdFrom);
+ virtual void sizeAllocate(core::Allocation *containingBoxAllocation) = 0;
+ void draw (core::View *view, core::Rectangle *area);
+ void queueResize(int ref);
+ };
+
+ class LeftFloatSide: public FloatSide
+ {
+ protected:
+ int calcBorderFromContainer(Float *vloat);
+ int calcBorderDiff(Textblock *child);
+
+ public:
+ LeftFloatSide(Textblock *floatContainer) : FloatSide(floatContainer) { }
+ void sizeAllocate(core::Allocation *containingBoxAllocation);
+ };
+
+ class RightFloatSide: public FloatSide
+ {
+ protected:
+ int calcBorderFromContainer(Float *vloat);
+ int calcBorderDiff(Textblock *child);
+
+ public:
+ RightFloatSide(Textblock *floatContainer) : FloatSide(floatContainer) { }
+ void sizeAllocate(core::Allocation *containingBoxAllocation);
+ };
+
+ FloatSide *leftFloatSide, *rightFloatSide;
+
+ // End of merge chaos.
+
protected:
enum {
/**
@@ -226,7 +295,8 @@ protected:
* page->lines[0].top is always 0. */
int top, boxAscent, boxDescent, contentAscent, contentDescent,
breakSpace, leftOffset;
-
+ int boxLeft, boxRight;
+
/* This is similar to descent, but includes the bottom margins of the
* widgets within this line. */
int marginDescent;
@@ -419,6 +489,15 @@ protected:
void calcTextSize (const char *text, size_t len, core::style::Style *style,
core::Requisition *size);
+ void addFloatIntoContainer(core::Widget *widget, Textblock *floatGenerator);
+ void handleFloatInContainer(Widget *widget, int lineNo,
+ int y, int lineWidth, int lineHeight);
+
+ inline int calcLeftFloatBorder(int y, Textblock *viewedFrom)
+ { return containingBox->leftFloatSide ? containingBox->leftFloatSide->calcBorder(y, viewedFrom) : 0; }
+ inline int calcRightFloatBorder(int y, Textblock *viewedFrom)
+ { return containingBox->rightFloatSide ? containingBox->rightFloatSide->calcBorder(y, viewedFrom) : 0; }
+
/**
* \brief Returns the x offset (the indentation plus any offset needed for
* centering or right justification) for the line.
@@ -428,7 +507,7 @@ protected:
*/
inline int lineXOffsetContents (Line *line)
{
- return innerPadding + line->leftOffset +
+ return innerPadding + line->leftOffset + line->boxLeft +
(line == lines->getFirstRef() ? line1OffsetEff : 0);
}
@@ -499,6 +578,8 @@ protected:
void markSizeChange (int ref);
void markExtremesChange (int ref);
+ void notifySetAsTopLevel();
+ void notifySetParent();
void setWidth (int width);
void setAscent (int ascent);
void setDescent (int descent);
@@ -558,6 +639,8 @@ public:
void addParbreak (int space, core::style::Style *style);
void addLinebreak (core::style::Style *style);
+ void addFloatIntoGenerator (core::Widget *widget, core::style::Style *style);
+
core::Widget *getWidgetAtPoint (int x, int y, int level);
void handOverBreak (core::style::Style *style);
void changeLinkColor (int link, int newColor);
diff --git a/dw/textblock_linebreaking.cc b/dw/textblock_linebreaking.cc
index 8fb577d1..7947d22f 100644
--- a/dw/textblock_linebreaking.cc
+++ b/dw/textblock_linebreaking.cc
@@ -796,6 +796,11 @@ void Textblock::accumulateWordData (int wordIndex)
int Textblock::calcAvailWidth (int lineIndex)
{
+ // BUG: This method must also include Line::boxLeft and Line::boxRight
+ // (introduced by floats), but since the recent changes in line breaking
+ // (together with hyphenation), this line is often not yet created, so
+ // these values cannot be determined.
+
int availWidth =
this->availWidth - getStyle()->boxDiffWidth() - innerPadding;
if (limitTextWidth &&
@@ -805,9 +810,9 @@ int Textblock::calcAvailWidth (int lineIndex)
if (lineIndex == 0)
availWidth -= line1OffsetEff;
- //PRINTF("[%p] CALC_AVAIL_WIDTH => %d - %d - %d = %d\n",
- // this, this->availWidth, getStyle()->boxDiffWidth(), innerPadding,
- // availWidth);
+ PRINTF ("[%p] CALC_AVAIL_WIDTH (%d of %d) => %d - %d - %d = %d\n",
+ this, lineIndex, lines->size(), this->availWidth,
+ getStyle()->boxDiffWidth(), innerPadding, availWidth);
return availWidth;
}
@@ -916,8 +921,11 @@ void Textblock::rewrap ()
for (int i = firstWord; i < words->size (); i++) {
Word *word = words->getRef (i);
- if (word->content.type == core::Content::WIDGET)
- calcWidgetSize (word->content.widget, &word->size);
+ if (word->content.type == core::Content::WIDGET &&
+ // ABC
+ word->content.widget->parentRef ==
+ (1 | (dw::core::style::FLOAT_NONE << 1) | ((lines->size () - 1) << 3)))
+ calcWidgetSize (word->content.widget, &word->size);
wordWrap (i, false);
diff --git a/dw/types.hh b/dw/types.hh
index 65983fad..abed38e6 100644
--- a/dw/types.hh
+++ b/dw/types.hh
@@ -190,8 +190,9 @@ struct Content
TEXT = 1 << 2,
WIDGET = 1 << 3,
BREAK = 1 << 4,
+ FLOAT_REF = 1 << 6, /** \todo A bit ugly. */
ALL = 0xff,
- REAL_CONTENT = 0xff ^ (START | END),
+ REAL_CONTENT = 0xff ^ (START | END | FLOAT_REF),
SELECTION_CONTENT = TEXT | WIDGET | BREAK
};
diff --git a/dw/widget.cc b/dw/widget.cc
index 8ca0681a..193c5aac 100644
--- a/dw/widget.cc
+++ b/dw/widget.cc
@@ -108,6 +108,8 @@ void Widget::setParent (Widget *parent)
if (!buttonSensitiveSet)
buttonSensitive = parent->buttonSensitive;
+ notifySetParent();
+
//DBG_OBJ_ASSOC (widget, parent);
//printf ("%p becomes a child of %p\n", this, parent);
}
@@ -567,6 +569,25 @@ void Widget::markExtremesChange (int ref)
{
}
+/**
+ * \brief This method is called after a widget has been set as the top of a
+ * widget tree.
+ *
+ * A widget may override this method when it is necessary to be notified.
+ */
+void Widget::notifySetAsTopLevel()
+{
+}
+
+/**
+ * \brief This method is called after a widget has been added to a parent.
+ *
+ * A widget may override this method when it is necessary to be notified.
+ */
+void Widget::notifySetParent()
+{
+}
+
void Widget::setWidth (int width)
{
}
diff --git a/dw/widget.hh b/dw/widget.hh
index b751a282..e18344c7 100644
--- a/dw/widget.hh
+++ b/dw/widget.hh
@@ -178,6 +178,9 @@ protected:
*/
virtual void markExtremesChange (int ref);
+ virtual void notifySetAsTopLevel();
+ virtual void notifySetParent();
+
virtual bool buttonPressImpl (EventButton *event);
virtual bool buttonReleaseImpl (EventButton *event);
virtual bool motionNotifyImpl (EventMotion *event);