diff options
-rw-r--r-- | dw/style.cc | 14 | ||||
-rw-r--r-- | dw/style.hh | 1 | ||||
-rw-r--r-- | dw/widget.cc | 190 | ||||
-rw-r--r-- | dw/widget.hh | 2 | ||||
-rw-r--r-- | src/cssparser.cc | 12 | ||||
-rw-r--r-- | src/styleengine.cc | 12 |
6 files changed, 157 insertions, 74 deletions
diff --git a/dw/style.cc b/dw/style.cc index 5edb7047..d548d209 100644 --- a/dw/style.cc +++ b/dw/style.cc @@ -73,6 +73,7 @@ void StyleAttrs::initValues () backgroundPositionX = createPerLength (0); backgroundPositionY = createPerLength (0); width = height = lineHeight = LENGTH_AUTO; + minWidth = maxWidth = minHeight = maxHeight = LENGTH_AUTO; vloat = FLOAT_NONE; clear = CLEAR_NONE; position = POSITION_STATIC; @@ -116,6 +117,7 @@ void StyleAttrs::resetValues () backgroundPositionY = createPerLength (0); width = LENGTH_AUTO; height = LENGTH_AUTO; + minWidth = maxWidth = minHeight = maxHeight = LENGTH_AUTO; margin.setVal (0); borderWidth.setVal (0); @@ -175,6 +177,10 @@ bool StyleAttrs::equals (object::Object *other) { wordSpacing == otherAttrs->wordSpacing && width == otherAttrs->width && height == otherAttrs->height && + minWidth == otherAttrs->minWidth && + maxWidth == otherAttrs->maxWidth && + minHeight == otherAttrs->minHeight && + maxHeight == otherAttrs->maxHeight && lineHeight == otherAttrs->lineHeight && textIndent == otherAttrs->textIndent && margin.equals (&otherAttrs->margin) && @@ -227,6 +233,10 @@ int StyleAttrs::hashValue () { wordSpacing + width + height + + minWidth + + maxWidth + + minHeight + + maxHeight + lineHeight + textIndent + margin.hashValue () + @@ -351,6 +361,10 @@ void Style::copyAttrs (StyleAttrs *attrs) height = attrs->height; lineHeight = attrs->lineHeight; textIndent = attrs->textIndent; + minWidth = attrs->minWidth; + maxWidth = attrs->maxWidth; + minHeight = attrs->minHeight; + maxHeight = attrs->maxHeight; margin = attrs->margin; borderWidth = attrs->borderWidth; padding = attrs->padding; diff --git a/dw/style.hh b/dw/style.hh index 578e65c0..eee06f20 100644 --- a/dw/style.hh +++ b/dw/style.hh @@ -532,6 +532,7 @@ public: int hBorderSpacing, vBorderSpacing, wordSpacing; Length width, height, lineHeight, textIndent; + Length minWidth, maxWidth, minHeight, maxHeight; Box margin, borderWidth, padding; BorderCollapse borderCollapse; diff --git a/dw/widget.cc b/dw/widget.cc index a407eab8..374c1c2a 100644 --- a/dw/widget.cc +++ b/dw/widget.cc @@ -671,25 +671,27 @@ void Widget::correctRequisition (Requisition *requisition, DBG_OBJ_MSG ("resize", 1, "no parent, regarding viewport"); DBG_OBJ_MSG_START (); - if (style::isAbsLength (getStyle()->width)) { - DBG_OBJ_MSGF ("resize", 1, "absolute width: %dpx", - style::absLengthVal (getStyle()->width)); - requisition->width = - misc::max (style::absLengthVal (getStyle()->width) - + boxDiffWidth (), - getMinWidth (NULL, true)); - } else if (style::isPerLength (getStyle()->width)) { - DBG_OBJ_MSGF ("resize", 1, "percentage width: %g%%", - 100 * style::perLengthVal_useThisOnlyForDebugging - (getStyle()->width)); - int viewportWidth = - layout->viewportWidth - (layout->canvasHeightGreater ? - layout->vScrollbarThickness : 0); - requisition->width = - misc::max (applyPerWidth (viewportWidth, getStyle()->width), - getMinWidth (NULL, true)); - } - + int limit = getMinWidth (NULL, true); + int viewportWidth = + layout->viewportWidth - (layout->canvasHeightGreater ? + layout->vScrollbarThickness : 0); + + int width = calcWidth (getStyle()->width, viewportWidth, NULL, limit); + int minWidth = + calcWidth (getStyle()->minWidth, viewportWidth, NULL, limit); + int maxWidth = + calcWidth (getStyle()->maxWidth, viewportWidth, NULL, limit); + + DBG_OBJ_MSGF ("resize", 1, "width = %d, minWidth = %d, maxWidth = %d", + width, minWidth, maxWidth); + + if (width != -1) + requisition->width = width; + if (minWidth != -1 && requisition->width < minWidth) + requisition->width = minWidth; + if (maxWidth != -1 && requisition->width < maxWidth) + requisition->width = maxWidth; + // TODO Perhaps split first, then add box ascent and descent. if (style::isAbsLength (getStyle()->height)) { DBG_OBJ_MSGF ("resize", 1, "absolute height: %dpx", @@ -742,19 +744,26 @@ void Widget::correctExtremes (Extremes *extremes) DBG_OBJ_MSG ("resize", 1, "no parent, regarding viewport"); DBG_OBJ_MSG_START (); - if (style::isAbsLength (getStyle()->width)) - extremes->minWidth = extremes->maxWidth = - misc::max (style::absLengthVal (getStyle()->width) - + boxDiffWidth (), - getMinWidth (extremes, false)); - else if (style::isPerLength (getStyle()->width)) { - int viewportWidth = - layout->viewportWidth - (layout->canvasHeightGreater ? - layout->vScrollbarThickness : 0); - extremes->minWidth = extremes->maxWidth = - misc::max (applyPerWidth (viewportWidth, getStyle()->width), - getMinWidth (extremes, false)); - } + int limit = getMinWidth (extremes, false); + int viewportWidth = + layout->viewportWidth - (layout->canvasHeightGreater ? + layout->vScrollbarThickness : 0); + + int width = calcWidth (getStyle()->width, viewportWidth, NULL, limit); + int minWidth = + calcWidth (getStyle()->minWidth, viewportWidth, NULL, limit); + int maxWidth = + calcWidth (getStyle()->maxWidth, viewportWidth, NULL, limit); + + DBG_OBJ_MSGF ("resize", 1, "width = %d, minWidth = %d, maxWidth = %d", + width, minWidth, maxWidth); + + if (width != -1) + extremes->minWidth = extremes->maxWidth = width; + if (minWidth != -1) + extremes->minWidth = minWidth; + if (maxWidth != -1) + extremes->maxWidth = maxWidth; DBG_OBJ_MSG_END (); } else if (parent) { @@ -774,6 +783,46 @@ void Widget::correctExtremes (Extremes *extremes) DBG_OBJ_LEAVE (); } +int Widget::calcWidth (style::Length cssValue, int refWidth, Widget *refWidget, + int minWidth) +{ + DBG_OBJ_ENTER ("resize", 0, "calcWidth", "0x%x, %d, %p, %d", + cssValue, refWidth, refWidget, minWidth); + + assert (refWidth != -1 || refWidget != NULL); + + int width = 0; + + if (style::isAbsLength (cssValue)) { + DBG_OBJ_MSGF ("resize", 1, "absolute width: %dpx", + style::absLengthVal (cssValue)); + width = + misc::max (style::absLengthVal (cssValue) + boxDiffWidth (), minWidth); + } else if (style::isPerLength (cssValue)) { + DBG_OBJ_MSGF ("resize", 1, "percentage width: %g%%", + 100 * + style::perLengthVal_useThisOnlyForDebugging (cssValue)); + if (refWidth != -1) + width = misc::max (applyPerWidth (refWidth, cssValue), minWidth); + else { + int availWidth = refWidget->getAvailWidth (false); + if (availWidth != -1) { + int containerWidth = availWidth - refWidget->boxDiffWidth (); + width = + misc::max (applyPerWidth (containerWidth, cssValue), minWidth); + } else + width = -1; + } + } else { + DBG_OBJ_MSG ("resize", 1, "not specified"); + width = -1; + } + + DBG_OBJ_MSGF ("resize", 1, "=> %d", width); + DBG_OBJ_LEAVE (); + return width; +} + /** * \brief Wrapper for Widget::getExtremesImpl(). */ @@ -1011,6 +1060,13 @@ void Widget::setStyle (style::Style *style) style->display == style::DISPLAY_TABLE_ROW ? "table-row" : style->display == style::DISPLAY_TABLE_CELL ? "table-cell" : "???"); + + DBG_OBJ_SET_NUM ("style.width (raw)", style->width); + DBG_OBJ_SET_NUM ("style.min-width (raw)", style->minWidth); + DBG_OBJ_SET_NUM ("style.max-width (raw)", style->maxWidth); + DBG_OBJ_SET_NUM ("style.height (raw)", style->height); + DBG_OBJ_SET_NUM ("style.min-height (raw)", style->minHeight); + DBG_OBJ_SET_NUM ("style.max-height (raw)", style->maxHeight); } /** @@ -1470,21 +1526,22 @@ void Widget::correctReqWidthOfChild (Widget *child, Requisition *requisition) assert (this == child->quasiParent || this == child->container); - if (style::isAbsLength (child->getStyle()->width)) - requisition->width = - misc::max (style::absLengthVal (child->getStyle()->width) - + child->boxDiffWidth (), - child->getMinWidth (NULL, true)); - else if (style::isPerLength (child->getStyle()->width)) { - int availWidth = getAvailWidth (false); - if (availWidth != -1) { - int containerWidth = availWidth - boxDiffWidth (); - requisition->width = - misc::max (child->applyPerWidth (containerWidth, - child->getStyle()->width), - child->getMinWidth (NULL, true)); - } - } + int limit = child->getMinWidth (NULL, true); + int width = child->calcWidth (child->getStyle()->width, -1, this, limit); + int minWidth = + child->calcWidth (child->getStyle()->minWidth, -1, this, limit); + int maxWidth = + child->calcWidth (child->getStyle()->maxWidth, -1, this, limit); + + DBG_OBJ_MSGF ("resize", 1, "width = %d, minWidth = %d, maxWidth = %d", + width, minWidth, maxWidth); + + if (width != -1) + requisition->width = width; + if (minWidth != -1 && requisition->width < minWidth) + requisition->width = minWidth; + if (maxWidth != -1 && requisition->width > maxWidth) + requisition->width = maxWidth; DBG_OBJ_MSGF ("resize", 1, "=> %d * (%d + %d)", requisition->width, requisition->ascent, @@ -1543,29 +1600,22 @@ void Widget::correctExtremesOfChild (Widget *child, Extremes *extremes) (child->container ? child->container : child->parent); if (effContainer == this) { - if (style::isAbsLength (child->getStyle()->width)) { - DBG_OBJ_MSGF ("resize", 1, "absolute width: %dpx", - style::absLengthVal (child->getStyle()->width)); - extremes->minWidth = extremes->maxWidth = - misc::max (style::absLengthVal (child->getStyle()->width) - + child->boxDiffWidth (), - child->getMinWidth (extremes, false)); - } else if (style::isPerLength (child->getStyle()->width)) { - DBG_OBJ_MSGF ("resize", 1, "percentage width: %g%%", - 100 * style::perLengthVal_useThisOnlyForDebugging - (child->getStyle()->width)); - int availWidth = getAvailWidth (false); - if (availWidth != -1) { - int containerWidth = availWidth - boxDiffWidth (); - DBG_OBJ_MSGF ("resize", 1, "containerWidth = %d - %d = %d", - availWidth, boxDiffWidth (), containerWidth); - extremes->minWidth = extremes->maxWidth = - misc::max (child->applyPerWidth (containerWidth, - child->getStyle()->width), - child->getMinWidth (extremes, false)); - } - } else - DBG_OBJ_MSG ("resize", 1, "no specification"); + int limit = child->getMinWidth (extremes, false); + int width = child->calcWidth (child->getStyle()->width, -1, this, limit); + int minWidth = + child->calcWidth (child->getStyle()->minWidth, -1, this, limit); + int maxWidth = + child->calcWidth (child->getStyle()->maxWidth, -1, this, limit); + + DBG_OBJ_MSGF ("resize", 1, "width = %d, minWidth = %d, maxWidth = %d", + width, minWidth, maxWidth); + + if (width != -1) + extremes->minWidth = extremes->maxWidth = width; + if (minWidth != -1) + extremes->minWidth = minWidth; + if (maxWidth != -1) + extremes->maxWidth = maxWidth; } else { DBG_OBJ_MSG ("resize", 1, "delegated to (effective) container"); DBG_OBJ_MSG_START (); diff --git a/dw/widget.hh b/dw/widget.hh index 2599d14c..88bc2a61 100644 --- a/dw/widget.hh +++ b/dw/widget.hh @@ -431,6 +431,8 @@ public: void correctRequisition (Requisition *requisition, void (*splitHeightFun) (int, int*, int*)); void correctExtremes (Extremes *extremes); + int calcWidth (style::Length cssValue, int refWidth, Widget *refWidget, + int minWidth); virtual int applyPerWidth (int containerWidth, style::Length perWidth); virtual int applyPerHeight (int containerHeight, style::Length perHeight); diff --git a/src/cssparser.cc b/src/cssparser.cc index 794bf6b7..accdf478 100644 --- a/src/cssparser.cc +++ b/src/cssparser.cc @@ -239,10 +239,14 @@ const CssPropertyInfo Css_property_info[CSS_PROPERTY_LAST] = { {CSS_TYPE_SIGNED_LENGTH, CSS_TYPE_AUTO, CSS_TYPE_UNUSED}, NULL}, {"marker-offset", {CSS_TYPE_UNUSED}, NULL}, {"marks", {CSS_TYPE_UNUSED}, NULL}, - {"max-height", {CSS_TYPE_UNUSED}, NULL}, - {"max-width", {CSS_TYPE_UNUSED}, NULL}, - {"min-height", {CSS_TYPE_UNUSED}, NULL}, - {"min-width", {CSS_TYPE_UNUSED}, NULL}, + {"max-height", {CSS_TYPE_LENGTH_PERCENTAGE, CSS_TYPE_AUTO, CSS_TYPE_UNUSED}, + NULL}, + {"max-width", {CSS_TYPE_LENGTH_PERCENTAGE, CSS_TYPE_AUTO, CSS_TYPE_UNUSED}, + NULL}, + {"min-height", {CSS_TYPE_LENGTH_PERCENTAGE, CSS_TYPE_AUTO, CSS_TYPE_UNUSED}, + NULL}, + {"min-width", {CSS_TYPE_LENGTH_PERCENTAGE, CSS_TYPE_AUTO, CSS_TYPE_UNUSED}, + NULL}, {"outline-color", {CSS_TYPE_UNUSED}, NULL}, {"outline-style", {CSS_TYPE_UNUSED}, NULL}, {"outline-width", {CSS_TYPE_UNUSED}, NULL}, diff --git a/src/styleengine.cc b/src/styleengine.cc index 74a6330f..f5f0a315 100644 --- a/src/styleengine.cc +++ b/src/styleengine.cc @@ -713,6 +713,18 @@ void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props, else if (attrs->wordSpacing < -1000) attrs->wordSpacing = -1000; break; + case CSS_PROPERTY_MIN_WIDTH: + computeLength (&attrs->minWidth, p->value.intVal, attrs->font); + break; + case CSS_PROPERTY_MAX_WIDTH: + computeLength (&attrs->maxWidth, p->value.intVal, attrs->font); + break; + case CSS_PROPERTY_MIN_HEIGHT: + computeLength (&attrs->minHeight, p->value.intVal, attrs->font); + break; + case CSS_PROPERTY_MAX_HEIGHT: + computeLength (&attrs->maxHeight, p->value.intVal, attrs->font); + break; case PROPERTY_X_LINK: attrs->x_link = p->value.intVal; break; |