Commit 452d92b6 authored by Xiaocheng Hu's avatar Xiaocheng Hu Committed by Commit Bot

Merge AdjustInlineBoxPositionForTextDirection() into inline_box_traversal.cc

This patch merges the template function into inline_box_traversal.cc
to reuse the left and right traversal strategies defined there, and also
hide implementation details of bidi adjustment

This is also a preparation for implementing NG bidi implementation by
generalizing existing code: crrev.com/c/1038058

Bug: 822575
Change-Id: Ie64f005b3e5f510cf3664000ecb5fd5d157b6bac
Reviewed-on: https://chromium-review.googlesource.com/1048974
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
Reviewed-by: default avatarEmil A Eklund <eae@chromium.org>
Cr-Commit-Position: refs/heads/master@{#559290}
parent 6d57d9f6
...@@ -45,130 +45,6 @@ namespace blink { ...@@ -45,130 +45,6 @@ namespace blink {
namespace { namespace {
class LeftEdge {
STATIC_ONLY(LeftEdge);
public:
static InlineBoxPosition UnadjustedInlineBoxPosition(
const InlineBox& inline_box) {
return InlineBoxPosition(&inline_box, inline_box.CaretLeftmostOffset());
}
static const InlineBox* BackwardLeafChild(const InlineBox& inline_box) {
return inline_box.PrevLeafChild();
}
static const InlineBox* BackwardLeafChildIgnoringLineBreak(
const InlineBox& inline_box) {
return inline_box.PrevLeafChildIgnoringLineBreak();
}
// Returns true if |inlineBox| starts different direction of embedded text ru.
// See [1] for details.
// [1] UNICODE BIDIRECTIONAL ALGORITHM, http://unicode.org/reports/tr9/
static bool IsStartOfDifferentDirection(const InlineBox& inline_box) {
const InlineBox* prev_box = inline_box.PrevLeafChild();
if (!prev_box)
return true;
if (prev_box->Direction() == inline_box.Direction())
return true;
DCHECK_NE(prev_box->BidiLevel(), inline_box.BidiLevel());
return prev_box->BidiLevel() > inline_box.BidiLevel();
}
static const InlineBox* FindForwardBidiRun(const InlineBox& inline_box,
unsigned bidi_level) {
return InlineBoxTraversal::FindRightBidiRun(inline_box, bidi_level);
}
static InlineBoxPosition FindForwardBoundaryOfEntireBidiRunIgnoringLineBreak(
const InlineBox& inline_box,
unsigned bidi_level) {
const InlineBox& result_box =
InlineBoxTraversal::FindRightBoundaryOfEntireBidiRunIgnoringLineBreak(
inline_box, bidi_level);
return InlineBoxPosition(&result_box, result_box.CaretRightmostOffset());
}
static InlineBoxPosition FindBackwardBoundaryOfEntireBidiRun(
const InlineBox& inline_box,
unsigned bidi_level) {
const InlineBox& result_box =
InlineBoxTraversal::FindLeftBoundaryOfEntireBidiRun(inline_box,
bidi_level);
return InlineBoxPosition(&result_box, result_box.CaretLeftmostOffset());
}
static InlineBoxPosition FindBackwardBoundaryOfBidiRunIgnoringLineBreak(
const InlineBox& inline_box,
unsigned bidi_level) {
const InlineBox& result_box =
InlineBoxTraversal::FindLeftBoundaryOfBidiRunIgnoringLineBreak(
inline_box, bidi_level);
return InlineBoxPosition(&result_box, result_box.CaretLeftmostOffset());
}
};
class RightEdge {
STATIC_ONLY(RightEdge);
public:
static InlineBoxPosition UnadjustedInlineBoxPosition(
const InlineBox& inline_box) {
return InlineBoxPosition(&inline_box, inline_box.CaretRightmostOffset());
}
static const InlineBox* BackwardLeafChild(const InlineBox& inline_box) {
return inline_box.NextLeafChild();
}
static const InlineBox* BackwardLeafChildIgnoringLineBreak(
const InlineBox& inline_box) {
return inline_box.NextLeafChildIgnoringLineBreak();
}
// TODO(editing-dev): This function is almost identical to
// LeftEdge::IsStartOfDifferentDirection(). Try to unify them.
static bool IsStartOfDifferentDirection(const InlineBox& inline_box) {
const InlineBox* const next_box = inline_box.NextLeafChild();
if (!next_box)
return true;
return next_box->BidiLevel() >= inline_box.BidiLevel();
}
static const InlineBox* FindForwardBidiRun(const InlineBox& inline_box,
unsigned bidi_level) {
return InlineBoxTraversal::FindLeftBidiRun(inline_box, bidi_level);
}
static InlineBoxPosition FindForwardBoundaryOfEntireBidiRunIgnoringLineBreak(
const InlineBox& inline_box,
unsigned bidi_level) {
const InlineBox& result_box =
InlineBoxTraversal::FindLeftBoundaryOfEntireBidiRunIgnoringLineBreak(
inline_box, bidi_level);
return InlineBoxPosition(&result_box, result_box.CaretLeftmostOffset());
}
static InlineBoxPosition FindBackwardBoundaryOfEntireBidiRun(
const InlineBox& inline_box,
unsigned bidi_level) {
const InlineBox& result_box =
InlineBoxTraversal::FindRightBoundaryOfEntireBidiRun(inline_box,
bidi_level);
return InlineBoxPosition(&result_box, result_box.CaretRightmostOffset());
}
static InlineBoxPosition FindBackwardBoundaryOfBidiRunIgnoringLineBreak(
const InlineBox& inline_box,
unsigned bidi_level) {
const InlineBox& result_box =
InlineBoxTraversal::FindRightBoundaryOfBidiRunIgnoringLineBreak(
inline_box, bidi_level);
return InlineBoxPosition(&result_box, result_box.CaretRightmostOffset());
}
};
bool IsNonTextLeafChild(LayoutObject* object) { bool IsNonTextLeafChild(LayoutObject* object) {
if (object->SlowFirstChild()) if (object->SlowFirstChild())
return false; return false;
...@@ -226,70 +102,14 @@ PositionTemplate<Strategy> UpstreamIgnoringEditingBoundaries( ...@@ -226,70 +102,14 @@ PositionTemplate<Strategy> UpstreamIgnoringEditingBoundaries(
return position; return position;
} }
// |EdgeSide| defines which edge of |inline_box| to adjust. When
// traversing leaf InlineBoxes, "forward" means the direction from the adjusted
// edge to the other edge of |inline_box|, namely:
// - |LeftEdge|: "forward" means left-to-right
// - |RightEdge|: "forward" means right-to-left
template <typename EdgeSide>
InlineBoxPosition AdjustInlineBoxPositionForPrimaryDirection(
const InlineBox& inline_box) {
if (EdgeSide::IsStartOfDifferentDirection(inline_box))
return EdgeSide::UnadjustedInlineBoxPosition(inline_box);
const unsigned level = EdgeSide::BackwardLeafChild(inline_box)->BidiLevel();
const InlineBox* const forward_box =
EdgeSide::FindForwardBidiRun(inline_box, level);
// For example, abc FED 123 ^ CBA when adjusting right edge of 123
if (forward_box && forward_box->BidiLevel() == level)
return EdgeSide::UnadjustedInlineBoxPosition(inline_box);
// For example, abc 123 ^ CBA when adjusting right edge of 123
return EdgeSide::FindBackwardBoundaryOfEntireBidiRun(inline_box, level);
}
template <typename EdgeSide>
InlineBoxPosition AdjustInlineBoxPositionForTextDirectionAlgorithm(
const InlineBox& inline_box,
UnicodeBidi unicode_bidi) {
const TextDirection primary_direction =
inline_box.Root().Block().Style()->Direction();
if (inline_box.Direction() == primary_direction)
return AdjustInlineBoxPositionForPrimaryDirection<EdgeSide>(inline_box);
if (unicode_bidi == UnicodeBidi::kPlaintext)
return EdgeSide::UnadjustedInlineBoxPosition(inline_box);
const unsigned char level = inline_box.BidiLevel();
const InlineBox* const backward_box =
EdgeSide::BackwardLeafChildIgnoringLineBreak(inline_box);
if (!backward_box || backward_box->BidiLevel() < level) {
// Backward edge of a secondary run. Set to the forward edge of the entire
// run.
return EdgeSide::FindForwardBoundaryOfEntireBidiRunIgnoringLineBreak(
inline_box, level);
}
if (backward_box->BidiLevel() <= level)
return EdgeSide::UnadjustedInlineBoxPosition(inline_box);
// Forward edge of a "tertiary" run. Set to the backward edge of that run.
return EdgeSide::FindBackwardBoundaryOfBidiRunIgnoringLineBreak(inline_box,
level);
}
InlineBoxPosition AdjustInlineBoxPositionForTextDirection( InlineBoxPosition AdjustInlineBoxPositionForTextDirection(
InlineBox* inline_box, InlineBox* inline_box,
int caret_offset, int caret_offset,
UnicodeBidi unicode_bidi) { UnicodeBidi unicode_bidi) {
DCHECK(caret_offset == inline_box->CaretLeftmostOffset() || DCHECK(caret_offset == inline_box->CaretLeftmostOffset() ||
caret_offset == inline_box->CaretRightmostOffset()); caret_offset == inline_box->CaretRightmostOffset());
return caret_offset == inline_box->CaretLeftmostOffset() return BidiAdjustment::AdjustForCaretPositionResolution(
? AdjustInlineBoxPositionForTextDirectionAlgorithm<LeftEdge>( InlineBoxPosition(inline_box, caret_offset), unicode_bidi);
*inline_box, unicode_bidi)
: AdjustInlineBoxPositionForTextDirectionAlgorithm<RightEdge>(
*inline_box, unicode_bidi);
} }
// Returns true if |caret_offset| is at edge of |box| based on |affinity|. // Returns true if |caret_offset| is at edge of |box| based on |affinity|.
......
...@@ -5,13 +5,32 @@ ...@@ -5,13 +5,32 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_INLINE_BOX_TRAVERSAL_H_ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_INLINE_BOX_TRAVERSAL_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_INLINE_BOX_TRAVERSAL_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_INLINE_BOX_TRAVERSAL_H_
// TODO(xiaochengh): Rename this file to |bidi_adjustment.h|
#include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/allocator.h"
namespace blink { namespace blink {
class InlineBox; class InlineBox;
struct InlineBoxPosition;
enum class UnicodeBidi : unsigned;
class BidiAdjustment final {
STATIC_ONLY(BidiAdjustment);
public:
// TODO(xiaochengh): Eliminate |unicode_bidi| from parameters.
static InlineBoxPosition AdjustForCaretPositionResolution(
const InlineBoxPosition&,
UnicodeBidi unicode_bidi);
// TODO(xiaochengh): Clients of InlineBoxTraversal should be wrapped into
// new member functions here.
};
// This class provides common traveral functions on list of |InlineBox|. // This class provides common traveral functions on list of |InlineBox|.
// TODO(xiaochengh): Code using InlineBoxTraversal should be merged into the .cc
// file and templatized to share code with NG bidi traversal.
class InlineBoxTraversal final { class InlineBoxTraversal final {
STATIC_ONLY(InlineBoxTraversal); STATIC_ONLY(InlineBoxTraversal);
......
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