Changeset 176262 in webkit


Ignore:
Timestamp:
Nov 18, 2014 9:54:52 AM (9 years ago)
Author:
hyatt@apple.com
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.
Location:
trunk
Files:
2 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r176258 r176262  
     12014-11-17  David Hyatt  <hyatt@apple.com>
     2
     3        Improve Ruby selection (getting rid of overlap and improving gap filling)
     4        https://bugs.webkit.org/show_bug.cgi?id=138250
     5
     6        Reviewed by Dean Jackson.
     7
     8        Added fast/repaint/selection-ruby-rl.html
     9
     10        * fast/repaint/selection-ruby-rl-expected.txt: Added.
     11        * fast/repaint/selection-ruby-rl.html: Added.
     12
    1132014-11-18  Commit Queue  <commit-queue@webkit.org>
    214
  • trunk/Source/WebCore/ChangeLog

    r176261 r176262  
     12014-11-17  David Hyatt  <hyatt@apple.com>
     2
     3        Improve Ruby selection (getting rid of overlap and improving gap filling)
     4        https://bugs.webkit.org/show_bug.cgi?id=138250
     5
     6        Reviewed by Dean Jackson.
     7
     8        * rendering/RenderBlock.cpp:
     9        (WebCore::RenderBlock::selectionGaps):
     10        (WebCore::RenderBlock::blockSelectionGaps):
     11        Add Ruby text in along with the Ruby base.
     12
     13        * rendering/RenderBlockFlow.cpp:
     14        (WebCore::RenderBlockFlow::inlineSelectionGaps):
     15        Don't let block gaps get filled in here.
     16
     17        * rendering/RenderRubyBase.h:
     18        Expose accessor to the ruby run.
     19
     20        * rendering/RenderRubyText.cpp:
     21        (WebCore::RenderRubyText::rubyRun):
     22        * rendering/RenderRubyText.h:
     23        Add accessor to the ruby run.
     24
     25        * rendering/RootInlineBox.cpp:
     26        (WebCore::RootInlineBox::selectionTop):
     27        (WebCore::RootInlineBox::selectionBottom):
     28        Improve selectionTop and selectionBottom of ruby bases to avoid the
     29        ruby text. Improve the selectionTop and selectionBottom of ruby texts
     30        to fill the gap up to the previous/next line as appropriate.
     31
    1322014-11-18  Shivakumar JM  <shiva.jm@samsung.com>
    233
  • trunk/Source/WebCore/rendering/RenderBlock.cpp

    r175965 r176262  
    18831883
    18841884    // Go ahead and fill the vertical gap all the way to the bottom of our block if the selection extends past our block.
    1885     if (&rootBlock == this && (selectionState() != SelectionBoth && selectionState() != SelectionEnd) && !isRubyBase()) {
     1885    if (&rootBlock == this && (selectionState() != SelectionBoth && selectionState() != SelectionEnd) && !isRubyBase() && !isRubyText()) {
    18861886        result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock,
    18871887            lastLogicalTop, lastLogicalLeft, lastLogicalRight, logicalHeight(), cache, paintInfo));
     
    19281928
    19291929        bool paintsOwnSelection = curr->shouldPaintSelectionGaps() || curr->isTable(); // FIXME: Eventually we won't special-case table like this.
    1930         bool fillBlockGaps = !isRubyBase() && (paintsOwnSelection || (curr->canBeSelectionLeaf() && childState != SelectionNone));
     1930        bool fillBlockGaps = (paintsOwnSelection || (curr->canBeSelectionLeaf() && childState != SelectionNone)) && !isRubyBase() && !isRubyText();
    19311931        if (fillBlockGaps) {
    19321932            // We need to fill the vertical gap above this object.
  • trunk/Source/WebCore/rendering/RenderBlockFlow.cpp

    r175583 r176262  
    30133013
    30143014        if (!containsStart && !lastSelectedLine &&
    3015             selectionState() != SelectionStart && selectionState() != SelectionBoth)
     3015            selectionState() != SelectionStart && selectionState() != SelectionBoth && !isRubyBase())
    30163016            result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, selTop, cache, paintInfo));
    30173017       
  • trunk/Source/WebCore/rendering/RenderRubyBase.h

    r175084 r176262  
    4444   
    4545    virtual const char* renderName() const override { return "RenderRubyBase (anonymous)"; }
     46   
     47    RenderRubyRun* rubyRun() const;
    4648
    4749private:
     
    5658    void moveBlockChildren(RenderRubyBase* toBase, RenderObject* beforeChild = 0);
    5759
    58     RenderRubyRun* rubyRun() const;
    59 
    6060    // Allow RenderRubyRun to manipulate the children within ruby bases.
    6161    friend class RenderRubyRun;
     
    6464} // namespace WebCore
    6565
     66SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderRubyBase, isRubyBase())
     67
    6668#endif // RenderRubyBase_h
  • trunk/Source/WebCore/rendering/RenderRubyText.cpp

    r170774 r176262  
    3333
    3434#include "RenderRubyText.h"
     35#include "RenderRubyRun.h"
    3536
    3637namespace WebCore {
     
    4344RenderRubyText::~RenderRubyText()
    4445{
     46}
     47
     48RenderRubyRun* RenderRubyText::rubyRun() const
     49{
     50    ASSERT(parent());
     51    return downcast<RenderRubyRun>(parent());
    4552}
    4653
  • trunk/Source/WebCore/rendering/RenderRubyText.h

    r174117 r176262  
    4444
    4545    virtual bool isChildAllowed(const RenderObject&, const RenderStyle&) const override;
     46   
     47    RenderRubyRun* rubyRun() const;
    4648
    4749private:
     
    5759} // namespace WebCore
    5860
     61SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderRubyText, isRubyText())
     62
    5963#endif // RenderRubyText_h
  • trunk/Source/WebCore/rendering/RootInlineBox.cpp

    r174840 r176262  
    3535#include "RenderFlowThread.h"
    3636#include "RenderInline.h"
     37#include "RenderRubyBase.h"
     38#include "RenderRubyRun.h"
     39#include "RenderRubyText.h"
    3740#include "RenderView.h"
    3841#include "VerticalPositionCache.h"
     
    595598{
    596599    LayoutUnit selectionTop = m_lineTop;
    597 
     600   
    598601    if (m_hasAnnotationsBefore)
    599602        selectionTop -= !renderer().style().isFlippedLinesWritingMode() ? computeOverAnnotationAdjustment(m_lineTop) : computeUnderAnnotationAdjustment(m_lineTop);
     
    601604    if (renderer().style().isFlippedLinesWritingMode())
    602605        return selectionTop;
     606
     607    if (renderer().isRubyBase()) {
     608        // 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.
     609        RenderRubyBase* base = &downcast<RenderRubyBase>(renderer());
     610        RenderRubyRun* run = base->rubyRun();
     611        if (run) {
     612            RenderRubyText* text = run->rubyText();
     613            if (text && text->logicalTop() < base->logicalTop()) {
     614                // The ruby text is above the ruby base. Just return now in order to avoid painting on top of the ruby text.
     615                return selectionTop;
     616            }
     617        }
     618    } else if (renderer().isRubyText()) {
     619        // The ruby text selection should go all the way to the selection top of the containing line.
     620        RenderRubyText* text = &downcast<RenderRubyText>(renderer());
     621        RenderRubyRun* run = text->rubyRun();
     622        if (run && run->inlineBoxWrapper()) {
     623            RenderRubyBase* base = run->rubyBase();
     624            if (base && text->logicalTop() < base->logicalTop()) {
     625                // The ruby text is above the ruby base.
     626                const RootInlineBox& containingLine = run->inlineBoxWrapper()->root();
     627                LayoutUnit enclosingSelectionTop = containingLine.selectionTop();
     628                LayoutUnit deltaBetweenObjects = text->logicalTop() + run->logicalTop();
     629                LayoutUnit selectionTopInRubyTextCoords = enclosingSelectionTop - deltaBetweenObjects;
     630                return std::min(selectionTop, selectionTopInRubyTextCoords);
     631            }
     632        }
     633    }
    603634
    604635    LayoutUnit prevBottom = prevRootBox() ? prevRootBox()->selectionBottom() : blockFlow().borderAndPaddingBefore();
     
    650681    if (m_hasAnnotationsAfter)
    651682        selectionBottom += !renderer().style().isFlippedLinesWritingMode() ? computeUnderAnnotationAdjustment(m_lineBottom) : computeOverAnnotationAdjustment(m_lineBottom);
    652 
     683   
    653684    if (!renderer().style().isFlippedLinesWritingMode() || !nextRootBox())
    654685        return selectionBottom;
     686   
     687    if (renderer().isRubyBase()) {
     688        // 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.
     689        RenderRubyBase* base = &downcast<RenderRubyBase>(renderer());
     690        RenderRubyRun* run = base->rubyRun();
     691        if (run) {
     692            RenderRubyText* text = run->rubyText();
     693            if (text && text->logicalTop() > base->logicalTop()) {
     694                // The ruby text is below the ruby base. Just return now in order to avoid painting on top of the ruby text.
     695                return selectionBottom;
     696            }
     697        }
     698    } else if (renderer().isRubyText()) {
     699        // The ruby text selection should go all the way to the selection bottom of the containing line.
     700        RenderRubyText* text = &downcast<RenderRubyText>(renderer());
     701        RenderRubyRun* run = text->rubyRun();
     702        if (run && run->inlineBoxWrapper()) {
     703            RenderRubyBase* base = run->rubyBase();
     704            if (base && text->logicalTop() > base->logicalTop()) {
     705                // The ruby text is above the ruby base.
     706                const RootInlineBox& containingLine = run->inlineBoxWrapper()->root();
     707                LayoutUnit enclosingSelectionBottom = containingLine.selectionBottom();
     708                LayoutUnit deltaBetweenObjects = text->logicalTop() + run->logicalTop();
     709                LayoutUnit selectionBottomInRubyTextCoords = enclosingSelectionBottom - deltaBetweenObjects;
     710                return std::min(selectionBottom, selectionBottomInRubyTextCoords);
     711            }
     712        }
     713    }
    655714
    656715    LayoutUnit nextTop = nextRootBox()->selectionTop();
Note: See TracChangeset for help on using the changeset viewer.