Commit 685e00f8 authored by Xiaocheng Hu's avatar Xiaocheng Hu Committed by Commit Bot

Simplify RenderedPosition equivalence relationship

RenderedPosition defines an "equivalence" relationship that,
when we have two adjacent inline boxes, the following two RPs are
considered equivalent:
- RP at the rightmost offset in the left-hand-side box
- RP at the leftmost offset in the right-hand-side box

However, with RenderedPosition being used only in SelectionController
for bidi adjustment, such general operation isn't needed:
- There's no need to check equivalence for RPs that are not at bidi
  boundaries
- For RPs at bidi boundaries, we can move the RP to the box with higher
  bidi level, and then compare the RPs directly

Therefore, this patch changes RP's constructor that, if an RP is
created at bidi boundary, make sure it's in the box with higher bidi
level. In this way, there's no need to define equivalence, and existing
call sites can simply check equality.

This is a preparation patch for implementing same bidi adjustment
in layout NG.

Bug: 811502
Change-Id: Ic4171e60efb47a31a9f1916a185953c1fc660bb7
Reviewed-on: https://chromium-review.googlesource.com/1052988
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
Reviewed-by: default avatarYoichi Osato <yoichio@chromium.org>
Cr-Commit-Position: refs/heads/master@{#557768}
parent 8db438f7
...@@ -46,14 +46,37 @@ ...@@ -46,14 +46,37 @@
namespace blink { namespace blink {
RenderedPosition::RenderedPosition(const VisiblePositionInFlatTree& position) // static
: inline_box_(nullptr), offset_(0) { RenderedPosition RenderedPosition::Create(
const VisiblePositionInFlatTree& position) {
if (position.IsNull()) if (position.IsNull())
return; return RenderedPosition();
InlineBoxPosition box_position = InlineBoxPosition box_position =
ComputeInlineBoxPosition(position.ToPositionWithAffinity()); ComputeInlineBoxPosition(position.ToPositionWithAffinity());
inline_box_ = box_position.inline_box; if (!box_position.inline_box)
offset_ = box_position.offset_in_box; return RenderedPosition();
const InlineBox* box = box_position.inline_box;
const int offset = box_position.offset_in_box;
// When at bidi boundary, ensure that |inline_box_| belongs to the higher-
// level bidi run.
// For example, abc FED |ghi should be changed into abc FED| ghi
if (offset == box->CaretLeftmostOffset()) {
const InlineBox* prev_box = box->PrevLeafChildIgnoringLineBreak();
if (prev_box && prev_box->BidiLevel() > box->BidiLevel())
return RenderedPosition(prev_box, prev_box->CaretRightmostOffset());
}
// For example, abc| FED ghi should be changed into abc |FED ghi
if (offset == box->CaretRightmostOffset()) {
const InlineBox* next_box = box->NextLeafChildIgnoringLineBreak();
if (next_box && next_box->BidiLevel() > box->BidiLevel())
return RenderedPosition(next_box, next_box->CaretLeftmostOffset());
}
return RenderedPosition(box, offset);
} }
const InlineBox* RenderedPosition::PrevLeafChild() const { const InlineBox* RenderedPosition::PrevLeafChild() const {
...@@ -68,14 +91,6 @@ const InlineBox* RenderedPosition::NextLeafChild() const { ...@@ -68,14 +91,6 @@ const InlineBox* RenderedPosition::NextLeafChild() const {
return next_leaf_child_.value(); return next_leaf_child_.value();
} }
bool RenderedPosition::IsEquivalent(const RenderedPosition& other) const {
return (inline_box_ == other.inline_box_ && offset_ == other.offset_) ||
(AtLeftmostOffsetInBox() && other.AtRightmostOffsetInBox() &&
PrevLeafChild() == other.inline_box_) ||
(AtRightmostOffsetInBox() && other.AtLeftmostOffsetInBox() &&
NextLeafChild() == other.inline_box_);
}
unsigned char RenderedPosition::BidiLevelOnLeft() const { unsigned char RenderedPosition::BidiLevelOnLeft() const {
const InlineBox* box = const InlineBox* box =
AtLeftmostOffsetInBox() ? PrevLeafChild() : inline_box_; AtLeftmostOffsetInBox() ? PrevLeafChild() : inline_box_;
......
...@@ -51,10 +51,12 @@ class CORE_EXPORT RenderedPosition { ...@@ -51,10 +51,12 @@ class CORE_EXPORT RenderedPosition {
public: public:
RenderedPosition(); RenderedPosition();
explicit RenderedPosition(const VisiblePositionInFlatTree&); static RenderedPosition Create(const VisiblePositionInFlatTree&);
bool IsEquivalent(const RenderedPosition&) const;
bool IsNull() const { return !inline_box_; } bool IsNull() const { return !inline_box_; }
bool operator==(const RenderedPosition& other) const {
return inline_box_ == other.inline_box_ && offset_ == other.offset_;
}
unsigned char BidiLevelOnLeft() const; unsigned char BidiLevelOnLeft() const;
unsigned char BidiLevelOnRight() const; unsigned char BidiLevelOnRight() const;
...@@ -85,7 +87,6 @@ class CORE_EXPORT RenderedPosition { ...@@ -85,7 +87,6 @@ class CORE_EXPORT RenderedPosition {
static CompositedSelection ComputeCompositedSelection(const FrameSelection&); static CompositedSelection ComputeCompositedSelection(const FrameSelection&);
private: private:
bool operator==(const RenderedPosition&) const { return false; }
explicit RenderedPosition(const InlineBox*, int offset); explicit RenderedPosition(const InlineBox*, int offset);
const InlineBox* PrevLeafChild() const; const InlineBox* PrevLeafChild() const;
......
...@@ -770,8 +770,8 @@ static SelectionInFlatTree AdjustEndpointsAtBidiBoundary( ...@@ -770,8 +770,8 @@ static SelectionInFlatTree AdjustEndpointsAtBidiBoundary(
DCHECK(visible_base.IsValid()); DCHECK(visible_base.IsValid());
DCHECK(visible_extent.IsValid()); DCHECK(visible_extent.IsValid());
RenderedPosition base(visible_base); RenderedPosition base = RenderedPosition::Create(visible_base);
RenderedPosition extent(visible_extent); RenderedPosition extent = RenderedPosition::Create(visible_extent);
const SelectionInFlatTree& unchanged_selection = const SelectionInFlatTree& unchanged_selection =
SelectionInFlatTree::Builder() SelectionInFlatTree::Builder()
...@@ -779,13 +779,12 @@ static SelectionInFlatTree AdjustEndpointsAtBidiBoundary( ...@@ -779,13 +779,12 @@ static SelectionInFlatTree AdjustEndpointsAtBidiBoundary(
visible_extent.DeepEquivalent()) visible_extent.DeepEquivalent())
.Build(); .Build();
if (base.IsNull() || extent.IsNull() || base.IsEquivalent(extent)) if (base.IsNull() || extent.IsNull() || base == extent)
return unchanged_selection; return unchanged_selection;
if (base.AtLeftBoundaryOfBidiRun()) { if (base.AtLeftBoundaryOfBidiRun()) {
if (!extent.AtRightBoundaryOfBidiRun(base.BidiLevelOnRight()) && if (!extent.AtRightBoundaryOfBidiRun(base.BidiLevelOnRight()) &&
base.IsEquivalent( base == extent.LeftBoundaryOfBidiRun(base.BidiLevelOnRight())) {
extent.LeftBoundaryOfBidiRun(base.BidiLevelOnRight()))) {
return SelectionInFlatTree::Builder() return SelectionInFlatTree::Builder()
.SetBaseAndExtent( .SetBaseAndExtent(
CreateVisiblePosition(base.PositionAtLeftBoundaryOfBiDiRun()) CreateVisiblePosition(base.PositionAtLeftBoundaryOfBiDiRun())
...@@ -798,8 +797,7 @@ static SelectionInFlatTree AdjustEndpointsAtBidiBoundary( ...@@ -798,8 +797,7 @@ static SelectionInFlatTree AdjustEndpointsAtBidiBoundary(
if (base.AtRightBoundaryOfBidiRun()) { if (base.AtRightBoundaryOfBidiRun()) {
if (!extent.AtLeftBoundaryOfBidiRun(base.BidiLevelOnLeft()) && if (!extent.AtLeftBoundaryOfBidiRun(base.BidiLevelOnLeft()) &&
base.IsEquivalent( base == extent.RightBoundaryOfBidiRun(base.BidiLevelOnLeft())) {
extent.RightBoundaryOfBidiRun(base.BidiLevelOnLeft()))) {
return SelectionInFlatTree::Builder() return SelectionInFlatTree::Builder()
.SetBaseAndExtent( .SetBaseAndExtent(
CreateVisiblePosition(base.PositionAtRightBoundaryOfBiDiRun()) CreateVisiblePosition(base.PositionAtRightBoundaryOfBiDiRun())
...@@ -811,8 +809,7 @@ static SelectionInFlatTree AdjustEndpointsAtBidiBoundary( ...@@ -811,8 +809,7 @@ static SelectionInFlatTree AdjustEndpointsAtBidiBoundary(
} }
if (extent.AtLeftBoundaryOfBidiRun() && if (extent.AtLeftBoundaryOfBidiRun() &&
extent.IsEquivalent( extent == base.LeftBoundaryOfBidiRun(extent.BidiLevelOnRight())) {
base.LeftBoundaryOfBidiRun(extent.BidiLevelOnRight()))) {
return SelectionInFlatTree::Builder() return SelectionInFlatTree::Builder()
.SetBaseAndExtent( .SetBaseAndExtent(
visible_base.DeepEquivalent(), visible_base.DeepEquivalent(),
...@@ -822,8 +819,7 @@ static SelectionInFlatTree AdjustEndpointsAtBidiBoundary( ...@@ -822,8 +819,7 @@ static SelectionInFlatTree AdjustEndpointsAtBidiBoundary(
} }
if (extent.AtRightBoundaryOfBidiRun() && if (extent.AtRightBoundaryOfBidiRun() &&
extent.IsEquivalent( extent == base.RightBoundaryOfBidiRun(extent.BidiLevelOnLeft())) {
base.RightBoundaryOfBidiRun(extent.BidiLevelOnLeft()))) {
return SelectionInFlatTree::Builder() return SelectionInFlatTree::Builder()
.SetBaseAndExtent( .SetBaseAndExtent(
visible_base.DeepEquivalent(), visible_base.DeepEquivalent(),
......
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