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); }
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); }
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(); }
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); }
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); }
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; }
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(); }
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)); }
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); }
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(); }
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; }