OLD | NEW |
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 16 matching lines...) Expand all Loading... |
27 | 27 |
28 #include "core/editing/EditingUtilities.h" | 28 #include "core/editing/EditingUtilities.h" |
29 #include "core/editing/VisibleUnits.h" | 29 #include "core/editing/VisibleUnits.h" |
30 #include "core/frame/FrameView.h" | 30 #include "core/frame/FrameView.h" |
31 #include "core/frame/Settings.h" | 31 #include "core/frame/Settings.h" |
32 #include "core/layout/LayoutBlock.h" | 32 #include "core/layout/LayoutBlock.h" |
33 #include "core/layout/LayoutView.h" | 33 #include "core/layout/LayoutView.h" |
34 #include "core/layout/api/LayoutBlockItem.h" | 34 #include "core/layout/api/LayoutBlockItem.h" |
35 #include "core/layout/api/LayoutItem.h" | 35 #include "core/layout/api/LayoutItem.h" |
36 #include "core/paint/PaintInfo.h" | 36 #include "core/paint/PaintInfo.h" |
| 37 #include "core/paint/PaintLayer.h" |
37 #include "platform/graphics/GraphicsContext.h" | 38 #include "platform/graphics/GraphicsContext.h" |
| 39 #include "platform/graphics/GraphicsLayer.h" |
| 40 #include "platform/graphics/paint/DrawingRecorder.h" |
38 | 41 |
39 namespace blink { | 42 namespace blink { |
40 | 43 |
41 CaretBase::CaretBase(CaretVisibility visibility) | 44 CaretBase::CaretBase(CaretVisibility visibility) |
42 : m_caretVisibility(visibility) | 45 : m_caretVisibility(visibility) |
43 { | 46 { |
44 } | 47 } |
45 | 48 |
46 CaretBase::~CaretBase() = default; | 49 CaretBase::~CaretBase() = default; |
47 | 50 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 { | 135 { |
133 LayoutBlock* caretPainter = caretLayoutObject(node); | 136 LayoutBlock* caretPainter = caretLayoutObject(node); |
134 if (!caretPainter) | 137 if (!caretPainter) |
135 return IntRect(); | 138 return IntRect(); |
136 | 139 |
137 LayoutRect localRect(rect); | 140 LayoutRect localRect(rect); |
138 caretPainter->flipForWritingMode(localRect); | 141 caretPainter->flipForWritingMode(localRect); |
139 return caretPainter->localToAbsoluteQuad(FloatRect(localRect)).enclosingBoun
dingBox(); | 142 return caretPainter->localToAbsoluteQuad(FloatRect(localRect)).enclosingBoun
dingBox(); |
140 } | 143 } |
141 | 144 |
| 145 DisplayItemClient* CaretBase::displayItemClientForCaret(Node* node) |
| 146 { |
| 147 LayoutBlock* caretLayoutBlock = caretLayoutObject(node); |
| 148 if (caretLayoutBlock->usesCompositedScrolling()) |
| 149 return static_cast<DisplayItemClient*>(caretLayoutBlock->layer()->graphi
csLayerBackingForScrolling()); |
| 150 return caretLayoutBlock; |
| 151 } |
| 152 |
142 // TODO(yoichio): |node| is FrameSelection::m_previousCaretNode and this is bad | 153 // TODO(yoichio): |node| is FrameSelection::m_previousCaretNode and this is bad |
143 // design. We should use only previous layoutObject or Rectangle to invalidate | 154 // design. We should use only previous layoutObject or Rectangle to invalidate |
144 // old caret. | 155 // old caret. |
145 void CaretBase::invalidateLocalCaretRect(Node* node, const LayoutRect& rect) | 156 void CaretBase::invalidateLocalCaretRect(Node* node, const LayoutRect& rect) |
146 { | 157 { |
147 LayoutBlockItem caretPainter = LayoutBlockItem(caretLayoutObject(node)); | 158 LayoutBlock* caretLayoutBlock = caretLayoutObject(node); |
148 if (!caretPainter) | 159 if (!caretLayoutBlock) |
149 return; | 160 return; |
150 | 161 |
151 // FIXME: Need to over-paint 1 pixel to workaround some rounding problems. | 162 // FIXME: Need to over-paint 1 pixel to workaround some rounding problems. |
152 // https://bugs.webkit.org/show_bug.cgi?id=108283 | 163 // https://bugs.webkit.org/show_bug.cgi?id=108283 |
153 LayoutRect inflatedRect = rect; | 164 LayoutRect inflatedRect = rect; |
154 inflatedRect.inflate(LayoutUnit(1)); | 165 inflatedRect.inflate(LayoutUnit(1)); |
155 | 166 |
156 // FIXME: We should use mapLocalToAncestor() since we know we're not un-root
ed. | |
157 mapCaretRectToCaretPainter(LayoutItem(node->layoutObject()), caretPainter, i
nflatedRect); | |
158 | |
159 // FIXME: We should not allow paint invalidation out of paint invalidation s
tate. crbug.com/457415 | 167 // FIXME: We should not allow paint invalidation out of paint invalidation s
tate. crbug.com/457415 |
160 DisablePaintInvalidationStateAsserts disabler; | 168 DisablePaintInvalidationStateAsserts disabler; |
161 caretPainter.invalidatePaintRectangle(inflatedRect); | 169 |
| 170 node->layoutObject()->invalidatePaintRectangle(inflatedRect, displayItemClie
ntForCaret(node)); |
162 } | 171 } |
163 | 172 |
164 bool CaretBase::shouldRepaintCaret(Node& node) const | 173 bool CaretBase::shouldRepaintCaret(Node& node) const |
165 { | 174 { |
166 // If PositionAnchorType::BeforeAnchor or PositionAnchorType::AfterAnchor, | 175 // If PositionAnchorType::BeforeAnchor or PositionAnchorType::AfterAnchor, |
167 // carets need to be repainted not only when the node is contentEditable but | 176 // carets need to be repainted not only when the node is contentEditable but |
168 // also when its parentNode() is contentEditable. | 177 // also when its parentNode() is contentEditable. |
169 node.document().updateStyleAndLayoutTree(); | 178 node.document().updateStyleAndLayoutTree(); |
170 return hasEditableStyle(node) || (node.parentNode() && hasEditableStyle(*nod
e.parentNode())); | 179 return hasEditableStyle(node) || (node.parentNode() && hasEditableStyle(*nod
e.parentNode())); |
171 } | 180 } |
(...skipping 13 matching lines...) Expand all Loading... |
185 if (caretRectChanged) | 194 if (caretRectChanged) |
186 return; | 195 return; |
187 | 196 |
188 if (LayoutViewItem view = node->document().layoutViewItem()) { | 197 if (LayoutViewItem view = node->document().layoutViewItem()) { |
189 node->document().updateStyleAndLayoutTree(); | 198 node->document().updateStyleAndLayoutTree(); |
190 if (hasEditableStyle(*node) || shouldRepaintCaret(view)) | 199 if (hasEditableStyle(*node) || shouldRepaintCaret(view)) |
191 invalidateLocalCaretRect(node, localCaretRectWithoutUpdate()); | 200 invalidateLocalCaretRect(node, localCaretRectWithoutUpdate()); |
192 } | 201 } |
193 } | 202 } |
194 | 203 |
195 void CaretBase::paintCaret(Node* node, GraphicsContext& context, const LayoutPoi
nt& paintOffset) const | 204 void CaretBase::paintCaret(Node* node, GraphicsContext& context, const LayoutPoi
nt& paintOffset, DisplayItem::Type displayItemType) const |
196 { | 205 { |
197 if (m_caretVisibility == CaretVisibility::Hidden) | 206 if (m_caretVisibility == CaretVisibility::Hidden) |
198 return; | 207 return; |
199 | 208 |
| 209 if (DrawingRecorder::useCachedDrawingIfPossible(context, *displayItemClientF
orCaret(node), displayItemType)) |
| 210 return; |
| 211 |
200 LayoutRect drawingRect = localCaretRectWithoutUpdate(); | 212 LayoutRect drawingRect = localCaretRectWithoutUpdate(); |
201 if (LayoutBlock* layoutObject = caretLayoutObject(node)) | 213 if (LayoutBlock* layoutObject = caretLayoutObject(node)) |
202 layoutObject->flipForWritingMode(drawingRect); | 214 layoutObject->flipForWritingMode(drawingRect); |
203 drawingRect.moveBy(roundedIntPoint(paintOffset)); | 215 drawingRect.moveBy(roundedIntPoint(paintOffset)); |
204 | 216 |
205 Color caretColor = Color::black; | 217 Color caretColor = Color::black; |
206 | 218 |
207 Element* element; | 219 Element* element; |
208 if (node->isElementNode()) | 220 if (node->isElementNode()) |
209 element = toElement(node); | 221 element = toElement(node); |
210 else | 222 else |
211 element = node->parentElement(); | 223 element = node->parentElement(); |
212 | 224 |
213 if (element && element->layoutObject()) | 225 if (element && element->layoutObject()) |
214 caretColor = element->layoutObject()->resolveColor(CSSPropertyColor); | 226 caretColor = element->layoutObject()->resolveColor(CSSPropertyColor); |
215 | 227 |
| 228 DrawingRecorder drawingRecorder(context, *displayItemClientForCaret(node), D
isplayItem::Caret, FloatRect(drawingRect)); |
| 229 |
216 context.fillRect(FloatRect(drawingRect), caretColor); | 230 context.fillRect(FloatRect(drawingRect), caretColor); |
217 } | 231 } |
218 | 232 |
219 void CaretBase::setCaretVisibility(CaretVisibility visibility) | 233 void CaretBase::setCaretVisibility(CaretVisibility visibility) |
220 { | 234 { |
221 m_caretVisibility = visibility; | 235 m_caretVisibility = visibility; |
222 } | 236 } |
223 | 237 |
224 } // namespace blink | 238 } // namespace blink |
OLD | NEW |