| 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 27 matching lines...) Expand all Loading... |
| 38 #include "core/paint/PaintLayer.h" | 38 #include "core/paint/PaintLayer.h" |
| 39 #include "platform/graphics/GraphicsContext.h" | 39 #include "platform/graphics/GraphicsContext.h" |
| 40 #include "platform/graphics/GraphicsLayer.h" | 40 #include "platform/graphics/GraphicsLayer.h" |
| 41 #include "platform/graphics/paint/DrawingRecorder.h" | 41 #include "platform/graphics/paint/DrawingRecorder.h" |
| 42 | 42 |
| 43 namespace blink { | 43 namespace blink { |
| 44 | 44 |
| 45 CaretBase::CaretBase() = default; | 45 CaretBase::CaretBase() = default; |
| 46 CaretBase::~CaretBase() = default; | 46 CaretBase::~CaretBase() = default; |
| 47 | 47 |
| 48 DEFINE_TRACE(CaretBase) {} | |
| 49 | |
| 50 static inline bool caretRendersInsideNode(Node* node) { | 48 static inline bool caretRendersInsideNode(Node* node) { |
| 51 return node && !isDisplayInsideTable(node) && !editingIgnoresContent(*node); | 49 return node && !isDisplayInsideTable(node) && !editingIgnoresContent(*node); |
| 52 } | 50 } |
| 53 | 51 |
| 54 LayoutBlock* CaretBase::caretLayoutObject(Node* node) { | 52 LayoutBlock* CaretBase::caretLayoutObject(Node* node) { |
| 55 if (!node) | 53 if (!node) |
| 56 return nullptr; | 54 return nullptr; |
| 57 | 55 |
| 58 LayoutObject* layoutObject = node->layoutObject(); | 56 LayoutObject* layoutObject = node->layoutObject(); |
| 59 if (!layoutObject) | 57 if (!layoutObject) |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 | 106 |
| 109 // Get the layoutObject that will be responsible for painting the caret | 107 // Get the layoutObject that will be responsible for painting the caret |
| 110 // (which is either the layoutObject we just found, or one of its containers). | 108 // (which is either the layoutObject we just found, or one of its containers). |
| 111 LayoutBlockItem caretPainterItem = | 109 LayoutBlockItem caretPainterItem = |
| 112 LayoutBlockItem(caretLayoutObject(caretPosition.anchorNode())); | 110 LayoutBlockItem(caretLayoutObject(caretPosition.anchorNode())); |
| 113 | 111 |
| 114 return mapCaretRectToCaretPainter(LayoutItem(layoutObject), caretPainterItem, | 112 return mapCaretRectToCaretPainter(LayoutItem(layoutObject), caretPainterItem, |
| 115 caretLocalRect); | 113 caretLocalRect); |
| 116 } | 114 } |
| 117 | 115 |
| 118 LayoutRect CaretBase::computeCaretRect(const VisiblePosition& caretPosition) { | |
| 119 return computeCaretRect(caretPosition.toPositionWithAffinity()); | |
| 120 } | |
| 121 | |
| 122 IntRect CaretBase::absoluteBoundsForLocalRect(Node* node, | |
| 123 const LayoutRect& rect) const { | |
| 124 LayoutBlock* caretPainter = caretLayoutObject(node); | |
| 125 if (!caretPainter) | |
| 126 return IntRect(); | |
| 127 | |
| 128 LayoutRect localRect(rect); | |
| 129 caretPainter->flipForWritingMode(localRect); | |
| 130 return caretPainter->localToAbsoluteQuad(FloatRect(localRect)) | |
| 131 .enclosingBoundingBox(); | |
| 132 } | |
| 133 | |
| 134 // TODO(yoichio): |node| is FrameSelection::m_previousCaretNode and this is bad | 116 // TODO(yoichio): |node| is FrameSelection::m_previousCaretNode and this is bad |
| 135 // design. We should use only previous layoutObject or Rectangle to invalidate | 117 // design. We should use only previous layoutObject or Rectangle to invalidate |
| 136 // old caret. | 118 // old caret. |
| 137 void CaretBase::invalidateLocalCaretRect(Node* node, const LayoutRect& rect) { | 119 void CaretBase::invalidateLocalCaretRect(Node* node, const LayoutRect& rect) { |
| 138 LayoutBlock* caretLayoutBlock = caretLayoutObject(node); | 120 LayoutBlock* caretLayoutBlock = caretLayoutObject(node); |
| 139 if (!caretLayoutBlock) | 121 if (!caretLayoutBlock) |
| 140 return; | 122 return; |
| 141 | 123 |
| 142 // FIXME: Need to over-paint 1 pixel to workaround some rounding problems. | 124 // FIXME: Need to over-paint 1 pixel to workaround some rounding problems. |
| 143 // https://bugs.webkit.org/show_bug.cgi?id=108283 | 125 // https://bugs.webkit.org/show_bug.cgi?id=108283 |
| 144 LayoutRect inflatedRect = rect; | 126 LayoutRect inflatedRect = rect; |
| 145 inflatedRect.inflate(LayoutUnit(1)); | 127 inflatedRect.inflate(LayoutUnit(1)); |
| 146 | 128 |
| 147 // FIXME: We should not allow paint invalidation out of paint invalidation | 129 // FIXME: We should not allow paint invalidation out of paint invalidation |
| 148 // state. crbug.com/457415 | 130 // state. crbug.com/457415 |
| 149 DisablePaintInvalidationStateAsserts disabler; | 131 DisablePaintInvalidationStateAsserts disabler; |
| 150 | 132 |
| 151 m_visualRect = | 133 m_visualRect = |
| 152 node->layoutObject()->invalidatePaintRectangle(inflatedRect, this); | 134 node->layoutObject()->invalidatePaintRectangle(inflatedRect, this); |
| 153 } | 135 } |
| 154 | 136 |
| 155 bool CaretBase::shouldRepaintCaret(Node& node) const { | |
| 156 // If PositionAnchorType::BeforeAnchor or PositionAnchorType::AfterAnchor, | |
| 157 // carets need to be repainted not only when the node is contentEditable but | |
| 158 // also when its parentNode() is contentEditable. | |
| 159 node.document().updateStyleAndLayoutTree(); | |
| 160 return hasEditableStyle(node) || | |
| 161 (node.parentNode() && hasEditableStyle(*node.parentNode())); | |
| 162 } | |
| 163 | |
| 164 void CaretBase::invalidateCaretRect(Node* node, | 137 void CaretBase::invalidateCaretRect(Node* node, |
| 165 const LayoutRect& caretLocalRect) { | 138 const LayoutRect& caretLocalRect) { |
| 166 node->document().updateStyleAndLayoutTree(); | 139 node->document().updateStyleAndLayoutTree(); |
| 167 if (hasEditableStyle(*node)) | 140 if (hasEditableStyle(*node)) |
| 168 invalidateLocalCaretRect(node, caretLocalRect); | 141 invalidateLocalCaretRect(node, caretLocalRect); |
| 169 } | 142 } |
| 170 | 143 |
| 171 void CaretBase::paintCaret(Node* node, | 144 void CaretBase::paintCaret(Node* node, |
| 172 GraphicsContext& context, | 145 GraphicsContext& context, |
| 173 const DisplayItemClient& client, | |
| 174 const LayoutRect& caretLocalRect, | 146 const LayoutRect& caretLocalRect, |
| 175 const LayoutPoint& paintOffset, | 147 const LayoutPoint& paintOffset, |
| 176 DisplayItem::Type displayItemType) { | 148 DisplayItem::Type displayItemType) { |
| 177 if (DrawingRecorder::useCachedDrawingIfPossible(context, client, | 149 if (DrawingRecorder::useCachedDrawingIfPossible(context, *this, |
| 178 displayItemType)) | 150 displayItemType)) |
| 179 return; | 151 return; |
| 180 | 152 |
| 181 LayoutRect drawingRect = caretLocalRect; | 153 LayoutRect drawingRect = caretLocalRect; |
| 182 if (LayoutBlock* layoutObject = caretLayoutObject(node)) | 154 if (LayoutBlock* layoutObject = caretLayoutObject(node)) |
| 183 layoutObject->flipForWritingMode(drawingRect); | 155 layoutObject->flipForWritingMode(drawingRect); |
| 184 drawingRect.moveBy(paintOffset); | 156 drawingRect.moveBy(paintOffset); |
| 185 | 157 |
| 186 const Color caretColor = | 158 const Color caretColor = |
| 187 node->layoutObject()->resolveColor(CSSPropertyCaretColor); | 159 node->layoutObject()->resolveColor(CSSPropertyCaretColor); |
| 188 IntRect paintRect = pixelSnappedIntRect(drawingRect); | 160 IntRect paintRect = pixelSnappedIntRect(drawingRect); |
| 189 DrawingRecorder drawingRecorder(context, client, DisplayItem::kCaret, | 161 DrawingRecorder drawingRecorder(context, *this, DisplayItem::kCaret, |
| 190 paintRect); | 162 paintRect); |
| 191 context.fillRect(paintRect, caretColor); | 163 context.fillRect(paintRect, caretColor); |
| 192 } | 164 } |
| 193 | 165 |
| 194 String CaretBase::debugName() const { | 166 String CaretBase::debugName() const { |
| 195 return "Caret"; | 167 return "Caret"; |
| 196 } | 168 } |
| 197 | 169 |
| 198 LayoutRect CaretBase::visualRect() const { | 170 LayoutRect CaretBase::visualRect() const { |
| 199 return m_visualRect; | 171 return m_visualRect; |
| 200 } | 172 } |
| 201 | 173 |
| 202 } // namespace blink | 174 } // namespace blink |
| OLD | NEW |