Title: [114784] trunk
Revision
114784
Author
[email protected]
Date
2012-04-20 14:40:26 -0700 (Fri, 20 Apr 2012)

Log Message

Source/WebCore: <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().

LayoutTests: 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.

Modified Paths

Added Paths

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&);
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to