OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/paint/BlockPaintInvalidator.h" | 5 #include "core/paint/BlockPaintInvalidator.h" |
6 | 6 |
7 #include "core/editing/DragCaret.h" | |
7 #include "core/editing/FrameSelection.h" | 8 #include "core/editing/FrameSelection.h" |
8 #include "core/frame/LocalFrame.h" | 9 #include "core/frame/LocalFrame.h" |
9 #include "core/layout/LayoutBlock.h" | 10 #include "core/layout/LayoutBlock.h" |
11 #include "core/page/Page.h" | |
10 #include "core/paint/BoxPaintInvalidator.h" | 12 #include "core/paint/BoxPaintInvalidator.h" |
13 #include "core/paint/ObjectPaintInvalidator.h" | |
11 #include "core/paint/PaintInvalidator.h" | 14 #include "core/paint/PaintInvalidator.h" |
15 #include "core/paint/PaintLayer.h" | |
12 | 16 |
13 namespace blink { | 17 namespace blink { |
14 | 18 |
19 struct CaretVisualRects { | |
20 bool hasCursorCaret = false; | |
yosin_UTC9
2017/01/31 20:12:58
It is better to move |bool| member to end of membe
| |
21 LayoutRect cursorCaretRect; | |
22 bool hasDragCaret = false; | |
23 LayoutRect dragCaretRect; | |
24 }; | |
25 | |
26 typedef HashMap<const LayoutBlock*, CaretVisualRects> CaretVisualRectsMap; | |
yosin_UTC9
2017/01/31 20:12:58
nit: Let's use using to C++-ish.
using CaretVisu
| |
27 static CaretVisualRectsMap& caretVisualRectsMap() { | |
28 DEFINE_STATIC_LOCAL(CaretVisualRectsMap, map, ()); | |
chrishtr
2017/01/31 22:51:04
Why can't you store these on the block instead of
| |
29 return map; | |
30 } | |
31 | |
32 static void setPreviousCaretVisualRects(const LayoutBlock& block, | |
33 const CaretVisualRects& rects) { | |
34 DCHECK(block.hasPreviousCaretVisualRects() == | |
yosin_UTC9
2017/01/31 20:12:58
nit: DCHECK_EQ
| |
35 caretVisualRectsMap().contains(&block)); | |
36 if (rects.cursorCaretRect.isEmpty() && rects.dragCaretRect.isEmpty()) { | |
37 BlockPaintInvalidator::clearPreviousCaretVisualRects(block); | |
yosin_UTC9
2017/01/31 20:12:58
nit: early return style to decrease indentation of
| |
38 } else { | |
39 caretVisualRectsMap().set(&block, rects); | |
40 block.getMutableForPainting().setHasPreviousCaretVisualRects(true); | |
41 } | |
42 } | |
43 | |
44 void BlockPaintInvalidator::blockWillBeDestroyed(const LayoutBlock& block) { | |
45 DCHECK(block.hasPreviousCaretVisualRects() == | |
yosin_UTC9
2017/01/31 20:12:58
nit: DCHECK_EQ
| |
46 caretVisualRectsMap().contains(&block)); | |
47 if (block.hasPreviousCaretVisualRects()) | |
48 caretVisualRectsMap().remove(&block); | |
49 } | |
50 | |
51 void BlockPaintInvalidator::setMayNeedPaintInvalidationForCaretsIfNeeded( | |
52 const LocalFrame& localFrameRoot) { | |
53 DCHECK(&localFrameRoot == localFrameRoot.localFrameRoot()); | |
yosin_UTC9
2017/01/31 20:12:58
nit: DCHECK_EQ
| |
54 for (auto& item : caretVisualRectsMap()) { | |
yosin_UTC9
2017/01/31 20:12:58
nit: s/auto&/const auto&/
We don't never change en
| |
55 const LayoutBlock* block = item.key; | |
56 const CaretVisualRects& rects = item.value; | |
57 DCHECK(block->hasPreviousCaretVisualRects()); | |
58 if (block->frame()->localFrameRoot() != &localFrameRoot) | |
59 continue; | |
60 if (rects.hasCursorCaret != block->hasCursorCaret() || | |
61 rects.hasDragCaret != block->hasDragCaret()) | |
62 block->getMutableForPainting().setMayNeedPaintInvalidation(); | |
63 } | |
64 } | |
65 | |
66 void BlockPaintInvalidator::clearPreviousCaretVisualRects( | |
67 const LayoutBlock& block) { | |
68 if (block.hasPreviousCaretVisualRects()) { | |
yosin_UTC9
2017/01/31 20:12:58
nit: early-return style to decrease indentation.
| |
69 caretVisualRectsMap().remove(&block); | |
70 block.getMutableForPainting().setHasPreviousCaretVisualRects(false); | |
71 } | |
72 } | |
73 | |
74 LayoutRect BlockPaintInvalidator::invalidateCaretIfNeeded( | |
75 PaintInvalidationReason reason, | |
76 const LayoutRect& oldVisualRect, | |
77 const LayoutRect& newLocalRect, | |
78 const DisplayItemClient& displayItemClient) { | |
79 LayoutRect newVisualRect = newLocalRect; | |
80 if (!newVisualRect.isEmpty()) { | |
81 // Over-paint 1 pixel to workaround wkbug.com/108283. | |
82 // TODO(wangxianzhu): This might be unnecessary now. | |
83 newVisualRect.inflate(1); | |
yosin_UTC9
2017/01/31 20:12:58
Agree. Let's getting rid of this patch to see whic
| |
84 | |
85 m_context.mapLocalRectToPaintInvalidationBacking(m_block, newVisualRect); | |
86 newVisualRect.move(m_block.scrollAdjustmentForPaintInvalidation( | |
87 *m_context.paintInvalidationContainer)); | |
88 } | |
89 | |
90 if (m_block.caretsNeedPaintInvalidation() || newVisualRect != oldVisualRect) { | |
91 ObjectPaintInvalidatorWithContext objectInvalidator(m_block, m_context); | |
92 if (!isImmediateFullPaintInvalidationReason(reason)) { | |
93 objectInvalidator.fullyInvalidatePaint(PaintInvalidationCaret, | |
94 oldVisualRect, newVisualRect); | |
95 } | |
96 | |
97 m_context.paintingLayer->setNeedsRepaint(); | |
98 objectInvalidator.invalidateDisplayItemClient(displayItemClient, | |
99 PaintInvalidationCaret); | |
100 } | |
101 | |
102 return newVisualRect; | |
103 } | |
104 | |
105 void BlockPaintInvalidator::invalidateCaretsIfNeeded( | |
106 PaintInvalidationReason reason) { | |
107 bool hadCarets = m_block.hasPreviousCaretVisualRects(); | |
108 DCHECK(hadCarets == caretVisualRectsMap().contains(&m_block)); | |
yosin_UTC9
2017/01/31 20:12:58
nit: DCHECK_EQ
| |
109 | |
110 bool hasCursorCaret = m_block.hasCursorCaret(); | |
yosin_UTC9
2017/01/31 20:12:58
nit: s/bool/const bool/
| |
111 bool hasDragCaret = m_block.hasDragCaret(); | |
yosin_UTC9
2017/01/31 20:12:58
nit: s/bool/const bool/
| |
112 if (!hadCarets && !hasCursorCaret && !hasDragCaret) | |
113 return; | |
114 | |
115 CaretVisualRects oldCaretVisualRects; | |
116 CaretVisualRects newCaretVisualRects; | |
117 if (hadCarets) | |
118 oldCaretVisualRects = caretVisualRectsMap().get(&m_block); | |
119 | |
120 FrameSelection& selection = m_block.frame()->selection(); | |
121 newCaretVisualRects.hasCursorCaret = hasCursorCaret; | |
122 newCaretVisualRects.cursorCaretRect = invalidateCaretIfNeeded( | |
123 reason, oldCaretVisualRects.cursorCaretRect, | |
124 hasCursorCaret ? selection.caretLocalRect() : LayoutRect(), | |
125 selection.getCaretDisplayItemClient()); | |
126 if (hasCursorCaret) | |
127 selection.setCaretVisualRect(newCaretVisualRects.cursorCaretRect); | |
128 | |
129 DragCaret& dragCaret = m_block.frame()->page()->dragCaret(); | |
130 newCaretVisualRects.hasDragCaret = hasDragCaret; | |
131 newCaretVisualRects.dragCaretRect = invalidateCaretIfNeeded( | |
132 reason, oldCaretVisualRects.dragCaretRect, | |
133 hasDragCaret ? dragCaret.caretLocalRect() : LayoutRect(), | |
134 dragCaret.getDisplayItemClient()); | |
135 if (hasDragCaret) | |
136 dragCaret.setVisualRect(newCaretVisualRects.dragCaretRect); | |
137 | |
138 setPreviousCaretVisualRects(m_block, newCaretVisualRects); | |
139 } | |
140 | |
15 PaintInvalidationReason BlockPaintInvalidator::invalidatePaintIfNeeded() { | 141 PaintInvalidationReason BlockPaintInvalidator::invalidatePaintIfNeeded() { |
16 PaintInvalidationReason reason = | 142 PaintInvalidationReason reason = |
17 BoxPaintInvalidator(m_block, m_context).invalidatePaintIfNeeded(); | 143 BoxPaintInvalidator(m_block, m_context).invalidatePaintIfNeeded(); |
18 | 144 |
19 if (reason != PaintInvalidationNone && m_block.hasCaret()) { | 145 invalidateCaretsIfNeeded(reason); |
20 FrameSelection& selection = m_block.frame()->selection(); | 146 |
21 selection.setCaretRectNeedsUpdate(); | |
22 selection.invalidateCaretRect(true); | |
23 } | |
24 return reason; | 147 return reason; |
25 } | 148 } |
26 } | 149 } |
OLD | NEW |