Bug 485149 - Using box-shadow on a <fieldset> with <legend> does not follow box shape. r=roc

This commit is contained in:
Mats Palmgren 2013-04-17 22:16:14 +02:00
parent 3022251072
commit 109767f361
7 changed files with 218 additions and 17 deletions

View File

@ -1214,7 +1214,8 @@ nsCSSRendering::PaintBoxShadowOuter(nsPresContext* aPresContext,
} else {
nativeTheme = false;
nscoord twipsRadii[8];
NS_ASSERTION(aFrameArea.Size() == aForFrame->GetSize(), "unexpected size");
NS_ASSERTION(aFrameArea.Size() == aForFrame->VisualBorderRectRelativeToSelf().Size(),
"unexpected size");
hasBorderRadius = aForFrame->GetBorderRadii(twipsRadii);
if (hasBorderRadius) {
ComputePixelRadii(twipsRadii, twipsPerPixel, &borderRadii);

View File

@ -2385,7 +2385,7 @@ void
nsDisplayBoxShadowOuter::Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx) {
nsPoint offset = ToReferenceFrame();
nsRect borderRect = nsRect(offset, mFrame->GetSize());
nsRect borderRect = mFrame->VisualBorderRectRelativeToSelf() + offset;
nsPresContext* presContext = mFrame->PresContext();
nsAutoTArray<nsRect,10> rects;
ComputeDisjointRectangles(mVisibleRegion, &rects);

View File

@ -3,9 +3,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// YY need to pass isMultiple before create called
//#include "nsFormControlFrame.h"
#include "nsContainerFrame.h"
#include "nsLegendFrame.h"
#include "nsIDOMNode.h"
@ -13,7 +10,6 @@
#include "nsIDOMHTMLLegendElement.h"
#include "nsCSSRendering.h"
#include <algorithm>
//#include "nsIDOMHTMLCollection.h"
#include "nsIContent.h"
#include "nsIFrame.h"
#include "nsISupports.h"
@ -35,7 +31,7 @@ using namespace mozilla::layout;
class nsLegendFrame;
class nsFieldSetFrame : public nsContainerFrame {
class nsFieldSetFrame MOZ_FINAL : public nsContainerFrame {
public:
NS_DECL_FRAMEARENA_HELPERS
@ -55,6 +51,21 @@ public:
uint32_t aFlags) MOZ_OVERRIDE;
virtual nscoord GetBaseline() const;
/**
* The area to paint box-shadows around. It's the border rect except
* when there's a <legend> we offset the y-position to the center of it.
*/
virtual nsRect VisualBorderRectRelativeToSelf() const MOZ_OVERRIDE {
nscoord topBorder = StyleBorder()->GetComputedBorderWidth(NS_SIDE_TOP);
nsRect r(nsPoint(0,0), GetSize());
if (topBorder < mLegendRect.height) {
nscoord yoff = (mLegendRect.height - topBorder) / 2;
r.y += yoff;
r.height -= yoff;
}
return r;
}
NS_IMETHOD Reflow(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
@ -229,20 +240,14 @@ void
nsFieldSetFrame::PaintBorderBackground(nsRenderingContext& aRenderingContext,
nsPoint aPt, const nsRect& aDirtyRect, uint32_t aBGFlags)
{
const nsStyleBorder* borderStyle = StyleBorder();
nscoord topBorder = borderStyle->GetComputedBorderWidth(NS_SIDE_TOP);
nscoord yoff = 0;
nsPresContext* presContext = PresContext();
// if the border is smaller than the legend. Move the border down
// to be centered on the legend.
// FIXME: This means border-radius clamping is incorrect; we should
// override nsIFrame::GetBorderRadii.
if (topBorder < mLegendRect.height)
yoff = (mLegendRect.height - topBorder)/2;
nsRect rect(aPt.x, aPt.y + yoff, mRect.width, mRect.height - yoff);
nsRect rect = VisualBorderRectRelativeToSelf();
nscoord yoff = rect.y;
rect += aPt;
nsPresContext* presContext = PresContext();
nsCSSRendering::PaintBackground(presContext, aRenderingContext, this,
aDirtyRect, rect, aBGFlags);
@ -251,6 +256,7 @@ nsFieldSetFrame::PaintBorderBackground(nsRenderingContext& aRenderingContext,
this, rect, aDirtyRect);
if (mLegendFrame) {
nscoord topBorder = StyleBorder()->GetComputedBorderWidth(NS_SIDE_TOP);
// Use the rect of the legend frame, not mLegendRect, so we draw our
// border under the legend's left and right margins.

View File

@ -1008,6 +1008,14 @@ public:
nsRect GetContentRect() const;
nsRect GetContentRectRelativeToSelf() const;
/**
* The area to paint box-shadows around. The default is the border rect.
* (nsFieldSetFrame overrides this).
*/
virtual nsRect VisualBorderRectRelativeToSelf() const {
return nsRect(0, 0, mRect.width, mRect.height);
}
/**
* Get the size, in app units, of the border radii. It returns FALSE iff all
* returned radii == 0 (so no border radii), TRUE otherwise.

View File

@ -0,0 +1,95 @@
<!DOCTYPE HTML>
<html><head>
<meta charset="utf-8">
<title>Testcase for bug 485149</title>
<style type="text/css">
html,body {
color:black; background-color:white; font-size:16px; padding:0; margin:0;
}
body {padding:20px;}
field {
display:block;
overflow:hidden;
background:yellow;
box-shadow:0 0 5px 5px #cccccc;
border:1px solid #000000;
border-radius:7px;
width:200px;
height:50px;
margin-left:5px;
margin-right:2px;
padding:10px;
border-box;
}
.with-legend {
margin-top:8px;
height:42px;
}
p { height:40px; margin:0; }
#mask1 {
position:absolute;
left:0;
top:0;
background:black;
z-index:1;
width:150px;
height:700px;
}
#mask2 {
position:absolute;
left:170px;
top:330px;
background:black;
z-index:1;
width:150px;
height:300px;
}
#mask3 {
position:absolute;
left:0;
top:380px;
background:black;
z-index:1;
width:300px;
height:300px;
}
</style>
</head>
<body>
<field class="with-legend">
1
</field>
<p></p>
<field class="with-legend" style="position:relative">
2
</field>
<p></p>
<field>
3
</field>
<p></p>
<field class="with-legend" style="border-color:transparent">
4
</field>
<div id="mask1"></div>
<div id="mask2"></div>
<div id="mask3"></div>
</body>
</html>

View File

@ -0,0 +1,90 @@
<!DOCTYPE HTML>
<html><head>
<meta charset="utf-8">
<title>Testcase for bug 485149</title>
<style type="text/css">
html,body {
color:black; background-color:white; font-size:16px; padding:0; margin:0;
}
body {padding:20px;}
fieldset {
overflow:hidden;
background:yellow;
box-shadow:0 0 5px 5px #cccccc;
border:1px solid #000000;
border-radius:7px;
width:200px;
height:50px;
margin-left:5px;
margin-right:2px;
padding:10px;
}
legend { height:16px; }
p { height:40px; margin:0; }
#mask1 {
position:absolute;
left:0;
top:0;
background:black;
z-index:1;
width:150px;
height:700px;
}
#mask2 {
position:absolute;
left:170px;
top:330px;
background:black;
z-index:1;
width:150px;
height:300px;
}
#mask3 {
position:absolute;
left:0;
top:380px;
background:black;
z-index:1;
width:300px;
height:300px;
}
</style>
</head>
<body>
<fieldset><legend>Legend</legend>
1
</fieldset>
<p></p>
<fieldset style="position:relative;"><legend>Legend</legend>
2
</fieldset>
<p></p>
<fieldset>
3
</fieldset>
<p></p>
<fieldset><legend style="width:150px;"></legend>
4
</fieldset>
<div id="mask1"></div>
<div id="mask2"></div>
<div id="mask3"></div>
</body>
</html>

View File

@ -25,3 +25,4 @@ random-if(d2d) == boxshadow-threecorners.html boxshadow-threecorners-ref.html
== overflow-not-scrollable-2.html overflow-not-scrollable-2-ref.html
fails-if(Android) == 611574-1.html 611574-1-ref.html
fails-if(Android) == 611574-2.html 611574-2-ref.html
fuzzy-if(winWidget,5,30) == fieldset.html fieldset-ref.html # minor anti-aliasing problem on Windows