Skip to content
Permalink
Browse files
[CSSRegions] Regions should not slice line box rendering
https://bugs.webkit.org/show_bug.cgi?id=66198

Source/WebCore:

Created a new LayoutState constructor for the RenderFlowThread. It will
set m_isPaginated to true and force a pageHeight if 1. The actual pageHeight is
not used, because pageLogicalHeightForOffset will actually redirect the call
to RenderFlowThread.

Removed some of the duplicate code that calculated the page logical offset.
Added new methods like logicalPageOffset, pageLogicalHeightForOffset,
pageRemainingLogicalHeightForOffset.

There are still some issues related to incremental layout and different region widths.
Those issues will be addressed in different patches.

Reviewed by David Hyatt.

Tests: fast/regions/text-region-breaks.html
       fast/regions/text-region-split-horizontal-bt.html
       fast/regions/text-region-split-vertical-rl.html
       fast/regions/text-region-split-vertical.html
       fast/regions/text-region-split.html

* rendering/LayoutState.cpp:
(WebCore::LayoutState::LayoutState):
* rendering/LayoutState.h:
(WebCore::LayoutState::LayoutState):
(WebCore::LayoutState::isPaginated):
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::positionNewFloats):
(WebCore::RenderBlock::adjustForRegionFittingIfNeeded):
(WebCore::RenderBlock::nextPageLogicalTopExcludingBoundaryPoint):
(WebCore::RenderBlock::nextPageLogicalTopIncludingBoundaryPoint):
(WebCore::inNormalFlow):
(WebCore::RenderBlock::applyBeforeBreak):
(WebCore::RenderBlock::applyAfterBreak):
(WebCore::RenderBlock::logicalPageOffset):
(WebCore::RenderBlock::pageLogicalHeightForOffset):
(WebCore::RenderBlock::pageRemainingLogicalHeightForOffset):
(WebCore::RenderBlock::adjustForUnsplittableChild):
(WebCore::RenderBlock::adjustLinePositionForPagination):
* rendering/RenderBlock.h:
* rendering/RenderFlowThread.cpp:
(WebCore::RenderFlowThread::layout):
(WebCore::RenderFlowThread::regionLogicalHeightForLine):
(WebCore::RenderFlowThread::regionRemainingLogicalHeightForLine):
* rendering/RenderFlowThread.h:
* rendering/RenderView.cpp:
(WebCore::RenderView::pushLayoutState):
* rendering/RenderView.h:
(WebCore::LayoutStateMaintainer::LayoutStateMaintainer):
(WebCore::LayoutStateMaintainer::push):

LayoutTests:

Also updated the results for some older tests that now work correctly.

Reviewed by David Hyatt.

* fast/regions/resources/helper.js:
(isDebugEnabled):
(assertEqualRects):
(testBoundingRects):
(assertRectContains):
(addPageLevelDebugBox):
(testContentToRegionsMapping):
* fast/regions/text-region-breaks-expected.txt: Added.
* fast/regions/text-region-breaks.html: Added.
* fast/regions/text-region-split-expected.txt: Added.
* fast/regions/text-region-split-horizontal-bt-expected.txt: Added.
* fast/regions/text-region-split-horizontal-bt.html: Added.
* fast/regions/text-region-split-vertical-expected.txt: Added.
* fast/regions/text-region-split-vertical-rl-expected.txt: Added.
* fast/regions/text-region-split-vertical-rl.html: Added.
* fast/regions/text-region-split-vertical.html: Added.
* fast/regions/text-region-split.html: Added.
* fast/regions/webkit-flow-floats-inside-regions-bounds-expected.txt:
* fast/regions/webkit-flow-inlines-inside-regions-bounds-expected.txt:
* fast/regions/webkit-flow-inlines-inside-regions-bounds-vertical-expected.txt:
* fast/regions/webkit-flow-inlines-inside-regions-bounds-vertical-rl-expected.txt:
* fast/repaint/japanese-rl-selection-repaint-in-regions.html:
* platform/mac/fast/repaint/japanese-rl-selection-repaint-in-regions-expected.png:
* platform/mac/fast/repaint/japanese-rl-selection-repaint-in-regions-expected.txt:


Canonical link: https://commits.webkit.org/84134@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@95264 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
achicu committed Sep 16, 2011
1 parent 864e960 commit 172fc0eb14ebf6be93e926efc5e5eefcf401a999
Showing 27 changed files with 612 additions and 117 deletions.
@@ -1,3 +1,37 @@
2011-09-15 Alexandru Chiculita <achicu@adobe.com>

[CSSRegions] Regions should not slice line box rendering
https://bugs.webkit.org/show_bug.cgi?id=66198

Also updated the results for some older tests that now work correctly.

Reviewed by David Hyatt.

* fast/regions/resources/helper.js:
(isDebugEnabled):
(assertEqualRects):
(testBoundingRects):
(assertRectContains):
(addPageLevelDebugBox):
(testContentToRegionsMapping):
* fast/regions/text-region-breaks-expected.txt: Added.
* fast/regions/text-region-breaks.html: Added.
* fast/regions/text-region-split-expected.txt: Added.
* fast/regions/text-region-split-horizontal-bt-expected.txt: Added.
* fast/regions/text-region-split-horizontal-bt.html: Added.
* fast/regions/text-region-split-vertical-expected.txt: Added.
* fast/regions/text-region-split-vertical-rl-expected.txt: Added.
* fast/regions/text-region-split-vertical-rl.html: Added.
* fast/regions/text-region-split-vertical.html: Added.
* fast/regions/text-region-split.html: Added.
* fast/regions/webkit-flow-floats-inside-regions-bounds-expected.txt:
* fast/regions/webkit-flow-inlines-inside-regions-bounds-expected.txt:
* fast/regions/webkit-flow-inlines-inside-regions-bounds-vertical-expected.txt:
* fast/regions/webkit-flow-inlines-inside-regions-bounds-vertical-rl-expected.txt:
* fast/repaint/japanese-rl-selection-repaint-in-regions.html:
* platform/mac/fast/repaint/japanese-rl-selection-repaint-in-regions-expected.png:
* platform/mac/fast/repaint/japanese-rl-selection-repaint-in-regions-expected.txt:

2011-09-15 Keishi Hattori <keishi@webkit.org>

[chromium] rebaseline expectations due to r95239
@@ -1,3 +1,9 @@
function isDebugEnabled()
{
// Add #debug at the end of the url to visually debug the test case.
return window.location.hash == "#debug";
}

function rectToArray(rect) {
return [rect.top, rect.left, rect.bottom, rect.right, rect.width, rect.height];
}
@@ -22,7 +28,7 @@ function assertEqualRects(results, name, actualRect, expectedRect, tolerance) {
if (areEqualRects(actualRect, expectedRect, tolerance))
return;

results.push("FAIL(" + name + " bounding rect was: [" + actualRect.join(", ") + "], expected: [" + expectedRect.join(", ") + "]");
results.push("FAIL(" + name + ") bounding rect was: [" + actualRect.join(", ") + "], expected: [" + expectedRect.join(", ") + "]");
}

function testBoundingRects(expectedBoundingRects, tolerance)
@@ -42,4 +48,60 @@ function testBoundingRects(expectedBoundingRects, tolerance)
document.write("<p>" + (results.length ? results.join("<br />") : "PASS") + "</p>");

return !results.length;
}

function assertRectContains(results, name, containerRect, insideRect, tolerance) {
// make the container rect bigger with tolerance
var left = containerRect.left - tolerance;
var right = containerRect.right + tolerance;
var top = containerRect.top - tolerance;
var bottom = containerRect.bottom + tolerance;
var pass = left <= insideRect.left && insideRect.right <= right
&& top <= insideRect.top && insideRect.bottom <= bottom;
if (!pass)
results.push("FAIL(" + name + ") outside bounding rect was: [" + rectToArray(containerRect).join(", ") + "], and inside was: [" + rectToArray(insideRect).join(", ") + "]");
return pass;
}

function addPageLevelDebugBox(rect, color) {
var el = document.createElement("div");
el.style.position = "absolute";
el.style.left = rect.left + "px";
el.style.top = rect.top + "px";
el.style.width = rect.width + "px";
el.style.height = rect.height + "px";
el.style.backgroundColor = color;
document.body.appendChild(el);
}

function testContentToRegionsMapping(tolerance)
{
if (tolerance === undefined)
tolerance = 0;

var debug = isDebugEnabled();
var drawnRegions = {};

var elements = document.getElementsByClassName("check");
var results = [];
for (var i = 0; i < elements.length; ++i) {
var el = elements[i];
var regionId = el.className.split(" ")[1];
var region = document.getElementById(regionId);
var regionRect = region.getBoundingClientRect();
var contentRect = el.getClientRects();
if (debug && !drawnRegions[regionId]) {
addPageLevelDebugBox(regionRect, "rgba(255,0,0,0.3)");
drawnRegions[regionId] = true;
}
for (var j = 0; j < contentRect.length; ++j) {
var passed = assertRectContains(results, el.className, regionRect, contentRect[j], tolerance);
if (debug)
addPageLevelDebugBox(contentRect[j], passed ? "rgba(0,255,0,0.3)" : "rgba(255,0,255,0.5)");
}
}

document.write("<p>" + (results.length ? results.join("<br />") : "PASS") + "</p>");

return !results.length && !debug;
}
@@ -0,0 +1 @@
PASS
@@ -0,0 +1,50 @@
<!DOCTYPE html>

<style>
#content { -webkit-flow: 'flow'; }
.region { content: -webkit-from-flow("flow"); }
.finished #content, .finished .region { display: none; }

#region1 { width: 70px; height: 60px; }
#region2 { width: 200px; height: 100px; }
#region3 { width: 110px; height: 120px; }
#region4 { width: 220px; height: 100px; }
#region5 { width: 200px; height: 140px; }
</style>

<div id="content">
<div style="-webkit-region-break-after: always"><b class="check region1">Region 1</b></div>

<div>
<div>
<div style="-webkit-region-break-after: always">
<div>
<b class="check region2">Region 2</b>
<div style="-webkit-region-break-before: always; margin-top:35px;"><b class="check region3">Region 3</b></div>
</div>
</div>
</div>
</div>

<div><b class="check region4">Region 4</b></div>


<div style="-webkit-region-break-inside: avoid;">
<b class="check region5 start">Start of region 5.</b> Do not split these lines. Do not split these lines. Do not split these lines. Do not split these lines. Do not split these lines. Do not split these lines. Do not split these lines. <b class="check region5 end">End of region 5.</b>
</div>

</div>

<div id="region1" class="region"></div>
<div id="region2" class="region"></div>
<div id="region3" class="region"></div>
<div id="region4" class="region"></div>
<div id="region5" class="region"></div>

<script src="resources/helper.js"></script>
<script>
if (window.layoutTestController)
layoutTestController.dumpAsText();
if (testContentToRegionsMapping())
document.body.className = "finished";
</script>
@@ -0,0 +1 @@
PASS
@@ -0,0 +1 @@
PASS
@@ -0,0 +1,44 @@
<!DOCTYPE html>

<style>
html { -webkit-writing-mode: horizontal-bt; }

#content { -webkit-flow: 'flow'; }
.region { content: -webkit-from-flow("flow"); }
.finished #content, .finished .region { display: none; }

#region1 { width: 70px; height: 60px; }
#region2 { width: 200px; height: 100px; }
#region3 { width: 110px; height: 120px; }
#region4 { width: 220px; height: 100px; }
#region5 { width: 110px; height: 200px; }
#region6 { width: 300px; height: 120px; }
</style>

<div id="content">
<p style="-webkit-region-break-after: always"><b class="check region1">Text in region 1.</b> This paragraph has "<i>-webkit-region-break-after: always</i>". <b class="check region2">There should be nothing in this region after this line.</b></p>

<p><b class="check region3">First element in the region 3.</b> Some text inside a flow. Some text inside a flow. Some text inside a flow. <b class="check region4">Text in region 4.</b> </p>

<p>
<!-- Using the paragraph element to test nested blocks region-breaks. -->
<div><span class="check region4">Simple line in region 4.</span></div>
<div style="-webkit-margin-before:50px;"><b class="check region5">First line in region 5.</b> This paragraph displays in region 5 because it has a margin-top, which is too high to fit in the previous region.</div>
<div style="-webkit-region-break-before: always"><b class="check region6">First line in region 6.</b> This paragraph uses "<i>-webkit-region-break-before: always</i>".</div>
</p>
</div>

<div id="region1" class="region"></div>
<div id="region2" class="region"></div>
<div id="region3" class="region"></div>
<div id="region4" class="region"></div>
<div id="region5" class="region"></div>
<div id="region6" class="region"></div>

<script src="resources/helper.js"></script>
<script>
if (window.layoutTestController)
layoutTestController.dumpAsText();
if (testContentToRegionsMapping())
document.body.className = "finished";
</script>
@@ -0,0 +1 @@
PASS
@@ -0,0 +1 @@
PASS
@@ -0,0 +1,44 @@
<!DOCTYPE html>

<style>
html { -webkit-writing-mode: vertical-rl; }

#content { -webkit-flow: 'flow'; }
.region { content: -webkit-from-flow("flow"); }
.finished #content, .finished .region { display: none; }

#region1 { width: 70px; height: 60px; }
#region2 { width: 200px; height: 100px; }
#region3 { width: 110px; height: 120px; }
#region4 { width: 220px; height: 100px; }
#region5 { width: 110px; height: 200px; }
#region6 { width: 300px; height: 120px; }
</style>

<div id="content">
<p style="-webkit-region-break-after: always"><b class="check region1">Text in region 1.</b> This paragraph has "<i>-webkit-region-break-after: always</i>". <b class="check region2">There should be nothing in this region after this line.</b></p>

<p><b class="check region3">First element in the region 3.</b> Some text inside a flow. Some text inside a flow. Some text inside a flow. <b class="check region4">Text in region 4.</b> </p>

<p>
<!-- Using the paragraph element to test nested blocks region-breaks. -->
<div><span class="check region4">Simple line in region 4.</span></div>
<div style="-webkit-margin-before:80px;"><b class="check region5">First line in region 5.</b> This paragraph displays in region 5 because it has a margin-top, which is too high to fit in the previous region.</div>
<div style="-webkit-region-break-before: always"><b class="check region6">First line in region 6.</b> This paragraph uses "<i>-webkit-region-break-before: always</i>".</div>
</p>
</div>

<div id="region1" class="region"></div>
<div id="region2" class="region"></div>
<div id="region3" class="region"></div>
<div id="region4" class="region"></div>
<div id="region5" class="region"></div>
<div id="region6" class="region"></div>

<script src="resources/helper.js"></script>
<script>
if (window.layoutTestController)
layoutTestController.dumpAsText();
if (testContentToRegionsMapping())
document.body.className = "finished";
</script>
@@ -0,0 +1,44 @@
<!DOCTYPE html>

<style>
html { -webkit-writing-mode: vertical-lr; }

#content { -webkit-flow: 'flow'; }
.region { content: -webkit-from-flow("flow"); }
.finished #content, .finished .region { display: none; }

#region1 { height: 70px; width: 60px; }
#region2 { height: 200px; width: 150px; }
#region3 { height: 110px; width: 120px; }
#region4 { height: 220px; width: 100px; }
#region5 { height: 110px; width: 200px; }
#region6 { height: 300px; width: 120px; }
</style>

<div id="content">
<p style="-webkit-region-break-after: always"><b class="check region1">Text in region 1.</b> This paragraph has "<i>-webkit-region-break-after: always</i>". <b class="check region2">There should be nothing in this region after this line.</b></p>

<p><b class="check region3">First element in the region 3.</b> Some text inside a flow. Some text inside a flow. Some text inside a flow. <b class="check region4">Text in region 4.</b> </p>

<p>
<!-- Using the paragraph element to test nested blocks region-breaks. -->
<div><span class="check region4">Simple line in region 4.</span></div>
<div style="-webkit-margin-before:50px;"><b class="check region5">First line in region 5.</b> This paragraph displays in region 5 because it has a margin-top, which is too high to fit in the previous region.</div>
<div style="-webkit-region-break-before: always"><b class="check region6">First line in region 6.</b> This paragraph uses "<i>-webkit-region-break-before: always</i>".</div>
</p>
</div>

<div id="region1" class="region"></div>
<div id="region2" class="region"></div>
<div id="region3" class="region"></div>
<div id="region4" class="region"></div>
<div id="region5" class="region"></div>
<div id="region6" class="region"></div>

<script src="resources/helper.js"></script>
<script>
if (window.layoutTestController)
layoutTestController.dumpAsText();
if (testContentToRegionsMapping())
document.body.className = "finished";
</script>
@@ -0,0 +1,42 @@
<!DOCTYPE html>

<style>
#content { -webkit-flow: 'flow'; }
.region { content: -webkit-from-flow("flow"); }
.finished #content, .finished .region { display: none; }

#region1 { width: 70px; height: 60px; }
#region2 { width: 200px; height: 100px; }
#region3 { width: 110px; height: 120px; }
#region4 { width: 220px; height: 100px; }
#region5 { width: 110px; height: 200px; }
#region6 { width: 300px; height: 120px; }
</style>

<div id="content">
<p style="-webkit-region-break-after: always"><b class="check region1">Text in region 1.</b> This paragraph has "<i>-webkit-region-break-after: always</i>". <b class="check region2">There should be nothing in this region after this line.</b></p>

<p><b class="check region3">First element in the region 3.</b> Some text inside a flow. Some text inside a flow. Some text inside a flow. <b class="check region4">Text in region 4.</b> </p>

<p>
<!-- Using the paragraph element to test nested blocks region-breaks. -->
<div><span class="check region4">Simple line in region 4.</span></div>
<div style="margin-top:50px;"><b class="check region5">First line in region 5.</b> This paragraph displays in region 5 because it has a margin-top, which is too high to fit in the previous region.</div>
<div style="-webkit-region-break-before: always"><b class="check region6">First line in region 6.</b> This paragraph uses "<i>-webkit-region-break-before: always</i>".</div>
</p>
</div>

<div id="region1" class="region"></div>
<div id="region2" class="region"></div>
<div id="region3" class="region"></div>
<div id="region4" class="region"></div>
<div id="region5" class="region"></div>
<div id="region6" class="region"></div>

<script src="resources/helper.js"></script>
<script>
if (window.layoutTestController)
layoutTestController.dumpAsText();
if (testContentToRegionsMapping())
document.body.className = "finished";
</script>

0 comments on commit 172fc0e

Please sign in to comment.