diff options
Diffstat (limited to 'WebCore/rendering/RenderFlexibleBox.cpp')
-rw-r--r-- | WebCore/rendering/RenderFlexibleBox.cpp | 236 |
1 files changed, 111 insertions, 125 deletions
diff --git a/WebCore/rendering/RenderFlexibleBox.cpp b/WebCore/rendering/RenderFlexibleBox.cpp index 636c873..83ec721 100644 --- a/WebCore/rendering/RenderFlexibleBox.cpp +++ b/WebCore/rendering/RenderFlexibleBox.cpp @@ -44,7 +44,7 @@ public: FlexBoxIterator(RenderFlexibleBox* parent) { box = parent; - if (box->style()->boxOrient() == HORIZONTAL && box->style()->direction() == RTL) + if (box->style()->boxOrient() == HORIZONTAL && !box->style()->isLeftToRightDirection()) forward = box->style()->boxDirection() != BNORMAL; else forward = box->style()->boxDirection() == BNORMAL; @@ -266,12 +266,12 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren, int /*pageHeight FIXM // bottom margin max values to 0. This way we don't factor in the values // twice when we collapse with our previous vertically adjacent and // following vertically adjacent blocks. - int pos = maxPosMarginBefore(); - int neg = maxNegMarginBefore(); - if (maxPosMarginAfter() > pos) - pos = maxPosMarginAfter(); - if (maxNegMarginAfter() > neg) - neg = maxNegMarginAfter(); + int pos = maxPositiveMarginBefore(); + int neg = maxNegativeMarginBefore(); + if (maxPositiveMarginAfter() > pos) + pos = maxPositiveMarginAfter(); + if (maxNegativeMarginAfter() > neg) + neg = maxNegativeMarginAfter(); setMaxMarginBeforeValues(pos, neg); setMaxMarginAfterValues(0, 0); } @@ -342,8 +342,6 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren) bool haveFlex = false; gatherFlexChildrenInfo(iterator, relayoutChildren, highestFlexGroup, lowestFlexGroup, haveFlex); - bool paginated = view()->layoutState()->isPaginated(); - RenderBox* child; RenderBlock::startDelayUpdateScrollInfo(); @@ -374,11 +372,8 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren) // Compute the child's vertical margins. child->computeBlockDirectionMargins(this); - if (!child->needsLayout() && paginated && view()->layoutState()->m_pageHeight) { - RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0; - if (childRenderBlock && view()->layoutState()->pageY(child->y()) != childRenderBlock->pageY()) - childRenderBlock->markForPaginationRelayout(); - } + if (!child->needsLayout()) + child->markForPaginationRelayoutIfNeeded(); // Now do the layout. child->layoutIfNeeded(); @@ -407,7 +402,7 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren) } if (!iterator.first() && hasLineIfEmpty()) - setHeight(height() + lineHeight(true, true)); + setHeight(height() + lineHeight(true, style()->isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes)); setHeight(height() + toAdd); @@ -425,7 +420,7 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren) if (child->isPositioned()) { child->containingBlock()->insertPositionedObject(child); if (child->style()->hasStaticX()) { - if (style()->direction() == LTR) + if (style()->isLeftToRightDirection()) child->layer()->setStaticX(xPos); else child->layer()->setStaticX(width() - xPos); } @@ -448,11 +443,8 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren) if (oldChildHeight != child->height()) child->setChildNeedsLayout(true, false); - if (!child->needsLayout() && paginated && view()->layoutState()->m_pageHeight) { - RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0; - if (childRenderBlock && view()->layoutState()->pageY(child->y()) != childRenderBlock->pageY()) - childRenderBlock->markForPaginationRelayout(); - } + if (!child->needsLayout()) + child->markForPaginationRelayoutIfNeeded(); child->layoutIfNeeded(); @@ -583,8 +575,8 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren) RenderBlock::finishDelayUpdateScrollInfo(); - if (remainingSpace > 0 && ((style()->direction() == LTR && style()->boxPack() != BSTART) || - (style()->direction() == RTL && style()->boxPack() != BEND))) { + if (remainingSpace > 0 && ((style()->isLeftToRightDirection() && style()->boxPack() != BSTART) + || (!style()->isLeftToRightDirection() && style()->boxPack() != BEND))) { // Children must be repositioned. int offset = 0; if (style()->boxPack() == BJUSTIFY) { @@ -653,7 +645,7 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren) { int xPos = borderLeft() + paddingLeft(); int yPos = borderTop() + paddingTop(); - if (style()->direction() == RTL) + if (!style()->isLeftToRightDirection()) xPos = width() - paddingRight() - borderRight(); int toAdd = borderBottom() + paddingBottom() + horizontalScrollbarHeight(); bool heightSpecified = false; @@ -667,8 +659,6 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren) bool haveFlex = false; gatherFlexChildrenInfo(iterator, relayoutChildren, highestFlexGroup, lowestFlexGroup, haveFlex); - bool paginated = view()->layoutState()->isPaginated(); - RenderBox* child; // We confine the line clamp ugliness to vertical flexible boxes (thus keeping it out of @@ -696,7 +686,7 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren) if (child->isPositioned()) { child->containingBlock()->insertPositionedObject(child); if (child->style()->hasStaticX()) { - if (style()->direction() == LTR) + if (style()->isLeftToRightDirection()) child->layer()->setStaticX(borderLeft()+paddingLeft()); else child->layer()->setStaticX(borderRight()+paddingRight()); @@ -718,11 +708,8 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren) // Add in the child's marginTop to our height. setHeight(height() + child->marginTop()); - if (!child->needsLayout() && paginated && view()->layoutState()->m_pageHeight) { - RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0; - if (childRenderBlock && view()->layoutState()->pageY(child->y()) != childRenderBlock->pageY()) - childRenderBlock->markForPaginationRelayout(); - } + if (!child->needsLayout()) + child->markForPaginationRelayoutIfNeeded(); // Now do a layout. child->layoutIfNeeded(); @@ -735,13 +722,13 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren) childX += child->marginLeft() + max(0, (contentWidth() - (child->width() + child->marginLeft() + child->marginRight()))/2); break; case BEND: - if (style()->direction() == RTL) + if (!style()->isLeftToRightDirection()) childX += child->marginLeft(); else childX += contentWidth() - child->marginRight() - child->width(); break; default: // BSTART/BSTRETCH - if (style()->direction() == LTR) + if (style()->isLeftToRightDirection()) childX += child->marginLeft(); else childX += contentWidth() - child->marginRight() - child->width(); @@ -758,7 +745,7 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren) yPos = height(); if (!iterator.first() && hasLineIfEmpty()) - setHeight(height() + lineHeight(true, true)); + setHeight(height() + lineHeight(true, style()->isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes)); setHeight(height() + toAdd); @@ -934,103 +921,102 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren) void RenderFlexibleBox::applyLineClamp(FlexBoxIterator& iterator, bool relayoutChildren) { int maxLineCount = 0; - RenderBox* child = iterator.first(); - while (child) { - if (!child->isPositioned()) { - if (relayoutChildren || (child->isReplaced() && (child->style()->width().isPercent() || child->style()->height().isPercent())) || - (child->style()->height().isAuto() && child->isBlockFlow() && !child->needsLayout())) { - child->setChildNeedsLayout(true, false); - - // Dirty all the positioned objects. - if (child->isRenderBlock()) { - toRenderBlock(child)->markPositionedObjectsForLayout(); - toRenderBlock(child)->clearTruncation(); - } + for (RenderBox* child = iterator.first(); child; child = iterator.next()) { + if (child->isPositioned()) + continue; + + if (relayoutChildren || (child->isReplaced() && (child->style()->width().isPercent() || child->style()->height().isPercent())) + || (child->style()->height().isAuto() && child->isBlockFlow() && !child->needsLayout())) { + child->setChildNeedsLayout(true, false); + + // Dirty all the positioned objects. + if (child->isRenderBlock()) { + toRenderBlock(child)->markPositionedObjectsForLayout(); + toRenderBlock(child)->clearTruncation(); } - child->layoutIfNeeded(); - if (child->style()->height().isAuto() && child->isBlockFlow()) - maxLineCount = max(maxLineCount, toRenderBlock(child)->lineCount()); } - child = iterator.next(); + child->layoutIfNeeded(); + if (child->style()->height().isAuto() && child->isBlockFlow()) + maxLineCount = max(maxLineCount, toRenderBlock(child)->lineCount()); } - - // Get the # of lines and then alter all block flow children with auto height to use the + + // Get the number of lines and then alter all block flow children with auto height to use the // specified height. We always try to leave room for at least one line. LineClampValue lineClamp = style()->lineClamp(); int numVisibleLines = lineClamp.isPercentage() ? max(1, (maxLineCount + 1) * lineClamp.value() / 100) : lineClamp.value(); - if (numVisibleLines < maxLineCount) { - for (child = iterator.first(); child; child = iterator.next()) { - if (child->isPositioned() || !child->style()->height().isAuto() || !child->isBlockFlow()) - continue; - - RenderBlock* blockChild = toRenderBlock(child); - int lineCount = blockChild->lineCount(); - if (lineCount <= numVisibleLines) - continue; - - int newHeight = blockChild->heightForLineCount(numVisibleLines); - if (newHeight == child->height()) - continue; - - child->setChildNeedsLayout(true, false); - child->setOverrideSize(newHeight); - m_flexingChildren = true; - child->layoutIfNeeded(); - m_flexingChildren = false; - child->setOverrideSize(-1); - - // FIXME: For now don't support RTL. - if (style()->direction() != LTR) - continue; - - // Get the last line - RootInlineBox* lastLine = blockChild->lineAtIndex(lineCount-1); - if (!lastLine) - continue; - - RootInlineBox* lastVisibleLine = blockChild->lineAtIndex(numVisibleLines-1); - if (!lastVisibleLine) - continue; - - const UChar ellipsisAndSpace[2] = { horizontalEllipsis, ' ' }; - DEFINE_STATIC_LOCAL(AtomicString, ellipsisAndSpaceStr, (ellipsisAndSpace, 2)); - DEFINE_STATIC_LOCAL(AtomicString, ellipsisStr, (&horizontalEllipsis, 1)); - const Font& font = style(numVisibleLines == 1)->font(); - - // Get ellipsis width, and if the last child is an anchor, it will go after the ellipsis, so add in a space and the anchor width too - int totalWidth; - InlineBox* anchorBox = lastLine->lastChild(); - if (anchorBox && anchorBox->renderer()->node() && anchorBox->renderer()->node()->isLink()) - totalWidth = anchorBox->logicalWidth() + font.width(TextRun(ellipsisAndSpace, 2)); - else { - anchorBox = 0; - totalWidth = font.width(TextRun(&horizontalEllipsis, 1)); - } - - // See if this width can be accommodated on the last visible line - RenderBlock* destBlock = toRenderBlock(lastVisibleLine->renderer()); - RenderBlock* srcBlock = toRenderBlock(lastLine->renderer()); - - // FIXME: Directions of src/destBlock could be different from our direction and from one another. - if (srcBlock->style()->direction() != LTR) - continue; - if (destBlock->style()->direction() != LTR) - continue; - int ltr = true; - - int blockRightEdge = destBlock->logicalRightOffsetForLine(lastVisibleLine->y(), false); - int blockLeftEdge = destBlock->logicalLeftOffsetForLine(lastVisibleLine->y(), false); - - int blockEdge = ltr ? blockRightEdge : blockLeftEdge; - if (!lastVisibleLine->canAccommodateEllipsis(ltr, blockEdge, - lastVisibleLine->x() + lastVisibleLine->logicalWidth(), - totalWidth)) - continue; - - // Let the truncation code kick in. - lastVisibleLine->placeEllipsis(anchorBox ? ellipsisAndSpaceStr : ellipsisStr, ltr, blockLeftEdge, blockRightEdge, totalWidth, anchorBox); - destBlock->setHasMarkupTruncation(true); + if (numVisibleLines >= maxLineCount) + return; + + for (RenderBox* child = iterator.first(); child; child = iterator.next()) { + if (child->isPositioned() || !child->style()->height().isAuto() || !child->isBlockFlow()) + continue; + + RenderBlock* blockChild = toRenderBlock(child); + int lineCount = blockChild->lineCount(); + if (lineCount <= numVisibleLines) + continue; + + int newHeight = blockChild->heightForLineCount(numVisibleLines); + if (newHeight == child->height()) + continue; + + child->setChildNeedsLayout(true, false); + child->setOverrideSize(newHeight); + m_flexingChildren = true; + child->layoutIfNeeded(); + m_flexingChildren = false; + child->setOverrideSize(-1); + + // FIXME: For now don't support RTL. + if (style()->direction() != LTR) + continue; + + // Get the last line + RootInlineBox* lastLine = blockChild->lineAtIndex(lineCount-1); + if (!lastLine) + continue; + + RootInlineBox* lastVisibleLine = blockChild->lineAtIndex(numVisibleLines-1); + if (!lastVisibleLine) + continue; + + const UChar ellipsisAndSpace[2] = { horizontalEllipsis, ' ' }; + DEFINE_STATIC_LOCAL(AtomicString, ellipsisAndSpaceStr, (ellipsisAndSpace, 2)); + DEFINE_STATIC_LOCAL(AtomicString, ellipsisStr, (&horizontalEllipsis, 1)); + const Font& font = style(numVisibleLines == 1)->font(); + + // Get ellipsis width, and if the last child is an anchor, it will go after the ellipsis, so add in a space and the anchor width too + int totalWidth; + InlineBox* anchorBox = lastLine->lastChild(); + if (anchorBox && anchorBox->renderer()->node() && anchorBox->renderer()->node()->isLink()) + totalWidth = anchorBox->logicalWidth() + font.width(TextRun(ellipsisAndSpace, 2)); + else { + anchorBox = 0; + totalWidth = font.width(TextRun(&horizontalEllipsis, 1)); } + + // See if this width can be accommodated on the last visible line + RenderBlock* destBlock = toRenderBlock(lastVisibleLine->renderer()); + RenderBlock* srcBlock = toRenderBlock(lastLine->renderer()); + + // FIXME: Directions of src/destBlock could be different from our direction and from one another. + if (!srcBlock->style()->isLeftToRightDirection()) + continue; + + bool leftToRight = destBlock->style()->isLeftToRightDirection(); + if (!leftToRight) + continue; + + int blockRightEdge = destBlock->logicalRightOffsetForLine(lastVisibleLine->y(), false); + int blockLeftEdge = destBlock->logicalLeftOffsetForLine(lastVisibleLine->y(), false); + + int blockEdge = leftToRight ? blockRightEdge : blockLeftEdge; + if (!lastVisibleLine->canAccommodateEllipsis(leftToRight, blockEdge, lastVisibleLine->x() + lastVisibleLine->logicalWidth(), totalWidth)) + continue; + + // Let the truncation code kick in. + lastVisibleLine->placeEllipsis(anchorBox ? ellipsisAndSpaceStr : ellipsisStr, leftToRight, blockLeftEdge, blockRightEdge, totalWidth, anchorBox); + destBlock->setHasMarkupTruncation(true); } } |