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

Side by Side Diff: third_party/WebKit/Source/core/editing/CaretDisplayItemClient.cpp

Issue 2698313003: Fix caret paint invalidation when moving between blocks (Closed)
Patch Set: - 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2004, 2008, 2009, 2010 Apple Inc. All rights reserved. 2 * Copyright (C) 2004, 2008, 2009, 2010 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 LayoutBlockItem caretPainterItem = 110 LayoutBlockItem caretPainterItem =
111 LayoutBlockItem(caretLayoutBlock(caretPosition.anchorNode())); 111 LayoutBlockItem(caretLayoutBlock(caretPosition.anchorNode()));
112 LayoutRect caretLocalRectWithWritingMode = caretLocalRect; 112 LayoutRect caretLocalRectWithWritingMode = caretLocalRect;
113 caretPainterItem.flipForWritingMode(caretLocalRectWithWritingMode); 113 caretPainterItem.flipForWritingMode(caretLocalRectWithWritingMode);
114 return mapCaretRectToCaretPainter(LayoutItem(layoutObject), caretPainterItem, 114 return mapCaretRectToCaretPainter(LayoutItem(layoutObject), caretPainterItem,
115 caretLocalRectWithWritingMode); 115 caretLocalRectWithWritingMode);
116 } 116 }
117 117
118 void CaretDisplayItemClient::updateStyleAndLayoutIfNeeded( 118 void CaretDisplayItemClient::updateStyleAndLayoutIfNeeded(
119 const PositionWithAffinity& caretPosition) { 119 const PositionWithAffinity& caretPosition) {
120 m_previousLayoutBlock = m_layoutBlock;
121 m_previousVisualRect = m_visualRect;
122
120 LayoutBlock* newLayoutBlock = caretLayoutBlock(caretPosition.anchorNode()); 123 LayoutBlock* newLayoutBlock = caretLayoutBlock(caretPosition.anchorNode());
121 if (newLayoutBlock != m_layoutBlock) { 124 if (newLayoutBlock != m_layoutBlock) {
122 if (m_layoutBlock) 125 if (m_layoutBlock)
123 m_layoutBlock->setMayNeedPaintInvalidation(); 126 m_layoutBlock->setMayNeedPaintInvalidation();
124 m_previousLayoutBlock = m_layoutBlock;
125 m_layoutBlock = newLayoutBlock; 127 m_layoutBlock = newLayoutBlock;
126 m_needsPaintInvalidation = true; 128 if (newLayoutBlock)
127 } else { 129 m_needsPaintInvalidation = true;
128 m_previousLayoutBlock = nullptr; 130 m_visualRect = LayoutRect();
129 } 131 }
130 132
131 if (!newLayoutBlock) { 133 if (!newLayoutBlock) {
132 m_color = Color(); 134 m_color = Color();
133 m_localRect = LayoutRect(); 135 m_localRect = LayoutRect();
134 return; 136 return;
135 } 137 }
136 138
137 Color newColor; 139 Color newColor;
138 if (caretPosition.anchorNode()) { 140 if (caretPosition.anchorNode()) {
(...skipping 12 matching lines...) Expand all
151 } 153 }
152 154
153 if (m_needsPaintInvalidation) 155 if (m_needsPaintInvalidation)
154 newLayoutBlock->setMayNeedPaintInvalidation(); 156 newLayoutBlock->setMayNeedPaintInvalidation();
155 } 157 }
156 158
157 void CaretDisplayItemClient::invalidatePaintIfNeeded( 159 void CaretDisplayItemClient::invalidatePaintIfNeeded(
158 const LayoutBlock& block, 160 const LayoutBlock& block,
159 const PaintInvalidatorContext& context, 161 const PaintInvalidatorContext& context,
160 PaintInvalidationReason layoutBlockPaintInvalidationReason) { 162 PaintInvalidationReason layoutBlockPaintInvalidationReason) {
161 if (block == m_previousLayoutBlock) { 163 if (block == m_layoutBlock) {
162 // Invalidate the previous caret if it was in a different block. 164 invalidatePaintInCurrentLayoutBlock(context,
163 // m_previousLayoutBlock is set only when it's different from m_layoutBlock. 165 layoutBlockPaintInvalidationReason);
164 DCHECK(block != m_layoutBlock);
165
166 ObjectPaintInvalidatorWithContext objectInvalidator(*m_previousLayoutBlock,
167 context);
168 if (!isImmediateFullPaintInvalidationReason(
169 layoutBlockPaintInvalidationReason)) {
170 objectInvalidator.fullyInvalidatePaint(PaintInvalidationCaret,
171 m_visualRect, LayoutRect());
172 }
173
174 // If m_layoutBlock is not null, the following will be done when
175 // the new caret is invalidated in m_layoutBlock.
176 if (!m_layoutBlock) {
Xianzhu 2017/02/17 18:02:58 The "will be done" assumption was incorrect becaus
177 context.paintingLayer->setNeedsRepaint();
178 objectInvalidator.invalidateDisplayItemClient(*this,
179 PaintInvalidationCaret);
180 m_visualRect = LayoutRect();
Xianzhu 2017/02/17 18:02:58 This is moved into updateStyleAndLayoutIfNeeded().
181 m_needsPaintInvalidation = false;
182 }
183
184 m_previousLayoutBlock = nullptr;
185 return; 166 return;
186 } 167 }
187 168
188 if (block != m_layoutBlock) 169 if (block == m_previousLayoutBlock) {
189 return; 170 invalidatePaintInPreviousLayoutBlock(context,
171 layoutBlockPaintInvalidationReason);
172 }
173 }
190 174
191 // Invalidate the new caret, and the old caret if it was in the same block. 175 void CaretDisplayItemClient::invalidatePaintInPreviousLayoutBlock(
176 const PaintInvalidatorContext& context,
177 PaintInvalidationReason layoutBlockPaintInvalidationReason) {
178 DCHECK(m_previousLayoutBlock);
179
180 ObjectPaintInvalidatorWithContext objectInvalidator(*m_previousLayoutBlock,
181 context);
182 if (!isImmediateFullPaintInvalidationReason(
183 layoutBlockPaintInvalidationReason)) {
184 objectInvalidator.invalidatePaintUsingContainer(
185 *context.paintInvalidationContainer, m_previousVisualRect,
186 PaintInvalidationCaret);
187 }
188
189 context.paintingLayer->setNeedsRepaint();
190 objectInvalidator.invalidateDisplayItemClient(*this, PaintInvalidationCaret);
191 m_previousLayoutBlock = nullptr;
192 }
193
194 void CaretDisplayItemClient::invalidatePaintInCurrentLayoutBlock(
195 const PaintInvalidatorContext& context,
196 PaintInvalidationReason layoutBlockPaintInvalidationReason) {
197 DCHECK(m_layoutBlock);
198
192 LayoutRect newVisualRect; 199 LayoutRect newVisualRect;
193 if (m_layoutBlock && !m_localRect.isEmpty()) { 200 if (!m_localRect.isEmpty()) {
194 newVisualRect = m_localRect; 201 newVisualRect = m_localRect;
195 context.mapLocalRectToPaintInvalidationBacking(*m_layoutBlock, 202 context.mapLocalRectToPaintInvalidationBacking(*m_layoutBlock,
196 newVisualRect); 203 newVisualRect);
197 newVisualRect.move(m_layoutBlock->scrollAdjustmentForPaintInvalidation( 204 newVisualRect.move(m_layoutBlock->scrollAdjustmentForPaintInvalidation(
198 *context.paintInvalidationContainer)); 205 *context.paintInvalidationContainer));
199 206
200 if (m_layoutBlock->usesCompositedScrolling()) { 207 if (m_layoutBlock->usesCompositedScrolling()) {
201 // The caret should use scrolling coordinate space. 208 // The caret should use scrolling coordinate space.
202 DCHECK(m_layoutBlock == context.paintInvalidationContainer); 209 DCHECK(m_layoutBlock == context.paintInvalidationContainer);
203 newVisualRect.move(LayoutSize(m_layoutBlock->scrolledContentOffset())); 210 newVisualRect.move(LayoutSize(m_layoutBlock->scrolledContentOffset()));
204 } 211 }
205 } 212 }
206 213
207 if (m_needsPaintInvalidation || newVisualRect != m_visualRect) { 214 if (!m_needsPaintInvalidation && newVisualRect == m_visualRect)
208 m_needsPaintInvalidation = false; 215 return;
209 216
210 ObjectPaintInvalidatorWithContext objectInvalidator(*m_layoutBlock, 217 m_needsPaintInvalidation = false;
211 context);
212 if (!isImmediateFullPaintInvalidationReason(
213 layoutBlockPaintInvalidationReason)) {
214 objectInvalidator.fullyInvalidatePaint(PaintInvalidationCaret,
215 m_visualRect, newVisualRect);
216 }
217 218
218 context.paintingLayer->setNeedsRepaint(); 219 ObjectPaintInvalidatorWithContext objectInvalidator(*m_layoutBlock, context);
219 objectInvalidator.invalidateDisplayItemClient(*this, 220 if (!isImmediateFullPaintInvalidationReason(
220 PaintInvalidationCaret); 221 layoutBlockPaintInvalidationReason)) {
222 objectInvalidator.fullyInvalidatePaint(PaintInvalidationCaret, m_visualRect,
223 newVisualRect);
221 } 224 }
222 225
226 context.paintingLayer->setNeedsRepaint();
227 objectInvalidator.invalidateDisplayItemClient(*this, PaintInvalidationCaret);
228
223 m_visualRect = newVisualRect; 229 m_visualRect = newVisualRect;
224 } 230 }
225 231
226 void CaretDisplayItemClient::paintCaret( 232 void CaretDisplayItemClient::paintCaret(
227 GraphicsContext& context, 233 GraphicsContext& context,
228 const LayoutPoint& paintOffset, 234 const LayoutPoint& paintOffset,
229 DisplayItem::Type displayItemType) const { 235 DisplayItem::Type displayItemType) const {
230 if (DrawingRecorder::useCachedDrawingIfPossible(context, *this, 236 if (DrawingRecorder::useCachedDrawingIfPossible(context, *this,
231 displayItemType)) 237 displayItemType))
232 return; 238 return;
233 239
234 LayoutRect drawingRect = m_localRect; 240 LayoutRect drawingRect = m_localRect;
235 drawingRect.moveBy(paintOffset); 241 drawingRect.moveBy(paintOffset);
236 242
237 IntRect paintRect = pixelSnappedIntRect(drawingRect); 243 IntRect paintRect = pixelSnappedIntRect(drawingRect);
238 DrawingRecorder drawingRecorder(context, *this, DisplayItem::kCaret, 244 DrawingRecorder drawingRecorder(context, *this, DisplayItem::kCaret,
239 paintRect); 245 paintRect);
240 context.fillRect(paintRect, m_color); 246 context.fillRect(paintRect, m_color);
241 } 247 }
242 248
243 String CaretDisplayItemClient::debugName() const { 249 String CaretDisplayItemClient::debugName() const {
244 return "Caret"; 250 return "Caret";
245 } 251 }
246 252
247 LayoutRect CaretDisplayItemClient::visualRect() const { 253 LayoutRect CaretDisplayItemClient::visualRect() const {
248 return m_visualRect; 254 return m_visualRect;
249 } 255 }
250 256
251 } // namespace blink 257 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698