aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dw/outofflowmgr.cc103
-rw-r--r--dw/outofflowmgr.hh25
-rw-r--r--lout/identity.cc16
-rw-r--r--lout/identity.hh4
-rw-r--r--lout/misc.hh5
5 files changed, 128 insertions, 25 deletions
diff --git a/dw/outofflowmgr.cc b/dw/outofflowmgr.cc
index 519cf8b0..af5d8e13 100644
--- a/dw/outofflowmgr.cc
+++ b/dw/outofflowmgr.cc
@@ -11,16 +11,66 @@ using namespace dw::core::style;
namespace dw {
+OutOfFlowMgr::Float::Float (OutOfFlowMgr *oofm, Widget *widget,
+ Textblock *generatingBlock)
+{
+ this->oofm = oofm;
+ this->widget = widget;
+ this->generatingBlock = generatingBlock;
+
+ positioned = false;
+ positioned = false;
+ yReq = yReal = size.width = size.ascent = size.descent = 0;
+ dirty = true;
+}
+
+void OutOfFlowMgr::Float::intoStringBuffer(StringBuffer *sb)
+{
+ sb->append (positioned ? "{+ widget = " : "{- widget = ");
+ sb->appendPointer (widget);
+
+ if (widget) {
+ sb->append (" (");
+ sb->append (widget->getClassName ());
+ sb->append (")");
+ }
+
+ sb->append (", generatingBlock = ");
+ sb->appendPointer (generatingBlock);
+ sb->append (", positioned = ");
+ sb->appendBool (positioned);
+ sb->append (", yReq = ");
+ sb->appendInt (yReq);
+ sb->append (", yReal = ");
+ sb->appendInt (yReal);
+ sb->append (", size = { ");
+ sb->appendInt (size.width);
+ sb->append (", ");
+ sb->appendInt (size.ascent);
+ sb->append (" + ");
+ sb->appendInt (size.descent);
+ sb->append (" }, dirty = ");
+ sb->appendBool (dirty);
+ sb->append (positioned ? " +}" : " -}");
+}
+
int OutOfFlowMgr::Float::compareTo(Comparable *other)
{
Float *otherFloat = (Float*)other;
- if (generatingBlock->wasAllocated()) {
- assert (otherFloat->generatingBlock->wasAllocated());
- return yForContainer() - otherFloat->yForContainer();
+ if (positioned && otherFloat->positioned) {
+ if (generatingBlock->wasAllocated()) {
+ assert (otherFloat->generatingBlock->wasAllocated());
+ return yForContainer() - otherFloat->yForContainer();
+ } else {
+ assert (generatingBlock == otherFloat->generatingBlock);
+ return yReal - otherFloat->yReal;
+ }
} else {
- assert (generatingBlock == otherFloat->generatingBlock);
- return yReal - otherFloat->yReal;
+ if (positioned)
+ return 1; // !otherFloat->positioned can be assumed.
+ else // !positioned
+ return otherFloat->positioned ? -1 : 0;
}
}
@@ -57,6 +107,7 @@ bool OutOfFlowMgr::Float::covers (Textblock *textblock, int y, int h)
fly = yReal;
}
+ oofm->ensureFloatSize (this);
int flh = dirty ? 0 : size.ascent + size.descent;
return fly + flh > reqy && fly < reqy + h;
@@ -68,7 +119,7 @@ int OutOfFlowMgr::SortedFloatsVector::find (Textblock *textblock, int y)
{
cleanup ();
- Float key (oofm);
+ Float key (oofm, NULL, NULL);
key.generatingBlock = textblock;
key.yReal = y;
@@ -383,12 +434,7 @@ void OutOfFlowMgr::addWidget (Widget *widget, Textblock *generatingBlock)
if (widget->getStyle()->vloat != FLOAT_NONE) {
TBInfo *tbInfo = registerCaller (generatingBlock);
- Float *vloat = new Float (this);
- vloat->widget = widget;
- vloat->generatingBlock = generatingBlock;
- vloat->dirty = true;
- vloat->positioned = false;
- vloat->yReq = vloat->yReal = INT_MIN;
+ Float *vloat = new Float (this, widget, generatingBlock);
switch (widget->getStyle()->vloat) {
case FLOAT_LEFT:
@@ -501,7 +547,7 @@ Widget *OutOfFlowMgr::getWidgetAtPoint (SortedFloatsVector *list,
*/
void OutOfFlowMgr::tellNoPosition (Widget *widget)
{
- tellPositionOrNot (widget, INT_MIN, false);
+ tellPositionOrNot (widget, 0, false);
}
@@ -514,12 +560,10 @@ void OutOfFlowMgr::tellPosition (Widget *widget, int y)
void OutOfFlowMgr::tellPositionOrNot (Widget *widget, int y, bool positioned)
{
Float *vloat = findFloatByWidget(widget);
- //printf ("[%p] TELL_POSITION_OR_NOT: vloat = %p, y = %d (%d => %d), "
- // "positioned = %s (%s)\n", containingBlock, vloat,
- // y, vloat->yReq, vloat->yReal,
- // positioned ? "true" : "false",
- // vloat->positioned ? "true" : "false");
-
+
+ //printf ("[%p] TELL_POSITION_OR_NOT (%p, %d, %s)\n",
+ // containingBlock, widget, y, positioned ? "true" : "false");
+ //printf (" vloat: %s\n", vloat->toString());
if ((!positioned && !vloat->positioned) ||
(positioned && vloat->positioned && y == vloat->yReq))
@@ -539,22 +583,41 @@ void OutOfFlowMgr::tellPositionOrNot (Widget *widget, int y, bool positioned)
vloat->positioned = positioned;
if (positioned) {
- // Test collisions (on both sides.
+ ensureFloatSize (vloat);
+
+ // Test collisions (on both sides).
// It is assumed that there are no floats below this float
// within this generator. For this reason, (i) search is simple
// (candidate is at the end of the list), and (ii) no other
// floats have to be adjusted.
+ listSame->change (vloat);
+
+ //for (lout::container::typed::Iterator<Float> it = listSame->iterator();
+ // it.hasNext(); ) {
+ // Float *v2 = it.getNext();
+ // printf (" %s\n", v2->toString());
+ //}
+
if (listSame->size() > 1) {
Float *last = listSame->get (listSame->size () - 1);
if (last == vloat) // TODO Should this not always be the case?
last = listSame->get (listSame->size () - 2);
+
+ //printf (" compare: %s\n", last->toString());
+ //printf (" with: %s\n", vloat->toString());
+ //printf (" covers? %s\n",
+ // last->covers (vloat->generatingBlock, vloat->yReal,
+ // vloat->size.ascent + vloat->size.descent) ?
+ // "yes" : "no");
if (last->covers (vloat->generatingBlock, vloat->yReal,
vloat->size.ascent + vloat->size.descent))
vloat->yReal = last->yForTextblock (vloat->generatingBlock)
+ last->size.ascent + last->size.descent;
+
+ //printf (" => %s\n", vloat->toString());
}
if (listOpp->size() > 0) {
diff --git a/dw/outofflowmgr.hh b/dw/outofflowmgr.hh
index 6dc12279..8d5a965c 100644
--- a/dw/outofflowmgr.hh
+++ b/dw/outofflowmgr.hh
@@ -35,8 +35,10 @@ private:
core::Requisition size;
bool dirty;
- Float (OutOfFlowMgr *oofm) { this->oofm = oofm; }
+ Float (OutOfFlowMgr *oofm, core::Widget *widget,
+ Textblock *generatingBlock);
+ void intoStringBuffer(lout::misc::StringBuffer *sb);
int compareTo(Comparable *other);
int yForTextblock (Textblock *textblock, int y);
@@ -47,14 +49,22 @@ private:
bool covers (Textblock *textblock, int y, int h);
};
- class SortedFloatsVector: public lout::container::typed::Vector<Float>
+ /**
+ * This list is kept sorted.
+ *
+ * To prevent accessing methods of the base class in an
+ * uncontrolled way, the inheritance is private, not public; this
+ * means that all methods must be delegated (see iterator(), size()
+ * etc. below.)
+ */
+ class SortedFloatsVector: private lout::container::typed::Vector<Float>
{
private:
OutOfFlowMgr *oofm;
bool dirty;
-
+
inline void cleanup () { if (dirty) { sort (); dirty = false; } }
-
+
public:
inline SortedFloatsVector (OutOfFlowMgr *oofm) :
lout::container::typed::Vector<Float> (1, false)
@@ -65,6 +75,13 @@ private:
inline void insert (Float *vloat) { cleanup (); insertSorted (vloat); }
inline void change (Float *vloat) { dirty = true; }
void moveTo (SortedFloatsVector *dest);
+
+ inline lout::container::typed::Iterator<Float> iterator()
+ { return lout::container::typed::Vector<Float>::iterator (); }
+ inline int size () // For size, cleanup is irrelevant.
+ { return lout::container::typed::Vector<Float>::size (); }
+ inline Float *get (int pos)
+ { cleanup(); return lout::container::typed::Vector<Float>::get (pos); }
};
class TBInfo: public lout::object::Object
diff --git a/lout/identity.cc b/lout/identity.cc
index ebe95ef0..aecd9d5f 100644
--- a/lout/identity.cc
+++ b/lout/identity.cc
@@ -39,6 +39,22 @@ IdentifiableObject::Class::Class (IdentifiableObject::Class *parent, int id,
this->className = className;
}
+void IdentifiableObject::Class::intoStringBuffer(misc::StringBuffer *sb)
+{
+ sb->append ("<class ");
+ sb->append (className);
+ sb->append (" (");
+ sb->appendInt (id);
+ sb->append (")");
+
+ if (parent) {
+ sb->append (", parent: ");
+ parent->intoStringBuffer (sb);
+ }
+
+ sb->append (">");
+}
+
HashTable <ConstString, IdentifiableObject::Class>
*IdentifiableObject::classesByName =
new HashTable<ConstString, IdentifiableObject::Class> (true, true);
diff --git a/lout/identity.hh b/lout/identity.hh
index 1f0b4bdf..df42b204 100644
--- a/lout/identity.hh
+++ b/lout/identity.hh
@@ -106,6 +106,8 @@ private:
const char *className;
Class (Class *parent, int id, const char *className);
+
+ void intoStringBuffer(misc::StringBuffer *sb);
};
static container::typed::HashTable <object::ConstString,
@@ -121,7 +123,7 @@ protected:
public:
IdentifiableObject ();
- virtual void intoStringBuffer(misc::StringBuffer *sb);
+ void intoStringBuffer(misc::StringBuffer *sb);
/**
* \brief Returns the class identifier.
diff --git a/lout/misc.hh b/lout/misc.hh
index cff8e05b..2ed5e1b0 100644
--- a/lout/misc.hh
+++ b/lout/misc.hh
@@ -515,6 +515,11 @@ public:
* about memory management.
*/
inline void append(const char *str) { appendNoCopy(strdup(str)); }
+ inline void appendInt(int n)
+ { char buf[32]; sprintf (buf, "%d", n); append (buf); }
+ inline void appendPointer(void *p)
+ { char buf[32]; sprintf (buf, "%p", p); append (buf); }
+ inline void appendBool(bool b) { append (b ? "true" : "false"); }
void appendNoCopy(char *str);
const char *getChars();
void clear ();