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()) {