Commit 89209304 authored by Manuel Rego Casasnovas's avatar Manuel Rego Casasnovas Committed by Commit Bot

[css-contain] Apply optimization in SetText if text doesn't wrap

This is an extra case in which we can apply the SetText optimization
introduced in r578233.
If the text is longer than the container, but we know
it's not going to wrap, then we can apply the optimization anyway and
avoid the layout as we know it's not going to be split
in multiple lines.
Thanks to this patch the optimization will be applied in more cases.

The patch also removes the TODO about trying to avoid measuring
the text length. That was tried in
https://chromium-review.googlesource.com/1275848 but discarded
as it is not possible to avoid measuring the text
if we want to store proper values for widths.

Bug=805785
TEST=fast/css/containment/change-text-node-data-nowrap.html

Change-Id: Ifa708d2a40b95254420750672941de18f5a6f3c7
Reviewed-on: https://chromium-review.googlesource.com/c/1333750Reviewed-by: default avatarChristian Biesinger <cbiesinger@chromium.org>
Commit-Queue: Manuel Rego <rego@igalia.com>
Cr-Commit-Position: refs/heads/master@{#607786}
parent 73063d16
<!DOCTYPE html>
<meta charset="utf-8">
<style>
div {
display: inline-block;
float: left;
background: silver;
width: 100px;
height: 100px;
margin: 20px;
font-size: 25px;
overflow: hidden;
line-height: 1;
white-space: nowrap;
}
.first-line::first-line {
font-size: 30px;
}
</style>
<div>baar</div>
<div>baarbaar baarbaar</div>
<div>baarbaarbaar baarbaarbaar baarbaarbaar baarbaarbaar baarbaarbaar</div>
<div>baar baar baar baar</div>
<div>baar</div>
<div>b &#x55e8;</div>
<div class="first-line">baar</div>
<div class="first-line">baarbaar baarbaar</div>
<div class="first-line">baarbaarbaar baarbaarbaar baarbaarbaar baarbaarbaar baarbaarbaar</div>
<div class="first-line">baar baar baar baar</div>
<div class="first-line">baar</div>
<div class="first-line">b &#x55e8;</div>
<!DOCTYPE html>
<meta charset="utf-8">
<link rel="match" href="change-text-node-data-expected.html">
<style>
div {
display: inline-block;
float: left;
background: silver;
width: 100px;
height: 100px;
margin: 20px;
font-size: 25px;
overflow: hidden;
contain: layout size;
line-height: 1;
white-space: nowrap;
}
.first-line::first-line {
font-size: 30px;
}
</style>
<script>
const originalValues = [
"foo",
"foofoo foofoo",
"foofoofoo foofoofoo foofoofoo foofoofoo foofoofoo",
"foo",
"foo foo foo foo foo",
"foo",
];
const newValues = [
"baar",
"baarbaar baarbaar",
"baarbaarbaar baarbaarbaar baarbaarbaar baarbaarbaar baarbaarbaar",
"baar baar baar baar",
"baar",
"b \u55e8",
];
function setupTest() {
originalValues.forEach((text) => {
let div = document.createElement("div");
div.appendChild(document.createTextNode(text));
document.body.appendChild(div);
});
originalValues.forEach((text) => {
let firstLineDiv = document.createElement("div");
firstLineDiv.className = "first-line";
firstLineDiv.appendChild(document.createTextNode(text));
document.body.appendChild(firstLineDiv);
});
}
function changeTextNodeData() {
let divs = document.getElementsByTagName("div");
for (let i = 0; i < divs.length; i++) {
divs[i].childNodes[0].data = newValues[i % newValues.length];
}
}
function runTest() {
setupTest();
document.body.offsetLeft;
changeTextNodeData();
}
</script>
<body onload="runTest();">
</body>
...@@ -1657,10 +1657,10 @@ void LayoutText::SetTextWithOffset(scoped_refptr<StringImpl> text, ...@@ -1657,10 +1657,10 @@ void LayoutText::SetTextWithOffset(scoped_refptr<StringImpl> text,
FloatRect glyph_bounds; FloatRect glyph_bounds;
float text_width = float text_width =
style_to_use->GetFont().Width(text_run, nullptr, &glyph_bounds); style_to_use->GetFont().Width(text_run, nullptr, &glyph_bounds);
// TODO(rego): We could avoid measuring text width in some specific // If the text is not wrapping we don't care if it fits or not in the
// situations (e.g. if "white-space" property is "pre" and "overflow-wrap" // container as it's not going to be split in multiple lines.
// is "normal"). if (!style_to_use->AutoWrap() ||
if (text_width <= ContainingBlock()->ContentLogicalWidth()) { (text_width <= ContainingBlock()->ContentLogicalWidth())) {
FirstTextBox()->ManuallySetStartLenAndLogicalWidth( FirstTextBox()->ManuallySetStartLenAndLogicalWidth(
offset, text->length(), LayoutUnit(text_width)); offset, text->length(), LayoutUnit(text_width));
SetFirstTextBoxLogicalLeft(text_width); SetFirstTextBoxLogicalLeft(text_width);
......
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