Commit 345274f3 authored by Xiaocheng Hu's avatar Xiaocheng Hu Committed by Commit Bot

[LayoutNG] Introduce NGPhysicalFragment::ResolvedDirection()

This patch introduces NGPhysicalFragment::ResolvedDirection() for text
and atomic inline fragments to obtain the resolved direction in bidi
inline layout (which can be different from CSS 'direction' property).

This patch is split from crrev.com/c/1038058 and has LGTM there. It is
a preparation for the following patches:
- crrev.com/c/1038058: bidi adjustment for caret position computation
- crrev.com/c/1056395: fix caret rect on atomic inlines in bidi text
- crrev.com/c/1056029: fix hit testing on atomic inlines in bidi text

Bug: 811502, 822575
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_layout_tests_layout_ng
Change-Id: I1e5fa1817ff987264181547d05e10774ff286fe5
Reviewed-on: https://chromium-review.googlesource.com/1058085Reviewed-by: default avatarEmil A Eklund <eae@chromium.org>
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#558545}
parent 37f4d3c4
......@@ -203,4 +203,24 @@ PositionWithAffinity NGPhysicalTextFragment::PositionForPoint(
return PositionWithAffinity(position, TextAffinity::kDownstream);
}
UBiDiLevel NGPhysicalTextFragment::BidiLevel() const {
// TODO(xiaochengh): Make the implementation more efficient with, e.g.,
// binary search and/or LayoutNGText::InlineItems().
const auto& items = InlineItemsOfContainingBlock();
const NGInlineItem* containing_item = std::find_if(
items.begin(), items.end(), [this](const NGInlineItem& item) {
return item.StartOffset() <= StartOffset() &&
item.EndOffset() >= EndOffset();
});
DCHECK(containing_item);
DCHECK_NE(containing_item, items.end());
return containing_item->BidiLevel();
}
TextDirection NGPhysicalTextFragment::ResolvedDirection() const {
if (TextShapeResult())
return TextShapeResult()->Direction();
return NGPhysicalFragment::ResolvedDirection();
}
} // namespace blink
......@@ -147,6 +147,9 @@ class CORE_EXPORT NGPhysicalTextFragment final : public NGPhysicalFragment {
PositionWithAffinity PositionForPoint(const NGPhysicalOffset&) const override;
UBiDiLevel BidiLevel() const override;
TextDirection ResolvedDirection() const override;
private:
LayoutUnit InlinePositionForOffset(unsigned offset,
LayoutUnit (*round)(float),
......
......@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/ng_outline_utils.h"
......@@ -185,6 +186,21 @@ PositionWithAffinity NGPhysicalBoxFragment::PositionForPoint(
return PositionForPointInInlineFormattingContext(point);
}
UBiDiLevel NGPhysicalBoxFragment::BidiLevel() const {
// TODO(xiaochengh): Make the implementation more efficient.
DCHECK(IsInline());
DCHECK(IsAtomicInline());
const auto& inline_items = InlineItemsOfContainingBlock();
const NGInlineItem* self_item =
std::find_if(inline_items.begin(), inline_items.end(),
[this](const NGInlineItem& item) {
return GetLayoutObject() == item.GetLayoutObject();
});
DCHECK(self_item);
DCHECK_NE(self_item, inline_items.end());
return self_item->BidiLevel();
}
scoped_refptr<NGPhysicalFragment> NGPhysicalBoxFragment::CloneWithoutOffset()
const {
Vector<scoped_refptr<NGPhysicalFragment>> children_copy(children_);
......
......@@ -52,6 +52,8 @@ class CORE_EXPORT NGPhysicalBoxFragment final
PositionWithAffinity PositionForPoint(const NGPhysicalOffset&) const override;
UBiDiLevel BidiLevel() const override;
scoped_refptr<NGPhysicalFragment> CloneWithoutOffset() const;
private:
......
......@@ -8,8 +8,10 @@
#include "third_party/blink/renderer/core/layout/layout_object_inlines.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_border_edges.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_node.h"
#include "third_party/blink/renderer/core/layout/ng/ng_break_token.h"
#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
......@@ -334,6 +336,38 @@ void NGPhysicalFragment::PropagateContentsVisualRect(
parent_visual_rect->Unite(visual_rect);
}
const Vector<NGInlineItem>& NGPhysicalFragment::InlineItemsOfContainingBlock()
const {
DCHECK(IsInline());
DCHECK(GetLayoutObject());
LayoutBlockFlow* block_flow =
GetLayoutObject()->Parent()->EnclosingNGBlockFlow();
// TODO(xiaochengh): Code below is copied from ng_offset_mapping.cc with
// modification. Unify them.
DCHECK(block_flow);
DCHECK(block_flow->ChildrenInline());
NGBlockNode block_node = NGBlockNode(block_flow);
DCHECK(block_node.CanUseNewLayout());
NGLayoutInputNode node = block_node.FirstChild();
DCHECK(node);
DCHECK(node.IsInline());
// TODO(xiaochengh): Handle ::first-line.
return ToNGInlineNode(node).ItemsData(false).items;
}
UBiDiLevel NGPhysicalFragment::BidiLevel() const {
NOTREACHED();
return 0;
}
TextDirection NGPhysicalFragment::ResolvedDirection() const {
DCHECK(IsInline());
DCHECK(IsText() || IsAtomicInline());
// TODO(xiaochengh): Store direction in |base_direction_| flag.
return DirectionFromLevel(BidiLevel());
}
scoped_refptr<NGPhysicalFragment> NGPhysicalFragment::CloneWithoutOffset()
const {
switch (Type()) {
......
......@@ -15,11 +15,14 @@
#include "third_party/blink/renderer/core/layout/ng/ng_style_variant.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
#include <unicode/ubidi.h>
namespace blink {
class ComputedStyle;
class LayoutObject;
class Node;
class NGInlineItem;
struct NGPhysicalOffsetRect;
struct NGPixelSnappedPhysicalBoxStrut;
class PaintLayer;
......@@ -181,6 +184,13 @@ class CORE_EXPORT NGPhysicalFragment
virtual PositionWithAffinity PositionForPoint(
const NGPhysicalOffset&) const = 0;
// Returns the bidi level of a text or atomic inline fragment.
virtual UBiDiLevel BidiLevel() const;
// Returns the resolved direction of a text or atomic inline fragment. Not to
// be confused with the CSS 'direction' property.
virtual TextDirection ResolvedDirection() const;
scoped_refptr<NGPhysicalFragment> CloneWithoutOffset() const;
String ToString() const;
......@@ -214,6 +224,8 @@ class CORE_EXPORT NGPhysicalFragment
unsigned sub_type,
scoped_refptr<NGBreakToken> break_token = nullptr);
const Vector<NGInlineItem>& InlineItemsOfContainingBlock() const;
LayoutObject* layout_object_;
scoped_refptr<const ComputedStyle> style_;
NGPhysicalSize size_;
......
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