Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(230)

Unified Diff: third_party/WebKit/Source/core/editing/CaretDisplayItemClient.cpp

Issue 2665823002: Invalidate caret during paint invalidation (Closed)
Patch Set: NeedsRebaseline Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/editing/CaretDisplayItemClient.cpp
diff --git a/third_party/WebKit/Source/core/editing/CaretDisplayItemClient.cpp b/third_party/WebKit/Source/core/editing/CaretDisplayItemClient.cpp
index 88ef35c3a152c177b5e43fd1244ab872d89cf678..80930cebdb36b5b90b90111f5db06ad9b0e957d9 100644
--- a/third_party/WebKit/Source/core/editing/CaretDisplayItemClient.cpp
+++ b/third_party/WebKit/Source/core/editing/CaretDisplayItemClient.cpp
@@ -34,10 +34,11 @@
#include "core/layout/api/LayoutBlockItem.h"
#include "core/layout/api/LayoutItem.h"
#include "core/layout/api/LayoutViewItem.h"
+#include "core/paint/ObjectPaintInvalidator.h"
#include "core/paint/PaintInfo.h"
+#include "core/paint/PaintInvalidator.h"
#include "core/paint/PaintLayer.h"
#include "platform/graphics/GraphicsContext.h"
-#include "platform/graphics/GraphicsLayer.h"
#include "platform/graphics/paint/DrawingRecorder.h"
namespace blink {
@@ -45,11 +46,11 @@ namespace blink {
CaretDisplayItemClient::CaretDisplayItemClient() = default;
CaretDisplayItemClient::~CaretDisplayItemClient() = default;
-static inline bool caretRendersInsideNode(Node* node) {
+static inline bool caretRendersInsideNode(const Node* node) {
return node && !isDisplayInsideTable(node) && !editingIgnoresContent(*node);
}
-LayoutBlock* CaretDisplayItemClient::caretLayoutObject(Node* node) {
+LayoutBlock* CaretDisplayItemClient::caretLayoutBlock(const Node* node) {
if (!node)
return nullptr;
@@ -107,54 +108,136 @@ LayoutRect CaretDisplayItemClient::computeCaretRect(
// Get the layoutObject that will be responsible for painting the caret
// (which is either the layoutObject we just found, or one of its containers).
LayoutBlockItem caretPainterItem =
- LayoutBlockItem(caretLayoutObject(caretPosition.anchorNode()));
+ LayoutBlockItem(caretLayoutBlock(caretPosition.anchorNode()));
return mapCaretRectToCaretPainter(LayoutItem(layoutObject), caretPainterItem,
caretLocalRect);
}
-// TODO(yoichio): |node| is FrameSelection::m_previousCaretNode and this is bad
-// design. We should use only previous layoutObject or Rectangle to invalidate
-// old caret.
-void CaretDisplayItemClient::invalidateLocalCaretRect(Node* node,
- const LayoutRect& rect) {
- LayoutBlock* caretLayoutBlock = caretLayoutObject(node);
- if (!caretLayoutBlock)
+void CaretDisplayItemClient::updateStyleAndLayoutIfNeeded(
+ const PositionWithAffinity& caretPosition) {
+ LayoutBlock* newLayoutBlock = caretLayoutBlock(caretPosition.anchorNode());
+ if (newLayoutBlock != m_layoutBlock) {
+ if (m_layoutBlock)
+ m_layoutBlock->setMayNeedPaintInvalidation();
+ m_previousLayoutBlock = m_layoutBlock;
+ m_layoutBlock = newLayoutBlock;
+ m_needsPaintInvalidation = true;
+ } else {
+ m_previousLayoutBlock = nullptr;
+ }
+
+ if (!newLayoutBlock) {
+ m_color = Color();
+ m_localRect = LayoutRect();
+ return;
+ }
+
+ Color newColor;
+ if (caretPosition.anchorNode()) {
+ newColor = caretPosition.anchorNode()->layoutObject()->resolveColor(
+ CSSPropertyCaretColor);
+ }
+ if (newColor != m_color) {
+ m_needsPaintInvalidation = true;
+ m_color = newColor;
+ }
+
+ LayoutRect newLocalRect = computeCaretRect(caretPosition);
+ if (newLocalRect != m_localRect) {
+ m_needsPaintInvalidation = true;
+ m_localRect = newLocalRect;
+ }
+
+ if (m_needsPaintInvalidation)
+ newLayoutBlock->setMayNeedPaintInvalidation();
+}
+
+void CaretDisplayItemClient::invalidatePaintIfNeeded(
+ const LayoutBlock& block,
+ const PaintInvalidatorContext& context,
+ PaintInvalidationReason layoutBlockPaintInvalidationReason) {
+ if (block == m_previousLayoutBlock) {
+ // Invalidate the previous caret if it was in a different block.
+ // m_previousLayoutBlock is set only when it's different from m_layoutBlock.
+ DCHECK(block != m_layoutBlock);
+
+ ObjectPaintInvalidatorWithContext objectInvalidator(*m_previousLayoutBlock,
+ context);
+ if (!isImmediateFullPaintInvalidationReason(
+ layoutBlockPaintInvalidationReason)) {
+ objectInvalidator.fullyInvalidatePaint(PaintInvalidationCaret,
+ m_visualRect, LayoutRect());
+ }
+
+ // If m_layoutBlock is not null, the following will be done when
+ // the new caret is invalidated in m_layoutBlock.
+ if (!m_layoutBlock) {
+ context.paintingLayer->setNeedsRepaint();
+ objectInvalidator.invalidateDisplayItemClient(*this,
+ PaintInvalidationCaret);
+ m_visualRect = LayoutRect();
+ m_needsPaintInvalidation = false;
+ }
+
+ m_previousLayoutBlock = nullptr;
+ return;
+ }
+
+ if (block != m_layoutBlock)
return;
- // FIXME: Need to over-paint 1 pixel to workaround some rounding problems.
- // https://bugs.webkit.org/show_bug.cgi?id=108283
- LayoutRect inflatedRect = rect;
- inflatedRect.inflate(LayoutUnit(1));
+ // Invalidate the new caret, and the old caret if it was in the same block.
+ LayoutRect newVisualRect;
+ if (m_layoutBlock && !m_localRect.isEmpty()) {
+ newVisualRect = m_localRect;
+ context.mapLocalRectToPaintInvalidationBacking(*m_layoutBlock,
+ newVisualRect);
+ newVisualRect.move(m_layoutBlock->scrollAdjustmentForPaintInvalidation(
+ *context.paintInvalidationContainer));
+
+ if (m_layoutBlock->usesCompositedScrolling()) {
+ // The caret should use scrolling coordinate space.
+ DCHECK(m_layoutBlock == context.paintInvalidationContainer);
+ newVisualRect.move(LayoutSize(m_layoutBlock->scrolledContentOffset()));
+ }
+ }
+
+ if (m_needsPaintInvalidation || newVisualRect != m_visualRect) {
+ m_needsPaintInvalidation = false;
- // FIXME: We should not allow paint invalidation out of paint invalidation
- // state. crbug.com/457415
- DisablePaintInvalidationStateAsserts disabler;
+ ObjectPaintInvalidatorWithContext objectInvalidator(*m_layoutBlock,
+ context);
+ if (!isImmediateFullPaintInvalidationReason(
+ layoutBlockPaintInvalidationReason)) {
+ objectInvalidator.fullyInvalidatePaint(PaintInvalidationCaret,
+ m_visualRect, newVisualRect);
+ }
+
+ context.paintingLayer->setNeedsRepaint();
+ objectInvalidator.invalidateDisplayItemClient(*this,
+ PaintInvalidationCaret);
+ }
- m_visualRect =
- node->layoutObject()->invalidatePaintRectangle(inflatedRect, this);
+ m_visualRect = newVisualRect;
}
-void CaretDisplayItemClient::paintCaret(Node* node,
- GraphicsContext& context,
- const LayoutRect& caretLocalRect,
- const LayoutPoint& paintOffset,
- DisplayItem::Type displayItemType) {
+void CaretDisplayItemClient::paintCaret(
+ GraphicsContext& context,
+ const LayoutPoint& paintOffset,
+ DisplayItem::Type displayItemType) const {
if (DrawingRecorder::useCachedDrawingIfPossible(context, *this,
displayItemType))
return;
- LayoutRect drawingRect = caretLocalRect;
- if (LayoutBlock* layoutObject = caretLayoutObject(node))
- layoutObject->flipForWritingMode(drawingRect);
+ LayoutRect drawingRect = m_localRect;
+ m_layoutBlock->flipForWritingMode(drawingRect);
drawingRect.moveBy(paintOffset);
- const Color caretColor =
- node->layoutObject()->resolveColor(CSSPropertyCaretColor);
IntRect paintRect = pixelSnappedIntRect(drawingRect);
DrawingRecorder drawingRecorder(context, *this, DisplayItem::kCaret,
paintRect);
- context.fillRect(paintRect, caretColor);
+ context.fillRect(paintRect, m_color);
}
String CaretDisplayItemClient::debugName() const {
« no previous file with comments | « third_party/WebKit/Source/core/editing/CaretDisplayItemClient.h ('k') | third_party/WebKit/Source/core/editing/DragCaret.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698