blob: 297bda00eae1c69f3286d4bc0b7acdf9eb9d73cc [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_CARET_NAVIGATOR_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_CARET_NAVIGATOR_H_
#include "base/optional.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/editing/text_affinity.h"
#include "third_party/blink/renderer/platform/text/text_direction.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include <unicode/ubidi.h>
namespace blink {
struct NGInlineNodeData;
// Hosts the |text_content| of an inline formatting context and provides
// bidi-related utilities, including checking bidi levels, computing visual
// left/right characters and visual left/right caret movements.
// Design doc: http://bit.ly/2QVAwGq
class CORE_EXPORT NGCaretNavigator {
public:
NGCaretNavigator(NGCaretNavigator&&);
explicit NGCaretNavigator(const NGInlineNodeData&);
~NGCaretNavigator();
// Abstraction of a caret position in |text_|.
struct Position {
unsigned offset;
TextAffinity affinity;
bool operator==(const Position& other) const {
return offset == other.offset && affinity == other.affinity;
}
};
// Returns the bidi level or resolved direction of the character at the given
// logical |index|.
UBiDiLevel BidiLevelAt(unsigned index) const;
TextDirection TextDirectionAt(unsigned index) const;
// Returns true if the characters at indexes |offset - 1| and |offset| both
// exist and are at different bidi levels.
bool OffsetIsBidiBoundary(unsigned offset) const;
// Returns the resolved direction of the anchor character of a caret position.
TextDirection TextDirectionAt(const Position&) const;
// Returns the logical index that a Position is anchored to.
unsigned AnchorCharacterIndex(const Position&) const;
// Returns the visual left/right edge caret position of the character at the
// given logical |index|.
Position LeftEdgeOf(unsigned index) const;
Position RightEdgeOf(unsigned index) const;
// Left/right visual movements
// TODO(xiaochengh): Handle the following
// - Grapheme clusters
// - Enterable atomic inlines
// - Editing-ignored contents
// - Multiple lines
enum class VisualMovementResultType {
kWithinContext,
kBeforeContext,
kAfterContext
};
// Given the character at the logical |index|, returns the logical index of
// the character at its left/right side.
struct VisualCharacterMovementResult {
bool IsWithinContext() const {
return type == VisualMovementResultType::kWithinContext;
}
bool IsBeforeContext() const {
return type == VisualMovementResultType::kBeforeContext;
}
bool IsAfterContext() const {
return type == VisualMovementResultType::kAfterContext;
}
VisualMovementResultType type;
base::Optional<unsigned> index;
};
VisualCharacterMovementResult LeftCharacterOf(unsigned index) const;
VisualCharacterMovementResult RightCharacterOf(unsigned index) const;
// Given a caret position, moves it left/right by one grapheme cluster and
// returns the result.
struct VisualCaretMovementResult {
bool IsWithinContext() const {
return type == VisualMovementResultType::kWithinContext;
}
bool IsBeforeContext() const {
return type == VisualMovementResultType::kBeforeContext;
}
bool IsAfterContext() const {
return type == VisualMovementResultType::kAfterContext;
}
VisualMovementResultType type;
base::Optional<Position> position;
};
VisualCaretMovementResult LeftPositionOf(const Position&) const;
VisualCaretMovementResult RightPositionOf(const Position&) const;
private:
String text_;
// TODO(xiaochengh): Add line-aware index.
// TODO(xiaochengh): Reduce memory consumption.
Vector<UBiDiLevel, 32> bidi_levels_;
Vector<int32_t, 32> indices_in_visual_order_;
Vector<int32_t, 32> visual_indices_;
bool is_bidi_enabled_;
TextDirection base_direction_;
DISALLOW_COPY_AND_ASSIGN(NGCaretNavigator);
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_CARET_NAVIGATOR_H_