Commit 05fd6942 authored by yosin's avatar yosin Committed by Commit bot

Get rid of CaretBase::m_caretLocalRect

This patch gets rid of |CaretBase::m_caretLocalRect| to reduce number of states
in |CaretBase| to simplify class hiarachity for improving code health.

After this patch, |CaretBase| represents |DisplayItemClient| for caret.
Following patch will rename |CaretBase| to |DisplayCaretItemClient| and
|DragCaretController|, which should rename to |DragCaret| is derived from
|DisplayCaretItemClient| and makes |DisplayCaretItemClient| had no public
member except for destructor.

This patch is a preparation of [1]

[1] http://crrev.com/1958093002 On-demand visible selection canonicalizataion

BUG=680384
TEST=n/a; no behavior changes

Review-Url: https://codereview.chromium.org/2623053006
Cr-Commit-Position: refs/heads/master@{#443207}
parent 9438f509
......@@ -47,10 +47,6 @@ CaretBase::~CaretBase() = default;
DEFINE_TRACE(CaretBase) {}
void CaretBase::clearCaretRect() {
m_caretLocalRect = LayoutRect();
}
static inline bool caretRendersInsideNode(Node* node) {
return node && !isDisplayInsideTable(node) && !editingIgnoresContent(*node);
}
......@@ -77,53 +73,50 @@ LayoutBlock* CaretBase::caretLayoutObject(Node* node) {
: layoutObject->containingBlock();
}
static void mapCaretRectToCaretPainter(LayoutItem caretLayoutItem,
LayoutBlockItem caretPainterItem,
LayoutRect& caretRect) {
static LayoutRect mapCaretRectToCaretPainter(
LayoutItem caretLayoutItem,
LayoutBlockItem caretPainterItem,
const LayoutRect& passedCaretRect) {
// FIXME: This shouldn't be called on un-rooted subtrees.
// FIXME: This should probably just use mapLocalToAncestor.
// Compute an offset between the caretLayoutItem and the caretPainterItem.
DCHECK(caretLayoutItem.isDescendantOf(caretPainterItem));
bool unrooted = false;
LayoutRect caretRect = passedCaretRect;
while (caretLayoutItem != caretPainterItem) {
LayoutItem containerItem = caretLayoutItem.container();
if (containerItem.isNull()) {
unrooted = true;
break;
}
if (containerItem.isNull())
return LayoutRect();
caretRect.move(caretLayoutItem.offsetFromContainer(containerItem));
caretLayoutItem = containerItem;
}
if (unrooted)
caretRect = LayoutRect();
return caretRect;
}
void CaretBase::updateCaretRect(const PositionWithAffinity& caretPosition) {
m_caretLocalRect = LayoutRect();
LayoutRect CaretBase::computeCaretRect(
const PositionWithAffinity& caretPosition) {
if (caretPosition.isNull())
return;
return LayoutRect();
DCHECK(caretPosition.anchorNode()->layoutObject());
// First compute a rect local to the layoutObject at the selection start.
LayoutObject* layoutObject;
m_caretLocalRect = localCaretRectOfPosition(caretPosition, layoutObject);
const LayoutRect& caretLocalRect =
localCaretRectOfPosition(caretPosition, layoutObject);
// 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()));
mapCaretRectToCaretPainter(LayoutItem(layoutObject), caretPainterItem,
m_caretLocalRect);
return mapCaretRectToCaretPainter(LayoutItem(layoutObject), caretPainterItem,
caretLocalRect);
}
void CaretBase::updateCaretRect(const VisiblePosition& caretPosition) {
updateCaretRect(caretPosition.toPositionWithAffinity());
LayoutRect CaretBase::computeCaretRect(const VisiblePosition& caretPosition) {
return computeCaretRect(caretPosition.toPositionWithAffinity());
}
IntRect CaretBase::absoluteBoundsForLocalRect(Node* node,
......@@ -168,21 +161,24 @@ bool CaretBase::shouldRepaintCaret(Node& node) const {
(node.parentNode() && hasEditableStyle(*node.parentNode()));
}
void CaretBase::invalidateCaretRect(Node* node) {
void CaretBase::invalidateCaretRect(Node* node,
const LayoutRect& caretLocalRect) {
node->document().updateStyleAndLayoutTree();
if (hasEditableStyle(*node))
invalidateLocalCaretRect(node, localCaretRectWithoutUpdate());
invalidateLocalCaretRect(node, caretLocalRect);
}
void CaretBase::paintCaret(Node* node,
GraphicsContext& context,
const DisplayItemClient& client,
const LayoutRect& caretLocalRect,
const LayoutPoint& paintOffset,
DisplayItem::Type displayItemType) const {
if (DrawingRecorder::useCachedDrawingIfPossible(context, *this,
DisplayItem::Type displayItemType) {
if (DrawingRecorder::useCachedDrawingIfPossible(context, client,
displayItemType))
return;
LayoutRect drawingRect = localCaretRectWithoutUpdate();
LayoutRect drawingRect = caretLocalRect;
if (LayoutBlock* layoutObject = caretLayoutObject(node))
layoutObject->flipForWritingMode(drawingRect);
drawingRect.moveBy(paintOffset);
......@@ -190,7 +186,7 @@ void CaretBase::paintCaret(Node* node,
const Color caretColor =
node->layoutObject()->resolveColor(CSSPropertyCaretColor);
IntRect paintRect = pixelSnappedIntRect(drawingRect);
DrawingRecorder drawingRecorder(context, *this, DisplayItem::kCaret,
DrawingRecorder drawingRecorder(context, client, DisplayItem::kCaret,
paintRect);
context.fillRect(paintRect, caretColor);
}
......
......@@ -48,23 +48,29 @@ class CORE_EXPORT CaretBase : public GarbageCollectedFinalized<CaretBase>,
CaretBase();
virtual ~CaretBase();
void invalidateCaretRect(Node*);
void clearCaretRect();
void invalidateCaretRect(Node*, const LayoutRect&);
// Creating VisiblePosition causes synchronous layout so we should use the
// PositionWithAffinity version if possible.
// A position in HTMLTextFromControlElement is a typical example.
void updateCaretRect(const PositionWithAffinity& caretPosition);
void updateCaretRect(const VisiblePosition& caretPosition);
static LayoutRect computeCaretRect(const PositionWithAffinity& caretPosition);
// TODO(yosin): We should move |computeCaretRect()| with |VisiblePosition| to
// "FrameCaret.cpp" as static file local function.
static LayoutRect computeCaretRect(const VisiblePosition& caretPosition);
// TODO(yosin): We should move |absoluteBoundsForLocalRect()| with
// |VisiblePosition| to "FrameCaret.cpp" as static file local function.
IntRect absoluteBoundsForLocalRect(Node*, const LayoutRect&) const;
bool shouldRepaintCaret(Node&) const;
void paintCaret(Node*,
GraphicsContext&,
const LayoutPoint&,
DisplayItem::Type) const;
const LayoutRect& localCaretRectWithoutUpdate() const {
return m_caretLocalRect;
}
// TODO(yosin): We should move |shouldRepaintCaret()| to "FrameCaret.cpp" as
// static file local function.
bool shouldRepaintCaret(Node&) const;
static void paintCaret(Node*,
GraphicsContext&,
const DisplayItemClient&,
const LayoutRect& caretLocalRect,
const LayoutPoint&,
DisplayItem::Type);
static LayoutBlock* caretLayoutObject(Node*);
void invalidateLocalCaretRect(Node*, const LayoutRect&);
......@@ -76,9 +82,6 @@ class CORE_EXPORT CaretBase : public GarbageCollectedFinalized<CaretBase>,
DECLARE_VIRTUAL_TRACE();
private:
// caret rect in coords local to the layoutObject responsible for painting the
// caret
LayoutRect m_caretLocalRect;
LayoutRect m_visualRect;
};
......
......@@ -61,20 +61,20 @@ void DragCaretController::setCaretPosition(
DisableCompositingQueryAsserts disabler;
if (Node* node = m_position.anchorNode())
m_caretBase->invalidateCaretRect(node);
m_caretBase->invalidateCaretRect(node, m_caretLocalRect);
m_position = createVisiblePosition(position).toPositionWithAffinity();
Document* document = nullptr;
if (Node* node = m_position.anchorNode()) {
m_caretBase->invalidateCaretRect(node);
m_caretBase->invalidateCaretRect(node, m_caretLocalRect);
document = &node->document();
setContext(document);
}
if (m_position.isNull()) {
m_caretBase->clearCaretRect();
m_caretLocalRect = LayoutRect();
} else {
DCHECK(!m_position.isOrphan());
document->updateStyleAndLayoutTree();
m_caretBase->updateCaretRect(m_position);
m_caretLocalRect = CaretBase::computeCaretRect(m_position);
}
}
......@@ -112,8 +112,9 @@ void DragCaretController::paintDragCaret(LocalFrame* frame,
GraphicsContext& context,
const LayoutPoint& paintOffset) const {
if (m_position.anchorNode()->document().frame() == frame) {
m_caretBase->paintCaret(m_position.anchorNode(), context, paintOffset,
DisplayItem::kDragCaret);
CaretBase::paintCaret(m_position.anchorNode(), context, *m_caretBase,
m_caretLocalRect, paintOffset,
DisplayItem::kDragCaret);
}
}
......
......@@ -63,6 +63,9 @@ class DragCaretController final
void nodeWillBeRemoved(Node&) final;
PositionWithAffinity m_position;
// caret rect in coords local to the layoutObject responsible for painting the
// caret
LayoutRect m_caretLocalRect;
const Member<CaretBase> m_caretBase;
};
......
......@@ -209,6 +209,7 @@ void FrameCaret::invalidateCaretRect(bool forceInvalidation) {
m_previousCaretVisibility = m_caretVisibility;
}
// TDOO(yosin): We should mark |FrameCaret::absoluteCaretBounds()| to |const|.
IntRect FrameCaret::absoluteCaretBounds() {
DCHECK_NE(m_frame->document()->lifecycle().state(),
DocumentLifecycle::InPaintInvalidation);
......@@ -216,20 +217,18 @@ IntRect FrameCaret::absoluteCaretBounds() {
DocumentLifecycle::DisallowTransitionScope disallowTransition(
m_frame->document()->lifecycle());
if (!isActive()) {
clearCaretRect();
} else {
if (enclosingTextControl(caretPosition().position())) {
if (isVisuallyEquivalentCandidate(caretPosition().position()))
updateCaretRect(caretPosition());
else
updateCaretRect(createVisiblePosition(caretPosition()));
} else {
updateCaretRect(createVisiblePosition(caretPosition()));
}
Node* const caretNode = caretPosition().anchorNode();
if (!isActive())
return absoluteBoundsForLocalRect(caretNode, LayoutRect());
// TODO(yosin): We should get rid of text control short path since layout
// tree is clean.
if (enclosingTextControl(caretPosition().position()) &&
isVisuallyEquivalentCandidate(caretPosition().position())) {
return absoluteBoundsForLocalRect(caretNode,
computeCaretRect(caretPosition()));
}
return absoluteBoundsForLocalRect(caretPosition().anchorNode(),
localCaretRectWithoutUpdate());
return absoluteBoundsForLocalRect(
caretNode, computeCaretRect(createVisiblePosition(caretPosition())));
}
void FrameCaret::setShouldShowBlockCursor(bool shouldShowBlockCursor) {
......@@ -248,9 +247,9 @@ void FrameCaret::paintCaret(GraphicsContext& context,
if (!(isActive() && m_shouldPaintCaret))
return;
updateCaretRect(caretPosition());
CaretBase::paintCaret(caretPosition().anchorNode(), context, paintOffset,
DisplayItem::kCaret);
const LayoutRect caretLocalRect = computeCaretRect(caretPosition());
CaretBase::paintCaret(caretPosition().anchorNode(), context, *this,
caretLocalRect, paintOffset, DisplayItem::kCaret);
}
void FrameCaret::dataWillChange(const CharacterData& node) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment