Commit f610bd8e authored by Koji Ishii's avatar Koji Ishii Committed by Commit Bot

[LayoutNG] Remove trailing spaces of blocks in phase 1

This patch changes NGInlineItemsBuilder to remove trailing
spaces at the end of blocks.

It used to do so, but stopped in https://crrev.com/c/1022191
because doing so reduces opportunities to re-use NGInlineItem
and increases shaping when contents are added.

However, for fonts that has kerning before a space character,
this change increased re-shaping every block end. Given line
breaking is more often ran than adding contents dynamically,
this turned out to be not a good trade off. We could re-shape
only end-part in RestoreTrailingCollapsibleSpace to achieve
the originally intended optimizations.

This speeds up blink_perf tests on Windows by ~10%.

This patch also fixes a few cases where space collapsing is
incorrect when items are re-used.

Bug: 636993
Cq-Include-Trybots: luci.chromium.try:linux_layout_tests_layout_ng
Change-Id: Id6e0c262db29b4d39ddd4eb1f55b18da2c7e5880
Reviewed-on: https://chromium-review.googlesource.com/1163240
Commit-Queue: Koji Ishii <kojii@chromium.org>
Reviewed-by: default avatarEmil A Eklund <eae@chromium.org>
Cr-Commit-Position: refs/heads/master@{#581149}
parent f792e7d8
...@@ -13,9 +13,9 @@ layer at (0,0) size 800x262 ...@@ -13,9 +13,9 @@ layer at (0,0) size 800x262
text run at (124,0) width 274: " be a green bar stacked on top of a blue bar." text run at (124,0) width 274: " be a green bar stacked on top of a blue bar."
LayoutNGListItem {DIV} at (0,36) size 784x202 [color=#00FF00] [bgcolor=#00FF00] LayoutNGListItem {DIV} at (0,36) size 784x202 [color=#00FF00] [bgcolor=#00FF00]
LayoutNGBlockFlow (anonymous) at (0,0) size 784x101 LayoutNGBlockFlow (anonymous) at (0,0) size 784x101
LayoutInline (anonymous) at (0,0) size 30x97 LayoutInline (anonymous) at (0,0) size 27x97
LayoutText (anonymous) at (-1,2) size 30x97 LayoutText (anonymous) at (-1,2) size 27x97
text run at (-1,2) width 30: "\x{2022}" text run at (-1,2) width 27: "\x{2022}"
LayoutNGBlockFlow {DIV} at (0,101) size 784x101 [bgcolor=#0000FF] LayoutNGBlockFlow {DIV} at (0,101) size 784x101 [bgcolor=#0000FF]
LayoutText {#text} at (0,2) size 21x97 LayoutText {#text} at (0,2) size 21x97
text run at (0,2) width 21: " " text run at (0,2) width 21: " "
...@@ -73,10 +73,10 @@ layer at (0,0) size 800x100 ...@@ -73,10 +73,10 @@ layer at (0,0) size 800x100
text run at (139,0) width 12: "K" text run at (139,0) width 12: "K"
LayoutText {#text} at (151,0) size 4x19 LayoutText {#text} at (151,0) size 4x19
text run at (151,0) width 4: " " text run at (151,0) width 4: " "
LayoutInline {SPAN} at (0,0) size 9x19 LayoutInline {SPAN} at (0,0) size 10x19
LayoutInline {<pseudo:before>} at (0,0) size 9x19 LayoutInline {<pseudo:before>} at (0,0) size 10x19
LayoutCounter (anonymous) at (155,0) size 9x19 LayoutCounter (anonymous) at (155,0) size 10x19
text run at (155,0) width 9: "L" text run at (155,0) width 10: "L"
LayoutText {#text} at (0,0) size 0x0 LayoutText {#text} at (0,0) size 0x0
LayoutNGBlockFlow {DIV} at (0,56) size 784x20 LayoutNGBlockFlow {DIV} at (0,56) size 784x20
LayoutText {#text} at (0,0) size 165x19 LayoutText {#text} at (0,0) size 165x19
......
...@@ -73,10 +73,10 @@ layer at (0,0) size 800x100 ...@@ -73,10 +73,10 @@ layer at (0,0) size 800x100
text run at (139,0) width 12: "K" text run at (139,0) width 12: "K"
LayoutText {#text} at (151,0) size 4x19 LayoutText {#text} at (151,0) size 4x19
text run at (151,0) width 4: " " text run at (151,0) width 4: " "
LayoutInline {SPAN} at (0,0) size 9x19 LayoutInline {SPAN} at (0,0) size 10x19
LayoutInline {<pseudo:before>} at (0,0) size 9x19 LayoutInline {<pseudo:before>} at (0,0) size 10x19
LayoutCounter (anonymous) at (155,0) size 9x19 LayoutCounter (anonymous) at (155,0) size 10x19
text run at (155,0) width 9: "L" text run at (155,0) width 10: "L"
LayoutText {#text} at (0,0) size 0x0 LayoutText {#text} at (0,0) size 0x0
LayoutNGBlockFlow {DIV} at (0,56) size 784x20 LayoutNGBlockFlow {DIV} at (0,56) size 784x20
LayoutText {#text} at (0,0) size 165x19 LayoutText {#text} at (0,0) size 165x19
......
...@@ -73,10 +73,10 @@ layer at (0,0) size 800x100 ...@@ -73,10 +73,10 @@ layer at (0,0) size 800x100
text run at (289,0) width 28: "A.K" text run at (289,0) width 28: "A.K"
LayoutText {#text} at (317,0) size 3x19 LayoutText {#text} at (317,0) size 3x19
text run at (317,0) width 3: " " text run at (317,0) width 3: " "
LayoutInline {SPAN} at (0,0) size 25x19 LayoutInline {SPAN} at (0,0) size 26x19
LayoutInline {<pseudo:before>} at (0,0) size 25x19 LayoutInline {<pseudo:before>} at (0,0) size 26x19
LayoutCounter (anonymous) at (320,0) size 25x19 LayoutCounter (anonymous) at (320,0) size 26x19
text run at (320,0) width 25: "A.L" text run at (320,0) width 26: "A.L"
LayoutText {#text} at (0,0) size 0x0 LayoutText {#text} at (0,0) size 0x0
LayoutNGBlockFlow {DIV} at (0,56) size 784x20 LayoutNGBlockFlow {DIV} at (0,56) size 784x20
LayoutText {#text} at (0,0) size 346x19 LayoutText {#text} at (0,0) size 346x19
......
...@@ -73,10 +73,10 @@ layer at (0,0) size 800x100 ...@@ -73,10 +73,10 @@ layer at (0,0) size 800x100
text run at (289,0) width 28: "A.K" text run at (289,0) width 28: "A.K"
LayoutText {#text} at (317,0) size 3x19 LayoutText {#text} at (317,0) size 3x19
text run at (317,0) width 3: " " text run at (317,0) width 3: " "
LayoutInline {SPAN} at (0,0) size 25x19 LayoutInline {SPAN} at (0,0) size 26x19
LayoutInline {<pseudo:before>} at (0,0) size 25x19 LayoutInline {<pseudo:before>} at (0,0) size 26x19
LayoutCounter (anonymous) at (320,0) size 25x19 LayoutCounter (anonymous) at (320,0) size 26x19
text run at (320,0) width 25: "A.L" text run at (320,0) width 26: "A.L"
LayoutText {#text} at (0,0) size 0x0 LayoutText {#text} at (0,0) size 0x0
LayoutNGBlockFlow {DIV} at (0,56) size 784x20 LayoutNGBlockFlow {DIV} at (0,56) size 784x20
LayoutText {#text} at (0,0) size 346x19 LayoutText {#text} at (0,0) size 346x19
......
This page tests whether a click event propagates with the correct target and positioning. See rdar://problem/4477126. This page tests whether a click event propagates with the correct target and positioning. See rdar://problem/4477126.
click inside the red box:[] click inside the red box:[]
PASS: event target should be [object HTMLSpanElement] and is
PASS: event.pageX should be 175 and is
PASS: event.pageY should be 105 and is
PASS: event.clientX should be 175 and is
PASS: event.clientY should be 105 and is
PASS: event.layerX should be 7 and is
PASS: event.layerY should be 5 and is
PASS: event.offsetX should be 7 and is
PASS: event.offsetY should be 5 and is
PASS: event.x should be 175 and is
PASS: event.y should be 105 and is
layer at (0,0) size 800x600
LayoutView at (0,0) size 800x600
layer at (0,0) size 800x36
LayoutNGBlockFlow {HTML} at (0,0) size 800x36
LayoutNGBlockFlow {BODY} at (8,8) size 784x20
LayoutText {#text} at (0,0) size 551x19
text run at (0,0) width 551: "Tests that we paint area outline properly when the image is inside positioned containers."
layer at (20,50) size 0x0
LayoutNGBlockFlow (positioned) {DIV} at (20,50) size 0x0
layer at (30,60) size 50x55
LayoutNGBlockFlow (positioned) {DIV} at (10,10) size 50x55
LayoutImage {IMG} at (0,0) size 50x50
LayoutText {#text} at (0,0) size 0x0
LayoutInline {MAP} at (0,0) size 0x19
LayoutInline {AREA} at (0,0) size 0x19
LayoutText {#text} at (0,0) size 0x0
layer at (0,0) size 800x600
LayoutView at (0,0) size 800x600
layer at (0,0) size 800x36
LayoutNGBlockFlow {HTML} at (0,0) size 800x36
LayoutNGBlockFlow {BODY} at (8,8) size 784x20
LayoutText {#text} at (0,0) size 437x19
text run at (0,0) width 437: "Tests that we paint area outline properly when the paintroot is shifted."
layer at (5,50) size 50x55
LayoutNGBlockFlow (positioned) {DIV} at (5,50) size 50x55
LayoutImage {IMG} at (0,0) size 50x50
LayoutText {#text} at (0,0) size 0x0
LayoutInline {MAP} at (0,0) size 0x19
LayoutInline {AREA} at (0,0) size 0x19
LayoutText {#text} at (0,0) size 0x0
layer at (0,0) size 800x600
LayoutView at (0,0) size 800x600
layer at (0,0) size 800x36
LayoutNGBlockFlow {HTML} at (0,0) size 800x36
LayoutNGBlockFlow {BODY} at (8,8) size 784x20
LayoutText {#text} at (0,0) size 551x19
text run at (0,0) width 551: "Tests that we paint area outline properly when the image is inside positioned containers."
layer at (20,50) size 0x0
LayoutNGBlockFlow (positioned) {DIV} at (20,50) size 0x0
layer at (30,60) size 50x55
LayoutNGBlockFlow (positioned) {DIV} at (10,10) size 50x55
LayoutImage {IMG} at (0,0) size 50x50
LayoutText {#text} at (0,0) size 0x0
LayoutInline {MAP} at (0,0) size 0x19
LayoutInline {AREA} at (0,0) size 0x19
LayoutText {#text} at (0,0) size 0x0
layer at (0,0) size 800x600
LayoutView at (0,0) size 800x600
layer at (0,0) size 800x36
LayoutNGBlockFlow {HTML} at (0,0) size 800x36
LayoutNGBlockFlow {BODY} at (8,8) size 784x20
LayoutText {#text} at (0,0) size 437x19
text run at (0,0) width 437: "Tests that we paint area outline properly when the paintroot is shifted."
layer at (5,50) size 50x55
LayoutNGBlockFlow (positioned) {DIV} at (5,50) size 50x55
LayoutImage {IMG} at (0,0) size 50x50
LayoutText {#text} at (0,0) size 0x0
LayoutInline {MAP} at (0,0) size 0x19
LayoutInline {AREA} at (0,0) size 0x19
LayoutText {#text} at (0,0) size 0x0
...@@ -56,8 +56,7 @@ NGInlineItem::NGInlineItem(NGInlineItemType type, ...@@ -56,8 +56,7 @@ NGInlineItem::NGInlineItem(NGInlineItemType type,
unsigned start, unsigned start,
unsigned end, unsigned end,
const ComputedStyle* style, const ComputedStyle* style,
LayoutObject* layout_object, LayoutObject* layout_object)
bool end_may_collapse)
: start_offset_(start), : start_offset_(start),
end_offset_(end), end_offset_(end),
style_(style), style_(style),
...@@ -72,7 +71,7 @@ NGInlineItem::NGInlineItem(NGInlineItemType type, ...@@ -72,7 +71,7 @@ NGInlineItem::NGInlineItem(NGInlineItemType type,
should_create_box_fragment_(false), should_create_box_fragment_(false),
style_variant_(static_cast<unsigned>(NGStyleVariant::kStandard)), style_variant_(static_cast<unsigned>(NGStyleVariant::kStandard)),
end_collapse_type_(kNotCollapsible), end_collapse_type_(kNotCollapsible),
end_may_collapse_(end_may_collapse), is_end_collapsible_newline_(false),
is_symbol_marker_(false) { is_symbol_marker_(false) {
DCHECK_GE(end, start); DCHECK_GE(end, start);
ComputeBoxProperties(); ComputeBoxProperties();
...@@ -97,7 +96,7 @@ NGInlineItem::NGInlineItem(const NGInlineItem& other, ...@@ -97,7 +96,7 @@ NGInlineItem::NGInlineItem(const NGInlineItem& other,
should_create_box_fragment_(other.should_create_box_fragment_), should_create_box_fragment_(other.should_create_box_fragment_),
style_variant_(other.style_variant_), style_variant_(other.style_variant_),
end_collapse_type_(other.end_collapse_type_), end_collapse_type_(other.end_collapse_type_),
end_may_collapse_(other.end_may_collapse_), is_end_collapsible_newline_(other.is_end_collapsible_newline_),
is_symbol_marker_(other.is_symbol_marker_) { is_symbol_marker_(other.is_symbol_marker_) {
DCHECK_GE(end, start); DCHECK_GE(end, start);
} }
...@@ -329,4 +328,15 @@ bool NGInlineItem::HasEndEdge() const { ...@@ -329,4 +328,15 @@ bool NGInlineItem::HasEndEdge() const {
!ToLayoutInline(GetLayoutObject())->Continuation(); !ToLayoutInline(GetLayoutObject())->Continuation();
} }
void NGInlineItem::SetEndCollapseType(NGCollapseType type) {
DCHECK(Type() == NGInlineItem::kText || type == kOpaqueToCollapsing ||
(Type() == NGInlineItem::kControl && type == kCollapsible));
end_collapse_type_ = type;
}
void NGInlineItem::SetEndCollapseType(NGCollapseType type, bool is_newline) {
SetEndCollapseType(type);
is_end_collapsible_newline_ = is_newline;
}
} // namespace blink } // namespace blink
...@@ -51,12 +51,12 @@ class CORE_EXPORT NGInlineItem { ...@@ -51,12 +51,12 @@ class CORE_EXPORT NGInlineItem {
enum NGCollapseType { enum NGCollapseType {
// No collapsible spaces. // No collapsible spaces.
kNotCollapsible, kNotCollapsible,
// A collapsible space run that does not contain segment breaks.
kCollapsibleSpace,
// A collapsible space run that contains segment breaks.
kCollapsibleNewline,
// This item is opaque to whitespace collapsing. // This item is opaque to whitespace collapsing.
kOpaqueToCollapsing kOpaqueToCollapsing,
// This item ends with collapsible spaces.
kCollapsible,
// Collapsible spaces at the end of this item were collapsed.
kCollapsed,
}; };
// The constructor and destructor can't be implicit or inlined, because they // The constructor and destructor can't be implicit or inlined, because they
...@@ -65,8 +65,7 @@ class CORE_EXPORT NGInlineItem { ...@@ -65,8 +65,7 @@ class CORE_EXPORT NGInlineItem {
unsigned start, unsigned start,
unsigned end, unsigned end,
const ComputedStyle* style = nullptr, const ComputedStyle* style = nullptr,
LayoutObject* layout_object = nullptr, LayoutObject* layout_object = nullptr);
bool end_may_collapse = false);
~NGInlineItem(); ~NGInlineItem();
// Copy constructor adjusting start/end and shape results. // Copy constructor adjusting start/end and shape results.
...@@ -123,12 +122,12 @@ class CORE_EXPORT NGInlineItem { ...@@ -123,12 +122,12 @@ class CORE_EXPORT NGInlineItem {
NGCollapseType EndCollapseType() const { NGCollapseType EndCollapseType() const {
return static_cast<NGCollapseType>(end_collapse_type_); return static_cast<NGCollapseType>(end_collapse_type_);
} }
void SetEndCollapseType(NGCollapseType type) { end_collapse_type_ = type; } void SetEndCollapseType(NGCollapseType type);
// Whether the item may be affected by whitespace collapsing. Unlike the // Whether the end collapsible space run contains a newline.
// EndCollapseType() method this returns true even if a trailing space has // Valid only when kCollapsible or kCollapsed.
// been removed. bool IsEndCollapsibleNewline() const { return is_end_collapsible_newline_; }
bool EndMayCollapse() const { return end_may_collapse_; } void SetEndCollapseType(NGCollapseType type, bool is_newline);
static void Split(Vector<NGInlineItem>&, unsigned index, unsigned offset); static void Split(Vector<NGInlineItem>&, unsigned index, unsigned offset);
...@@ -189,7 +188,7 @@ class CORE_EXPORT NGInlineItem { ...@@ -189,7 +188,7 @@ class CORE_EXPORT NGInlineItem {
unsigned should_create_box_fragment_ : 1; unsigned should_create_box_fragment_ : 1;
unsigned style_variant_ : 2; unsigned style_variant_ : 2;
unsigned end_collapse_type_ : 2; // NGCollapseType unsigned end_collapse_type_ : 2; // NGCollapseType
unsigned end_may_collapse_ : 1; unsigned is_end_collapsible_newline_ : 1;
unsigned is_symbol_marker_ : 1; unsigned is_symbol_marker_ : 1;
friend class NGInlineNode; friend class NGInlineNode;
}; };
......
...@@ -154,13 +154,12 @@ class NGInlineItemsBuilderTemplate { ...@@ -154,13 +154,12 @@ class NGInlineItemsBuilderTemplate {
void RemoveTrailingCollapsibleSpaceIfExists(); void RemoveTrailingCollapsibleSpaceIfExists();
void RemoveTrailingCollapsibleSpace(NGInlineItem*); void RemoveTrailingCollapsibleSpace(NGInlineItem*);
void RestoreTrailingCollapsibleSpaceIfRemoved();
void RestoreTrailingCollapsibleSpace(NGInlineItem*);
void Exit(LayoutObject*); void Exit(LayoutObject*);
}; };
template <>
CORE_EXPORT String
NGInlineItemsBuilderTemplate<NGOffsetMappingBuilder>::ToString();
template <> template <>
CORE_EXPORT bool NGInlineItemsBuilderTemplate<NGOffsetMappingBuilder>::Append( CORE_EXPORT bool NGInlineItemsBuilderTemplate<NGOffsetMappingBuilder>::Append(
const String&, const String&,
......
...@@ -294,16 +294,12 @@ const NGOffsetMapping* NGInlineNode::ComputeOffsetMappingIfNeeded() { ...@@ -294,16 +294,12 @@ const NGOffsetMapping* NGInlineNode::ComputeOffsetMappingIfNeeded() {
NGInlineItemsBuilderForOffsetMapping builder(&items); NGInlineItemsBuilderForOffsetMapping builder(&items);
CollectInlinesInternal(GetLayoutBlockFlow(), &builder, nullptr); CollectInlinesInternal(GetLayoutBlockFlow(), &builder, nullptr);
String text = builder.ToString(); String text = builder.ToString();
DCHECK_EQ(data->text_content, text);
// The trailing space of the text for offset mapping may be removed. If not,
// share the string instance.
if (text == data->text_content)
text = data->text_content;
// TODO(xiaochengh): This doesn't compute offset mapping correctly when // TODO(xiaochengh): This doesn't compute offset mapping correctly when
// text-transform CSS property changes text length. // text-transform CSS property changes text length.
NGOffsetMappingBuilder& mapping_builder = builder.GetOffsetMappingBuilder(); NGOffsetMappingBuilder& mapping_builder = builder.GetOffsetMappingBuilder();
mapping_builder.SetDestinationString(text); mapping_builder.SetDestinationString(data->text_content);
data->offset_mapping = data->offset_mapping =
std::make_unique<NGOffsetMapping>(mapping_builder.Build()); std::make_unique<NGOffsetMapping>(mapping_builder.Build());
} }
......
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