Diff
Modified: trunk/LayoutTests/ChangeLog (114783 => 114784)
--- trunk/LayoutTests/ChangeLog 2012-04-20 21:37:03 UTC (rev 114783)
+++ trunk/LayoutTests/ChangeLog 2012-04-20 21:40:26 UTC (rev 114784)
@@ -1,3 +1,13 @@
+2012-04-20 Dan Bernstein <[email protected]>
+
+ Selection highlights of lines in adjoining blocks can overlap
+ https://bugs.webkit.org/show_bug.cgi?id=84489
+
+ Reviewed by Anders Carlsson.
+
+ * fast/block/line-layout/selection-highlight-overlap-expected.html: Added.
+ * fast/block/line-layout/selection-highlight-overlap.html: Added.
+
2012-04-20 Dmitry Titov <[email protected]>
Rebaselining svg/css/getComputedStyle-basic.html after
Added: trunk/LayoutTests/fast/block/line-layout/selection-highlight-overlap-expected.html (0 => 114784)
--- trunk/LayoutTests/fast/block/line-layout/selection-highlight-overlap-expected.html (rev 0)
+++ trunk/LayoutTests/fast/block/line-layout/selection-highlight-overlap-expected.html 2012-04-20 21:40:26 UTC (rev 114784)
@@ -0,0 +1,16 @@
+<style>
+ body { font-size: 64px; font-family: ahem; color: transparent; }
+ div { outline: 1px dashed green; }
+ div > div { outline: initial; background-color: rgba(0, 0, 255, .4); }
+</style>
+<div>
+ <div style="height: 30px; margin-left: 128px;"></div>
+</div>
+<div>
+ <div style="height: 17px; margin-left: 128px;"></div>
+ <div style="height: 47px;"></div>
+</div>
+<div style="margin-top: -10px; height: 64px;">
+ <div style="height: 10px; background-color: transparent;"></div>
+ <div style="height: 54px; width: 256px;"></div>
+</div>
Added: trunk/LayoutTests/fast/block/line-layout/selection-highlight-overlap.html (0 => 114784)
--- trunk/LayoutTests/fast/block/line-layout/selection-highlight-overlap.html (rev 0)
+++ trunk/LayoutTests/fast/block/line-layout/selection-highlight-overlap.html 2012-04-20 21:40:26 UTC (rev 114784)
@@ -0,0 +1,11 @@
+<style>
+ body { font-size: 64px; font-family: ahem; color: transparent; }
+ div { outline: 1px dashed green; }
+ div::selection { background-color: rgba(0, 0, 255, .4); }
+</style>
+<div id="start" style="line-height: 30px;">queue theory</div>
+<div>problem</div>
+<div id="end" style="margin-top: -10px;">information</div>
+<script>
+ getSelection().setBaseAndExtent(document.getElementById("start").firstChild, 2, document.getElementById("end").firstChild, 4);
+</script>
Modified: trunk/Source/WebCore/ChangeLog (114783 => 114784)
--- trunk/Source/WebCore/ChangeLog 2012-04-20 21:37:03 UTC (rev 114783)
+++ trunk/Source/WebCore/ChangeLog 2012-04-20 21:40:26 UTC (rev 114784)
@@ -1,3 +1,31 @@
+2012-04-20 Dan Bernstein <[email protected]>
+
+ <rdar://problem/10786000> Selection highlights of lines in adjoining blocks can overlap
+ https://bugs.webkit.org/show_bug.cgi?id=84489
+
+ Reviewed by Anders Carlsson.
+
+ Test: fast/block/line-layout/selection-highlight-overlap.html
+
+ * rendering/EllipsisBox.cpp:
+ (WebCore::EllipsisBox::selectionRect): Changed to use
+ selection{Top,Height}AdjustedForPrecedingBlock().
+ * rendering/InlineTextBox.cpp:
+ (WebCore::InlineTextBox::paintSelection): Ditto.
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::inlineSelectionGaps): Ditto.
+ (WebCore::RenderBlock::blockBeforeWithinSelectionRoot): Added. Returns the block which is
+ likely to contain the selected line just before the first line in this block, if it is
+ within the same selection root.
+ * rendering/RenderBlock.h:
+ * rendering/RootInlineBox.cpp:
+ (WebCore::RootInlineBox::selectionTopAdjustedForPrecedingBlock): Added. If the selection
+ starts before our block, finds the last line in the preceding block and adjusts the selection
+ top to avoid overlap with that line’s selection bottom.
+ * rendering/RootInlineBox.h:
+ (WebCore::RootInlineBox::selectionHeightAdjustedForPrecedingBlock): Added. Like
+ selectionHeight(), but uses selectionTopAdjustedForPrecedingBlock().
+
2012-04-20 Xianzhu Wang <[email protected]>
Crash in getOrDrawNodeHighlight after r114659
Modified: trunk/Source/WebCore/rendering/EllipsisBox.cpp (114783 => 114784)
--- trunk/Source/WebCore/rendering/EllipsisBox.cpp 2012-04-20 21:37:03 UTC (rev 114783)
+++ trunk/Source/WebCore/rendering/EllipsisBox.cpp 2012-04-20 21:40:26 UTC (rev 114784)
@@ -78,7 +78,7 @@
RenderStyle* style = m_renderer->style(isFirstLineStyle());
const Font& font = style->font();
// FIXME: Why is this always LTR? Fix by passing correct text run flags below.
- return enclosingIntRect(font.selectionRectForText(RenderBlock::constructTextRun(renderer(), font, m_str, style, TextRun::AllowTrailingExpansion), IntPoint(x(), y() + root()->selectionTop()), root()->selectionHeight()));
+ return enclosingIntRect(font.selectionRectForText(RenderBlock::constructTextRun(renderer(), font, m_str, style, TextRun::AllowTrailingExpansion), IntPoint(x(), y() + root()->selectionTopAdjustedForPrecedingBlock()), root()->selectionHeightAdjustedForPrecedingBlock()));
}
void EllipsisBox::paintSelection(GraphicsContext* context, const LayoutPoint& paintOffset, RenderStyle* style, const Font& font)
Modified: trunk/Source/WebCore/rendering/InlineTextBox.cpp (114783 => 114784)
--- trunk/Source/WebCore/rendering/InlineTextBox.cpp 2012-04-20 21:37:03 UTC (rev 114783)
+++ trunk/Source/WebCore/rendering/InlineTextBox.cpp 2012-04-20 21:40:26 UTC (rev 114784)
@@ -841,8 +841,12 @@
if (respectHyphen)
ePos = textRun.length();
- int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
- int selHeight = selectionHeight();
+ LayoutUnit selectionBottom = root()->selectionBottom();
+ LayoutUnit selectionTop = root()->selectionTopAdjustedForPrecedingBlock();
+
+ int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom - logicalBottom() : logicalTop() - selectionTop;
+ int selHeight = max<LayoutUnit>(0, selectionBottom - selectionTop);
+
FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
FloatRect clipRect(localOrigin, FloatSize(m_logicalWidth, selHeight));
Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (114783 => 114784)
--- trunk/Source/WebCore/rendering/RenderBlock.cpp 2012-04-20 21:37:03 UTC (rev 114783)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp 2012-04-20 21:40:26 UTC (rev 114784)
@@ -3213,8 +3213,8 @@
// Now paint the gaps for the lines.
for (; curr && curr->hasSelectedChildren(); curr = curr->nextRootBox()) {
- LayoutUnit selTop = curr->selectionTop();
- LayoutUnit selHeight = curr->selectionHeight();
+ LayoutUnit selTop = curr->selectionTopAdjustedForPrecedingBlock();
+ LayoutUnit selHeight = curr->selectionHeightAdjustedForPrecedingBlock();
if (!containsStart && !lastSelectedLine &&
selectionState() != SelectionStart && selectionState() != SelectionBoth)
@@ -3406,6 +3406,36 @@
return logicalRight;
}
+RenderBlock* RenderBlock::blockBeforeWithinSelectionRoot(LayoutSize& offset) const
+{
+ if (isSelectionRoot())
+ return 0;
+
+ const RenderBox* object = this;
+ RenderBox* sibling;
+ do {
+ sibling = object->previousSiblingBox();
+ while (sibling && (!sibling->isRenderBlock() || toRenderBlock(sibling)->isSelectionRoot()))
+ sibling = sibling->previousSiblingBox();
+
+ offset -= LayoutSize(object->logicalLeft(), object->logicalTop());
+ object = object->parentBox();
+ } while (!sibling && object && object->isRenderBlock() && !toRenderBlock(object)->isSelectionRoot());
+
+ if (!sibling)
+ return 0;
+
+ offset += LayoutSize(sibling->logicalLeft(), sibling->logicalTop());
+
+ RenderObject* child = sibling->lastChild();
+ while (child && child->isRenderBlock()) {
+ sibling = toRenderBlock(child);
+ offset += LayoutSize(sibling->logicalLeft(), sibling->logicalTop());
+ child = sibling->lastChild();
+ }
+ return toRenderBlock(sibling);
+}
+
void RenderBlock::insertPositionedObject(RenderBox* o)
{
ASSERT(!isAnonymousBlock());
Modified: trunk/Source/WebCore/rendering/RenderBlock.h (114783 => 114784)
--- trunk/Source/WebCore/rendering/RenderBlock.h 2012-04-20 21:37:03 UTC (rev 114783)
+++ trunk/Source/WebCore/rendering/RenderBlock.h 2012-04-20 21:40:26 UTC (rev 114784)
@@ -210,6 +210,8 @@
LayoutRect logicalRightSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
RenderObject* selObj, LayoutUnit logicalRight, LayoutUnit logicalTop, LayoutUnit logicalHeight, const PaintInfo*);
void getSelectionGapInfo(SelectionState, bool& leftGap, bool& rightGap);
+ RenderBlock* blockBeforeWithinSelectionRoot(LayoutSize& offset) const;
+
LayoutRect logicalRectToPhysicalRect(const LayoutPoint& physicalPosition, const LayoutRect& logicalRect);
// Helper methods for computing line counts and heights for line counts.
@@ -801,7 +803,7 @@
LayoutUnit lastLogicalTop, LayoutUnit lastLogicalLeft, LayoutUnit lastLogicalRight, LayoutUnit logicalBottom, const PaintInfo*);
LayoutUnit logicalLeftSelectionOffset(RenderBlock* rootBlock, LayoutUnit position);
LayoutUnit logicalRightSelectionOffset(RenderBlock* rootBlock, LayoutUnit position);
-
+
virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const;
virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const;
Modified: trunk/Source/WebCore/rendering/RootInlineBox.cpp (114783 => 114784)
--- trunk/Source/WebCore/rendering/RootInlineBox.cpp 2012-04-20 21:37:03 UTC (rev 114783)
+++ trunk/Source/WebCore/rendering/RootInlineBox.cpp 2012-04-20 21:40:26 UTC (rev 114784)
@@ -545,6 +545,29 @@
return prevBottom;
}
+LayoutUnit RootInlineBox::selectionTopAdjustedForPrecedingBlock() const
+{
+ LayoutUnit top = selectionTop();
+
+ RenderObject::SelectionState blockSelectionState = root()->block()->selectionState();
+ if (blockSelectionState != RenderObject::SelectionInside && blockSelectionState != RenderObject::SelectionEnd)
+ return top;
+
+ LayoutSize offsetToBlockBefore;
+ if (RenderBlock* block = root()->block()->blockBeforeWithinSelectionRoot(offsetToBlockBefore)) {
+ if (RootInlineBox* lastLine = block->lastRootBox()) {
+ RenderObject::SelectionState lastLineSelectionState = lastLine->selectionState();
+ if (lastLineSelectionState != RenderObject::SelectionInside && lastLineSelectionState != RenderObject::SelectionStart)
+ return top;
+
+ LayoutUnit lastLineSelectionBottom = lastLine->selectionBottom() + offsetToBlockBefore.height();
+ top = max(top, lastLineSelectionBottom);
+ }
+ }
+
+ return top;
+}
+
LayoutUnit RootInlineBox::selectionBottom() const
{
LayoutUnit selectionBottom = m_lineBottom;
Modified: trunk/Source/WebCore/rendering/RootInlineBox.h (114783 => 114784)
--- trunk/Source/WebCore/rendering/RootInlineBox.h 2012-04-20 21:37:03 UTC (rev 114783)
+++ trunk/Source/WebCore/rendering/RootInlineBox.h 2012-04-20 21:40:26 UTC (rev 114784)
@@ -63,6 +63,9 @@
LayoutUnit selectionBottom() const;
LayoutUnit selectionHeight() const { return max<LayoutUnit>(0, selectionBottom() - selectionTop()); }
+ LayoutUnit selectionTopAdjustedForPrecedingBlock() const;
+ LayoutUnit selectionHeightAdjustedForPrecedingBlock() const { return max<LayoutUnit>(0, selectionBottom() - selectionTopAdjustedForPrecedingBlock()); }
+
int blockDirectionPointInLine() const { return max(lineTop(), selectionTop()); }
LayoutUnit alignBoxesInBlockDirection(LayoutUnit heightOfBlock, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&);