Title: [176262] trunk
Revision
176262
Author
[email protected]
Date
2014-11-18 09:54:52 -0800 (Tue, 18 Nov 2014)

Log Message

Improve Ruby selection (getting rid of overlap and improving gap filling)
https://bugs.webkit.org/show_bug.cgi?id=138250

Reviewed by Dean Jackson.

Source/WebCore:

* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::selectionGaps):
(WebCore::RenderBlock::blockSelectionGaps):
Add Ruby text in along with the Ruby base.

* rendering/RenderBlockFlow.cpp:
(WebCore::RenderBlockFlow::inlineSelectionGaps):
Don't let block gaps get filled in here.

* rendering/RenderRubyBase.h:
Expose accessor to the ruby run.

* rendering/RenderRubyText.cpp:
(WebCore::RenderRubyText::rubyRun):
* rendering/RenderRubyText.h:
Add accessor to the ruby run.

* rendering/RootInlineBox.cpp:
(WebCore::RootInlineBox::selectionTop):
(WebCore::RootInlineBox::selectionBottom):
Improve selectionTop and selectionBottom of ruby bases to avoid the
ruby text. Improve the selectionTop and selectionBottom of ruby texts
to fill the gap up to the previous/next line as appropriate.

LayoutTests:

Added fast/repaint/selection-ruby-rl.html

* fast/repaint/selection-ruby-rl-expected.txt: Added.
* fast/repaint/selection-ruby-rl.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (176261 => 176262)


--- trunk/LayoutTests/ChangeLog	2014-11-18 17:45:00 UTC (rev 176261)
+++ trunk/LayoutTests/ChangeLog	2014-11-18 17:54:52 UTC (rev 176262)
@@ -1,3 +1,15 @@
+2014-11-17  David Hyatt  <[email protected]>
+
+        Improve Ruby selection (getting rid of overlap and improving gap filling)
+        https://bugs.webkit.org/show_bug.cgi?id=138250
+
+        Reviewed by Dean Jackson.
+
+        Added fast/repaint/selection-ruby-rl.html
+
+        * fast/repaint/selection-ruby-rl-expected.txt: Added.
+        * fast/repaint/selection-ruby-rl.html: Added.
+
 2014-11-18  Commit Queue  <[email protected]>
 
         Unreviewed, rolling out r176218.

Added: trunk/LayoutTests/fast/repaint/selection-ruby-rl-expected.txt (0 => 176262)


--- trunk/LayoutTests/fast/repaint/selection-ruby-rl-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/repaint/selection-ruby-rl-expected.txt	2014-11-18 17:54:52 UTC (rev 176262)
@@ -0,0 +1,14 @@
+Testing both hit testing and painting of selection.
+Testing both hit testing and painting of selection.
+Testing both hit testing and painting of selection.Some ruby
+Testing both hit testing and painting of selection.
+Testing both hit testing and painting of selection.
+Testing both hit testing and painting of selection.
+Testing both hit testing and painting of selection.
+Testing both hit testing and painting of selection.
+Testing both hit testing and painting of selection.
+Testing both hit testing and painting of selection.
+(repaint rects
+  (rect 774 39 18 83)
+)
+

Added: trunk/LayoutTests/fast/repaint/selection-ruby-rl.html (0 => 176262)


--- trunk/LayoutTests/fast/repaint/selection-ruby-rl.html	                        (rev 0)
+++ trunk/LayoutTests/fast/repaint/selection-ruby-rl.html	2014-11-18 17:54:52 UTC (rev 176262)
@@ -0,0 +1,29 @@
+<!doctype html>
+<html>
+<head>
+<script src=""
+<script>
+function repaintTest() {
+    if (eventSender) {
+        eventSender.mouseMoveTo(790, 40);
+        eventSender.mouseDown();
+        eventSender.mouseMoveTo(790, 40);
+        eventSender.mouseMoveTo(790, 120);
+        eventSender.mouseUp();
+    }
+}
+</script>
+
+</head>
+<body style="-webkit-writing-mode:vertical-rl" _onload_="runRepaintTest()">
+<span>Testing both hit testing</span> and painting of selection.<br>
+Testing both hit testing and painting of selection.<br>
+<ruby>Testing both hit testing and painting of selection.<rt>Some ruby</rt></ruby><br>
+Testing both hit testing and painting of selection.<br>
+Testing both hit testing and painting of selection.<br>
+Testing both hit testing and painting of selection.<br>
+Testing both hit testing and painting of selection.<br>
+Testing both hit testing and painting of selection.<br>
+Testing both hit testing and painting of selection.<br>
+Testing both hit testing and painting of selection.<br>
+</body>

Modified: trunk/Source/WebCore/ChangeLog (176261 => 176262)


--- trunk/Source/WebCore/ChangeLog	2014-11-18 17:45:00 UTC (rev 176261)
+++ trunk/Source/WebCore/ChangeLog	2014-11-18 17:54:52 UTC (rev 176262)
@@ -1,3 +1,34 @@
+2014-11-17  David Hyatt  <[email protected]>
+
+        Improve Ruby selection (getting rid of overlap and improving gap filling)
+        https://bugs.webkit.org/show_bug.cgi?id=138250
+
+        Reviewed by Dean Jackson.
+
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::selectionGaps):
+        (WebCore::RenderBlock::blockSelectionGaps):
+        Add Ruby text in along with the Ruby base.
+
+        * rendering/RenderBlockFlow.cpp:
+        (WebCore::RenderBlockFlow::inlineSelectionGaps):
+        Don't let block gaps get filled in here.
+
+        * rendering/RenderRubyBase.h:
+        Expose accessor to the ruby run.
+
+        * rendering/RenderRubyText.cpp:
+        (WebCore::RenderRubyText::rubyRun):
+        * rendering/RenderRubyText.h:
+        Add accessor to the ruby run.
+
+        * rendering/RootInlineBox.cpp:
+        (WebCore::RootInlineBox::selectionTop):
+        (WebCore::RootInlineBox::selectionBottom):
+        Improve selectionTop and selectionBottom of ruby bases to avoid the
+        ruby text. Improve the selectionTop and selectionBottom of ruby texts
+        to fill the gap up to the previous/next line as appropriate.
+
 2014-11-18  Shivakumar JM  <[email protected]>
 
         crypto: Use sequence<> instead of KeyUsage[] in IDL.

Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (176261 => 176262)


--- trunk/Source/WebCore/rendering/RenderBlock.cpp	2014-11-18 17:45:00 UTC (rev 176261)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp	2014-11-18 17:54:52 UTC (rev 176262)
@@ -1882,7 +1882,7 @@
         result = blockSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, cache, paintInfo);
 
     // Go ahead and fill the vertical gap all the way to the bottom of our block if the selection extends past our block.
-    if (&rootBlock == this && (selectionState() != SelectionBoth && selectionState() != SelectionEnd) && !isRubyBase()) {
+    if (&rootBlock == this && (selectionState() != SelectionBoth && selectionState() != SelectionEnd) && !isRubyBase() && !isRubyText()) {
         result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock,
             lastLogicalTop, lastLogicalLeft, lastLogicalRight, logicalHeight(), cache, paintInfo));
     }
@@ -1927,7 +1927,7 @@
         }
 
         bool paintsOwnSelection = curr->shouldPaintSelectionGaps() || curr->isTable(); // FIXME: Eventually we won't special-case table like this.
-        bool fillBlockGaps = !isRubyBase() && (paintsOwnSelection || (curr->canBeSelectionLeaf() && childState != SelectionNone));
+        bool fillBlockGaps = (paintsOwnSelection || (curr->canBeSelectionLeaf() && childState != SelectionNone)) && !isRubyBase() && !isRubyText();
         if (fillBlockGaps) {
             // We need to fill the vertical gap above this object.
             if (childState == SelectionEnd || childState == SelectionInside) {

Modified: trunk/Source/WebCore/rendering/RenderBlockFlow.cpp (176261 => 176262)


--- trunk/Source/WebCore/rendering/RenderBlockFlow.cpp	2014-11-18 17:45:00 UTC (rev 176261)
+++ trunk/Source/WebCore/rendering/RenderBlockFlow.cpp	2014-11-18 17:54:52 UTC (rev 176262)
@@ -3012,7 +3012,7 @@
         LayoutUnit selHeight = curr->selectionHeightAdjustedForPrecedingBlock();
 
         if (!containsStart && !lastSelectedLine &&
-            selectionState() != SelectionStart && selectionState() != SelectionBoth)
+            selectionState() != SelectionStart && selectionState() != SelectionBoth && !isRubyBase())
             result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, selTop, cache, paintInfo));
         
         LayoutRect logicalRect(curr->logicalLeft(), selTop, curr->logicalWidth(), selTop + selHeight);

Modified: trunk/Source/WebCore/rendering/RenderRubyBase.h (176261 => 176262)


--- trunk/Source/WebCore/rendering/RenderRubyBase.h	2014-11-18 17:45:00 UTC (rev 176261)
+++ trunk/Source/WebCore/rendering/RenderRubyBase.h	2014-11-18 17:54:52 UTC (rev 176262)
@@ -43,6 +43,8 @@
     virtual ~RenderRubyBase();
     
     virtual const char* renderName() const override { return "RenderRubyBase (anonymous)"; }
+    
+    RenderRubyRun* rubyRun() const;
 
 private:
     virtual bool isRubyBase() const override { return true; }
@@ -55,12 +57,12 @@
     void moveInlineChildren(RenderRubyBase* toBase, RenderObject* beforeChild = 0);
     void moveBlockChildren(RenderRubyBase* toBase, RenderObject* beforeChild = 0);
 
-    RenderRubyRun* rubyRun() const;
-
     // Allow RenderRubyRun to manipulate the children within ruby bases.
     friend class RenderRubyRun;
 };
 
 } // namespace WebCore
 
+SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderRubyBase, isRubyBase())
+
 #endif // RenderRubyBase_h

Modified: trunk/Source/WebCore/rendering/RenderRubyText.cpp (176261 => 176262)


--- trunk/Source/WebCore/rendering/RenderRubyText.cpp	2014-11-18 17:45:00 UTC (rev 176261)
+++ trunk/Source/WebCore/rendering/RenderRubyText.cpp	2014-11-18 17:54:52 UTC (rev 176262)
@@ -32,6 +32,7 @@
 #include "config.h"
 
 #include "RenderRubyText.h"
+#include "RenderRubyRun.h"
 
 namespace WebCore {
 
@@ -44,6 +45,12 @@
 {
 }
 
+RenderRubyRun* RenderRubyText::rubyRun() const
+{
+    ASSERT(parent());
+    return downcast<RenderRubyRun>(parent());
+}
+
 bool RenderRubyText::isChildAllowed(const RenderObject& child, const RenderStyle&) const
 {
     return child.isInline();

Modified: trunk/Source/WebCore/rendering/RenderRubyText.h (176261 => 176262)


--- trunk/Source/WebCore/rendering/RenderRubyText.h	2014-11-18 17:45:00 UTC (rev 176261)
+++ trunk/Source/WebCore/rendering/RenderRubyText.h	2014-11-18 17:54:52 UTC (rev 176262)
@@ -43,6 +43,8 @@
     Element& element() const { return downcast<Element>(nodeForNonAnonymous()); }
 
     virtual bool isChildAllowed(const RenderObject&, const RenderStyle&) const override;
+    
+    RenderRubyRun* rubyRun() const;
 
 private:
     virtual const char* renderName() const override { return "RenderRubyText"; }
@@ -56,4 +58,6 @@
 
 } // namespace WebCore
 
+SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderRubyText, isRubyText())
+
 #endif // RenderRubyText_h

Modified: trunk/Source/WebCore/rendering/RootInlineBox.cpp (176261 => 176262)


--- trunk/Source/WebCore/rendering/RootInlineBox.cpp	2014-11-18 17:45:00 UTC (rev 176261)
+++ trunk/Source/WebCore/rendering/RootInlineBox.cpp	2014-11-18 17:54:52 UTC (rev 176262)
@@ -34,6 +34,9 @@
 #include "PaintInfo.h"
 #include "RenderFlowThread.h"
 #include "RenderInline.h"
+#include "RenderRubyBase.h"
+#include "RenderRubyRun.h"
+#include "RenderRubyText.h"
 #include "RenderView.h"
 #include "VerticalPositionCache.h"
 #include <wtf/NeverDestroyed.h>
@@ -594,13 +597,41 @@
 LayoutUnit RootInlineBox::selectionTop() const
 {
     LayoutUnit selectionTop = m_lineTop;
-
+    
     if (m_hasAnnotationsBefore)
         selectionTop -= !renderer().style().isFlippedLinesWritingMode() ? computeOverAnnotationAdjustment(m_lineTop) : computeUnderAnnotationAdjustment(m_lineTop);
 
     if (renderer().style().isFlippedLinesWritingMode())
         return selectionTop;
 
+    if (renderer().isRubyBase()) {
+        // The ruby base selection should avoid intruding into the ruby text. This is only the case if there is an actual ruby text above us.
+        RenderRubyBase* base = &downcast<RenderRubyBase>(renderer());
+        RenderRubyRun* run = base->rubyRun();
+        if (run) {
+            RenderRubyText* text = run->rubyText();
+            if (text && text->logicalTop() < base->logicalTop()) {
+                // The ruby text is above the ruby base. Just return now in order to avoid painting on top of the ruby text.
+                return selectionTop;
+            }
+        }
+    } else if (renderer().isRubyText()) {
+        // The ruby text selection should go all the way to the selection top of the containing line.
+        RenderRubyText* text = &downcast<RenderRubyText>(renderer());
+        RenderRubyRun* run = text->rubyRun();
+        if (run && run->inlineBoxWrapper()) {
+            RenderRubyBase* base = run->rubyBase();
+            if (base && text->logicalTop() < base->logicalTop()) {
+                // The ruby text is above the ruby base.
+                const RootInlineBox& containingLine = run->inlineBoxWrapper()->root();
+                LayoutUnit enclosingSelectionTop = containingLine.selectionTop();
+                LayoutUnit deltaBetweenObjects = text->logicalTop() + run->logicalTop();
+                LayoutUnit selectionTopInRubyTextCoords = enclosingSelectionTop - deltaBetweenObjects;
+                return std::min(selectionTop, selectionTopInRubyTextCoords);
+            }
+        }
+    }
+
     LayoutUnit prevBottom = prevRootBox() ? prevRootBox()->selectionBottom() : blockFlow().borderAndPaddingBefore();
     if (prevBottom < selectionTop && blockFlow().containsFloats()) {
         // This line has actually been moved further down, probably from a large line-height, but possibly because the
@@ -649,9 +680,37 @@
 
     if (m_hasAnnotationsAfter)
         selectionBottom += !renderer().style().isFlippedLinesWritingMode() ? computeUnderAnnotationAdjustment(m_lineBottom) : computeOverAnnotationAdjustment(m_lineBottom);
-
+    
     if (!renderer().style().isFlippedLinesWritingMode() || !nextRootBox())
         return selectionBottom;
+    
+    if (renderer().isRubyBase()) {
+        // The ruby base selection should avoid intruding into the ruby text. This is only the case if there is an actual ruby text below us.
+        RenderRubyBase* base = &downcast<RenderRubyBase>(renderer());
+        RenderRubyRun* run = base->rubyRun();
+        if (run) {
+            RenderRubyText* text = run->rubyText();
+            if (text && text->logicalTop() > base->logicalTop()) {
+                // The ruby text is below the ruby base. Just return now in order to avoid painting on top of the ruby text.
+                return selectionBottom;
+            }
+        }
+    } else if (renderer().isRubyText()) {
+        // The ruby text selection should go all the way to the selection bottom of the containing line.
+        RenderRubyText* text = &downcast<RenderRubyText>(renderer());
+        RenderRubyRun* run = text->rubyRun();
+        if (run && run->inlineBoxWrapper()) {
+            RenderRubyBase* base = run->rubyBase();
+            if (base && text->logicalTop() > base->logicalTop()) {
+                // The ruby text is above the ruby base.
+                const RootInlineBox& containingLine = run->inlineBoxWrapper()->root();
+                LayoutUnit enclosingSelectionBottom = containingLine.selectionBottom();
+                LayoutUnit deltaBetweenObjects = text->logicalTop() + run->logicalTop();
+                LayoutUnit selectionBottomInRubyTextCoords = enclosingSelectionBottom - deltaBetweenObjects;
+                return std::min(selectionBottom, selectionBottomInRubyTextCoords);
+            }
+        }
+    }
 
     LayoutUnit nextTop = nextRootBox()->selectionTop();
     if (nextTop > selectionBottom && blockFlow().containsFloats()) {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to