Пример #1
0
void RenderTextControl::computePreferredLogicalWidths()
{
    ASSERT(preferredLogicalWidthsDirty());

    m_minPreferredLogicalWidth = 0;
    m_maxPreferredLogicalWidth = 0;

    if (style().logicalWidth().isFixed() && style().logicalWidth().value() >= 0)
        m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = adjustContentBoxLogicalWidthForBoxSizing(style().logicalWidth().value());
    else
        computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);

    if (style().logicalMinWidth().isFixed() && style().logicalMinWidth().value() > 0) {
        m_maxPreferredLogicalWidth = std::max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style().logicalMinWidth().value()));
        m_minPreferredLogicalWidth = std::max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style().logicalMinWidth().value()));
    }

    if (style().logicalMaxWidth().isFixed()) {
        m_maxPreferredLogicalWidth = std::min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style().logicalMaxWidth().value()));
        m_minPreferredLogicalWidth = std::min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style().logicalMaxWidth().value()));
    }

    LayoutUnit toAdd = borderAndPaddingLogicalWidth();

    m_minPreferredLogicalWidth += toAdd;
    m_maxPreferredLogicalWidth += toAdd;

    setPreferredLogicalWidthsDirty(false);
}
Пример #2
0
void RenderReplaced::computePreferredLogicalWidths()
{
    ASSERT(preferredLogicalWidthsDirty());

    // We cannot resolve any percent logical width here as the available logical
    // width may not be set on our containing block.
    if (style().logicalWidth().isPercentOrCalculated())
        computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
    else
        m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = computeReplacedLogicalWidth(ComputePreferred);

    const RenderStyle& styleToUse = style();
    if (styleToUse.logicalWidth().isPercentOrCalculated() || styleToUse.logicalMaxWidth().isPercentOrCalculated())
        m_minPreferredLogicalWidth = 0;

    if (styleToUse.logicalMinWidth().isFixed() && styleToUse.logicalMinWidth().value() > 0) {
        m_maxPreferredLogicalWidth = std::max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse.logicalMinWidth().value()));
        m_minPreferredLogicalWidth = std::max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse.logicalMinWidth().value()));
    }
    
    if (styleToUse.logicalMaxWidth().isFixed()) {
        m_maxPreferredLogicalWidth = std::min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse.logicalMaxWidth().value()));
        m_minPreferredLogicalWidth = std::min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse.logicalMaxWidth().value()));
    }

    LayoutUnit borderAndPadding = borderAndPaddingLogicalWidth();
    m_minPreferredLogicalWidth += borderAndPadding;
    m_maxPreferredLogicalWidth += borderAndPadding;

    setPreferredLogicalWidthsDirty(false);
}
Пример #3
0
void LayoutReplaced::computePreferredLogicalWidths()
{
    ASSERT(preferredLogicalWidthsDirty());

    // We cannot resolve some logical width here (i.e. percent, fill-available or fit-content)
    // as the available logical width may not be set on our containing block.
    const Length& logicalWidth = style()->logicalWidth();
    if (logicalWidth.hasPercent() || logicalWidth.isFillAvailable() || logicalWidth.isFitContent())
        computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
    else
        m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = computeReplacedLogicalWidth(ComputePreferred);

    const ComputedStyle& styleToUse = styleRef();
    if (styleToUse.logicalWidth().hasPercent() || styleToUse.logicalMaxWidth().hasPercent())
        m_minPreferredLogicalWidth = 0;

    if (styleToUse.logicalMinWidth().isFixed() && styleToUse.logicalMinWidth().value() > 0) {
        m_maxPreferredLogicalWidth = std::max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse.logicalMinWidth().value()));
        m_minPreferredLogicalWidth = std::max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse.logicalMinWidth().value()));
    }

    if (styleToUse.logicalMaxWidth().isFixed()) {
        m_maxPreferredLogicalWidth = std::min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse.logicalMaxWidth().value()));
        m_minPreferredLogicalWidth = std::min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse.logicalMaxWidth().value()));
    }

    LayoutUnit borderAndPadding = borderAndPaddingLogicalWidth();
    m_minPreferredLogicalWidth += borderAndPadding;
    m_maxPreferredLogicalWidth += borderAndPadding;

    clearPreferredLogicalWidthsDirty();
}
Пример #4
0
void RenderRegion::computePreferredLogicalWidths()
{
    ASSERT(preferredLogicalWidthsDirty());

    if (!isValid()) {
        RenderBlockFlow::computePreferredLogicalWidths();
        return;
    }

    // FIXME: Currently, the code handles only the <length> case for min-width/max-width.
    // It should also support other values, like percentage, calc or viewport relative.
    m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = 0;

    const RenderStyle& styleToUse = style();
    if (styleToUse.logicalWidth().isFixed() && styleToUse.logicalWidth().value() > 0)
        m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = adjustContentBoxLogicalWidthForBoxSizing(styleToUse.logicalWidth().value());
    else
        computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);

    if (styleToUse.logicalMinWidth().isFixed() && styleToUse.logicalMinWidth().value() > 0) {
        m_maxPreferredLogicalWidth = std::max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse.logicalMinWidth().value()));
        m_minPreferredLogicalWidth = std::max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse.logicalMinWidth().value()));
    }

    if (styleToUse.logicalMaxWidth().isFixed()) {
        m_maxPreferredLogicalWidth = std::min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse.logicalMaxWidth().value()));
        m_minPreferredLogicalWidth = std::min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse.logicalMaxWidth().value()));
    }

    LayoutUnit borderAndPadding = borderAndPaddingLogicalWidth();
    m_minPreferredLogicalWidth += borderAndPadding;
    m_maxPreferredLogicalWidth += borderAndPadding;
    setPreferredLogicalWidthsDirty(false);
}
Пример #5
0
void RenderGrid::computePreferredLogicalWidths()
{
    ASSERT(preferredLogicalWidthsDirty());

    m_minPreferredLogicalWidth = 0;
    m_maxPreferredLogicalWidth = 0;

    // FIXME: We don't take our own logical width into account.

    const Vector<GridTrackSize>& trackStyles = style()->gridColumns();

    for (size_t i = 0; i < trackStyles.size(); ++i) {
        LayoutUnit minTrackBreadth = computePreferredTrackWidth(trackStyles[i].minTrackBreadth(), i);
        LayoutUnit maxTrackBreadth = computePreferredTrackWidth(trackStyles[i].maxTrackBreadth(), i);
        maxTrackBreadth = std::max(maxTrackBreadth, minTrackBreadth);

        m_minPreferredLogicalWidth += minTrackBreadth;
        m_maxPreferredLogicalWidth += maxTrackBreadth;

        // FIXME: This should add in the scrollbarWidth (e.g. see RenderFlexibleBox).
    }

    // FIXME: We should account for min / max logical width.

    LayoutUnit borderAndPaddingInInlineDirection = borderAndPaddingLogicalWidth();
    m_minPreferredLogicalWidth += borderAndPaddingInInlineDirection;
    m_maxPreferredLogicalWidth += borderAndPaddingInInlineDirection;

    setPreferredLogicalWidthsDirty(false);
}
Пример #6
0
int RenderTextControl::textBlockLogicalWidth() const
{
    TextControlInnerTextElement* innerText = innerTextElement();
    ASSERT(innerText);

    LayoutUnit unitWidth = logicalWidth() - borderAndPaddingLogicalWidth();
    if (innerText->renderer())
        unitWidth -= innerText->renderBox()->paddingStart() + innerText->renderBox()->paddingEnd();

    return unitWidth;
}
Пример #7
0
int LayoutTextControl::textBlockLogicalWidth() const {
    Element* innerEditor = innerEditorElement();
    ASSERT(innerEditor);

    LayoutUnit unitWidth = logicalWidth() - borderAndPaddingLogicalWidth();
    if (innerEditor->layoutObject())
        unitWidth -= innerEditor->layoutBox()->paddingStart() +
                     innerEditor->layoutBox()->paddingEnd();

    return unitWidth.toInt();
}
Пример #8
0
void RenderBlockFlow::determineLogicalLeftPositionForChild(RenderBox* child)
{
    LayoutUnit startPosition = borderStart() + paddingStart();
    LayoutUnit totalAvailableLogicalWidth = borderAndPaddingLogicalWidth() + availableLogicalWidth();

    LayoutUnit childMarginStart = marginStartForChild(child);
    LayoutUnit newPosition = startPosition + childMarginStart;

    // If the child has an offset from the content edge to avoid floats then use that, otherwise let any negative
    // margin pull it back over the content edge or any positive margin push it out.
    if (child->style()->marginStartUsing(style()).isAuto())
        newPosition = std::max(newPosition, childMarginStart);

    child->setX(style()->isLeftToRightDirection() ? newPosition : totalAvailableLogicalWidth - newPosition - logicalWidthForChild(child));
}
Пример #9
0
void RenderReplaced::computePreferredLogicalWidths()
{
    ASSERT(preferredLogicalWidthsDirty());

    LayoutUnit borderAndPadding = borderAndPaddingLogicalWidth();
    m_maxPreferredLogicalWidth = computeMaxPreferredLogicalWidth() + borderAndPadding;

    if (style()->maxWidth().isFixed())
        m_maxPreferredLogicalWidth = min<LayoutUnit>(m_maxPreferredLogicalWidth, style()->maxWidth().value() + (style()->boxSizing() == CONTENT_BOX ? borderAndPadding : ZERO_LAYOUT_UNIT));

    if (hasRelativeDimensions())
        m_minPreferredLogicalWidth = 0;
    else
        m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth;

    setPreferredLogicalWidthsDirty(false);
}
Пример #10
0
void LayoutTextControl::computePreferredLogicalWidths() {
    ASSERT(preferredLogicalWidthsDirty());

    m_minPreferredLogicalWidth = LayoutUnit();
    m_maxPreferredLogicalWidth = LayoutUnit();
    const ComputedStyle& styleToUse = styleRef();

    if (styleToUse.logicalWidth().isFixed() &&
            styleToUse.logicalWidth().value() >= 0)
        m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth =
                                         adjustContentBoxLogicalWidthForBoxSizing(
                                             styleToUse.logicalWidth().value());
    else
        computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth,
                                      m_maxPreferredLogicalWidth);

    if (styleToUse.logicalMinWidth().isFixed() &&
            styleToUse.logicalMinWidth().value() > 0) {
        m_maxPreferredLogicalWidth = std::max(
                                         m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(
                                             styleToUse.logicalMinWidth().value()));
        m_minPreferredLogicalWidth = std::max(
                                         m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(
                                             styleToUse.logicalMinWidth().value()));
    }

    if (styleToUse.logicalMaxWidth().isFixed()) {
        m_maxPreferredLogicalWidth = std::min(
                                         m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(
                                             styleToUse.logicalMaxWidth().value()));
        m_minPreferredLogicalWidth = std::min(
                                         m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(
                                             styleToUse.logicalMaxWidth().value()));
    }

    LayoutUnit toAdd = borderAndPaddingLogicalWidth();

    m_minPreferredLogicalWidth += toAdd;
    m_maxPreferredLogicalWidth += toAdd;

    clearPreferredLogicalWidthsDirty();
}
Пример #11
0
void LayoutReplaced::computePositionedLogicalWidth(
    LogicalExtentComputedValues& computedValues) const {
    // The following is based off of the W3C Working Draft from April 11, 2006 of
    // CSS 2.1: Section 10.3.8 "Absolutely positioned, replaced elements"
    // <http://www.w3.org/TR/2005/WD-CSS21-20050613/visudet.html#abs-replaced-width>
    // (block-style-comments in this function correspond to text from the spec and
    // the numbers correspond to numbers in spec).

    // We don't use containingBlock(), since we may be positioned by an enclosing
    // relative positioned inline.
    const LayoutBoxModelObject* containerBlock =
        toLayoutBoxModelObject(container());

    const LayoutUnit containerLogicalWidth =
        containingBlockLogicalWidthForPositioned(containerBlock);
    const LayoutUnit containerRelativeLogicalWidth =
        containingBlockLogicalWidthForPositioned(containerBlock, false);

    // To match WinIE, in quirks mode use the parent's 'direction' property
    // instead of the the container block's.
    TextDirection containerDirection = containerBlock->style()->direction();

    // Variables to solve.
    bool isHorizontal = isHorizontalWritingMode();
    Length logicalLeft = style()->logicalLeft();
    Length logicalRight = style()->logicalRight();
    Length marginLogicalLeft =
        isHorizontal ? style()->marginLeft() : style()->marginTop();
    Length marginLogicalRight =
        isHorizontal ? style()->marginRight() : style()->marginBottom();
    LayoutUnit& marginLogicalLeftAlias = style()->isLeftToRightDirection()
                                         ? computedValues.m_margins.m_start
                                         : computedValues.m_margins.m_end;
    LayoutUnit& marginLogicalRightAlias = style()->isLeftToRightDirection()
                                          ? computedValues.m_margins.m_end
                                          : computedValues.m_margins.m_start;

    // ---------------------------------------------------------------------------
    // 1. The used value of 'width' is determined as for inline replaced
    //  elements.
    // ---------------------------------------------------------------------------
    // NOTE: This value of width is final in that the min/max width calculations
    // are dealt with in computeReplacedWidth().  This means that the steps to
    // produce correct max/min in the non-replaced version, are not necessary.
    computedValues.m_extent =
        computeReplacedLogicalWidth() + borderAndPaddingLogicalWidth();

    const LayoutUnit availableSpace =
        containerLogicalWidth - computedValues.m_extent;

    // ---------------------------------------------------------------------------
    // 2. If both 'left' and 'right' have the value 'auto', then if 'direction'
    //    of the containing block is 'ltr', set 'left' to the static position;
    //    else if 'direction' is 'rtl', set 'right' to the static position.
    // ---------------------------------------------------------------------------
    // see FIXME 1
    computeInlineStaticDistance(logicalLeft, logicalRight, this, containerBlock,
                                containerLogicalWidth);

    // ---------------------------------------------------------------------------
    // 3. If 'left' or 'right' are 'auto', replace any 'auto' on 'margin-left'
    //    or 'margin-right' with '0'.
    // ---------------------------------------------------------------------------
    if (logicalLeft.isAuto() || logicalRight.isAuto()) {
        if (marginLogicalLeft.isAuto())
            marginLogicalLeft.setValue(Fixed, 0);
        if (marginLogicalRight.isAuto())
            marginLogicalRight.setValue(Fixed, 0);
    }

    // ---------------------------------------------------------------------------
    // 4. If at this point both 'margin-left' and 'margin-right' are still 'auto',
    //    solve the equation under the extra constraint that the two margins must
    //    get equal values, unless this would make them negative, in which case
    //    when the direction of the containing block is 'ltr' ('rtl'), set
    //    'margin-left' ('margin-right') to zero and solve for 'margin-right'
    //    ('margin-left').
    // ---------------------------------------------------------------------------
    LayoutUnit logicalLeftValue;
    LayoutUnit logicalRightValue;

    if (marginLogicalLeft.isAuto() && marginLogicalRight.isAuto()) {
        // 'left' and 'right' cannot be 'auto' due to step 3
        ASSERT(!(logicalLeft.isAuto() && logicalRight.isAuto()));

        logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth);
        logicalRightValue = valueForLength(logicalRight, containerLogicalWidth);

        LayoutUnit difference =
            availableSpace - (logicalLeftValue + logicalRightValue);
        if (difference > LayoutUnit()) {
            marginLogicalLeftAlias = difference / 2;  // split the difference
            marginLogicalRightAlias =
                difference -
                marginLogicalLeftAlias;  // account for odd valued differences
        } else {
            // Use the containing block's direction rather than the parent block's
            // per CSS 2.1 reference test abspos-replaced-width-margin-000.
            if (containerDirection == LTR) {
                marginLogicalLeftAlias = LayoutUnit();
                marginLogicalRightAlias = difference;  // will be negative
            } else {
                marginLogicalLeftAlias = difference;  // will be negative
                marginLogicalRightAlias = LayoutUnit();
            }
        }

        // -------------------------------------------------------------------------
        // 5. If at this point there is an 'auto' left, solve the equation for that
        //    value.
        // -------------------------------------------------------------------------
    } else if (logicalLeft.isAuto()) {
        marginLogicalLeftAlias =
            valueForLength(marginLogicalLeft, containerRelativeLogicalWidth);
        marginLogicalRightAlias =
            valueForLength(marginLogicalRight, containerRelativeLogicalWidth);
        logicalRightValue = valueForLength(logicalRight, containerLogicalWidth);

        // Solve for 'left'
        logicalLeftValue =
            availableSpace -
            (logicalRightValue + marginLogicalLeftAlias + marginLogicalRightAlias);
    } else if (logicalRight.isAuto()) {
        marginLogicalLeftAlias =
            valueForLength(marginLogicalLeft, containerRelativeLogicalWidth);
        marginLogicalRightAlias =
            valueForLength(marginLogicalRight, containerRelativeLogicalWidth);
        logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth);

        // Solve for 'right'
        logicalRightValue =
            availableSpace -
            (logicalLeftValue + marginLogicalLeftAlias + marginLogicalRightAlias);
    } else if (marginLogicalLeft.isAuto()) {
        marginLogicalRightAlias =
            valueForLength(marginLogicalRight, containerRelativeLogicalWidth);
        logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth);
        logicalRightValue = valueForLength(logicalRight, containerLogicalWidth);

        // Solve for 'margin-left'
        marginLogicalLeftAlias =
            availableSpace -
            (logicalLeftValue + logicalRightValue + marginLogicalRightAlias);
    } else if (marginLogicalRight.isAuto()) {
        marginLogicalLeftAlias =
            valueForLength(marginLogicalLeft, containerRelativeLogicalWidth);
        logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth);
        logicalRightValue = valueForLength(logicalRight, containerLogicalWidth);

        // Solve for 'margin-right'
        marginLogicalRightAlias =
            availableSpace -
            (logicalLeftValue + logicalRightValue + marginLogicalLeftAlias);
    } else {
        // Nothing is 'auto', just calculate the values.
        marginLogicalLeftAlias =
            valueForLength(marginLogicalLeft, containerRelativeLogicalWidth);
        marginLogicalRightAlias =
            valueForLength(marginLogicalRight, containerRelativeLogicalWidth);
        logicalRightValue = valueForLength(logicalRight, containerLogicalWidth);
        logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth);
        // If the containing block is right-to-left, then push the left position as
        // far to the right as possible
        if (containerDirection == RTL) {
            int totalLogicalWidth =
                (computedValues.m_extent + logicalLeftValue + logicalRightValue +
                 marginLogicalLeftAlias + marginLogicalRightAlias)
                .toInt();
            logicalLeftValue =
                containerLogicalWidth - (totalLogicalWidth - logicalLeftValue);
        }
    }

    // ---------------------------------------------------------------------------
    // 6. If at this point the values are over-constrained, ignore the value for
    //    either 'left' (in case the 'direction' property of the containing block
    //    is 'rtl') or 'right' (in case 'direction' is 'ltr') and solve for that
    //    value.
    // ---------------------------------------------------------------------------
    // NOTE: Constraints imposed by the width of the containing block and its
    // content have already been accounted for above.
    //
    // FIXME: Deal with differing writing modes here.  Our offset needs to be in
    // the containing block's coordinate space, so that
    // can make the result here rather complicated to compute.
    //
    // Use computed values to calculate the horizontal position.
    //
    // FIXME: This hack is needed to calculate the logical left position for a
    // 'rtl' relatively positioned, inline containing block because right now, it
    // is using the logical left position of the first line box when really it
    // should use the last line box. When this is fixed elsewhere, this block
    // should be removed.
    if (containerBlock->isLayoutInline() &&
            !containerBlock->style()->isLeftToRightDirection()) {
        const LayoutInline* flow = toLayoutInline(containerBlock);
        InlineFlowBox* firstLine = flow->firstLineBox();
        InlineFlowBox* lastLine = flow->lastLineBox();
        if (firstLine && lastLine && firstLine != lastLine) {
            computedValues.m_position =
                logicalLeftValue + marginLogicalLeftAlias +
                lastLine->borderLogicalLeft() +
                (lastLine->logicalLeft() - firstLine->logicalLeft());
            return;
        }
    }

    LayoutUnit logicalLeftPos = logicalLeftValue + marginLogicalLeftAlias;
    computeLogicalLeftPositionedOffset(logicalLeftPos, this,
                                       computedValues.m_extent, containerBlock,
                                       containerLogicalWidth);
    computedValues.m_position = logicalLeftPos;
}