Commit 9333ba3e authored by Koji Ishii's avatar Koji Ishii Committed by Commit Bot

[FragmentItem] Avoid excessive marking line boxes dirty

This patch changes marking lines dirty only when
|HasInlineFragments|, not when |FirstTextBox|, which is
always nullptr with LayoutNG.

|DirtyLinesFromChangedChild| is supposed to do nothing for
|NGPaintFragment|, but actually marks items dirty when
|FragmentItem| is enabled.

Also code for |InlineTextBox| was moved to inside of an if
block not to run at all for LayoutNG.

Bug: 982194
Change-Id: Icd933a1c3b6ad76b9437900bf104fc526d332dce
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2237491
Commit-Queue: Yoshifumi Inoue <yosin@chromium.org>
Reviewed-by: default avatarYoshifumi Inoue <yosin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#776875}
parent 8991af40
...@@ -1760,69 +1760,71 @@ void LayoutText::SetTextWithOffset(scoped_refptr<StringImpl> text, ...@@ -1760,69 +1760,71 @@ void LayoutText::SetTextWithOffset(scoped_refptr<StringImpl> text,
int delta = new_len - old_len; int delta = new_len - old_len;
unsigned end = len ? offset + len - 1 : offset; unsigned end = len ? offset + len - 1 : offset;
RootInlineBox* first_root_box = nullptr;
RootInlineBox* last_root_box = nullptr;
bool dirtied_lines = false; bool dirtied_lines = false;
// Dirty all text boxes that include characters in between offset and if (!IsInLayoutNGInlineFormattingContext()) {
// offset+len. RootInlineBox* first_root_box = nullptr;
for (InlineTextBox* curr : TextBoxes()) { RootInlineBox* last_root_box = nullptr;
// FIXME: This shouldn't rely on the end of a dirty line box. See
// https://bugs.webkit.org/show_bug.cgi?id=97264 // Dirty all text boxes that include characters in between offset and
// Text run is entirely before the affected range. // offset+len.
if (curr->end() < offset) for (InlineTextBox* curr : TextBoxes()) {
continue; // FIXME: This shouldn't rely on the end of a dirty line box. See
// https://bugs.webkit.org/show_bug.cgi?id=97264
// Text run is entirely before the affected range.
if (curr->end() < offset)
continue;
// Text run is entirely after the affected range. // Text run is entirely after the affected range.
if (curr->Start() > end) { if (curr->Start() > end) {
curr->OffsetRun(delta); curr->OffsetRun(delta);
RootInlineBox* root = &curr->Root(); RootInlineBox* root = &curr->Root();
if (!first_root_box) { if (!first_root_box) {
first_root_box = root; first_root_box = root;
// The affected area was in between two runs. Go ahead and mark the root // The affected area was in between two runs. Go ahead and mark the
// box of the run after the affected area as dirty. // root box of the run after the affected area as dirty.
first_root_box->MarkDirty(); first_root_box->MarkDirty();
dirtied_lines = true;
}
last_root_box = root;
} else if (curr->end() >= offset && curr->end() <= end) {
// Text run overlaps with the left end of the affected range.
curr->DirtyLineBoxes();
dirtied_lines = true;
} else if (curr->Start() <= offset && curr->end() >= end) {
// Text run subsumes the affected range.
curr->DirtyLineBoxes();
dirtied_lines = true;
} else if (curr->Start() <= end && curr->end() >= end) {
// Text run overlaps with right end of the affected range.
curr->DirtyLineBoxes();
dirtied_lines = true; dirtied_lines = true;
} }
last_root_box = root;
} else if (curr->end() >= offset && curr->end() <= end) {
// Text run overlaps with the left end of the affected range.
curr->DirtyLineBoxes();
dirtied_lines = true;
} else if (curr->Start() <= offset && curr->end() >= end) {
// Text run subsumes the affected range.
curr->DirtyLineBoxes();
dirtied_lines = true;
} else if (curr->Start() <= end && curr->end() >= end) {
// Text run overlaps with right end of the affected range.
curr->DirtyLineBoxes();
dirtied_lines = true;
} }
}
// Now we have to walk all of the clean lines and adjust their cached line // Now we have to walk all of the clean lines and adjust their cached line
// break information to reflect our updated offsets. // break information to reflect our updated offsets.
if (last_root_box) if (last_root_box)
last_root_box = last_root_box->NextRootBox(); last_root_box = last_root_box->NextRootBox();
if (first_root_box) { if (first_root_box) {
RootInlineBox* prev = first_root_box->PrevRootBox(); RootInlineBox* prev = first_root_box->PrevRootBox();
if (prev) if (prev)
first_root_box = prev; first_root_box = prev;
} else if (LastTextBox()) { } else if (LastTextBox()) {
DCHECK(!last_root_box); DCHECK(!last_root_box);
first_root_box = &LastTextBox()->Root(); first_root_box = &LastTextBox()->Root();
first_root_box->MarkDirty(); first_root_box->MarkDirty();
dirtied_lines = true; dirtied_lines = true;
} }
for (RootInlineBox* curr = first_root_box; curr && curr != last_root_box; for (RootInlineBox* curr = first_root_box; curr && curr != last_root_box;
curr = curr->NextRootBox()) { curr = curr->NextRootBox()) {
if (curr->LineBreakObj().IsEqual(this) && curr->LineBreakPos() > end) if (curr->LineBreakObj().IsEqual(this) && curr->LineBreakPos() > end)
curr->SetLineBreakPos(clampTo<int>(curr->LineBreakPos() + delta)); curr->SetLineBreakPos(clampTo<int>(curr->LineBreakPos() + delta));
}
} }
// If the text node is empty, dirty the line where new text will be inserted. // If the text node is empty, dirty the line where new text will be inserted.
if (!FirstTextBox() && Parent()) { if (!HasInlineFragments() && Parent()) {
Parent()->DirtyLinesFromChangedChild(this); Parent()->DirtyLinesFromChangedChild(this);
dirtied_lines = true; dirtied_lines = true;
} }
......
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