Bug 1587127: Ensure no backplate is drawn for lines that have only visibility:hidden descendants. r=dholbert

Differential Revision: https://phabricator.services.mozilla.com/D48725

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Morgan Reschenberg 2019-10-30 15:45:45 +00:00
parent 1d804e6a9a
commit 36e1ff99a9
4 changed files with 155 additions and 4 deletions

View File

@ -123,6 +123,50 @@ static bool BlockHasAnyFloats(nsIFrame* aFrame) {
return false;
}
/**
* Determines whether the given frame is visible or has
* visible children that participate in the same line. Frames
* that are not line participants do not have their
* children checked.
*/
static bool FrameHasVisibleInlineContent(nsIFrame* aFrame) {
MOZ_ASSERT(aFrame, "Frame argument cannot be null");
if (aFrame->StyleVisibility()->IsVisible()) {
return true;
}
if (aFrame->IsFrameOfType(nsIFrame::eLineParticipant)) {
for (nsIFrame* kid : aFrame->PrincipalChildList()) {
if (kid->StyleVisibility()->IsVisible() ||
FrameHasVisibleInlineContent(kid)) {
return true;
}
}
}
return false;
}
/**
* Determines whether any of the frames descended from the
* given line have inline content with 'visibility: visible'.
* This function calls FrameHasVisibleInlineContent to process
* each frame in the line's child list.
*/
static bool LineHasVisibleInlineContent(nsLineBox* aLine) {
nsIFrame* kid = aLine->mFirstChild;
int32_t n = aLine->GetChildCount();
while (n-- > 0) {
if (FrameHasVisibleInlineContent(kid)) {
return true;
}
kid = kid->GetNextSibling();
}
return false;
}
#ifdef DEBUG
# include "nsBlockDebugFlags.h"
@ -6873,9 +6917,9 @@ void nsBlockFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
}
if (!lineInLine && !curBackplateArea.IsEmpty()) {
// If we have encountered a non-inline line, but were previously forming
// a backplate, we should add the backplate to the display list as-is
// and render future backplates disjointly.
// If we have encountered a non-inline line but were previously
// forming a backplate, we should add the backplate to the display
// list as-is and render future backplates disjointly.
MOZ_ASSERT(shouldDrawBackplate,
"if this master switch is off, curBackplateArea "
"must be empty and we shouldn't get here");
@ -6893,7 +6937,8 @@ void nsBlockFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
}
lastY = lineArea.y;
lastYMost = lineArea.YMost();
if (lineInLine && shouldDrawBackplate) {
if (lineInLine && shouldDrawBackplate &&
LineHasVisibleInlineContent(line)) {
nsRect lineBackplate = lineArea + aBuilder->ToReferenceFrame(this);
if (curBackplateArea.IsEmpty()) {
curBackplateArea = lineBackplate;

View File

@ -0,0 +1,55 @@
<!DOCTYPE html>
<html>
<head>
<title>Reference: Only lines containing visible content (visibility: visible) should receive backplates.</title>
<style>
body {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8%2F9hAAAABGdBTUEAALGPC%2FxhBQAAABh0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjAxHK4kRQAAABpJREFUOMtjZBCu%2F89AAWAcNWDUgFEDhosBAObLGSGp9PphAAAAAElFTkSuQmCC");
}
.hidden {
visibility: hidden;
}
.visible {
visibility: visible;
}
.fake-backplate {
background-color: white;
}
</style>
</head>
<body>
<div>
<span class="fake-backplate">AAAA</span>
<div class="hidden">BBBB</div>
<span class="fake-backplate">CCCC</span>
<div class="hidden">
DDDD
<div class="visible"><span class="fake-backplate">EEEE</span></div>
FFFF
</div>
</div>
<div class="fake-backplate" style="display: inline-block;">
<span class="fake-backplate">GGGG</span>
<br>
<span class="fake-backplate">HHHH</span>
<span class="hidden">IIII</span>
<span class="fake-backplate">JJJJ</span>
<span class="hidden">
KKKK
<span class="visible fake-backplate">LLLL</span>
MMMM
</span>
<span class="fake-backplate">NNNN</span>
<span class="hidden">
<span style="display:inline-block">
1
<span class="visible fake-backplate">2</span>
</span>
<span style="display:inline-block" class="visible fake-backplate">
3
</span>
4
</span>
</div>
</body>
</html>

View File

@ -0,0 +1,50 @@
<!DOCTYPE html>
<html>
<head>
<title>Only lines containing visible content (visibility: visible) should receive backplates.</title>
<style>
body {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8%2F9hAAAABGdBTUEAALGPC%2FxhBQAAABh0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjAxHK4kRQAAABpJREFUOMtjZBCu%2F89AAWAcNWDUgFEDhosBAObLGSGp9PphAAAAAElFTkSuQmCC");
}
.hidden {
visibility: hidden;
}
.visible {
visibility: visible;
}
</style>
</head>
<body>
<div>
AAAA<!-- no whitespace between elements
--><div class="hidden">BBBB</div><!-- no whitespace between elements
-->CCCC<!-- no whitespace between elements
--><div class="hidden">
DDDD
<div class="visible">EEEE</div>
FFFF
</div>
</div>
GGGG
<br>
HHHH
<span class="hidden">IIII</span>
JJJJ
<span class="hidden">
KKKK
<span class="visible">LLLL</span>
MMMM
</span>
NNNN
<span class="hidden">
<span style="display:inline-block">
1
<span class="visible">2</span>
</span>
<span style="display:inline-block" class="visible">
3
</span>
4<!-- no whitespace between elements
--></span>
</body>
</html>

View File

@ -15,3 +15,4 @@ fuzzy-if(cocoaWidget,255-255,1384-1384) fuzzy-if(winWidget,30-48,48-48) == backp
fuzzy-if(cocoaWidget,255-255,52-52) fuzzy-if(winWidget,15-15,48-48) == backplate-bg-image-007.html backplate-bg-image-007-ref.html
fuzzy-if(cocoaWidget,255-255,2842-2842) fuzzy-if(gtkWidget,255-255,620-620) fuzzy-if(winWidget||Android,255-255,480-481) == backplate-bg-image-008.html backplate-bg-image-008-ref.html
fuzzy-if(cocoaWidget,255-255,504-504) fuzzy-if(gtkWidget,255-255,1050-1050) fuzzy-if(winWidget||Android,255-255,480-480) == backplate-bg-image-009.html backplate-bg-image-009-ref.html
fuzzy-if(cocoaWidget,255-255,621-621) fuzzy-if(winWidget,255-255,128-128) fuzzy-if(Android,255-255,240-240) == backplate-bg-image-010.html backplate-bg-image-010-ref.html