aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dw/outofflowmgr.cc182
-rw-r--r--dw/outofflowmgr.hh38
-rw-r--r--dw/textblock.cc24
-rw-r--r--dw/textblock.hh5
-rw-r--r--dw/widget.hh4
-rw-r--r--src/cssparser.cc2
6 files changed, 163 insertions, 92 deletions
diff --git a/dw/outofflowmgr.cc b/dw/outofflowmgr.cc
index caa7fee5..b6bd3b07 100644
--- a/dw/outofflowmgr.cc
+++ b/dw/outofflowmgr.cc
@@ -472,16 +472,6 @@ void OutOfFlowMgr::TBInfo::updateAllocation ()
DBG_OBJ_LEAVE_O (getWidget ());
}
-OutOfFlowMgr::AbsolutelyPositioned::AbsolutelyPositioned (OutOfFlowMgr *oofm,
- Widget *widget,
- Textblock
- *generatingBlock,
- int externalIndex)
-{
- this->widget = widget;
- dirty = true;
-}
-
OutOfFlowMgr::OutOfFlowMgr (Textblock *containingBlock)
{
DBG_OBJ_CREATE ("dw::OutOfFlowMgr");
@@ -509,7 +499,9 @@ OutOfFlowMgr::OutOfFlowMgr (Textblock *containingBlock)
leftFloatsMark = rightFloatsMark = 0;
lastLeftTBIndex = lastRightTBIndex = 0;
- absolutelyPositioned = new Vector<AbsolutelyPositioned> (1, true);
+ absolutelyPositioned = new Vector<Widget> (1, false);
+
+ DBG_OBJ_SET_NUM ("absolutelyPositioned.size", absolutelyPositioned->size());
containingBlockWasAllocated = containingBlock->wasAllocated ();
containingBlockAllocation = *(containingBlock->getAllocation());
@@ -595,6 +587,8 @@ void OutOfFlowMgr::sizeAllocateEnd (Textblock *caller)
sizeAllocateFloats (LEFT, leftFloatsCB->size () - 1);
sizeAllocateFloats (RIGHT, rightFloatsCB->size () - 1);
+ sizeAllocateAbsolutelyPositioned ();
+
// Check changes of both textblocks and floats allocation. (All
// is checked by hasRelationChanged (...).)
for (lout::container::typed::Iterator<TypedPointer <Textblock> > it =
@@ -661,7 +655,7 @@ void OutOfFlowMgr::containerSizeChangedForChildren ()
for (int i = 0; i < rightFloatsAll->size (); i++)
rightFloatsAll->get(i)->getWidget()->containerSizeChanged ();
for (int i = 0; i < absolutelyPositioned->size(); i++)
- absolutelyPositioned->get(i)->widget->containerSizeChanged ();
+ absolutelyPositioned->get(i)->containerSizeChanged ();
DBG_OBJ_LEAVE ();
}
@@ -1260,9 +1254,14 @@ int OutOfFlowMgr::calcFloatX (Float *vloat, Side side, int gbX, int gbWidth,
void OutOfFlowMgr::draw (View *view, Rectangle *area)
{
+ DBG_OBJ_ENTER ("draw", 0, "draw", "%d, %d, %d * %d",
+ area->x, area->y, area->width, area->height);
+
drawFloats (leftFloatsCB, view, area);
drawFloats (rightFloatsCB, view, area);
drawAbsolutelyPositioned (view, area);
+
+ DBG_OBJ_LEAVE ();
}
void OutOfFlowMgr::drawFloats (SortedFloatsVector *list, View *view,
@@ -1282,10 +1281,10 @@ void OutOfFlowMgr::drawFloats (SortedFloatsVector *list, View *view,
void OutOfFlowMgr::drawAbsolutelyPositioned (View *view, Rectangle *area)
{
for (int i = 0; i < absolutelyPositioned->size(); i++) {
- AbsolutelyPositioned *abspos = absolutelyPositioned->get(i);
+ Widget *child = absolutelyPositioned->get(i);
Rectangle childArea;
- if (abspos->widget->intersects (area, &childArea))
- abspos->widget->draw (view, &childArea);
+ if (child->intersects (area, &childArea))
+ child->draw (view, &childArea);
}
}
@@ -1309,8 +1308,7 @@ bool OutOfFlowMgr::isWidgetOutOfFlow (Widget *widget)
bool OutOfFlowMgr::isWidgetHandledByOOFM (Widget *widget)
{
// May be extended for fixed (and relative?) positions.
- return isWidgetFloat (widget);
- // TODO temporary disabled: || isWidgetAbsolutelyPositioned (widget);
+ return isWidgetFloat (widget) || isWidgetAbsolutelyPositioned (widget);
}
void OutOfFlowMgr::addWidgetInFlow (Textblock *textblock,
@@ -1416,12 +1414,13 @@ void OutOfFlowMgr::addWidgetOOF (Widget *widget, Textblock *generatingBlock,
floatsByWidget->put (new TypedPointer<Widget> (widget), vloat);
} else if (isWidgetAbsolutelyPositioned (widget)) {
- AbsolutelyPositioned *abspos =
- new AbsolutelyPositioned (this, widget, generatingBlock,
- externalIndex);
- absolutelyPositioned->put (abspos);
+ absolutelyPositioned->put (widget);
widget->parentRef =
createRefAbsolutelyPositioned (absolutelyPositioned->size() - 1);
+ DBG_OBJ_SET_NUM ("absolutelyPositioned.size",
+ absolutelyPositioned->size());
+ DBG_OBJ_ARRSET_NUM ("absolutelyPositioned",
+ absolutelyPositioned->size() - 1, widget);
} else
// May be extended.
assertNotReached();
@@ -1492,8 +1491,7 @@ void OutOfFlowMgr::markSizeChange (int ref)
// differentiates many special cases), but the size is not known yet,
vloat->generatingBlock->borderChanged (vloat->yReal, vloat->getWidget ());
} else if (isRefAbsolutelyPositioned (ref)) {
- int i = getAbsolutelyPositionedIndexFromRef (ref);
- absolutelyPositioned->get(i)->dirty = true;
+ // Nothing to do.
} else
assertNotReached();
@@ -1537,10 +1535,9 @@ Widget *OutOfFlowMgr::getAbsolutelyPositionedWidgetAtPoint (int x, int y,
int level)
{
for (int i = 0; i < absolutelyPositioned->size(); i++) {
- AbsolutelyPositioned *abspos = absolutelyPositioned->get(i);
- if (abspos->widget->wasAllocated ()) {
- Widget *childAtPoint =
- abspos->widget->getWidgetAtPoint (x, y, level + 1);
+ Widget *child = absolutelyPositioned->get(i);
+ if (child->wasAllocated ()) {
+ Widget *childAtPoint = child->getWidgetAtPoint (x, y, level + 1);
if (childAtPoint)
return childAtPoint;
}
@@ -2300,6 +2297,48 @@ void OutOfFlowMgr::ensureFloatSize (Float *vloat)
DBG_OBJ_LEAVE ();
}
+int OutOfFlowMgr::getAvailWidthOfChild (Widget *child, bool forceValue)
+{
+ DBG_OBJ_ENTER ("resize.oofm", 0,
+ "OutOfFlowMgr/getAvailWidthOfChild", "%p, %s",
+ child, forceValue ? "true" : "false");
+
+ int width;
+
+ if (child->getStyle()->width == style::LENGTH_AUTO &&
+ child->getStyle()->minWidth == style::LENGTH_AUTO &&
+ child->getStyle()->maxWidth == style::LENGTH_AUTO) {
+ // TODO This should (perhaps?) only used when 'width' is undefined.
+ // TODO Is "boxDiffWidth()" correct here?
+ DBG_OBJ_MSG ("resize.oofm", 1, "no specification");
+ if (forceValue) {
+ int availWidth = containingBlock->getAvailWidth (true);
+ width = max (availWidth - containingBlock->boxDiffWidth ()
+ - getAbsPosLeft (child, availWidth)
+ - getAbsPosRight (child, availWidth),
+ 0);
+ } else
+ width = -1;
+ } else
+ // TODO Percentage widths must refer to padding area.
+ child->calcFinalWidth (child->getStyle(), -1, containingBlock, 0,
+ forceValue, &width);
+
+ if (width != -1)
+ width = max (width, child->getMinWidth (NULL, forceValue));
+
+ DBG_OBJ_MSGF ("resize.oofm", 1, "=> %d", width);
+ DBG_OBJ_LEAVE ();
+
+ return width;
+}
+
+int OutOfFlowMgr::getAvailHeightOfChild (Widget *child, bool forceValue)
+{
+ // TODO
+ return -1;
+}
+
void OutOfFlowMgr::getAbsolutelyPositionedSize (Requisition *cbReq, int *width,
int *height)
{
@@ -2307,6 +2346,17 @@ void OutOfFlowMgr::getAbsolutelyPositionedSize (Requisition *cbReq, int *width,
*width = *height = 0;
}
+int OutOfFlowMgr::getAbsPosBorder (style::Length cssValue, int refLength)
+{
+ if (style::isAbsLength (cssValue))
+ return style::absLengthVal (cssValue);
+ else if (style::isPerLength (cssValue))
+ return style::multiplyWithPerLength (refLength, cssValue);
+ else
+ // standard value for 'left', 'right', 'top', 'bottom':
+ return 0;
+}
+
void OutOfFlowMgr::getAbsolutelyPositionedExtremes (Extremes *cbExtr,
int *minWidth,
int *maxWidth)
@@ -2315,48 +2365,56 @@ void OutOfFlowMgr::getAbsolutelyPositionedExtremes (Extremes *cbExtr,
*minWidth = *maxWidth = 0;
}
-void OutOfFlowMgr::ensureAbsolutelyPositionedSizeAndPosition
- (AbsolutelyPositioned *abspos)
-{
- // TODO
- assertNotReached ();
-}
-
-int OutOfFlowMgr::calcValueForAbsolutelyPositioned
- (AbsolutelyPositioned *abspos, Length styleLen, int refLen)
-{
- assert (styleLen != LENGTH_AUTO);
- if (isAbsLength (styleLen))
- return absLengthVal (styleLen);
- else if (isPerLength (styleLen))
- return multiplyWithPerLength (refLen, styleLen);
- else {
- assertNotReached ();
- return 0; // compiler happiness
- }
-}
-
void OutOfFlowMgr::sizeAllocateAbsolutelyPositioned ()
{
+ DBG_OBJ_ENTER0 ("resize.oofm", 0, "sizeAllocateAbsolutelyPositioned");
+
for (int i = 0; i < absolutelyPositioned->size(); i++) {
Allocation *cbAllocation = getAllocation (containingBlock);
- AbsolutelyPositioned *abspos = absolutelyPositioned->get (i);
- ensureAbsolutelyPositionedSizeAndPosition (abspos);
+ Widget *child = absolutelyPositioned->get (i);
+
+ Requisition childRequisition;
+ child->sizeRequest (&childRequisition);
Allocation childAllocation;
- childAllocation.x = cbAllocation->x + abspos->xCB;
- childAllocation.y = cbAllocation->y + abspos->yCB;
- childAllocation.width = abspos->width;
- childAllocation.ascent = abspos->height;
- childAllocation.descent = 0; // TODO
-
- abspos->widget->sizeAllocate (&childAllocation);
-
- printf ("[%p] allocating child %p at: (%d, %d), %d x (%d + %d)\n",
- containingBlock, abspos->widget, childAllocation.x,
- childAllocation.y, childAllocation.width, childAllocation.ascent,
- childAllocation.descent);
+
+ childAllocation.x =
+ cbAllocation->x + getAbsPosLeft (child, cbAllocation->width);
+ childAllocation.y =
+ cbAllocation->y + getAbsPosTop (child, cbAllocation->ascent
+ + cbAllocation->descent);
+ // TODO (i) Consider {min|max}-{width|heigt}. (ii) Clarify where
+ // sizes refer to. (iii) Height is always apportioned to descent
+ // (ascent is preserved), which makes sense when the children
+ // are textblocks. (iv) Consider minimal length?
+
+ if (style::isAbsLength (child->getStyle()->width))
+ childAllocation.width = style::absLengthVal (child->getStyle()->width);
+ else if (style::isPerLength (child->getStyle()->width))
+ childAllocation.width =
+ style::multiplyWithPerLength (cbAllocation->width,
+ child->getStyle()->width);
+ else
+ childAllocation.width = childRequisition.width;
+
+ childAllocation.ascent = childRequisition.ascent;
+ childAllocation.descent = childRequisition.descent;
+ if (style::isAbsLength (child->getStyle()->height)) {
+ int height = style::absLengthVal (child->getStyle()->height);
+ splitHeightPreserveAscent (height, &childAllocation.ascent,
+ &childAllocation.descent);
+ } else if (style::isPerLength (child->getStyle()->height)) {
+ int height = style::multiplyWithPerLength (cbAllocation->ascent
+ + cbAllocation->descent,
+ child->getStyle()->height);
+ splitHeightPreserveAscent (height, &childAllocation.ascent,
+ &childAllocation.descent);
+ }
+
+ child->sizeAllocate (&childAllocation);
}
+
+ DBG_OBJ_LEAVE ();
}
} // namespace dw
diff --git a/dw/outofflowmgr.hh b/dw/outofflowmgr.hh
index b7283815..c5579368 100644
--- a/dw/outofflowmgr.hh
+++ b/dw/outofflowmgr.hh
@@ -214,18 +214,6 @@ private:
inline Textblock *getTextblock () { return (Textblock*)getWidget (); }
};
- class AbsolutelyPositioned: public lout::object::Object
- {
- public:
- core::Widget *widget;
- int xCB, yCB; // relative to the containing block
- int width, height;
- bool dirty;
-
- AbsolutelyPositioned (OutOfFlowMgr *oofm, core::Widget *widget,
- Textblock *generatingBlock, int externalIndex);
- };
-
// These two lists store all floats, in the order in which they are
// defined. Only used for iterators.
lout::container::typed::Vector<Float> *leftFloatsAll, *rightFloatsAll;
@@ -245,7 +233,7 @@ private:
lout::container::typed::HashTable<lout::object::TypedPointer <Textblock>,
TBInfo> *tbInfosByTextblock;
- lout::container::typed::Vector<AbsolutelyPositioned> *absolutelyPositioned;
+ lout::container::typed::Vector<core::Widget> *absolutelyPositioned;
int lastLeftTBIndex, lastRightTBIndex, leftFloatsMark, rightFloatsMark;
@@ -331,13 +319,19 @@ private:
int *height);
void getAbsolutelyPositionedExtremes (core::Extremes *cbExtr, int *minWidth,
int *maxWidth);
- void ensureAbsolutelyPositionedSizeAndPosition (AbsolutelyPositioned
- *abspos);
- int calcValueForAbsolutelyPositioned (AbsolutelyPositioned *abspos,
- core::style::Length styleLen,
- int refLen);
void sizeAllocateAbsolutelyPositioned ();
+ inline int getAbsPosLeft (core::Widget *child, int availWidth)
+ { return getAbsPosBorder (child->getStyle()->left, availWidth); }
+ inline int getAbsPosRight (core::Widget *child, int availWidth)
+ { return getAbsPosBorder (child->getStyle()->right, availWidth); }
+ inline int getAbsPosTop (core::Widget *child, int availHeight)
+ { return getAbsPosBorder (child->getStyle()->top, availHeight); }
+ inline int getAbsPosBottom (core::Widget *child, int availHeight)
+ { return getAbsPosBorder (child->getStyle()->bottom, availHeight); }
+
+ int getAbsPosBorder (core::style::Length cssValue, int refLength);
+
static inline bool isWidgetFloat (core::Widget *widget)
{ return widget->getStyle()->vloat != core::style::FLOAT_NONE; }
static inline bool isWidgetAbsolutelyPositioned (core::Widget *widget)
@@ -438,6 +432,12 @@ public:
int getClearPosition (Textblock *tb);
+ inline bool dealingWithSizeOfChild (core::Widget *child)
+ { return isWidgetAbsolutelyPositioned (child); }
+
+ int getAvailWidthOfChild (core::Widget *child, bool forceValue);
+ int getAvailHeightOfChild (core::Widget *child, bool forceValue);
+
inline static bool isRefOutOfFlow (int ref)
{ return ref != -1 && (ref & 1) != 0; }
inline static int createRefNormalFlow (int lineNo) { return lineNo << 1; }
@@ -456,7 +456,7 @@ public:
return rightFloatsAll->get(i - leftFloatsAll->size())->getWidget ();
else
return absolutelyPositioned->get(i - (leftFloatsAll->size() +
- rightFloatsAll->size()))->widget;
+ rightFloatsAll->size()));
}
inline bool affectsLeftBorder (core::Widget *widget) {
diff --git a/dw/textblock.cc b/dw/textblock.cc
index d2fb7857..0bf4b08a 100644
--- a/dw/textblock.cc
+++ b/dw/textblock.cc
@@ -708,12 +708,16 @@ int Textblock::getAvailWidthOfChild (Widget *child, bool forceValue)
int width = Widget::getAvailWidthOfChild (child, forceValue);
- if (forceValue && this == child->getContainer () &&
- !mustBeWidenedToAvailWidth ()) {
- core::Extremes extremes;
- getExtremes (&extremes);
- if (width > extremes.maxWidth)
- width = extremes.maxWidth;
+ if (outOfFlowMgr && outOfFlowMgr->dealingWithSizeOfChild (child))
+ width = outOfFlowMgr->getAvailWidthOfChild (child, forceValue);
+ else {
+ if (forceValue && this == child->getContainer () &&
+ !mustBeWidenedToAvailWidth ()) {
+ core::Extremes extremes;
+ getExtremes (&extremes);
+ if (width > extremes.maxWidth)
+ width = extremes.maxWidth;
+ }
}
DBG_OBJ_MSGF ("resize", 1, "=> %d", width);
@@ -721,7 +725,13 @@ int Textblock::getAvailWidthOfChild (Widget *child, bool forceValue)
return width;
}
-
+int Textblock::getAvailHeightOfChild (core::Widget *child, bool forceValue)
+{
+ if (outOfFlowMgr && outOfFlowMgr->dealingWithSizeOfChild (child))
+ return outOfFlowMgr->getAvailHeightOfChild (child, forceValue);
+ else
+ return Widget::getAvailHeightOfChild (child, forceValue);
+}
void Textblock::containerSizeChangedForChildren ()
{
diff --git a/dw/textblock.hh b/dw/textblock.hh
index 69fcd3da..5e8986b3 100644
--- a/dw/textblock.hh
+++ b/dw/textblock.hh
@@ -749,7 +749,10 @@ protected:
void sizeRequestImpl (core::Requisition *requisition);
void getExtremesImpl (core::Extremes *extremes);
void sizeAllocateImpl (core::Allocation *allocation);
- int getAvailWidthOfChild (Widget *child, bool forceValue);
+
+ int getAvailWidthOfChild (core::Widget *child, bool forceValue);
+ int getAvailHeightOfChild (core::Widget *child, bool forceValue);
+
void containerSizeChangedForChildren ();
bool affectsSizeChangeContainerChild (Widget *child);
bool usesAvailWidth ();
diff --git a/dw/widget.hh b/dw/widget.hh
index 0f3e2d37..a624eeb2 100644
--- a/dw/widget.hh
+++ b/dw/widget.hh
@@ -292,8 +292,6 @@ protected:
*/
virtual void markExtremesChange (int ref);
- int getMinWidth (Extremes *extremes, bool forceValue);
-
virtual int getAvailWidthOfChild (Widget *child, bool forceValue);
virtual int getAvailHeightOfChild (Widget *child, bool forceValue);
virtual void correctRequisitionOfChild (Widget *child,
@@ -441,6 +439,8 @@ public:
virtual int applyPerWidth (int containerWidth, style::Length perWidth);
virtual int applyPerHeight (int containerHeight, style::Length perHeight);
+ int getMinWidth (Extremes *extremes, bool forceValue);
+
virtual bool isBlockLevel ();
virtual bool isPossibleContainer ();
diff --git a/src/cssparser.cc b/src/cssparser.cc
index a8de027a..c02d817e 100644
--- a/src/cssparser.cc
+++ b/src/cssparser.cc
@@ -218,7 +218,7 @@ const CssPropertyInfo Css_property_info[CSS_PROPERTY_LAST] = {
{"font-weight", {CSS_TYPE_ENUM, CSS_TYPE_FONT_WEIGHT, CSS_TYPE_UNUSED},
Css_font_weight_enum_vals},
{"height", {CSS_TYPE_LENGTH_PERCENTAGE, CSS_TYPE_AUTO, CSS_TYPE_UNUSED}, NULL},
- {"left", {CSS_TYPE_UNUSED}, NULL},
+ {"left", {CSS_TYPE_LENGTH_PERCENTAGE, CSS_TYPE_UNUSED}, NULL},
{"letter-spacing", {CSS_TYPE_ENUM, CSS_TYPE_SIGNED_LENGTH, CSS_TYPE_UNUSED},
Css_letter_spacing_enum_vals},
{"line-height",