summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/dw-grows.doc18
-rw-r--r--dw/Makefile.am2
-rw-r--r--dw/alignedtablecell.cc16
-rw-r--r--dw/alignedtablecell.hh5
-rw-r--r--dw/bullet.cc5
-rw-r--r--dw/image.cc5
-rw-r--r--dw/listitem.cc5
-rw-r--r--dw/listitem.hh2
-rw-r--r--dw/oofawarewidget.cc9
-rw-r--r--dw/oofawarewidget.hh1
-rw-r--r--dw/ooffloatsmgr.cc98
-rw-r--r--dw/ooffloatsmgr.hh4
-rw-r--r--dw/oofpositionedmgr.cc2
-rw-r--r--dw/regardingborder.cc39
-rw-r--r--dw/regardingborder.hh24
-rw-r--r--dw/ruler.cc13
-rw-r--r--dw/ruler.hh15
-rw-r--r--dw/simpletablecell.cc13
-rw-r--r--dw/simpletablecell.hh5
-rw-r--r--dw/table.cc230
-rw-r--r--dw/table.hh5
-rw-r--r--dw/tablecell.cc3
-rw-r--r--dw/tablecell.hh5
-rw-r--r--dw/textblock.cc56
-rw-r--r--dw/textblock.hh41
-rw-r--r--dw/textblock_linebreaking.cc36
-rw-r--r--dw/types.hh1
-rw-r--r--dw/ui.cc18
-rw-r--r--dw/ui.hh14
-rw-r--r--dw/widget.cc57
-rw-r--r--dw/widget.hh7
-rw-r--r--lout/misc.hh16
-rw-r--r--src/dillo.cc4
-rw-r--r--src/html.cc21
-rw-r--r--test/dw_simple_container.cc287
35 files changed, 724 insertions, 358 deletions
diff --git a/doc/dw-grows.doc b/doc/dw-grows.doc
index 15150338..0d123d61 100644
--- a/doc/dw-grows.doc
+++ b/doc/dw-grows.doc
@@ -89,6 +89,24 @@ The rules for the calculation:
<b>Notice:</b> Currently, dw::core::Widget::getExtremesImpl must
set all four members in dw::core::Extremes; this may change.</div>
+Another **extension of extremes: *adjustmentWidth*.** This is used as
+minimum for the width, when "adjust_min_width" (or,
+"adjust_table_min_width", respectively) is set.
+
+The rules for the calculation:
+
+1. If a widget has no children, it can choose a suitable value,
+ typically based on dw::core::Extremes::minWidth and
+ dw::core::Extremes::minWidthIntrinsic.
+2. A widget must calculate *adjustmentWidth* from *adjustmentWidth* of
+ its children.
+
+*Note:* An implementation of dw::core::Widget::getExtremesImpl may set
+this value *after* calling dw::core::Widget::correctExtremesOfChild,
+so that it cannot be used for the correction of extremes. In this case
+*useAdjustmentWidth = false* should be passed to
+dw::core::Widget::correctExtremesOfChild. On the other hand, if known
+before, *useAdjustmentWidth* should be set to *true*.
Rules for *new* methods related to resizing
===========================================
diff --git a/dw/Makefile.am b/dw/Makefile.am
index 15055ad8..ba0c7539 100644
--- a/dw/Makefile.am
+++ b/dw/Makefile.am
@@ -84,6 +84,8 @@ libDw_widgets_a_SOURCES = \
oofpositionedmgr.hh \
outofflowmgr.cc \
outofflowmgr.hh \
+ regardingborder.cc \
+ regardingborder.hh \
ruler.cc \
ruler.hh \
simpletablecell.cc \
diff --git a/dw/alignedtablecell.cc b/dw/alignedtablecell.cc
index e7ab2741..dc7d88c9 100644
--- a/dw/alignedtablecell.cc
+++ b/dw/alignedtablecell.cc
@@ -17,8 +17,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-
-
#include "alignedtablecell.hh"
#include "table.hh"
#include "tablecell.hh"
@@ -58,6 +56,11 @@ bool AlignedTableCell::isBlockLevel ()
return tablecell::isBlockLevel ();
}
+bool AlignedTableCell::mustBeWidenedToAvailWidth ()
+{
+ return tablecell::mustBeWidenedToAvailWidth ();
+}
+
int AlignedTableCell::getAvailWidthOfChild (Widget *child, bool forceValue)
{
DBG_OBJ_ENTER ("resize", 0, "AlignedTableCell/getAvailWidthOfChild",
@@ -104,15 +107,18 @@ void AlignedTableCell::correctRequisitionOfChild (Widget *child,
}
void AlignedTableCell::correctExtremesOfChild (Widget *child,
- core::Extremes *extremes)
+ core::Extremes *extremes,
+ bool useAdjustmentWidth)
{
DBG_OBJ_ENTER ("resize", 0, "AlignedTableCell/correctExtremesOfChild",
"%p, %d (%d) / %d (%d)",
child, extremes->minWidth, extremes->minWidthIntrinsic,
extremes->maxWidth, extremes->maxWidthIntrinsic);
- AlignedTextblock::correctExtremesOfChild (child, extremes);
- tablecell::correctCorrectedExtremesOfChild (this, child, extremes);
+ AlignedTextblock::correctExtremesOfChild (child, extremes,
+ useAdjustmentWidth);
+ tablecell::correctCorrectedExtremesOfChild (this, child, extremes,
+ useAdjustmentWidth);
DBG_OBJ_LEAVE ();
}
diff --git a/dw/alignedtablecell.hh b/dw/alignedtablecell.hh
index 5325ba63..56196e6d 100644
--- a/dw/alignedtablecell.hh
+++ b/dw/alignedtablecell.hh
@@ -18,7 +18,8 @@ protected:
void correctRequisitionOfChild (Widget *child,
core::Requisition *requisition,
void (*splitHeightFun) (int, int*, int*));
- void correctExtremesOfChild (Widget *child, core::Extremes *extremes);
+ void correctExtremesOfChild (Widget *child, core::Extremes *extremes,
+ bool useAdjustmentWidth);
bool getAdjustMinWidth ();
@@ -39,6 +40,8 @@ public:
int applyPerHeight (int containerHeight, core::style::Length perHeight);
bool isBlockLevel ();
+
+ bool mustBeWidenedToAvailWidth ();
};
} // namespace dw
diff --git a/dw/bullet.cc b/dw/bullet.cc
index 0b4b5983..e01191c3 100644
--- a/dw/bullet.cc
+++ b/dw/bullet.cc
@@ -44,10 +44,9 @@ void Bullet::sizeRequestImpl (core::Requisition *requisition)
void Bullet::getExtremesImpl (core::Extremes *extremes)
{
- extremes->minWidth = extremes->maxWidth =
+ extremes->minWidth = extremes->maxWidth = extremes->adjustmentWidth =
+ extremes->minWidthIntrinsic = extremes->maxWidthIntrinsic =
lout::misc::max (getStyle()->font->xHeight * 4 / 5, 1);
- extremes->minWidthIntrinsic = extremes->minWidth;
- extremes->maxWidthIntrinsic = extremes->maxWidth;
}
void Bullet::containerSizeChangedForChildren ()
diff --git a/dw/image.cc b/dw/image.cc
index a1052726..7fb6c5eb 100644
--- a/dw/image.cc
+++ b/dw/image.cc
@@ -264,7 +264,10 @@ void Image::getExtremesImpl (core::Extremes *extremes)
extremes->minWidthIntrinsic = extremes->minWidth;
extremes->maxWidthIntrinsic = extremes->maxWidth;
- correctExtremes (extremes);
+ correctExtremes (extremes, false);
+
+ extremes->adjustmentWidth =
+ misc::min (extremes->minWidthIntrinsic, extremes->minWidth);
}
void Image::sizeAllocateImpl (core::Allocation *allocation)
diff --git a/dw/listitem.cc b/dw/listitem.cc
index 65293d8d..8bd2a93a 100644
--- a/dw/listitem.cc
+++ b/dw/listitem.cc
@@ -40,6 +40,11 @@ ListItem::~ListItem()
DBG_OBJ_DELETE ();
}
+bool ListItem::mustBeWidenedToAvailWidth ()
+{
+ return true;
+}
+
void ListItem::initWithWidget (core::Widget *widget,
core::style::Style *style)
{
diff --git a/dw/listitem.hh b/dw/listitem.hh
index 2e303d5d..20fa6e9d 100644
--- a/dw/listitem.hh
+++ b/dw/listitem.hh
@@ -18,6 +18,8 @@ public:
ListItem(ListItem *ref, bool limitTextWidth);
~ListItem();
+ bool mustBeWidenedToAvailWidth ();
+
void initWithWidget (core::Widget *widget, core::style::Style *style);
void initWithText (const char *text, core::style::Style *style);
};
diff --git a/dw/oofawarewidget.cc b/dw/oofawarewidget.cc
index 6e34b32f..c6b75306 100644
--- a/dw/oofawarewidget.cc
+++ b/dw/oofawarewidget.cc
@@ -339,6 +339,8 @@ void OOFAwareWidget::correctExtremesByOOF (Extremes *extremes)
extremes->maxWidth = max (extremes->maxWidth, oofMaxWidth);
extremes->maxWidthIntrinsic = max (extremes->maxWidthIntrinsic,
oofMinWidth);
+ extremes->adjustmentWidth = max (extremes->adjustmentWidth,
+ oofMinWidth);
DBG_OBJ_MSGF ("resize", 1, "after correction: %d (%d) / %d (%d)",
extremes->minWidth, extremes->minWidthIntrinsic,
@@ -809,6 +811,13 @@ Object *OOFAwareWidget::stackingIterator (bool atEnd)
return new OOFStackingIterator (this, atEnd);
}
+bool OOFAwareWidget::mustBeWidenedToAvailWidth ()
+{
+ // Only used for floats.
+ assertNotReached ();
+ return false;
+}
+
void OOFAwareWidget::borderChanged (int y, Widget *vloat)
{
assertNotReached ();
diff --git a/dw/oofawarewidget.hh b/dw/oofawarewidget.hh
index 17123910..5c87b423 100644
--- a/dw/oofawarewidget.hh
+++ b/dw/oofawarewidget.hh
@@ -260,6 +260,7 @@ public:
Widget **interruptedWidget);
lout::object::Object *stackingIterator (bool atEnd);
+ virtual bool mustBeWidenedToAvailWidth ();
virtual void borderChanged (int y, core::Widget *vloat);
virtual void clearPositionChanged ();
virtual void oofSizeChanged (bool extremesChanged);
diff --git a/dw/ooffloatsmgr.cc b/dw/ooffloatsmgr.cc
index f3844577..8758c1a3 100644
--- a/dw/ooffloatsmgr.cc
+++ b/dw/ooffloatsmgr.cc
@@ -750,10 +750,9 @@ bool OOFFloatsMgr::hasRelationChanged (TBInfo *tbInfo, Side side,
else {
Allocation *gba = getAllocation (vloat->generatingBlock);
- int newFlx =
- calcFloatX (vloat, side,
- gba->x - containerAllocation.x, gba->width,
- vloat->generatingBlock->getLineBreakWidth ());
+ int newFlx = calcFloatX (vloat, side,
+ gba->x - containerAllocation.x,
+ getGBWidthForAllocation (vloat));
int newFly = vloat->generatingBlock->getAllocation()->y
- containerAllocation.y + vloat->yReal;
@@ -1206,11 +1205,10 @@ void OOFFloatsMgr::sizeAllocateFloats (Side side, int newLastAllocatedFloat)
ensureFloatSize (vloat);
Allocation *gba = getAllocation (vloat->generatingBlock);
- int lineBreakWidth = vloat->generatingBlock->getLineBreakWidth();
Allocation childAllocation;
- childAllocation.x = cba->x +
- calcFloatX (vloat, side, gba->x - cba->x, gba->width, lineBreakWidth);
+ childAllocation.x = cba->x + calcFloatX (vloat, side, gba->x - cba->x,
+ getGBWidthForAllocation (vloat));
childAllocation.y = gba->y + vloat->yReal;
childAllocation.width = vloat->size.width;
childAllocation.ascent = vloat->size.ascent;
@@ -1224,27 +1222,39 @@ void OOFFloatsMgr::sizeAllocateFloats (Side side, int newLastAllocatedFloat)
DBG_OBJ_LEAVE ();
}
+// Used as argument "gbWidth" for calcFloatX(), in the context of allocation.
+int OOFFloatsMgr::getGBWidthForAllocation (Float *vloat)
+{
+ // See comments in getFloatsSize() for a detailed rationale ...
+ if (container->mustBeWidenedToAvailWidth ())
+ return vloat->generatingBlock->getLineBreakWidth ();
+ else
+ // ... but notice this difference: not GB width + float width is
+ // used, but only GB width, since the float width has already
+ // been included in getFloatsSize().
+ return min (getAllocation(vloat->generatingBlock)->width,
+ vloat->generatingBlock->getLineBreakWidth ());
+}
/**
* \brief ...
*
* gbX is given relative to the CB, as is the return value.
*/
-int OOFFloatsMgr::calcFloatX (Float *vloat, Side side, int gbX, int gbWidth,
- int gbLineBreakWidth)
+int OOFFloatsMgr::calcFloatX (Float *vloat, Side side, int gbX, int gbWidth)
{
- DBG_OBJ_ENTER ("resize.common", 0, "calcFloatX", "%p, %s, %d, %d, %d",
+ DBG_OBJ_ENTER ("resize.common", 0, "calcFloatX", "%p, %s, %d, %d",
vloat->getWidget (), side == LEFT ? "LEFT" : "RIGHT", gbX,
- gbWidth, gbLineBreakWidth);
+ gbWidth);
int x;
switch (side) {
case LEFT:
// Left floats are always aligned on the left side of the
// generator (content, not allocation) ...
- x = gbX + vloat->generatingBlock->boxOffsetX();
- DBG_OBJ_MSGF ("resize.oofm", 1, "left: x = %d + %d = %d",
- gbX, vloat->generatingBlock->boxOffsetX(), x);
+ x = gbX + vloat->generatingBlock->getStyle()->boxOffsetX();
+ DBG_OBJ_MSGF ("resize.common", 1, "left: x = %d + %d = %d",
+ gbX, vloat->generatingBlock->getStyle()->boxOffsetX(), x);
// ... but when the float exceeds the line break width of the
// container, it is corrected (but not left of the container).
// This way, we save space and, especially within tables, avoid
@@ -1254,8 +1264,7 @@ int OOFFloatsMgr::calcFloatX (Float *vloat, Side side, int gbX, int gbWidth,
x = max (0, container->getLineBreakWidth () - vloat->size.width);
DBG_OBJ_MSGF ("resize.common", 1,
"corrected to: max (0, %d - %d) = %d",
- container->getLineBreakWidth (), vloat->size.width,
- x);
+ container->getLineBreakWidth (), vloat->size.width, x);
}
break;
@@ -1264,17 +1273,13 @@ int OOFFloatsMgr::calcFloatX (Float *vloat, Side side, int gbX, int gbWidth,
// shifted to the right when they are too big (instead of
// shifting the generator to the right).
- // Notice that not the actual width, but the line break width is
- // used. (This changed for GROWS, where the width of a textblock
- // is often smaller that the line break.)
-
- x = max (gbX + gbLineBreakWidth - vloat->size.width
- - vloat->generatingBlock->boxRestWidth(),
+ x = max (gbX + gbWidth - vloat->size.width
+ - vloat->generatingBlock->getStyle()->boxRestWidth(),
// Do not exceed CB allocation:
0);
DBG_OBJ_MSGF ("resize.common", 1, "x = max (%d + %d - %d - %d, 0) = %d",
- gbX, gbLineBreakWidth, vloat->size.width,
- vloat->generatingBlock->boxRestWidth(), x);
+ gbX, gbWidth, vloat->size.width,
+ vloat->generatingBlock->getStyle()->boxRestWidth(), x);
break;
default:
@@ -1745,8 +1750,7 @@ bool OOFFloatsMgr::collidesH (Float *vloat, Float *other, SFVType type)
calcFloatX (vloat,
vloat->getWidget()->getStyle()->vloat == FLOAT_LEFT ?
LEFT : RIGHT,
- gba->x, gba->width,
- vloat->generatingBlock->getLineBreakWidth ());
+ gba->x, getGBWidthForAllocation (vloat));
// Generally: right border of the left float > left border of
// the right float (all in canvas coordinates).
@@ -1844,27 +1848,41 @@ void OOFFloatsMgr::getFloatsSize (Requisition *cbReq, Side side, int *width,
DBG_OBJ_MSGF ("resize.oofm", 1,
"float %p has generator %p (container is %p)",
vloat->getWidget (), vloat->generatingBlock, container);
-
- // BTW: as opposed to positioned elements, those floats which
- // are not generated by the container, or not yet allocated, and
- // so not considered here, need not be considered later; since
- // the relevant cases will trigger a call to borderChanged after
- // a positive hasRelationChanged test.
-
+
if (vloat->generatingBlock == container ||
wasAllocated (vloat->generatingBlock)) {
ensureFloatSize (vloat);
int x, y;
+
+ int effWidth;
+ if (container->mustBeWidenedToAvailWidth ())
+ // For most textblocks, the line break width is used for
+ // calculating the x position. (This changed for GROWS,
+ // where the width of a textblock is often smaller that
+ // the line break.)
+ effWidth = vloat->generatingBlock->getLineBreakWidth ();
+ else
+ // For some textblocks, like inline blocks, the line break
+ // width would be too large for right floats in some
+ // cases.
+ //
+ // (i) Consider a small inline block with only a few words
+ // in one line, narrower that line break width minus
+ // float width. In this case, the sum should be used.
+ //
+ // (ii) If there is more than one line, the line break
+ // will already be exceeded, and so be smaller that
+ // GB width + float width.
+ effWidth = min (cbReq->width + vloat->size.width,
+ vloat->generatingBlock->getLineBreakWidth ());
if (vloat->generatingBlock == container) {
- x = calcFloatX (vloat, side, 0, cbReq->width,
- vloat->generatingBlock->getLineBreakWidth ());
+ x = calcFloatX (vloat, side, 0, effWidth);
y = vloat->yReal;
} else {
Allocation *gba = getAllocation(vloat->generatingBlock);
- x = calcFloatX (vloat, side,
- gba->x - containerAllocation.x, gba->width,
- vloat->generatingBlock->getLineBreakWidth ());
+ x = calcFloatX (vloat, side, gba->x - containerAllocation.x,
+ effWidth);
y = gba->y - containerAllocation.y + vloat->yReal;
}
@@ -1938,11 +1956,11 @@ void OOFFloatsMgr::getFloatsExtremes (Extremes *cbExtr, Side side,
vloat->getWidget()->getExtremes (&extr);
// The calculation of extremes must be kept consistent with
- // getSize(). Especially this means for the *minimal* width:
+ // getFloatsSize(). Especially this means for the *minimal* width:
//
// - The right border (difference between float and
// container) does not have to be considered (see
- // getSize()).
+ // getFloatsSize()).
//
// - This is also the case for the left border, as seen in
// calcFloatX() ("... but when the float exceeds the line
diff --git a/dw/ooffloatsmgr.hh b/dw/ooffloatsmgr.hh
index b82019fe..12f7d7da 100644
--- a/dw/ooffloatsmgr.hh
+++ b/dw/ooffloatsmgr.hh
@@ -264,8 +264,8 @@ private:
void moveFromGBToCB (Side side);
void sizeAllocateFloats (Side side, int newLastAllocatedFloat);
- int calcFloatX (Float *vloat, Side side, int gbX, int gbWidth,
- int gbLineBreakWidth);
+ int getGBWidthForAllocation (Float *vloat);
+ int calcFloatX (Float *vloat, Side side, int gbX, int gbWidth);
bool hasRelationChanged (TBInfo *tbInfo,int *minFloatPos,
core::Widget **minFloat);
diff --git a/dw/oofpositionedmgr.cc b/dw/oofpositionedmgr.cc
index c46c1e2c..1e753bda 100644
--- a/dw/oofpositionedmgr.cc
+++ b/dw/oofpositionedmgr.cc
@@ -529,7 +529,7 @@ int OOFPositionedMgr::getAvailWidthOfChild (Widget *child, bool forceValue)
}
if (width != -1)
- width = max (width, child->getMinWidth (NULL, true, forceValue));
+ width = max (width, child->getMinWidth (NULL, forceValue));
DBG_OBJ_MSGF ("resize.oofm", 1, "=> %d", width);
DBG_OBJ_LEAVE ();
diff --git a/dw/regardingborder.cc b/dw/regardingborder.cc
new file mode 100644
index 00000000..2eb0b4bf
--- /dev/null
+++ b/dw/regardingborder.cc
@@ -0,0 +1,39 @@
+/*
+ * 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 "regardingborder.hh"
+
+#include <stdio.h>
+
+namespace dw {
+
+int RegardingBorder::CLASS_ID = -1;
+
+RegardingBorder::RegardingBorder ()
+{
+ DBG_OBJ_CREATE ("dw::RegardingBorder");
+ registerName ("dw::RegardingBorder", &CLASS_ID);
+}
+
+RegardingBorder::~RegardingBorder ()
+{
+ DBG_OBJ_DELETE ();
+}
+
+} // namespace dw
diff --git a/dw/regardingborder.hh b/dw/regardingborder.hh
new file mode 100644
index 00000000..1cb6c25f
--- /dev/null
+++ b/dw/regardingborder.hh
@@ -0,0 +1,24 @@
+#ifndef __DW_REGARDINGBORDER_HH__
+#define __DW_REGARDINGBORDER_HH__
+
+#include "oofawarewidget.hh"
+
+namespace dw {
+
+/**
+ * \brief Base class (rather a tag interface) for those widgets
+ * regarding borders defined by floats, and so allocated on the
+ * full width.
+ */
+class RegardingBorder: public oof::OOFAwareWidget
+{
+public:
+ static int CLASS_ID;
+
+ RegardingBorder ();
+ ~RegardingBorder ();
+};
+
+} // namespace dw
+
+#endif // __DW_REGARDINGBORDER_HH__
diff --git a/dw/ruler.cc b/dw/ruler.cc
index 979cb03c..f29ac5dd 100644
--- a/dw/ruler.cc
+++ b/dw/ruler.cc
@@ -26,8 +26,17 @@
namespace dw {
+int Ruler::CLASS_ID = -1;
+
Ruler::Ruler ()
{
+ DBG_OBJ_CREATE ("dw::Ruler");
+ registerName ("dw::Ruler", &CLASS_ID);
+}
+
+Ruler::~Ruler ()
+{
+ DBG_OBJ_DELETE ();
}
void Ruler::sizeRequestImpl (core::Requisition *requisition)
@@ -42,7 +51,9 @@ void Ruler::getExtremesImpl (core::Extremes *extremes)
extremes->minWidth = extremes->maxWidth = boxDiffWidth ();
extremes->minWidthIntrinsic = extremes->minWidth;
extremes->maxWidthIntrinsic = extremes->maxWidth;
- correctExtremes (extremes);
+ correctExtremes (extremes, false);
+ extremes->adjustmentWidth =
+ lout::misc::min (extremes->minWidthIntrinsic, extremes->minWidth);
}
bool Ruler::isBlockLevel ()
diff --git a/dw/ruler.hh b/dw/ruler.hh
index c94c2e55..50789398 100644
--- a/dw/ruler.hh
+++ b/dw/ruler.hh
@@ -1,7 +1,7 @@
#ifndef __RULER_HH__
#define __RULER_HH__
-#include "core.hh"
+#include "regardingborder.hh"
namespace dw {
@@ -10,10 +10,14 @@ namespace dw {
*
* This is really an empty widget, the HTML parser puts a border
* around it, and drawing is done in dw::core::Widget::drawWidgetBox.
- * The only remarkable point is that the HAS_CONTENT flag is
- * cleared.
+ *
+ * Ruler implements RegardingBorder; this way, it is simpler to fit
+ * the ruler exactly within the space between floats. Currently, the
+ * drawn area of the ruler is too large (but most of the superfluous
+ * part is hidden by the floats); this problem will soon solved here
+ * in the "dillo_grows" repository.
*/
-class Ruler: public core::Widget
+class Ruler: public RegardingBorder
{
protected:
void sizeRequestImpl (core::Requisition *requisition);
@@ -25,7 +29,10 @@ protected:
Widget **interruptedWidget);
public:
+ static int CLASS_ID;
+
Ruler ();
+ ~Ruler ();
bool isBlockLevel ();
diff --git a/dw/simpletablecell.cc b/dw/simpletablecell.cc
index 62b4a0a4..0f1d31c9 100644
--- a/dw/simpletablecell.cc
+++ b/dw/simpletablecell.cc
@@ -50,6 +50,11 @@ bool SimpleTableCell::isBlockLevel ()
return tablecell::isBlockLevel ();
}
+bool SimpleTableCell::mustBeWidenedToAvailWidth ()
+{
+ return tablecell::mustBeWidenedToAvailWidth ();
+}
+
int SimpleTableCell::getAvailWidthOfChild (Widget *child, bool forceValue)
{
DBG_OBJ_ENTER ("resize", 0, "SimpleTableCell/getAvailWidthOfChild",
@@ -94,15 +99,17 @@ void SimpleTableCell::correctRequisitionOfChild (Widget *child,
}
void SimpleTableCell::correctExtremesOfChild (Widget *child,
- core::Extremes *extremes)
+ core::Extremes *extremes,
+ bool useAdjustmentWidth)
{
DBG_OBJ_ENTER ("resize", 0, "SimpleTableCell/correctExtremesOfChild",
"%p, %d (%d) / %d (%d)",
child, extremes->minWidth, extremes->minWidthIntrinsic,
extremes->maxWidth, extremes->maxWidthIntrinsic);
- Textblock::correctExtremesOfChild (child, extremes);
- tablecell::correctCorrectedExtremesOfChild (this, child, extremes);
+ Textblock::correctExtremesOfChild (child, extremes, useAdjustmentWidth);
+ tablecell::correctCorrectedExtremesOfChild (this, child, extremes,
+ useAdjustmentWidth);
DBG_OBJ_LEAVE ();
}
diff --git a/dw/simpletablecell.hh b/dw/simpletablecell.hh
index c90fc040..90f24ae4 100644
--- a/dw/simpletablecell.hh
+++ b/dw/simpletablecell.hh
@@ -14,7 +14,8 @@ protected:
void correctRequisitionOfChild (Widget *child,
core::Requisition *requisition,
void (*splitHeightFun) (int, int*, int*));
- void correctExtremesOfChild (Widget *child, core::Extremes *extremes);
+ void correctExtremesOfChild (Widget *child, core::Extremes *extremes,
+ bool useAdjustmentWidth);
bool getAdjustMinWidth ();
@@ -30,6 +31,8 @@ public:
int applyPerHeight (int containerHeight, core::style::Length perHeight);
bool isBlockLevel ();
+
+ bool mustBeWidenedToAvailWidth ();
};
} // namespace dw
diff --git a/dw/table.cc b/dw/table.cc
index d6dbe633..dc112ef8 100644
--- a/dw/table.cc
+++ b/dw/table.cc
@@ -135,12 +135,13 @@ void Table::getExtremesImpl (core::Extremes *extremes)
if (numCols == 0)
extremes->minWidth = extremes->minWidthIntrinsic = extremes->maxWidth =
- extremes->maxWidthIntrinsic = boxDiffWidth ();
+ extremes->maxWidthIntrinsic = extremes->adjustmentWidth =
+ boxDiffWidth ();
else {
forceCalcColumnExtremes ();
extremes->minWidth = extremes->minWidthIntrinsic = extremes->maxWidth =
- extremes->maxWidthIntrinsic =
+ extremes->maxWidthIntrinsic = extremes->adjustmentWidth =
(numCols + 1) * getStyle()->hBorderSpacing + boxDiffWidth ();
for (int col = 0; col < numCols; col++) {
extremes->minWidth += colExtremes->getRef(col)->minWidth;
@@ -149,10 +150,11 @@ void Table::getExtremesImpl (core::Extremes *extremes)
extremes->maxWidth += colExtremes->getRef(col)->maxWidth;
extremes->maxWidthIntrinsic +=
colExtremes->getRef(col)->maxWidthIntrinsic;
+ extremes->adjustmentWidth += colExtremes->getRef(col)->adjustmentWidth;
}
}
- correctExtremes (extremes);
+ correctExtremes (extremes, true);
// For the order, see similar reasoning for dw::Textblock.
correctExtremesByOOF (extremes);
@@ -231,14 +233,32 @@ int Table::getAvailWidthOfChild (Widget *child, bool forceValue)
oofm->dealingWithSizeOfChild (child))
width = oofm->getAvailWidthOfChild (child, forceValue);
else {
- // Unlike other containers, the table widget sometimes narrows
- // columns to a width less than specified by CSS (see
- // forceCalcCellSizes). For this reason, the column widths have to
- // be calculated in all cases.
- if (forceValue) {
- calcCellSizes (false);
+ // We do not calculate the column widths at this point, because
+ // this tends to be rather inefficient for tables with many
+ // cells:
+ //
+ // For each of the n cells, some text is added (say, only one word
+ // per cell). Textblock::addText will eventually (via addText0
+ // etc.) call this method, Table::getAvailWidthOfChild. If
+ // calcCellSizes() is called here, this will call
+ // forceCalcCellSizes(), since the last call, sizes have to be
+ // re-calculated (because cells have been added). This will
+ // calculate the extremes for each existing cell, so
+ // Widget::getExtremes is called n * (n + 1) / 2 times. Even if the
+ // extremes are cached (so that getExtremesImpl does not have to be
+ // called in each case), this would make rendering tables with more
+ // than a few hundred cells unacceptably slow.
+ //
+ // Instead, column widths are calculated in Table::sizeRequestImpl.
+ //
+ // An alternative would be incremental resizing for tables; this
+ // approach resembles the behaviour before GROWS.
+
+ // TODO Does it still make sence to return -1 when forceValue is
+ // set?
+ if (forceValue)
width = calcAvailWidthForDescendant (child);
- } else
+ else
width = -1;
}
@@ -259,39 +279,31 @@ int Table::calcAvailWidthForDescendant (Widget *child)
assert (actualChild != NULL);
- // TODO This is inefficient. (Use parentRef?)
- int width = -1;
- for (int row = numRows - 1; width == -1 && row >= 0; row--) {
- for (int col = 0; width == -1 && col < numCols; col++) {
- int n = row * numCols + col;
- if (childDefined (n) &&
- children->get(n)->cell.widget == actualChild) {
- DBG_OBJ_MSGF ("resize", 1, "calculated from column %d", col);
- width = (children->get(n)->cell.colspanEff - 1)
- * getStyle()->hBorderSpacing;
- for (int i = 0; i < children->get(n)->cell.colspanEff; i++)
- width += colWidths->get (col + i);
- width = misc::max (width, 0);
-
- if (child != actualChild) {
- // For table cells (direct children: child == actualChild),
- // CSS 'width' is already regarded in the column calculation.
- // However, for children of the table cells, CSS 'width' must
- // be regarded here.
-
- int corrWidth = width;
- child->calcFinalWidth (child->getStyle(), -1, this, 0, true,
- &corrWidth);
-
- // But better not exceed it ... (TODO: Only here?)
- width = misc::min (width, corrWidth);
- }
- }
- }
+ // ActualChild->parentRef contains the position in the children
+ // array (see addCell()), so the column can be easily determined.
+ int col = actualChild->parentRef % numCols;
+ int colspanEff = children->get(actualChild->parentRef)->cell.colspanEff;
+ DBG_OBJ_MSGF ("resize", 1, "calculated from column %d, colspanEff = %d",
+ col, colspanEff);
+
+ int width = (colspanEff - 1) * getStyle()->hBorderSpacing;
+ for (int i = 0; i < colspanEff; i++)
+ width += colWidths->get (col + i);
+ width = misc::max (width, 0);
+
+ if (child != actualChild) {
+ // For table cells (direct children: child == actualChild), CSS
+ // 'width' is already regarded in the column calculation.
+ // However, for children of the table cells, CSS 'width' must be
+ // regarded here.
+
+ int corrWidth = width;
+ child->calcFinalWidth (child->getStyle(), -1, this, 0, true, &corrWidth);
+
+ // But better not exceed it ... (TODO: Only here?)
+ width = misc::min (width, corrWidth);
}
- assert (width != -1);
-
DBG_OBJ_MSGF ("resize", 1, "=> %d", width);
DBG_OBJ_LEAVE ();
return width;
@@ -563,6 +575,12 @@ void Table::addCell (Widget *widget, int colspan, int rowspan)
child->cell.rowspan = rowspan;
children->set (curRow * numCols + curCol, child);
+ // The position in the children array is assigned to parentRef,
+ // although incremental resizing is not implemented. Useful, e. g.,
+ // in calcAvailWidthForDescendant(). See also reallocChildren().
+ widget->parentRef = curRow * numCols + curCol;
+ DBG_OBJ_SET_NUM_O (widget, "parentRef", widget->parentRef);
+
curCol += colspanEff;
widget->parentRef = makeParentRefInFlow (0);
@@ -799,9 +817,35 @@ void Table::reallocChildren (int newNumCols, int newNumRows)
rowStyle->set (row, NULL);
// Rest is increased, when needed.
+ if (newNumCols > numCols) {
+ // Re-calculate parentRef. See addCell().
+ for (int row = 1; row < newNumRows; row++)
+ for (int col = 0; col < newNumCols; col++) {
+ int n = row * newNumCols + col;
+ Child *child = children->get (n);
+ if (child != NULL && child->type == Child::CELL) {
+ child->cell.widget->parentRef = n;
+ DBG_OBJ_SET_NUM_O (child->cell.widget, "parentRef",
+ child->cell.widget->parentRef);
+ }
+ }
+ }
+
numCols = newNumCols;
numRows = newNumRows;
+ // We initiate the column widths with a random value, to have a
+ // defined available width for the children before the column
+ // widths are actually calculated.
+
+ colWidths->setSize (numCols, 100);
+
+ DBG_IF_RTFL {
+ DBG_OBJ_SET_NUM ("colWidths.size", colWidths->size ());
+ for (int i = 0; i < colWidths->size (); i++)
+ DBG_OBJ_ARRSET_NUM ("colWidths", i, colWidths->get (i));
+ }
+
DBG_OBJ_SET_NUM ("numCols", numCols);
DBG_OBJ_SET_NUM ("numRows", numCols);
}
@@ -826,6 +870,64 @@ void Table::calcCellSizes (bool calcHeights)
void Table::forceCalcCellSizes (bool calcHeights)
{
+ // Since Table::getAvailWidthOfChild does not calculate the column
+ // widths, and so initially a random value (100) is returned, a
+ // correction is necessary. The old values are temporary preserved
+ // ...
+
+ lout::misc::SimpleVector<int> oldColWidths (8);
+ oldColWidths.setSize (colWidths->size ());
+ colWidths->copyTo (&oldColWidths);
+
+ actuallyCalcCellSizes (calcHeights);
+
+ // ... and then compared to the new ones. In case of a difference,
+ // the cell is told about this.
+
+ for (int col = 0; col < colWidths->size (); col++) {
+ if (oldColWidths.get (col) != colWidths->get (col)) {
+ for (int row = 0; row < numRows; row++) {
+ int n = row * numCols + col, col2;
+ Child *child = children->get(n);
+ if (child) {
+ Widget *cell;
+ switch (child->type) {
+ case Child::CELL:
+ cell = child->cell.widget;
+ break;
+
+ case Child::SPAN_SPACE:
+ // TODO Are Child::spanSpace::startRow and
+ // Child::spanSpace::startCol not defined?
+
+ // Search for actual cell. If not found, this means
+ // that a cell is spanning multiple columns *and*
+ // rows; in this case it has been processed before.
+
+ cell = NULL;
+ for (col2 = col - 1; col2 >= 0 && cell == NULL; col2--) {
+ int n2 = row * numCols + col2;
+ Child *child2 = children->get(n2);
+ if (child2 != NULL && child2->type == Child::CELL)
+ cell = child2->cell.widget;
+ }
+ break;
+
+ default:
+ misc::assertNotReached ();
+ cell = NULL;
+ }
+
+ if (cell)
+ cell->containerSizeChanged ();
+ }
+ }
+ }
+ }
+}
+
+void Table::actuallyCalcCellSizes (bool calcHeights)
+{
DBG_OBJ_ENTER0 ("resize", 0, "forceCalcCellSizes");
int childHeight;
@@ -835,10 +937,10 @@ void Table::forceCalcCellSizes (bool calcHeights)
getExtremes (&extremes);
int availWidth = getAvailWidth (true);
- // When adjust_table_min_width is set, use the minimal (intrinsic)
- // width for correction.
+ // When adjust_table_min_width is set, use perhaps the adjustment
+ // width for correction. (TODO: Is this necessary?)
int corrWidth =
- Table::getAdjustTableMinWidth () ? extremes.minWidthIntrinsic : 0;
+ Table::getAdjustTableMinWidth () ? extremes.adjustmentWidth : 0;
int totalWidth = misc::max (availWidth, corrWidth)
- ((numCols + 1) * getStyle()->hBorderSpacing + boxDiffWidth ());
@@ -847,13 +949,14 @@ void Table::forceCalcCellSizes (bool calcHeights)
availWidth, corrWidth, numCols, getStyle()->hBorderSpacing,
boxDiffWidth (), totalWidth);
- colWidths->setSize (numCols, 0);
+ assert (colWidths->size () == numCols); // This is set in addCell.
cumHeight->setSize (numRows + 1, 0);
rowSpanCells->setSize (0);
baseline->setSize (numRows);
misc::SimpleVector<int> *oldColWidths = colWidths;
colWidths = new misc::SimpleVector <int> (8);
+ colWidths->setSize (numCols);
int minWidth = 0, minWidthIntrinsic = 0, maxWidth = 0;
for (int col = 0; col < colExtremes->size(); col++) {
@@ -924,8 +1027,6 @@ void Table::forceCalcCellSizes (bool calcHeights)
} else {
DBG_OBJ_MSG ("resize", 1, "case 1b: treat percentages specially");
- colWidths->setSize (colExtremes->size(), 0);
-
// Keep track of the width which is apportioned to the rest
// of the columns with percentage width (widthPartPer), and
// the minimal width (intrinsic minimum) which is needed for
@@ -1048,7 +1149,6 @@ void Table::forceCalcCellSizes (bool calcHeights)
DBG_OBJ_MSG ("resize", 1, "finally setting column widths:");
DBG_OBJ_MSG_START ();
- colWidths->setSize (colExtremes->size());
indexNotSpecified = 0;
for (int col = 0; col < colExtremes->size(); col++)
if (colWidthSpecified->get (col)) {
@@ -1253,6 +1353,7 @@ void Table::forceCalcColumnExtremes ()
colExtremes->getRef(col)->minWidthIntrinsic = 0;
colExtremes->getRef(col)->maxWidth = 0;
colExtremes->getRef(col)->maxWidthIntrinsic = 0;
+ colExtremes->getRef(col)->adjustmentWidth = 0;
for (int row = 0; row < numRows; row++) {
DBG_OBJ_MSGF ("resize", 1, "row %d", row);
@@ -1284,6 +1385,10 @@ void Table::forceCalcColumnExtremes ()
colExtremes->getRef(col)->maxWidth,
cellExtremes.maxWidth);
+ colExtremes->getRef(col)->adjustmentWidth =
+ misc::max (colExtremes->getRef(col)->adjustmentWidth,
+ cellExtremes.adjustmentWidth);
+
core::style::Length childWidth =
children->get(n)->cell.widget->getStyle()->width;
if (childWidth != core::style::LENGTH_AUTO) {
@@ -1322,9 +1427,10 @@ void Table::forceCalcColumnExtremes ()
core::Extremes cellExtremes;
children->get(n)->cell.widget->getExtremes (&cellExtremes);
- calcExtremesSpanMulteCols (col, cs, &cellExtremes, MIN, MAX, NULL);
- calcExtremesSpanMulteCols (col, cs, &cellExtremes, MIN_INTR, MAX_INTR,
+ calcExtremesSpanMultiCols (col, cs, &cellExtremes, MIN, MAX, NULL);
+ calcExtremesSpanMultiCols (col, cs, &cellExtremes, MIN_INTR, MAX_INTR,
NULL);
+ calcAdjustmentWidthSpanMultiCols (col, cs, &cellExtremes);
core::style::Length childWidth =
children->get(n)->cell.widget->getStyle()->width;
@@ -1380,7 +1486,7 @@ void Table::forceCalcColumnExtremes ()
DBG_OBJ_LEAVE ();
}
-void Table::calcExtremesSpanMulteCols (int col, int cs,
+void Table::calcExtremesSpanMultiCols (int col, int cs,
core::Extremes *cellExtremes,
ExtrMod minExtrMod, ExtrMod maxExtrMod,
void *extrData)
@@ -1431,6 +1537,28 @@ void Table::calcExtremesSpanMulteCols (int col, int cs,
DBG_OBJ_LEAVE ();
}
+void Table::calcAdjustmentWidthSpanMultiCols (int col, int cs,
+ core::Extremes *cellExtremes)
+{
+ DBG_OBJ_ENTER ("resize", 0, "calcAdjustmentWidthSpanMultiCols",
+ "%d, %d, ...", col, cs);
+
+ int sumAdjustmentWidth = 0;
+ for (int j = 0; j < cs; j++)
+ sumAdjustmentWidth += colExtremes->getRef(col + j)->adjustmentWidth;
+
+ if (cellExtremes->adjustmentWidth > sumAdjustmentWidth) {
+ misc::SimpleVector<int> newAdjustmentWidth;
+ apportion2 (cellExtremes->adjustmentWidth, col, col + cs - 1, MIN, MAX,
+ NULL, &newAdjustmentWidth, 0);
+ for (int j = 0; j < cs; j++)
+ colExtremes->getRef(col + j)->adjustmentWidth =
+ newAdjustmentWidth.get (j);
+ }
+
+ DBG_OBJ_LEAVE ();
+}
+
/**
* \brief Actual apportionment function.
*/
diff --git a/dw/table.hh b/dw/table.hh
index 2ad56447..1a12cb60 100644
--- a/dw/table.hh
+++ b/dw/table.hh
@@ -434,14 +434,17 @@ private:
void calcCellSizes (bool calcHeights);
void forceCalcCellSizes (bool calcHeights);
+ void actuallyCalcCellSizes (bool calcHeights);
void apportionRowSpan ();
void _unused_calcColumnExtremes ();
void forceCalcColumnExtremes ();
- void calcExtremesSpanMulteCols (int col, int cs,
+ void calcExtremesSpanMultiCols (int col, int cs,
core::Extremes *cellExtremes,
ExtrMod minExtrMod, ExtrMod maxExtrMod,
void *extrData);
+ void calcAdjustmentWidthSpanMultiCols (int col, int cs,
+ core::Extremes *cellExtremes);
void apportion2 (int totalWidth, int firstCol, int lastCol,
ExtrMod minExtrMod, ExtrMod maxExtrMod, void *extrData,
diff --git a/dw/tablecell.cc b/dw/tablecell.cc
index 5c34c781..3e143c96 100644
--- a/dw/tablecell.cc
+++ b/dw/tablecell.cc
@@ -98,7 +98,8 @@ void correctCorrectedRequisitionOfChild (core::Widget *widget,
}
void correctCorrectedExtremesOfChild (core::Widget *widget, core::Widget *child,
- core::Extremes *extremes)
+ core::Extremes *extremes,
+ bool useAdjustmentWidth)
{
// Something to do?
}
diff --git a/dw/tablecell.hh b/dw/tablecell.hh
index f7936203..1300a944 100644
--- a/dw/tablecell.hh
+++ b/dw/tablecell.hh
@@ -7,6 +7,8 @@ namespace dw {
namespace tablecell {
+inline bool mustBeWidenedToAvailWidth () { return true; }
+
bool getAdjustMinWidth ();
bool isBlockLevel ();
@@ -21,7 +23,8 @@ void correctCorrectedRequisitionOfChild (core::Widget *widget,
void (*splitHeightFun) (int, int*,
int*));
void correctCorrectedExtremesOfChild (core::Widget *widget, core::Widget *child,
- core::Extremes *extremes);
+ core::Extremes *extremes,
+ bool useAdjustmentWidth);
int applyPerWidth (core::Widget *widget, int containerWidth,
core::style::Length perWidth);
diff --git a/dw/textblock.cc b/dw/textblock.cc
index 250c12d6..00968c61 100644
--- a/dw/textblock.cc
+++ b/dw/textblock.cc
@@ -434,7 +434,8 @@ void Textblock::getWordExtremes (Word *word, core::Extremes *extremes)
word->content.widget->getExtremes (extremes);
else
extremes->minWidth = extremes->minWidthIntrinsic = extremes->maxWidth =
- extremes->maxWidthIntrinsic = word->size.width;
+ extremes->maxWidthIntrinsic = extremes->adjustmentWidth =
+ word->size.width;
}
void Textblock::getExtremesImpl (core::Extremes *extremes)
@@ -462,12 +463,14 @@ void Textblock::getExtremesImpl (core::Extremes *extremes)
extremes->minWidthIntrinsic = 0;
extremes->maxWidth = 0;
extremes->maxWidthIntrinsic = 0;
+ extremes->adjustmentWidth = 0;
} else {
Paragraph *lastPar = paragraphs->getLastRef ();
extremes->minWidth = lastPar->maxParMin;
extremes->minWidthIntrinsic = lastPar->maxParMinIntrinsic;
extremes->maxWidth = lastPar->maxParMax;
extremes->maxWidthIntrinsic = lastPar->maxParMaxIntrinsic;
+ extremes->adjustmentWidth = lastPar->maxParAdjustmentWidth;
DBG_OBJ_MSGF ("resize", 1, "paragraphs[%d]->maxParMin = %d (%d)",
paragraphs->size () - 1, lastPar->maxParMin,
@@ -486,6 +489,7 @@ void Textblock::getExtremesImpl (core::Extremes *extremes)
extremes->minWidthIntrinsic += diff;
extremes->maxWidth += diff;
extremes->maxWidthIntrinsic += diff;
+ extremes->adjustmentWidth += diff;
DBG_OBJ_MSGF ("resize", 0, "after adding diff: %d (%d) / %d (%d)",
extremes->minWidth, extremes->minWidthIntrinsic,
@@ -493,7 +497,7 @@ void Textblock::getExtremesImpl (core::Extremes *extremes)
// For the order, see similar reasoning in sizeRequestImpl.
- correctExtremes (extremes);
+ correctExtremes (extremes, true);
DBG_OBJ_MSGF ("resize", 0, "after correction: %d (%d) / %d (%d)",
extremes->minWidth, extremes->minWidthIntrinsic,
@@ -2947,6 +2951,27 @@ void Textblock::queueDrawRange (int index1, int index2)
DBG_OBJ_LEAVE ();
}
+bool Textblock::mustBeWidenedToAvailWidth ()
+{
+ DBG_OBJ_ENTER0 ("resize", 0, "mustBeWidenedToAvailWidth");
+ bool toplevel = getParent () == NULL,
+ block = getStyle()->display == core::style::DISPLAY_BLOCK,
+ vloat = testWidgetFloat (this),
+ abspos = testWidgetAbsolutelyPositioned (this),
+ fixpos = testWidgetFixedlyPositioned (this),
+ // In detail, this depends on what the respective OOFM does
+ // with the child widget:
+ result = toplevel || (block && !(vloat || abspos || fixpos));
+ DBG_OBJ_MSGF ("resize", 0,
+ "=> %s (toplevel: %s, block: %s, float: %s, abspos: %s, "
+ "fixpos: %s)",
+ result ? "true" : "false", toplevel ? "true" : "false",
+ block ? "true" : "false", vloat ? "true" : "false",
+ abspos ? "true" : "false", fixpos ? "true" : "false");
+ DBG_OBJ_LEAVE ();
+ return result;
+}
+
/**
* Called by dw::OOFFloatsMgr when the border has changed due to a
* float (or some floats).
@@ -3136,48 +3161,49 @@ bool Textblock::isPossibleContainerParent (int oofmIndex)
return true;
}
-Textblock *Textblock::getTextblockForLine (Line *line)
+RegardingBorder *Textblock::getWidgetRegardingBorderForLine (Line *line)
{
- return getTextblockForLine (line->firstWord, line->lastWord);
+ return getWidgetRegardingBorderForLine (line->firstWord, line->lastWord);
}
-Textblock *Textblock::getTextblockForLine (int lineNo)
+RegardingBorder *Textblock::getWidgetRegardingBorderForLine (int lineNo)
{
// Can also be used for a line not yet existing.
int firstWord = lineNo == 0 ? 0 : lines->getRef(lineNo - 1)->lastWord + 1;
int lastWord = lineNo < lines->size() ?
lines->getRef(lineNo)->lastWord : words->size() - 1;
- return getTextblockForLine (firstWord, lastWord);
+ return getWidgetRegardingBorderForLine (firstWord, lastWord);
}
-Textblock *Textblock::getTextblockForLine (int firstWord, int lastWord)
+RegardingBorder *Textblock::getWidgetRegardingBorderForLine (int firstWord,
+ int lastWord)
{
- DBG_OBJ_ENTER ("resize", 0, "getTextblockForLine", "%d, %d",
+ DBG_OBJ_ENTER ("resize", 0, "getWidgetRegardingBorderForLine", "%d, %d",
firstWord, lastWord);
DBG_OBJ_MSGF ("resize", 1, "words.size = %d", words->size ());
- Textblock *textblock = NULL;
+ RegardingBorder *widgetRegardingBorder = NULL;
if (firstWord < words->size ()) {
- // A textblock is always between two line breaks, and so the
- // first word of the line.
+ // Any instance of a subclass of WidgetRegardingBorder is always
+ // between two line breaks, and so the first word of the line.
Word *word = words->getRef (firstWord);
DBG_MSG_WORD ("resize", 1, "<i>first word:</i> ", firstWord, "");
if (word->content.type == core::Content::WIDGET_IN_FLOW) {
Widget *widget = word->content.widget;
- if (widget->instanceOf (Textblock::CLASS_ID) &&
+ if (widget->instanceOf (RegardingBorder::CLASS_ID) &&
// Exclude cases where a textblock constitutes a new floats
// container.
!isOOFContainer (widget, OOFM_FLOATS))
- textblock = (Textblock*)widget;
+ widgetRegardingBorder = (RegardingBorder*)widget;
}
}
- DBG_OBJ_MSGF ("resize", 1, "=> %p", textblock);
+ DBG_OBJ_MSGF ("resize", 1, "=> %p", widgetRegardingBorder);
DBG_OBJ_LEAVE ();
- return textblock;
+ return widgetRegardingBorder;
}
/**
diff --git a/dw/textblock.hh b/dw/textblock.hh
index 0834e183..143cede3 100644
--- a/dw/textblock.hh
+++ b/dw/textblock.hh
@@ -3,7 +3,7 @@
#include <limits.h>
-#include "oofawarewidget.hh"
+#include "regardingborder.hh"
#include "../lout/misc.hh"
// These were used when improved line breaking and hyphenation were implemented.
@@ -200,7 +200,7 @@ namespace dw {
* - dw::oof::OOFAwareWidget (base class) and
* - \ref dw-out-of-flow.
*/
-class Textblock: public oof::OOFAwareWidget
+class Textblock: public RegardingBorder
{
private:
/**
@@ -353,6 +353,7 @@ protected:
hyphen width etc.) since the last possible
break within this paragraph. */
int parMinIntrinsic;
+ int parAdjustmentWidth;
int parMax; /* The sum of all word maxima in this
paragraph (plus spaces, hyphen width
etc.). */
@@ -361,6 +362,7 @@ protected:
int maxParMin; /* Maximum of all paragraph minima (value of
"parMin"), including this paragraph. */
int maxParMinIntrinsic;
+ int maxParAdjustmentWidth;
int maxParMax; /* Maximum of all paragraph maxima (value of
"parMax""), including this paragraph. */
int maxParMaxIntrinsic;
@@ -689,12 +691,12 @@ protected:
*/
inline bool mustBorderBeRegarded (Line *line)
{
- return getTextblockForLine (line) == NULL;
+ return getWidgetRegardingBorderForLine (line) == NULL;
}
inline bool mustBorderBeRegarded (int lineNo)
{
- return getTextblockForLine (lineNo) == NULL;
+ return getWidgetRegardingBorderForLine (lineNo) == NULL;
}
inline int _lineYOffsetWidgetAllocation (Line *line,
@@ -759,9 +761,10 @@ protected:
}
}
- Textblock *getTextblockForLine (Line *line);
- Textblock *getTextblockForLine (int lineNo);
- Textblock *getTextblockForLine (int firstWord, int lastWord);
+ RegardingBorder *getWidgetRegardingBorderForLine (Line *line);
+ RegardingBorder *getWidgetRegardingBorderForLine (int lineNo);
+ RegardingBorder *getWidgetRegardingBorderForLine (int firstWord,
+ int lastWord);
void printBorderChangedErrorAndAbort (int y, Widget *vloat,
int wrapLineIndex);
int yOffsetOfLineToBeCreated ();
@@ -850,29 +853,6 @@ protected:
int numBreaks, int *breakPos,
core::Requisition *wordSize);
- inline bool mustBeWidenedToAvailWidth () {
- DBG_OBJ_ENTER0 ("resize", 0, "mustBeWidenedToAvailWidth");
- bool toplevel = getParent () == NULL,
- block = getStyle()->display == core::style::DISPLAY_BLOCK,
- listitem = getStyle()->display == core::style::DISPLAY_LIST_ITEM,
- vloat = testWidgetFloat (this),
- abspos = testWidgetAbsolutelyPositioned (this),
- fixpos = testWidgetFixedlyPositioned (this),
- // In detail, this depends on what the respective OOFM does
- // with the child widget:
- result =
- toplevel || ((block || listitem) && !(vloat || abspos || fixpos));
- DBG_OBJ_MSGF ("resize", 0,
- "=> %s (toplevel: %s, block: %s, listitem: %s, float: %s, "
- "abspos: %s, fixpos: %s)",
- result ? "true" : "false", toplevel ? "true" : "false",
- block ? "true" : "false", listitem ? "true" : "false",
- vloat ? "true" : "false", abspos ? "true" : "false",
- fixpos ? "true" : "false");
- DBG_OBJ_LEAVE ();
- return result;
- }
-
public:
static int CLASS_ID;
@@ -905,6 +885,7 @@ public:
void changeWordStyle (int from, int to, core::style::Style *style,
bool includeFirstSpace, bool includeLastSpace);
+ bool mustBeWidenedToAvailWidth ();
void borderChanged (int y, core::Widget *vloat);
void clearPositionChanged ();
void oofSizeChanged (bool extremesChanged);
diff --git a/dw/textblock_linebreaking.cc b/dw/textblock_linebreaking.cc
index 666a38f8..a987d62f 100644
--- a/dw/textblock_linebreaking.cc
+++ b/dw/textblock_linebreaking.cc
@@ -435,6 +435,15 @@ Textblock::Line *Textblock::addLine (int firstWord, int lastWord,
word->effSpace, word->origSpace, i, lineWidth);
}
+ // Until here, lineWidth refers does not include floats on the left
+ // side. To include left floats, so that maxLineWidth, and
+ // eventually the requisition, is correct, line->textOffset has to
+ // be added, which was calculated just before in calcTextOffset().
+ // The correction in sizeAllocateImpl() is irrelevant in this
+ // regard. Also, right floats are not regarded here, but in
+ // OutOfFlowMgr::getSize(),
+ //lineWidth += line->textOffset; -- TODO: Does not work!
+
if (lines->size () == 1) {
// first line
line->maxLineWidth = lineWidth;
@@ -1259,17 +1268,18 @@ void Textblock::handleWordExtremes (int wordIndex)
Paragraph *par = paragraphs->getLastRef();
par->firstWord = par->lastWord = wordIndex;
- par->parMin = par->parMinIntrinsic = par->parMax = par->parMaxIntrinsic
- = 0;
+ par->parMin = par->parMinIntrinsic = par->parMax = par->parMaxIntrinsic =
+ par->parAdjustmentWidth = 0;
if (prevPar) {
par->maxParMin = prevPar->maxParMin;
par->maxParMinIntrinsic = prevPar->maxParMinIntrinsic;
par->maxParMax = prevPar->maxParMax;
par->maxParMaxIntrinsic = prevPar->maxParMaxIntrinsic;
+ par->maxParAdjustmentWidth = prevPar->maxParAdjustmentWidth;
} else
par->maxParMin = par->maxParMinIntrinsic = par->maxParMax =
- par->maxParMaxIntrinsic = 0;
+ par->maxParMaxIntrinsic = par->maxParAdjustmentWidth = 0;
DBG_OBJ_ARRATTRSET_NUM ("paragraphs", paragraphs->size() - 1, "maxParMin",
par->maxParMin);
@@ -1301,9 +1311,13 @@ void Textblock::handleWordExtremes (int wordIndex)
lastPar->parMin += wordExtremes.minWidth + word->hyphenWidth + corrDiffMin;
lastPar->parMinIntrinsic +=
wordExtremes.minWidthIntrinsic + word->hyphenWidth + corrDiffMin;
+ lastPar->parAdjustmentWidth +=
+ wordExtremes.adjustmentWidth + word->hyphenWidth + corrDiffMin;
lastPar->maxParMin = misc::max (lastPar->maxParMin, lastPar->parMin);
lastPar->maxParMinIntrinsic =
misc::max (lastPar->maxParMinIntrinsic, lastPar->parMinIntrinsic);
+ lastPar->maxParAdjustmentWidth =
+ misc::max (lastPar->maxParAdjustmentWidth, lastPar->parAdjustmentWidth);
DBG_OBJ_ARRATTRSET_NUM ("paragraphs", paragraphs->size() - 1, "parMin",
lastPar->parMin);
@@ -1313,15 +1327,24 @@ void Textblock::handleWordExtremes (int wordIndex)
lastPar->maxParMin);
DBG_OBJ_ARRATTRSET_NUM ("paragraphs", paragraphs->size() - 1,
"maxParMinIntrinsic", lastPar->maxParMinIntrinsic);
+ DBG_OBJ_ARRATTRSET_NUM ("paragraphs", paragraphs->size() - 1,
+ "parAdjustmentWidth", lastPar->parAdjustmentWidth);
+ DBG_OBJ_ARRATTRSET_NUM ("paragraphs", paragraphs->size() - 1,
+ "maxParAdjustmentWidth",
+ lastPar->maxParAdjustmentWidth);
if (word->badnessAndPenalty.lineCanBeBroken (1) &&
(word->flags & Word::UNBREAKABLE_FOR_MIN_WIDTH) == 0) {
- lastPar->parMin = lastPar->parMinIntrinsic = 0;
+ lastPar->parMin = lastPar->parMinIntrinsic = lastPar->parAdjustmentWidth
+ = 0;
DBG_OBJ_ARRATTRSET_NUM ("paragraphs", paragraphs->size() - 1, "parMin",
lastPar->parMin);
DBG_OBJ_ARRATTRSET_NUM ("paragraphs", paragraphs->size() - 1,
"parMinIntrinsic", lastPar->parMinIntrinsic);
+ DBG_OBJ_ARRATTRSET_NUM ("paragraphs", paragraphs->size() - 1,
+ "parAdjustmentWidth",
+ lastPar->parAdjustmentWidth);
}
// Maximum: between two *necessary* breaks.
@@ -1354,8 +1377,9 @@ void Textblock::correctLastWordExtremes ()
Word *word = words->getLastRef ();
if (word->badnessAndPenalty.lineCanBeBroken (1) &&
(word->flags & Word::UNBREAKABLE_FOR_MIN_WIDTH) == 0) {
- paragraphs->getLastRef()->parMin =
- paragraphs->getLastRef()->parMinIntrinsic = 0;
+ Paragraph *lastPar = paragraphs->getLastRef();
+ lastPar->parMin = lastPar->parMinIntrinsic =
+ lastPar->parAdjustmentWidth = 0;
PRINTF (" => corrected; parMin = %d\n",
paragraphs->getLastRef()->parMin);
}
diff --git a/dw/types.hh b/dw/types.hh
index 081b8db4..87f688aa 100644
--- a/dw/types.hh
+++ b/dw/types.hh
@@ -182,6 +182,7 @@ struct Extremes
int maxWidth;
int minWidthIntrinsic;
int maxWidthIntrinsic;
+ int adjustmentWidth;
};
struct Content
diff --git a/dw/ui.cc b/dw/ui.cc
index 2aed65de..07317dd2 100644
--- a/dw/ui.cc
+++ b/dw/ui.cc
@@ -56,7 +56,9 @@ void Embed::sizeRequestImpl (Requisition *requisition)
void Embed::getExtremesImpl (Extremes *extremes)
{
resource->getExtremes (extremes);
- correctExtremes (extremes);
+ correctExtremes (extremes, false);
+ extremes->adjustmentWidth =
+ misc::max (extremes->minWidthIntrinsic, extremes->minWidth);
}
void Embed::sizeAllocateImpl (Allocation *allocation)
@@ -81,9 +83,10 @@ void Embed::correctRequisitionOfChild (Widget *child,
resource->correctRequisitionOfChild (child, requisition, splitHeightFun);
}
-void Embed::correctExtremesOfChild (Widget *child, Extremes *extremes)
+void Embed::correctExtremesOfChild (Widget *child, Extremes *extremes,
+ bool useAdjustmentWidth)
{
- resource->correctExtremesOfChild (child, extremes);
+ resource->correctExtremesOfChild (child, extremes, useAdjustmentWidth);
}
void Embed::containerSizeChangedForChildren ()
@@ -249,7 +252,8 @@ void Resource::correctRequisitionOfChild (Widget *child,
misc::assertNotReached ();
}
-void Resource::correctExtremesOfChild (Widget *child, Extremes *extremes)
+void Resource::correctExtremesOfChild (Widget *child, Extremes *extremes,
+ bool useAdjustmentWidth)
{
// Only used when the resource contains other dillo widgets.
misc::assertNotReached ();
@@ -439,7 +443,8 @@ void ComplexButtonResource::correctRequisitionOfChild (Widget *child,
}
void ComplexButtonResource::correctExtremesOfChild (Widget *child,
- Extremes *extremes)
+ Extremes *extremes,
+ bool useAdjustmentWidth)
{
// Similar to Widget::correctExtremesOfChild, but for percentage
// the relief has to be considered.
@@ -455,7 +460,8 @@ void ComplexButtonResource::correctExtremesOfChild (Widget *child,
child->applyPerWidth (baseWidth, child->getStyle()->width);
}
} else
- getEmbed()->correctExtremesOfChildNoRec (child, extremes);
+ getEmbed()->correctExtremesOfChildNoRec (child, extremes,
+ useAdjustmentWidth);
}
void ComplexButtonResource::containerSizeChangedForChildren ()
diff --git a/dw/ui.hh b/dw/ui.hh
index 1ff896f5..a4c77ceb 100644
--- a/dw/ui.hh
+++ b/dw/ui.hh
@@ -237,7 +237,8 @@ protected:
void correctRequisitionOfChild (Widget *child,
Requisition *requisition,
void (*splitHeightFun) (int, int*, int*));
- void correctExtremesOfChild (Widget *child, Extremes *extremes);
+ void correctExtremesOfChild (Widget *child, Extremes *extremes,
+ bool useAdjustmentWidth);
void containerSizeChangedForChildren ();
@@ -270,8 +271,9 @@ public:
int*))
{ Widget::correctReqHeightOfChild (child, requisition, splitHeightFun); }
- virtual void correctExtremesOfChildNoRec (Widget *child, Extremes *extremes)
- { Widget::correctExtremesOfChild (child, extremes); }
+ virtual void correctExtremesOfChildNoRec (Widget *child, Extremes *extremes,
+ bool useAdjustmentWidth)
+ { Widget::correctExtremesOfChild (child, extremes, useAdjustmentWidth); }
};
/**
@@ -363,7 +365,8 @@ public:
Requisition *requisition,
void (*splitHeightFun) (int, int*,
int*));
- virtual void correctExtremesOfChild (Widget *child, Extremes *extremes);
+ virtual void correctExtremesOfChild (Widget *child, Extremes *extremes,
+ bool useAdjustmentWidth);
virtual void containerSizeChangedForChildren ();
virtual void setDisplayed (bool displayed);
@@ -439,7 +442,8 @@ public:
void correctRequisitionOfChild (Widget *child,
Requisition *requisition,
void (*splitHeightFun) (int, int*, int*));
- void correctExtremesOfChild (Widget *child, Extremes *extremes);
+ void correctExtremesOfChild (Widget *child, Extremes *extremes,
+ bool useAdjustmentWidth);
void containerSizeChangedForChildren ();
Iterator *iterator (Content::Type mask, bool atEnd);
diff --git a/dw/widget.cc b/dw/widget.cc
index d5c856d2..8f93701d 100644
--- a/dw/widget.cc
+++ b/dw/widget.cc
@@ -734,18 +734,18 @@ void Widget::sizeRequest (Requisition *requisition)
* context of correctExtemes etc., to avoid cyclic dependencies.
*
*/
-int Widget::getMinWidth (Extremes *extremes, bool useCorrected, bool forceValue)
-{
- if (extremes)
- DBG_OBJ_ENTER ("resize", 0, "getMinWidth", "[%d (%d) / %d (%d), %s, %s",
- extremes->minWidth, extremes->minWidthIntrinsic,
- extremes->maxWidth, extremes->maxWidthIntrinsic,
- useCorrected ? "true" : "false",
- forceValue ? "true" : "false");
- else
- DBG_OBJ_ENTER ("resize", 0, "getMinWidth", "(nil), %s, %s",
- useCorrected ? "true" : "false",
- forceValue ? "true" : "false");
+int Widget::getMinWidth (Extremes *extremes, bool forceValue)
+{
+ DBG_IF_RTFL {
+ if (extremes)
+ DBG_OBJ_ENTER ("resize", 0, "getMinWidth", "[%d (%d) / %d (%d), %s",
+ extremes->minWidth, extremes->minWidthIntrinsic,
+ extremes->maxWidth, extremes->maxWidthIntrinsic,
+ forceValue ? "true" : "false");
+ else
+ DBG_OBJ_ENTER ("resize", 0, "getMinWidth", "(nil), %s",
+ forceValue ? "true" : "false");
+ }
int minWidth;
@@ -761,13 +761,9 @@ int Widget::getMinWidth (Extremes *extremes, bool useCorrected, bool forceValue)
// TODO Not completely clear whether this is feasable: Within
// the context of getAvailWidth(false) etc., getExtremes may not
// be called. We ignore the minimal width then.
- if (extremes) {
- if (useCorrected)
- minWidth =
- misc::max (extremes->minWidth, extremes->minWidthIntrinsic);
- else
- minWidth = extremes->minWidthIntrinsic;
- } else
+ if (extremes)
+ minWidth = extremes->adjustmentWidth;
+ else
minWidth = 0;
} else
minWidth = 0;
@@ -894,7 +890,7 @@ void Widget::correctRequisition (Requisition *requisition,
DBG_OBJ_MSG ("resize", 1, "no parent, regarding viewport");
DBG_OBJ_MSG_START ();
- int limitMinWidth = getMinWidth (NULL, true, true);
+ int limitMinWidth = getMinWidth (NULL, true);
int viewportWidth =
layout->viewportWidth - (layout->canvasHeightGreater ?
layout->vScrollbarThickness : 0);
@@ -941,7 +937,7 @@ void Widget::correctRequisition (Requisition *requisition,
DBG_OBJ_LEAVE ();
}
-void Widget::correctExtremes (Extremes *extremes)
+void Widget::correctExtremes (Extremes *extremes, bool useAdjustmentWidth)
{
DBG_OBJ_ENTER ("resize", 0, "correctExtremes", "%d (%d) / %d (%d)",
extremes->minWidth, extremes->minWidthIntrinsic,
@@ -951,7 +947,8 @@ void Widget::correctExtremes (Extremes *extremes)
DBG_OBJ_MSG ("resize", 1, "no parent, regarding viewport");
DBG_OBJ_MSG_START ();
- int limitMinWidth = getMinWidth (extremes, false, false);
+ int limitMinWidth =
+ useAdjustmentWidth ? getMinWidth (extremes, false) : 0;
int viewportWidth =
layout->viewportWidth - (layout->canvasHeightGreater ?
layout->vScrollbarThickness : 0);
@@ -977,12 +974,12 @@ void Widget::correctExtremes (Extremes *extremes)
} else if (parent) {
DBG_OBJ_MSG ("resize", 1, "delegated to parent");
DBG_OBJ_MSG_START ();
- parent->correctExtremesOfChild (this, extremes);
+ parent->correctExtremesOfChild (this, extremes, useAdjustmentWidth);
DBG_OBJ_MSG_END ();
} else /* if (quasiParent) */ {
DBG_OBJ_MSG ("resize", 1, "delegated to quasiParent");
DBG_OBJ_MSG_START ();
- quasiParent->correctExtremesOfChild (this, extremes);
+ quasiParent->correctExtremesOfChild (this, extremes, useAdjustmentWidth);
DBG_OBJ_MSG_END ();
}
@@ -1153,6 +1150,7 @@ void Widget::getExtremes (Extremes *extremes)
DBG_OBJ_SET_NUM ("extremes.maxWidth", extremes->maxWidth);
DBG_OBJ_SET_NUM ("extremes.maxWidthIntrinsic",
extremes->maxWidthIntrinsic);
+ DBG_OBJ_SET_NUM ("extremes.adjustmentWidth", extremes->adjustmentWidth);
} else
*extremes = this->extremes;
@@ -1835,7 +1833,7 @@ void Widget::correctReqWidthOfChild (Widget *child, Requisition *requisition)
assert (this == child->quasiParent || this == child->container);
- int limitMinWidth = child->getMinWidth (NULL, true, true);
+ int limitMinWidth = child->getMinWidth (NULL, true);
child->calcFinalWidth (child->getStyle(), -1, this, limitMinWidth, false,
&requisition->width);
@@ -1881,7 +1879,8 @@ void Widget::correctReqHeightOfChild (Widget *child, Requisition *requisition,
DBG_OBJ_LEAVE ();
}
-void Widget::correctExtremesOfChild (Widget *child, Extremes *extremes)
+void Widget::correctExtremesOfChild (Widget *child, Extremes *extremes,
+ bool useAdjustmentWidth)
{
// See comment in correctRequisitionOfChild.
@@ -1895,7 +1894,8 @@ void Widget::correctExtremesOfChild (Widget *child, Extremes *extremes)
(child->container ? child->container : child->parent);
if (effContainer == this) {
- int limitMinWidth = child->getMinWidth (extremes, false, false);
+ int limitMinWidth =
+ useAdjustmentWidth ? child->getMinWidth (extremes, false) : 0;
int width = child->calcWidth (child->getStyle()->width, -1, this,
limitMinWidth, false);
int minWidth = child->calcWidth (child->getStyle()->minWidth, -1, this,
@@ -1915,7 +1915,8 @@ void Widget::correctExtremesOfChild (Widget *child, Extremes *extremes)
} else {
DBG_OBJ_MSG ("resize", 1, "delegated to (effective) container");
DBG_OBJ_MSG_START ();
- effContainer->correctExtremesOfChild (child, extremes);
+ effContainer->correctExtremesOfChild (child, extremes,
+ useAdjustmentWidth);
DBG_OBJ_MSG_END ();
}
diff --git a/dw/widget.hh b/dw/widget.hh
index a14cd55b..b1b51201 100644
--- a/dw/widget.hh
+++ b/dw/widget.hh
@@ -319,7 +319,8 @@ protected:
void correctReqWidthOfChild (Widget *child, Requisition *requisition);
void correctReqHeightOfChild (Widget *child, Requisition *requisition,
void (*splitHeightFun) (int, int*, int*));
- virtual void correctExtremesOfChild (Widget *child, Extremes *extremes);
+ virtual void correctExtremesOfChild (Widget *child, Extremes *extremes,
+ bool useAdjustmentWidth);
virtual void containerSizeChangedForChildren ();
@@ -448,7 +449,7 @@ public:
virtual bool getAdjustMinWidth () { return Widget::adjustMinWidth; }
void correctRequisition (Requisition *requisition,
void (*splitHeightFun) (int, int*, int*));
- void correctExtremes (Extremes *extremes);
+ void correctExtremes (Extremes *extremes, bool useAdjustmentWidth);
int calcWidth (style::Length cssValue, int refWidth, Widget *refWidget,
int limitMinWidth, bool forceValue);
void calcFinalWidth (style::Style *style, int refWidth, Widget *refWidget,
@@ -459,7 +460,7 @@ public:
virtual int applyPerWidth (int containerWidth, style::Length perWidth);
virtual int applyPerHeight (int containerHeight, style::Length perHeight);
- int getMinWidth (Extremes *extremes, bool useCorrected, bool forceValue);
+ int getMinWidth (Extremes *extremes, bool forceValue);
virtual bool isBlockLevel ();
virtual bool isPossibleContainer ();
diff --git a/lout/misc.hh b/lout/misc.hh
index b362fc2f..a0beb1b6 100644
--- a/lout/misc.hh
+++ b/lout/misc.hh
@@ -231,6 +231,22 @@ public:
assert (this->num > 0);
this->array[this->num - 1] = t;
}
+
+ /**
+ * \brief Copies some elements into another vector of the same
+ * type.
+ *
+ * Cannot be used to copy elements within one vector. (For this,
+ * it would have to be extended to copy backwards in some cases.)
+ */
+ inline void copyTo(SimpleVector<T> *dest, int thisStart = 0,
+ int thisLast = -1, int destStart = 0) {
+ assert (dest != this);
+ if (thisLast == -1)
+ thisLast = this->size () - 1;
+ for (int i = thisStart; i <= thisLast; i++)
+ dest->set (i - thisStart + destStart, get (i));
+ }
};
/**
diff --git a/src/dillo.cc b/src/dillo.cc
index 0e49e7b5..1efd3b2c 100644
--- a/src/dillo.cc
+++ b/src/dillo.cc
@@ -508,6 +508,10 @@ int main(int argc, char **argv)
Fl_Window::default_xclass("dillo");
Fl::scheme(prefs.theme);
+
+ // Disable drag and drop as it crashes on MacOSX
+ Fl::dnd_text_ops(0);
+
setColors();
if (!prefs.show_ui_tooltip) {
diff --git a/src/html.cc b/src/html.cc
index be4d3526..8e4f6ded 100644
--- a/src/html.cc
+++ b/src/html.cc
@@ -357,16 +357,22 @@ bool a_Html_tag_set_valign_attr(DilloHtml *html, const char *tag, int tagsize)
/*
- * Create and add a new Textblock to the current Textblock
+ * Create and add a new Textblock to the current Textblock. Typically
+ * only one of addBreaks and addBreakOpt is true.
*/
-static void Html_add_textblock(DilloHtml *html, bool addBreaks, int breakSpace)
+static void Html_add_textblock(DilloHtml *html, bool addBreaks, int breakSpace,
+ bool addBreakOpt)
{
Textblock *textblock = new Textblock (prefs.limit_text_width);
if (addBreaks)
HT2TB(html)->addParbreak (breakSpace, html->wordStyle ());
+
HT2TB(html)->addWidget (textblock, html->style ()); /* Works also for floats
etc. */
+ if (addBreakOpt)
+ HT2TB(html)->addBreakOption (html->style (), false);
+
if (addBreaks)
HT2TB(html)->addParbreak (breakSpace, html->wordStyle ());
S_TOP(html)->textblock = html->dw = textblock;
@@ -2029,7 +2035,7 @@ static void Html_tag_content_frameset (DilloHtml *html,
{
HT2TB(html)->addParbreak (9, html->wordStyle ());
HT2TB(html)->addText("--FRAME--", html->wordStyle ());
- Html_add_textblock(html, true, 5);
+ Html_add_textblock(html, true, 5, false);
}
/*
@@ -2811,7 +2817,7 @@ static void Html_tag_close_a(DilloHtml *html)
static void Html_tag_open_blockquote(DilloHtml *html,
const char *tag, int tagsize)
{
- Html_add_textblock(html, true, 9);
+ Html_add_textblock(html, true, 9, false);
}
/*
@@ -3075,7 +3081,7 @@ static void Html_tag_open_dt(DilloHtml *html, const char *tag, int tagsize)
*/
static void Html_tag_open_dd(DilloHtml *html, const char *tag, int tagsize)
{
- Html_add_textblock(html, true, 9);
+ Html_add_textblock(html, true, 9, false);
}
/*
@@ -3868,12 +3874,13 @@ static void Html_check_html5_obsolete(DilloHtml *html, int ni)
static void Html_display_block(DilloHtml *html)
{
- Html_add_textblock(html, !Html_will_textblock_be_out_of_flow (html), 0);
+ Html_add_textblock(html, !Html_will_textblock_be_out_of_flow (html), 0,
+ false /* Perhaps true for widgets oof? */);
}
static void Html_display_inline_block(DilloHtml *html)
{
- Html_add_textblock(html, false, 0);
+ Html_add_textblock(html, false, 0, true);
}
static void Html_display_listitem(DilloHtml *html)
diff --git a/test/dw_simple_container.cc b/test/dw_simple_container.cc
index 94dec2d5..c1f22458 100644
--- a/test/dw_simple_container.cc
+++ b/test/dw_simple_container.cc
@@ -27,183 +27,186 @@ using namespace lout::misc;
namespace dw {
- int SimpleContainer::CLASS_ID = -1;
+int SimpleContainer::CLASS_ID = -1;
- // ----------------------------------------------------------------------
+// ----------------------------------------------------------------------
- SimpleContainer::SimpleContainerIterator::SimpleContainerIterator
- (SimpleContainer *simpleContainer, Content::Type mask, bool atEnd) :
- Iterator (simpleContainer, mask, atEnd)
- {
- content.type = atEnd ? Content::END : Content::START;
- }
+SimpleContainer::SimpleContainerIterator::SimpleContainerIterator
+(SimpleContainer *simpleContainer, Content::Type mask, bool atEnd) :
+ Iterator (simpleContainer, mask, atEnd)
+{
+ content.type = atEnd ? Content::END : Content::START;
+}
- lout::object::Object *SimpleContainer::SimpleContainerIterator::clone ()
- {
- SimpleContainerIterator *sci =
- new SimpleContainerIterator ((SimpleContainer*)getWidget(),
- getMask(), false);
- sci->content = content;
- return sci;
- }
+lout::object::Object *SimpleContainer::SimpleContainerIterator::clone ()
+{
+ SimpleContainerIterator *sci =
+ new SimpleContainerIterator ((SimpleContainer*)getWidget(),
+ getMask(), false);
+ sci->content = content;
+ return sci;
+}
- int SimpleContainer::SimpleContainerIterator::index ()
- {
- switch (content.type) {
- case Content::START:
- return 0;
- case Content::WIDGET_IN_FLOW:
- return 1;
- case Content::END:
- return 2;
- default:
- assertNotReached ();
- return 0;
- }
+int SimpleContainer::SimpleContainerIterator::index ()
+{
+ switch (content.type) {
+ case Content::START:
+ return 0;
+ case Content::WIDGET_IN_FLOW:
+ return 1;
+ case Content::END:
+ return 2;
+ default:
+ assertNotReached ();
+ return 0;
}
+}
- int SimpleContainer::SimpleContainerIterator::compareTo
- (lout::object::Comparable *other)
- {
- return index () - ((SimpleContainerIterator*)other)->index ();
- }
+int SimpleContainer::SimpleContainerIterator::compareTo
+(lout::object::Comparable *other)
+{
+ return index () - ((SimpleContainerIterator*)other)->index ();
+}
- bool SimpleContainer::SimpleContainerIterator::next ()
- {
- SimpleContainer *simpleContainer = (SimpleContainer*)getWidget();
+bool SimpleContainer::SimpleContainerIterator::next ()
+{
+ SimpleContainer *simpleContainer = (SimpleContainer*)getWidget();
- if (content.type == Content::END)
- return false;
+ if (content.type == Content::END)
+ return false;
- // simple containers only contain widgets:
- if ((getMask() & Content::WIDGET_IN_FLOW) == 0) {
- content.type = Content::END;
- return false;
- }
+ // simple containers only contain widgets:
+ if ((getMask() & Content::WIDGET_IN_FLOW) == 0) {
+ content.type = Content::END;
+ return false;
+ }
- if (content.type == Content::START) {
- if (simpleContainer->child != NULL) {
- content.type = Content::WIDGET_IN_FLOW;
- content.widget = simpleContainer->child;
- return true;
- } else {
- content.type = Content::END;
- return false;
- }
- } else /* if (content.type == Content::WIDGET) */ {
+ if (content.type == Content::START) {
+ if (simpleContainer->child != NULL) {
+ content.type = Content::WIDGET_IN_FLOW;
+ content.widget = simpleContainer->child;
+ return true;
+ } else {
content.type = Content::END;
return false;
}
+ } else /* if (content.type == Content::WIDGET) */ {
+ content.type = Content::END;
+ return false;
}
+}
- bool SimpleContainer::SimpleContainerIterator::prev ()
- {
- SimpleContainer *simpleContainer = (SimpleContainer*)getWidget();
+bool SimpleContainer::SimpleContainerIterator::prev ()
+{
+ SimpleContainer *simpleContainer = (SimpleContainer*)getWidget();
- if (content.type == Content::START)
- return false;
+ if (content.type == Content::START)
+ return false;
- // simple containers only contain widgets:
- if ((getMask() & Content::WIDGET_IN_FLOW) == 0) {
- content.type = Content::START;
- return false;
- }
+ // simple containers only contain widgets:
+ if ((getMask() & Content::WIDGET_IN_FLOW) == 0) {
+ content.type = Content::START;
+ return false;
+ }
- if (content.type == Content::END) {
- if (simpleContainer->child != NULL) {
- content.type = Content::WIDGET_IN_FLOW;
- content.widget = simpleContainer->child;
- return true;
- } else {
- content.type = Content::START;
- return false;
- }
- } else /* if (content.type == Content::WIDGET) */ {
+ if (content.type == Content::END) {
+ if (simpleContainer->child != NULL) {
+ content.type = Content::WIDGET_IN_FLOW;
+ content.widget = simpleContainer->child;
+ return true;
+ } else {
content.type = Content::START;
return false;
}
+ } else /* if (content.type == Content::WIDGET) */ {
+ content.type = Content::START;
+ return false;
}
+}
- void SimpleContainer::SimpleContainerIterator::highlight (int start,
- int end,
- HighlightLayer layer)
- {
- /** todo Needs this an implementation? */
- }
-
- void SimpleContainer::SimpleContainerIterator::unhighlight (int direction,
- HighlightLayer
- layer)
- {
- /** todo Needs this an implementation? */
- }
-
- void SimpleContainer::SimpleContainerIterator::getAllocation (int start,
- int end,
- Allocation
- *allocation)
- {
- /** \bug Not implemented. */
- }
-
- // ----------------------------------------------------------------------
-
- SimpleContainer::SimpleContainer ()
- {
- registerName ("dw::SimpleContainer", &CLASS_ID);
- child = NULL;
- }
+void SimpleContainer::SimpleContainerIterator::highlight (int start,
+ int end,
+ HighlightLayer layer)
+{
+ /** todo Needs this an implementation? */
+}
- SimpleContainer::~SimpleContainer ()
- {
- if (child)
- delete child;
- }
+void SimpleContainer::SimpleContainerIterator::unhighlight (int direction,
+ HighlightLayer
+ layer)
+{
+ /** todo Needs this an implementation? */
+}
- void SimpleContainer::sizeRequestImpl (Requisition *requisition)
- {
- Requisition childReq;
- if (child)
- child->sizeRequest (&childReq);
- else
- childReq.width = childReq.ascent = childReq.descent = 0;
+void SimpleContainer::SimpleContainerIterator::getAllocation (int start,
+ int end,
+ Allocation
+ *allocation)
+{
+ /** \bug Not implemented. */
+}
- requisition->width = childReq.width + boxDiffWidth ();
- requisition->ascent = childReq.ascent + boxOffsetY ();
- requisition->descent = childReq.descent + boxRestHeight ();
+// ----------------------------------------------------------------------
- correctRequisition (requisition, splitHeightPreserveAscent);
- }
+SimpleContainer::SimpleContainer ()
+{
+ registerName ("dw::SimpleContainer", &CLASS_ID);
+ child = NULL;
+}
+SimpleContainer::~SimpleContainer ()
+{
+ if (child)
+ delete child;
+}
- void SimpleContainer::getExtremesImpl (Extremes *extremes)
- {
- Extremes childExtr;
- if (child)
- child->getExtremes (&childExtr);
- else
- childExtr.minWidth = childExtr.maxWidth = 0;
+void SimpleContainer::sizeRequestImpl (Requisition *requisition)
+{
+ Requisition childReq;
+ if (child)
+ child->sizeRequest (&childReq);
+ else
+ childReq.width = childReq.ascent = childReq.descent = 0;
- extremes->minWidth = childExtr.minWidth + boxDiffWidth ();
- extremes->maxWidth = childExtr.maxWidth + boxDiffWidth ();
+ requisition->width = childReq.width + boxDiffWidth ();
+ requisition->ascent = childReq.ascent + boxOffsetY ();
+ requisition->descent = childReq.descent + boxRestHeight ();
- correctExtremes (extremes);
- }
+ correctRequisition (requisition, splitHeightPreserveAscent);
+}
- void SimpleContainer::sizeAllocateImpl (Allocation *allocation)
- {
- Allocation childAlloc;
+void SimpleContainer::getExtremesImpl (Extremes *extremes)
+{
+ Extremes childExtr;
+ if (child)
+ child->getExtremes (&childExtr);
+ else
+ childExtr.minWidth = childExtr.minWidthIntrinsic = childExtr.maxWidth =
+ childExtr.maxWidthIntrinsic = extremes->adjustmentWidth = 0;
+
+ extremes->minWidth = childExtr.minWidth + boxDiffWidth ();
+ extremes->minWidthIntrinsic = childExtr.minWidthIntrinsic + boxDiffWidth ();
+ extremes->maxWidth = childExtr.maxWidth + boxDiffWidth ();
+ extremes->maxWidthIntrinsic = childExtr.maxWidthIntrinsic + boxDiffWidth ();
+ extremes->adjustmentWidth = childExtr.adjustmentWidth + boxDiffWidth ();
+
+ correctExtremes (extremes, true);
+}
- if (child) {
- childAlloc.x = allocation->x + boxOffsetX ();
- childAlloc.y = allocation->y + boxOffsetY ();
- childAlloc.width = allocation->width - boxDiffWidth ();
- childAlloc.ascent = allocation->ascent - boxOffsetY ();
- childAlloc.descent = allocation->descent - boxRestHeight ();
- child->sizeAllocate (&childAlloc);
- }
+void SimpleContainer::sizeAllocateImpl (Allocation *allocation)
+{
+ Allocation childAlloc;
+
+ if (child) {
+ childAlloc.x = allocation->x + boxOffsetX ();
+ childAlloc.y = allocation->y + boxOffsetY ();
+ childAlloc.width = allocation->width - boxDiffWidth ();
+ childAlloc.ascent = allocation->ascent - boxOffsetY ();
+ childAlloc.descent = allocation->descent - boxRestHeight ();
+ child->sizeAllocate (&childAlloc);
}
+}
void SimpleContainer::draw (View *view, Rectangle *area,
StackingIteratorStack *iteratorStack,