diff options
| author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-03-12 14:11:15 +0100 |
|---|---|---|
| committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-03-12 14:11:15 +0100 |
| commit | dd91e772430dc294e3bf478c119ef8d43c0a3358 (patch) | |
| tree | 6f33ce4d5872a5691e0291eb45bf6ab373a5f567 /Source/WebCore/rendering/RenderBlock.cpp | |
| parent | ad0d549d4cc13433f77c1ac8f0ab379c83d93f28 (diff) | |
| download | qtwebkit-dd91e772430dc294e3bf478c119ef8d43c0a3358.tar.gz | |
Imported WebKit commit 3db4eb1820ac8fb03065d7ea73a4d9db1e8fea1a (http://svn.webkit.org/repository/webkit/trunk@110422)
This includes build fixes for the latest qtbase/qtdeclarative as well as the final QML2 API.
Diffstat (limited to 'Source/WebCore/rendering/RenderBlock.cpp')
| -rwxr-xr-x | Source/WebCore/rendering/RenderBlock.cpp | 245 |
1 files changed, 199 insertions, 46 deletions
diff --git a/Source/WebCore/rendering/RenderBlock.cpp b/Source/WebCore/rendering/RenderBlock.cpp index 413c60ece..d87d77226 100755 --- a/Source/WebCore/rendering/RenderBlock.cpp +++ b/Source/WebCore/rendering/RenderBlock.cpp @@ -38,6 +38,7 @@ #include "InlineIterator.h" #include "InlineTextBox.h" #include "LayoutRepainter.h" +#include "OverflowEvent.h" #include "PODFreeListArena.h" #include "Page.h" #include "PaintInfo.h" @@ -83,8 +84,60 @@ typedef WTF::HashSet<RenderBlock*> DelayedUpdateScrollInfoSet; static int gDelayUpdateScrollInfo = 0; static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = 0; +// We only create "generated" renderers like one for first-letter and +// before/after pseudo elements if: +// - the firstLetterBlock can have children in the DOM and +// - the block doesn't have any special assumption on its text children. +// This correctly prevents form controls from having such renderers. +static inline bool canHaveGeneratedChildren(RenderObject* renderer) +{ + return (renderer->canHaveChildren() + && (!renderer->isDeprecatedFlexibleBox() + || static_cast<RenderDeprecatedFlexibleBox*>(renderer)->canHaveGeneratedChildren())); +} + bool RenderBlock::s_canPropagateFloatIntoSibling = false; +// This class helps dispatching the 'overflow' event on layout change. overflow can be set on RenderBoxes, yet the existing code +// only works on RenderBlocks. If this change, this class should be shared with other RenderBoxes. +class OverflowEventDispatcher { + WTF_MAKE_NONCOPYABLE(OverflowEventDispatcher); +public: + OverflowEventDispatcher(const RenderBlock* block) + : m_block(block) + , m_hadHorizontalLayoutOverflow(false) + , m_hadVerticalLayoutOverflow(false) + { + m_shouldDispatchEvent = !m_block->isAnonymous() && m_block->hasOverflowClip() && m_block->document()->hasListenerType(Document::OVERFLOWCHANGED_LISTENER); + if (m_shouldDispatchEvent) { + m_hadHorizontalLayoutOverflow = m_block->hasHorizontalLayoutOverflow(); + m_hadVerticalLayoutOverflow = m_block->hasVerticalLayoutOverflow(); + } + } + + ~OverflowEventDispatcher() + { + if (!m_shouldDispatchEvent) + return; + + bool hasHorizontalLayoutOverflow = m_block->hasHorizontalLayoutOverflow(); + bool hasVerticalLayoutOverflow = m_block->hasVerticalLayoutOverflow(); + + bool horizontalLayoutOverflowChanged = hasHorizontalLayoutOverflow != m_hadHorizontalLayoutOverflow; + bool verticalLayoutOverflowChanged = hasVerticalLayoutOverflow != m_hadVerticalLayoutOverflow; + if (horizontalLayoutOverflowChanged || verticalLayoutOverflowChanged) { + if (FrameView* frameView = m_block->document()->view()) + frameView->scheduleEvent(OverflowEvent::create(horizontalLayoutOverflowChanged, hasHorizontalLayoutOverflow, verticalLayoutOverflowChanged, hasVerticalLayoutOverflow), m_block->node()); + } + } + +private: + const RenderBlock* m_block; + bool m_shouldDispatchEvent; + bool m_hadHorizontalLayoutOverflow; + bool m_hadVerticalLayoutOverflow; +}; + // Our MarginInfo state used when laying out block children. RenderBlock::MarginInfo::MarginInfo(RenderBlock* block, LayoutUnit beforeBorderPadding, LayoutUnit afterBorderPadding) : m_atBeforeSideOfBlock(true) @@ -125,6 +178,7 @@ RenderBlock::RenderBlock(Node* node) , m_lineHeight(-1) , m_beingDestroyed(false) , m_hasPositionedFloats(false) + , m_hasMarkupTruncation(false) { setChildrenInline(true); } @@ -261,7 +315,7 @@ void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldSty m_lineHeight = -1; // Update pseudos for :before and :after now. - if (!isAnonymous() && document()->usesBeforeAfterRules() && canHaveChildren()) { + if (!isAnonymous() && document()->usesBeforeAfterRules() && canHaveGeneratedChildren(this)) { updateBeforeAfterContent(BEFORE); updateBeforeAfterContent(AFTER); } @@ -380,8 +434,17 @@ void RenderBlock::addChildToAnonymousColumnBlocks(RenderObject* newChild, Render ASSERT(!continuation()); // We don't yet support column spans that aren't immediate children of the multi-column block. // The goal is to locate a suitable box in which to place our child. - RenderBlock* beforeChildParent = toRenderBlock(beforeChild && beforeChild->parent()->isRenderBlock() ? beforeChild->parent() : lastChild()); - + RenderBlock* beforeChildParent = 0; + if (beforeChild) { + RenderObject* curr = beforeChild; + while (curr && curr->parent() != this) + curr = curr->parent(); + beforeChildParent = toRenderBlock(curr); + ASSERT(beforeChildParent); + ASSERT(beforeChildParent->isAnonymousColumnsBlock() || beforeChildParent->isAnonymousColumnSpanBlock()); + } else + beforeChildParent = toRenderBlock(lastChild()); + // If the new child is floating or positioned it can just go in that block. if (newChild->isFloatingOrPositioned()) { beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild); @@ -491,6 +554,14 @@ void RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock, if (beforeChild && childrenInline()) deleteLineBoxTree(); + // We have to remove the descendant child from our positioned objects list + // before we do the split and move some of the children to cloneBlock. Since + // we are doing layout anyway, it is easier to blow away the entire list, than + // traversing down the subtree looking for positioned childs and then remove them + // from our positioned objects list. + if (beforeChild) + removePositionedObjects(0); + // Now take all of the children from beforeChild to the end and remove // them from |this| and place them in the clone. moveChildrenTo(cloneBlock, beforeChild, 0, true); @@ -504,6 +575,7 @@ void RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock, // Once we hit the anonymous columns block we're done. RenderBoxModelObject* curr = toRenderBoxModelObject(parent()); RenderBoxModelObject* currChild = this; + RenderObject* currChildNextSibling = currChild->nextSibling(); while (curr && curr != fromBlock) { ASSERT(curr->isRenderBlock()); @@ -530,15 +602,20 @@ void RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock, // Someone may have indirectly caused a <q> to split. When this happens, the :after content // has to move into the inline continuation. Call updateBeforeAfterContent to ensure that the inline's :after // content gets properly destroyed. + bool isLastChild = (currChildNextSibling == blockCurr->lastChild()); if (document()->usesBeforeAfterRules()) blockCurr->children()->updateBeforeAfterContent(blockCurr, AFTER); + if (isLastChild && currChildNextSibling != blockCurr->lastChild()) + currChildNextSibling = 0; // We destroyed the last child, so now we need to update + // the value of currChildNextSibling. // Now we need to take all of the children starting from the first child // *after* currChild and append them all to the clone. - blockCurr->moveChildrenTo(cloneBlock, currChild->nextSibling(), 0, true); + blockCurr->moveChildrenTo(cloneBlock, currChildNextSibling, 0, true); // Keep walking up the chain. currChild = curr; + currChildNextSibling = currChild->nextSibling(); curr = toRenderBoxModelObject(curr->parent()); } @@ -547,7 +624,7 @@ void RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock, // Now take all the children after currChild and remove them from the fromBlock // and put them in the toBlock. - fromBlock->moveChildrenTo(toBlock, currChild->nextSibling(), 0, true); + fromBlock->moveChildrenTo(toBlock, currChildNextSibling, 0, true); } void RenderBlock::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox, @@ -835,7 +912,11 @@ void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild, // We are nested inside a multi-column element and are being split by the span. We have to break up // our block into continuations. RenderBoxModelObject* oldContinuation = continuation(); - setContinuation(newBox); + + // When we split an anonymous block, there's no need to do any continuation hookup, + // since we haven't actually split a real element. + if (!isAnonymousBlock()) + setContinuation(newBox); // Someone may have put a <p> inside a <q>, causing a split. When this happens, the :after content // has to move into the inline continuation. Call updateBeforeAfterContent to ensure that our :after @@ -1201,8 +1282,8 @@ void RenderBlock::removeChild(RenderObject* oldChild) // are floating, then we need to pull the content up also. RenderBlock* anonBlock = toRenderBlock((prev && prev->isAnonymousBlock()) ? prev : next); if ((anonBlock->previousSibling() || anonBlock->nextSibling()) - && (!anonBlock->previousSibling() || (anonBlock->previousSibling()->style()->styleType() != NOPSEUDO && anonBlock->previousSibling()->isFloating())) - && (!anonBlock->nextSibling() || (anonBlock->nextSibling()->style()->styleType() != NOPSEUDO && anonBlock->nextSibling()->isFloating()))) { + && (!anonBlock->previousSibling() || (anonBlock->previousSibling()->style()->styleType() != NOPSEUDO && anonBlock->previousSibling()->isFloating() && !anonBlock->previousSibling()->previousSibling())) + && (!anonBlock->nextSibling() || (anonBlock->nextSibling()->style()->styleType() != NOPSEUDO && anonBlock->nextSibling()->isFloating() && !anonBlock->nextSibling()->nextSibling()))) { collapseAnonymousBoxChild(this, anonBlock); } } @@ -1290,16 +1371,24 @@ void RenderBlock::finishDelayUpdateScrollInfo() void RenderBlock::updateScrollInfoAfterLayout() { - if (hasOverflowClip()) { - if (gDelayUpdateScrollInfo) - gDelayedUpdateScrollInfoSet->add(this); - else - layer()->updateScrollInfoAfterLayout(); + if (!hasOverflowClip()) + return; + + if (!hasLayer()) { + updateCachedSizeForOverflowClip(); + return; } + + if (gDelayUpdateScrollInfo) + gDelayedUpdateScrollInfoSet->add(this); + else + layer()->updateScrollInfoAfterLayout(); } void RenderBlock::layout() { + OverflowEventDispatcher dispatcher(this); + // Update our first letter info now. updateFirstLetter(); @@ -1522,7 +1611,7 @@ void RenderBlock::layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeigh repaintRect.inflate(maximalOutlineSize(PaintPhaseOutline)); - if (hasOverflowClip()) { + if (hasOverflowClipWithLayer()) { // Adjust repaint rect for scroll offset repaintRect.move(-scrolledContentOffset()); @@ -1631,8 +1720,12 @@ void RenderBlock::addOverflowFromPositionedObjects() positionedObject = *it; // Fixed positioned elements don't contribute to layout overflow, since they don't scroll with the content. - if (positionedObject->style()->position() != FixedPosition) - addOverflowFromChild(positionedObject); + if (positionedObject->style()->position() != FixedPosition) { + int x = positionedObject->x(); + if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) + x -= verticalScrollbarWidth(); + addOverflowFromChild(positionedObject, IntSize(x, positionedObject->y())); + } } } @@ -1742,6 +1835,10 @@ bool RenderBlock::handleRunInChild(RenderBox* child) return false; // FIXME: We don't handle non-block elements with run-in for now. if (!child->isRenderBlock()) + return false; + // Run-in child shouldn't intrude into the sibling block if it is part of a + // continuation chain. In that case, treat it as a normal block. + if (child->isElementContinuation() || child->virtualContinuation()) return false; RenderBlock* blockRunIn = toRenderBlock(child); @@ -2024,6 +2121,8 @@ LayoutUnit RenderBlock::computeStartPositionDeltaForChildAvoidingFloats(const Re void RenderBlock::determineLogicalLeftPositionForChild(RenderBox* child) { LayoutUnit startPosition = borderStart() + paddingStart(); + if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) + startPosition -= verticalScrollbarWidth(); LayoutUnit totalAvailableLogicalWidth = borderAndPaddingLogicalWidth() + availableLogicalWidth(); // Add in our start margin. @@ -2352,7 +2451,7 @@ bool RenderBlock::simplifiedLayout() if ((!posChildNeedsLayout() && !needsSimplifiedNormalFlowLayout()) || normalChildNeedsLayout() || selfNeedsLayout()) return false; - LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode()); + LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode()); if (needsPositionedMovementLayout() && !tryLayoutDoingPositionedMovementOnly()) return false; @@ -2545,7 +2644,7 @@ void RenderBlock::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with // z-index. We paint after we painted the background/border, so that the scrollbars will // sit above the background/border. - if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground) && paintInfo.shouldPaintWithinRoot(this)) + if (hasOverflowClipWithLayer() && style()->visibility() == VISIBLE && (phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground) && paintInfo.shouldPaintWithinRoot(this)) layer()->paintOverflowControls(paintInfo.context, roundedIntPoint(adjustedPaintOffset), paintInfo.rect); } @@ -3841,6 +3940,36 @@ LayoutUnit RenderBlock::logicalLeftOffsetForLine(LayoutUnit logicalTop, LayoutUn if (applyTextIndent && style()->isLeftToRightDirection()) left += textIndentOffset(); + if (style()->lineAlign() == LineAlignNone) + return left; + + // Push in our left offset so that it is aligned with the character grid. + LayoutState* layoutState = view()->layoutState(); + if (!layoutState) + return left; + + RenderBlock* lineGrid = layoutState->lineGrid(); + if (!lineGrid || lineGrid->style()->writingMode() != style()->writingMode()) + return left; + + // FIXME: Should letter-spacing apply? This is complicated since it doesn't apply at the edge? + float maxCharWidth = lineGrid->style()->font().primaryFont()->maxCharWidth(); + if (!maxCharWidth) + return left; + + LayoutUnit lineGridOffset = lineGrid->isHorizontalWritingMode() ? layoutState->lineGridOffset().width(): layoutState->lineGridOffset().height(); + LayoutUnit layoutOffset = lineGrid->isHorizontalWritingMode() ? layoutState->layoutOffset().width() : layoutState->layoutOffset().height(); + + // Push in to the nearest character width (truncated so that we pixel snap left). + // FIXME: Should be patched when subpixel layout lands, since this calculation doesn't have to pixel snap + // any more (https://bugs.webkit.org/show_bug.cgi?id=79946). + // FIXME: This is wrong for RTL (https://bugs.webkit.org/show_bug.cgi?id=79945). + // FIXME: This doesn't work with columns or regions (https://bugs.webkit.org/show_bug.cgi?id=79942). + // FIXME: This doesn't work when the inline position of the object isn't set ahead of time. + // FIXME: Dynamic changes to the font or to the inline position need to result in a deep relayout. + // (https://bugs.webkit.org/show_bug.cgi?id=79944) + float remainder = fmodf(maxCharWidth - fmodf(left + layoutOffset - lineGridOffset, maxCharWidth), maxCharWidth); + left += remainder; return left; } @@ -3860,6 +3989,36 @@ LayoutUnit RenderBlock::logicalRightOffsetForLine(LayoutUnit logicalTop, LayoutU if (applyTextIndent && !style()->isLeftToRightDirection()) right -= textIndentOffset(); + if (style()->lineAlign() == LineAlignNone) + return right; + + // Push in our right offset so that it is aligned with the character grid. + LayoutState* layoutState = view()->layoutState(); + if (!layoutState) + return right; + + RenderBlock* lineGrid = layoutState->lineGrid(); + if (!lineGrid || lineGrid->style()->writingMode() != style()->writingMode()) + return right; + + // FIXME: Should letter-spacing apply? This is complicated since it doesn't apply at the edge? + float maxCharWidth = lineGrid->style()->font().primaryFont()->maxCharWidth(); + if (!maxCharWidth) + return right; + + LayoutUnit lineGridOffset = lineGrid->isHorizontalWritingMode() ? layoutState->lineGridOffset().width(): layoutState->lineGridOffset().height(); + LayoutUnit layoutOffset = lineGrid->isHorizontalWritingMode() ? layoutState->layoutOffset().width() : layoutState->layoutOffset().height(); + + // Push in to the nearest character width (truncated so that we pixel snap right). + // FIXME: Should be patched when subpixel layout lands, since this calculation doesn't have to pixel snap + // any more (https://bugs.webkit.org/show_bug.cgi?id=79946). + // FIXME: This is wrong for RTL (https://bugs.webkit.org/show_bug.cgi?id=79945). + // FIXME: This doesn't work with columns or regions (https://bugs.webkit.org/show_bug.cgi?id=79942). + // FIXME: This doesn't work when the inline position of the object isn't set ahead of time. + // FIXME: Dynamic changes to the font or to the inline position need to result in a deep relayout. + // (https://bugs.webkit.org/show_bug.cgi?id=79944) + float remainder = fmodf(fmodf(right + layoutOffset - lineGridOffset, maxCharWidth), maxCharWidth); + right -= ceilf(remainder); return right; } @@ -4315,7 +4474,7 @@ LayoutUnit RenderBlock::getClearDelta(RenderBox* child, LayoutUnit logicalTop) bool RenderBlock::isPointInOverflowControl(HitTestResult& result, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset) { - if (!scrollsOverflow()) + if (!scrollsOverflow() || !hasLayer()) return false; return layer()->hitTestOverflowControls(result, pointInContainer - toLayoutSize(accumulatedOffset)); @@ -4619,12 +4778,17 @@ VisiblePosition RenderBlock::positionForPointWithInlineChildren(const LayoutPoin if (closestBox) { if (moveCaretToBoundary && pointInLogicalContents.y() < firstRootBoxWithChildren->selectionTop() && pointInLogicalContents.y() < firstRootBoxWithChildren->logicalTop()) { + InlineBox* box = firstRootBoxWithChildren->firstLeafChild(); + if (box->isLineBreak()) { + if (InlineBox* newBox = box->nextLeafChildIgnoringLineBreak()) + box = newBox; + } // y coordinate is above first root line box, so return the start of the first - return VisiblePosition(positionForBox(firstRootBoxWithChildren->firstLeafChild(), true), DOWNSTREAM); + return VisiblePosition(positionForBox(box, true), DOWNSTREAM); } // pass the box a top position that is inside it - LayoutPoint point(pointInLogicalContents.x(), closestBox->logicalTop()); + LayoutPoint point(pointInLogicalContents.x(), max(closestBox->root()->lineTop(), closestBox->root()->selectionTop())); if (!isHorizontalWritingMode()) point = point.transposedPoint(); if (closestBox->renderer()->isReplaced()) @@ -5810,23 +5974,12 @@ static inline bool shouldSkipForFirstLetter(UChar c) return isSpaceOrNewline(c) || c == noBreakSpace || isPunctuationForFirstLetter(c); } -// We only honor first-letter if -// - the firstLetterBlock can have children in the DOM and -// - the block doesn't have any special assumption on its text children. -// This correctly prevents form controls from honoring first-letter. -static inline bool isSafeToCreateFirstLetterRendererOn(RenderObject* renderer) -{ - return (renderer->canHaveChildren() - && !(renderer->isDeprecatedFlexibleBox() - && static_cast<RenderDeprecatedFlexibleBox*>(renderer)->buttonText())); -} - static inline RenderObject* findFirstLetterBlock(RenderBlock* start) { RenderObject* firstLetterBlock = start; while (true) { bool canHaveFirstLetterRenderer = firstLetterBlock->style()->hasPseudoStyle(FIRST_LETTER) - && isSafeToCreateFirstLetterRendererOn(firstLetterBlock); + && canHaveGeneratedChildren(firstLetterBlock); if (canHaveFirstLetterRenderer) return firstLetterBlock; @@ -5839,7 +5992,7 @@ static inline RenderObject* findFirstLetterBlock(RenderBlock* start) return 0; } - + void RenderBlock::updateFirstLetter() { if (!document()->usesFirstLetterRules()) @@ -5869,7 +6022,7 @@ void RenderBlock::updateFirstLetter() currChild = currChild->nextSibling(); } else if (currChild->isReplaced() || currChild->isRenderButton() || currChild->isMenuList()) break; - else if (currChild->style()->hasPseudoStyle(FIRST_LETTER) && currChild->canHaveChildren()) { + else if (currChild->style()->hasPseudoStyle(FIRST_LETTER) && canHaveGeneratedChildren(currChild)) { // We found a lower-level node with first-letter, which supersedes the higher-level style firstLetterBlock = currChild; currChild = currChild->firstChild(); @@ -6222,7 +6375,7 @@ void RenderBlock::setPageLogicalOffset(int logicalOffset) m_rareData->m_pageLogicalOffset = logicalOffset; } -void RenderBlock::absoluteRects(Vector<LayoutRect>& rects, const LayoutPoint& accumulatedOffset) const +void RenderBlock::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const { // For blocks inside inlines, we go ahead and include margins so that we run right up to the // inline boxes above and below us (thus getting merged with them to form a single irregular @@ -6230,12 +6383,12 @@ void RenderBlock::absoluteRects(Vector<LayoutRect>& rects, const LayoutPoint& ac if (isAnonymousBlockContinuation()) { // FIXME: This is wrong for block-flows that are horizontal. // https://bugs.webkit.org/show_bug.cgi?id=46781 - rects.append(LayoutRect(accumulatedOffset.x(), accumulatedOffset.y() - collapsedMarginBefore(), + rects.append(pixelSnappedIntRect(accumulatedOffset.x(), accumulatedOffset.y() - collapsedMarginBefore(), width(), height() + collapsedMarginBefore() + collapsedMarginAfter())); continuation()->absoluteRects(rects, accumulatedOffset - toLayoutSize(location() + inlineElementContinuation()->containingBlock()->location())); } else - rects.append(LayoutRect(accumulatedOffset, size())); + rects.append(pixelSnappedIntRect(accumulatedOffset, size())); } void RenderBlock::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const @@ -6393,7 +6546,7 @@ LayoutRect RenderBlock::localCaretRect(InlineBox* inlineBox, int caretOffset, La return LayoutRect(x, y, caretWidth, height); } -void RenderBlock::addFocusRingRects(Vector<LayoutRect>& rects, const LayoutPoint& additionalOffset) +void RenderBlock::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& additionalOffset) { // For blocks inside inlines, we go ahead and include margins so that we run right up to the // inline boxes above and below us (thus getting merged with them to form a single irregular @@ -6409,17 +6562,17 @@ void RenderBlock::addFocusRingRects(Vector<LayoutRect>& rects, const LayoutPoint float bottomMargin = nextInlineHasLineBox ? collapsedMarginAfter() : static_cast<LayoutUnit>(0); LayoutRect rect(additionalOffset.x(), additionalOffset.y() - topMargin, width(), height() + topMargin + bottomMargin); if (!rect.isEmpty()) - rects.append(rect); + rects.append(pixelSnappedIntRect(rect)); } else if (width() && height()) - rects.append(LayoutRect(additionalOffset, size())); + rects.append(pixelSnappedIntRect(additionalOffset, size())); if (!hasOverflowClip() && !hasControlClip()) { for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) { - LayoutUnit top = max(curr->lineTop(), static_cast<LayoutUnit>(curr->top())); - LayoutUnit bottom = min(curr->lineBottom(), static_cast<LayoutUnit>(curr->top() + curr->height())); + LayoutUnit top = max<LayoutUnit>(curr->lineTop(), curr->top()); + LayoutUnit bottom = min<LayoutUnit>(curr->lineBottom(), curr->top() + curr->height()); LayoutRect rect(additionalOffset.x() + curr->x(), additionalOffset.y() + top, curr->width(), bottom - top); if (!rect.isEmpty()) - rects.append(rect); + rects.append(pixelSnappedIntRect(rect)); } for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) { @@ -6582,7 +6735,7 @@ LayoutUnit RenderBlock::pageLogicalTopForOffset(LayoutUnit offset) const LayoutUnit pageLogicalHeight = renderView->layoutState()->pageLogicalHeight(); if (!pageLogicalHeight) return 0; - return cumulativeOffset - (cumulativeOffset - firstPageLogicalTop) % pageLogicalHeight; + return cumulativeOffset - roundToInt(cumulativeOffset - firstPageLogicalTop) % roundToInt(pageLogicalHeight); } return enclosingRenderFlowThread()->regionLogicalTopForLine(cumulativeOffset); } @@ -7203,7 +7356,7 @@ TextRun RenderBlock::constructTextRun(RenderObject* context, const Font& font, c if (flags & RespectDirection) textDirection = style->direction(); if (flags & RespectDirectionOverride) - directionalOverride |= style->unicodeBidi() == Override; + directionalOverride |= isOverride(style->unicodeBidi()); } TextRun run(characters, length, false, 0, 0, expansion, textDirection, directionalOverride); |
