Changeset 139282 in webkit


Ignore:
Timestamp:
Jan 9, 2013 10:23:32 PM (11 years ago)
Author:
commit-queue@webkit.org
Message:

Make caret repainting container-aware
https://bugs.webkit.org/show_bug.cgi?id=103955

Patch by Tien-Ren Chen <trchen@chromium.org> on 2013-01-09
Reviewed by Simon Fraser.

Source/WebCore:

Only invalidate local rects on the caret's repaint container,
instead of invalidating an absolute rect on the whole view.

Test: fast/repaint/caret-with-transformation.html

  • editing/FrameSelection.cpp:

(WebCore::caretRendersInsideNode):
(WebCore::caretRenderer):
(WebCore::FrameSelection::caretRenderer):
(WebCore::DragCaretController::caretRenderer):
(WebCore::repaintCaretForLocalRect):
(WebCore::FrameSelection::recomputeCaretRect):
(WebCore::CaretBase::invalidateCaretRect):
(WebCore::FrameSelection::focusedOrActiveStateChanged):

  • editing/FrameSelection.h:
  • rendering/RenderView.cpp:

(WebCore::RenderView::repaintSelection):

  • rendering/RenderView.h:

LayoutTests:

The caret repaint padding has been removed. Needs rebaseline.
Added test that carets should be repainted correctly on a transformed element.

  • fast/repaint/caret-with-transformation.html: Added.
  • platform/chromium/TestExpectations:
  • platform/mac/TestExpectations:
Location:
trunk
Files:
1 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r139281 r139282  
     12013-01-09  Tien-Ren Chen  <trchen@chromium.org>
     2
     3        Make caret repainting container-aware
     4        https://bugs.webkit.org/show_bug.cgi?id=103955
     5
     6        Reviewed by Simon Fraser.
     7
     8        The caret repaint padding has been removed. Needs rebaseline.
     9        Added test that carets should be repainted correctly on a transformed element.
     10
     11        * fast/repaint/caret-with-transformation.html: Added.
     12        * platform/chromium/TestExpectations:
     13        * platform/mac/TestExpectations:
     14
    1152013-01-09  Noel Gordon  <noel.gordon@gmail.com>
    216
  • trunk/LayoutTests/platform/chromium/TestExpectations

    r139251 r139282  
    43784378crbug.com/166932 [ Debug ] plugins/embed-attributes-setting.html [ Crash Pass ]
    43794379
     4380# Transient. Needs rebaseline.
     4381webkit.org/b/103955 fast/repaint/4774354.html [ ImageOnlyFailure ]
     4382webkit.org/b/103955 fast/repaint/4776765.html [ ImageOnlyFailure ]
     4383webkit.org/b/103955 fast/repaint/caret-outside-block.html [ ImageOnlyFailure ]
     4384webkit.org/b/103955 fast/repaint/japanese-rl-selection-repaint-in-regions.html [ ImageOnlyFailure ]
     4385webkit.org/b/103955 fast/repaint/japanese-rl-selection-repaint.html [ ImageOnlyFailure ]
     4386webkit.org/b/103955 fast/repaint/repaint-across-writing-mode-boundary.html [ ImageOnlyFailure ]
     4387webkit.org/b/103955 fast/repaint/selection-rl.html [ ImageOnlyFailure ]
     4388webkit.org/b/103955 fast/repaint/caret-with-transformation.html [ Missing ]
  • trunk/LayoutTests/platform/mac/TestExpectations

    r139229 r139282  
    12741274webkit.org/b/106415 fast/workers/worker-lifecycle.html [ Pass Failure ]
    12751275
     1276# Transient. Needs rebaseline.
     1277webkit.org/b/103955 fast/repaint/4774354.html [ ImageOnlyFailure ]
     1278webkit.org/b/103955 fast/repaint/4776765.html [ ImageOnlyFailure ]
     1279webkit.org/b/103955 fast/repaint/caret-outside-block.html [ ImageOnlyFailure ]
     1280webkit.org/b/103955 fast/repaint/japanese-rl-selection-repaint-in-regions.html [ ImageOnlyFailure ]
     1281webkit.org/b/103955 fast/repaint/japanese-rl-selection-repaint.html [ ImageOnlyFailure ]
     1282webkit.org/b/103955 fast/repaint/repaint-across-writing-mode-boundary.html [ ImageOnlyFailure ]
     1283webkit.org/b/103955 fast/repaint/selection-rl.html [ ImageOnlyFailure ]
     1284webkit.org/b/103955 fast/repaint/caret-with-transformation.html [ Missing ]
  • trunk/Source/WebCore/ChangeLog

    r139280 r139282  
     12013-01-09  Tien-Ren Chen  <trchen@chromium.org>
     2
     3        Make caret repainting container-aware
     4        https://bugs.webkit.org/show_bug.cgi?id=103955
     5
     6        Reviewed by Simon Fraser.
     7
     8        Only invalidate local rects on the caret's repaint container,
     9        instead of invalidating an absolute rect on the whole view.
     10
     11        Test: fast/repaint/caret-with-transformation.html
     12
     13        * editing/FrameSelection.cpp:
     14        (WebCore::caretRendersInsideNode):
     15        (WebCore::caretRenderer):
     16        (WebCore::FrameSelection::caretRenderer):
     17        (WebCore::DragCaretController::caretRenderer):
     18        (WebCore::repaintCaretForLocalRect):
     19        (WebCore::FrameSelection::recomputeCaretRect):
     20        (WebCore::CaretBase::invalidateCaretRect):
     21        (WebCore::FrameSelection::focusedOrActiveStateChanged):
     22        * editing/FrameSelection.h:
     23        * rendering/RenderView.cpp:
     24        (WebCore::RenderView::repaintSelection):
     25        * rendering/RenderView.h:
     26
    1272013-01-09  Ryosuke Niwa  <rniwa@webkit.org>
    228
  • trunk/Source/WebCore/editing/FrameSelection.cpp

    r137847 r139282  
    12201220}
    12211221
     1222static inline bool caretRendersInsideNode(Node* node)
     1223{
     1224    return node && !isTableElement(node) && !editingIgnoresContent(node);
     1225}
     1226
     1227static RenderObject* caretRenderer(Node* node)
     1228{
     1229    if (!node)
     1230        return 0;
     1231
     1232    RenderObject* renderer = node->renderer();
     1233    if (!renderer)
     1234        return 0;
     1235
     1236    // if caretNode is a block and caret is inside it then caret should be painted by that block
     1237    bool paintedByBlock = renderer->isBlockFlow() && caretRendersInsideNode(node);
     1238    return paintedByBlock ? renderer : renderer->containingBlock();
     1239}
     1240
    12221241bool CaretBase::updateCaretRect(Document* document, const VisiblePosition& caretPosition)
    12231242{
     
    12581277}
    12591278
    1260 static inline bool caretRendersInsideNode(Node* node)
    1261 {
    1262     return node && !isTableElement(node) && !editingIgnoresContent(node);
    1263 }
    1264 
    1265 RenderObject* CaretBase::caretRenderer(Node* node) const
    1266 {
    1267     if (!node)
    1268         return 0;
    1269 
    1270     RenderObject* renderer = node->renderer();
    1271     if (!renderer)
    1272         return 0;
    1273 
    1274     // if caretNode is a block and caret is inside it then caret should be painted by that block
    1275     bool paintedByBlock = renderer->isBlockFlow() && caretRendersInsideNode(node);
    1276     return paintedByBlock ? renderer : renderer->containingBlock();
    1277 }
    1278 
    12791279RenderObject* FrameSelection::caretRenderer() const
    12801280{
    1281     return CaretBase::caretRenderer(m_selection.start().deprecatedNode());
     1281    return WebCore::caretRenderer(m_selection.start().deprecatedNode());
    12821282}
    12831283
    12841284RenderObject* DragCaretController::caretRenderer() const
    12851285{
    1286     return CaretBase::caretRenderer(m_position.deepEquivalent().deprecatedNode());
     1286    return WebCore::caretRenderer(m_position.deepEquivalent().deprecatedNode());
    12871287}
    12881288
     
    13221322}
    13231323
    1324 static LayoutRect repaintRectForCaret(LayoutRect caret)
    1325 {
    1326     if (caret.isEmpty())
    1327         return LayoutRect();
    1328     // Ensure that the dirty rect intersects the block that paints the caret even in the case where
    1329     // the caret itself is just outside the block. See <https://bugs.webkit.org/show_bug.cgi?id=19086>.
    1330     caret.inflateX(1);
    1331     caret.inflateY(1);
    1332     return caret;
    1333 }
    1334 
    1335 IntRect CaretBase::caretRepaintRect(Node* node) const
    1336 {
    1337     return absoluteBoundsForLocalRect(node, repaintRectForCaret(localCaretRectWithoutUpdate()));
     1324static void repaintCaretForLocalRect(Node* node, const LayoutRect& rect)
     1325{
     1326    RenderObject* caretPainter = caretRenderer(node);
     1327    if (!caretPainter)
     1328        return;
     1329
     1330    caretPainter->repaintRectangle(rect);
    13381331}
    13391332
     
    13561349
    13571350    IntRect oldAbsCaretBounds = m_absCaretBounds;
    1358     // FIXME: Rename m_caretRect to m_localCaretRect.
    13591351    m_absCaretBounds = absoluteBoundsForLocalRect(m_selection.start().deprecatedNode(), localCaretRectWithoutUpdate());
    13601352    m_absCaretBoundsDirty = false;
     
    13641356
    13651357#if ENABLE(TEXT_CARET)
    1366     IntRect oldAbsoluteCaretRepaintBounds = m_absoluteCaretRepaintBounds;
    1367 #endif
    1368 
    1369     // We believe that we need to inflate the local rect before transforming it to obtain the repaint bounds.
    1370     m_absoluteCaretRepaintBounds = caretRepaintRect(m_selection.start().deprecatedNode());
    1371 
    1372 #if ENABLE(TEXT_CARET)
    13731358    if (RenderView* view = m_frame->document()->renderView()) {
    1374         // FIXME: make caret repainting container-aware.
    1375         view->repaintRectangleInViewAndCompositedLayers(oldAbsoluteCaretRepaintBounds, false);
     1359        Node* node = m_selection.start().deprecatedNode();
     1360        if (m_previousCaretNode)
     1361            repaintCaretForLocalRect(m_previousCaretNode.get(), oldRect);
     1362        m_previousCaretNode = node;
    13761363        if (shouldRepaintCaret(view, isContentEditable()))
    1377             view->repaintRectangleInViewAndCompositedLayers(m_absoluteCaretRepaintBounds, false);
     1364            repaintCaretForLocalRect(node, newRect);
    13781365    }
    13791366#endif
     
    14171404    if (RenderView* view = node->document()->renderView()) {
    14181405        if (shouldRepaintCaret(view, node->isContentEditable(Node::UserSelectAllIsAlwaysNonEditable)))
    1419             view->repaintRectangleInViewAndCompositedLayers(caretRepaintRect(node), false);
     1406            repaintCaretForLocalRect(node, localCaretRectWithoutUpdate());
    14201407    }
    14211408}
     
    16841671    // we have to update places those colors were painted.
    16851672    if (RenderView* view = m_frame->document()->renderView())
    1686         view->repaintRectangleInViewAndCompositedLayers(enclosingIntRect(bounds()));
     1673        view->repaintSelection();
    16871674
    16881675    // Caret appears in the active frame.
  • trunk/Source/WebCore/editing/FrameSelection.h

    r134191 r139282  
    6666    bool updateCaretRect(Document*, const VisiblePosition& caretPosition);
    6767    IntRect absoluteBoundsForLocalRect(Node*, const LayoutRect&) const;
    68     IntRect caretRepaintRect(Node*) const;
    6968    bool shouldRepaintCaret(const RenderView*, bool isContentEditable) const;
    7069    void paintCaret(Node*, GraphicsContext*, const LayoutPoint&, const LayoutRect& clipRect) const;
    71     RenderObject* caretRenderer(Node*) const;
    7270
    7371    const LayoutRect& localCaretRectWithoutUpdate() const { return m_caretLocalRect; }
     
    303301    TextGranularity m_granularity;
    304302
     303    RefPtr<Node> m_previousCaretNode; // The last node which painted the caret. Retained for clearing the old caret when it moves.
     304
    305305    RefPtr<EditingStyle> m_typingStyle;
    306306
     
    308308    // The painted bounds of the caret in absolute coordinates
    309309    IntRect m_absCaretBounds;
    310     // Similar to above, but inflated to ensure proper repaint (see https://bugs.webkit.org/show_bug.cgi?id=19086)
    311     IntRect m_absoluteCaretRepaintBounds;
    312310    bool m_absCaretBoundsDirty : 1;
    313311    bool m_caretPaint : 1;
  • trunk/Source/WebCore/rendering/RenderView.cpp

    r139197 r139282  
    546546}
    547547
     548void RenderView::repaintSelection() const
     549{
     550    document()->updateStyleIfNeeded();
     551
     552    HashSet<RenderBlock*> processedBlocks;
     553
     554    RenderObject* end = rendererAfterPosition(m_selectionEnd, m_selectionEndPos);
     555    for (RenderObject* o = m_selectionStart; o && o != end; o = o->nextInPreOrder()) {
     556        if (!o->canBeSelectionLeaf() && o != m_selectionStart && o != m_selectionEnd)
     557            continue;
     558        if (o->selectionState() == SelectionNone)
     559            continue;
     560
     561        RenderSelectionInfo(o, true).repaint();
     562
     563        // Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.
     564        for (RenderBlock* block = o->containingBlock(); block && !block->isRenderView(); block = block->containingBlock()) {
     565            if (processedBlocks.contains(block))
     566                break;
     567            processedBlocks.add(block);
     568            RenderSelectionInfo(block, true).repaint();
     569        }
     570    }
     571}
     572
    548573#if USE(ACCELERATED_COMPOSITING)
    549574// Compositing layer dimensions take outline size into account, so we have to recompute layer
  • trunk/Source/WebCore/rendering/RenderView.h

    r138838 r139282  
    9696    IntRect selectionBounds(bool clipToVisibleContent = true) const;
    9797    void selectionStartEnd(int& startPos, int& endPos) const;
     98    void repaintSelection() const;
    9899
    99100    bool printing() const;
Note: See TracChangeset for help on using the changeset viewer.