Bug 375403 originally started off as a simple request to enable window translucency when windows or popups use opacity, alpha transparent background or non-zero border radius but mutated to include refactoring non zero side testing r+sr=roc

This commit is contained in:
neil%parkwaycc.co.uk 2007-05-10 15:46:42 +00:00
Родитель 3d0478f569
Коммит fe64e07564
5 изменённых файлов: 77 добавлений и 70 удалений

Просмотреть файл

@ -465,35 +465,6 @@ void nsDisplayList::Sort(nsDisplayListBuilder* aBuilder,
::Sort(this, Count(), aCmp, aClosure); ::Sort(this, Count(), aCmp, aClosure);
} }
static PRBool
NonZeroStyleCoord(const nsStyleCoord& aCoord) {
switch (aCoord.GetUnit()) {
case eStyleUnit_Percent:
return aCoord.GetPercentValue() > 0;
case eStyleUnit_Coord:
return aCoord.GetCoordValue() > 0;
case eStyleUnit_Null:
return PR_FALSE;
default:
return PR_TRUE;
}
}
static PRBool
HasNonZeroSide(const nsStyleSides& aSides) {
nsStyleCoord coord;
aSides.GetTop(coord);
if (NonZeroStyleCoord(coord)) return PR_TRUE;
aSides.GetRight(coord);
if (NonZeroStyleCoord(coord)) return PR_TRUE;
aSides.GetBottom(coord);
if (NonZeroStyleCoord(coord)) return PR_TRUE;
aSides.GetLeft(coord);
if (NonZeroStyleCoord(coord)) return PR_TRUE;
return PR_FALSE;
}
PRBool PRBool
nsDisplayBackground::IsOpaque(nsDisplayListBuilder* aBuilder) { nsDisplayBackground::IsOpaque(nsDisplayListBuilder* aBuilder) {
// theme background overrides any other background // theme background overrides any other background
@ -506,7 +477,7 @@ nsDisplayBackground::IsOpaque(nsDisplayListBuilder* aBuilder) {
nsCSSRendering::FindBackground(mFrame->PresContext(), mFrame, &bg, &isCanvas); nsCSSRendering::FindBackground(mFrame->PresContext(), mFrame, &bg, &isCanvas);
if (!hasBG || (bg->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT) || if (!hasBG || (bg->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT) ||
bg->mBackgroundClip != NS_STYLE_BG_CLIP_BORDER || bg->mBackgroundClip != NS_STYLE_BG_CLIP_BORDER ||
HasNonZeroSide(mFrame->GetStyleBorder()->mBorderRadius) || nsLayoutUtils::HasNonZeroSide(mFrame->GetStyleBorder()->mBorderRadius) ||
NS_GET_A(bg->mBackgroundColor) < 255) NS_GET_A(bg->mBackgroundColor) < 255)
return PR_FALSE; return PR_FALSE;
return PR_TRUE; return PR_TRUE;
@ -525,7 +496,7 @@ nsDisplayBackground::IsUniform(nsDisplayListBuilder* aBuilder) {
if (!hasBG) if (!hasBG)
return PR_TRUE; return PR_TRUE;
if ((bg->mBackgroundFlags & NS_STYLE_BG_IMAGE_NONE) && if ((bg->mBackgroundFlags & NS_STYLE_BG_IMAGE_NONE) &&
!HasNonZeroSide(mFrame->GetStyleBorder()->mBorderRadius) && !nsLayoutUtils::HasNonZeroSide(mFrame->GetStyleBorder()->mBorderRadius) &&
bg->mBackgroundClip == NS_STYLE_BG_CLIP_BORDER) bg->mBackgroundClip == NS_STYLE_BG_CLIP_BORDER)
return PR_TRUE; return PR_TRUE;
return PR_FALSE; return PR_FALSE;
@ -594,7 +565,7 @@ nsDisplayOutline::OptimizeVisibility(nsDisplayListBuilder* aBuilder,
const nsStyleOutline* outline = mFrame->GetStyleOutline(); const nsStyleOutline* outline = mFrame->GetStyleOutline();
nsPoint origin = aBuilder->ToReferenceFrame(mFrame); nsPoint origin = aBuilder->ToReferenceFrame(mFrame);
if (nsRect(origin, mFrame->GetSize()).Contains(aVisibleRegion->GetBounds()) && if (nsRect(origin, mFrame->GetSize()).Contains(aVisibleRegion->GetBounds()) &&
!HasNonZeroSide(outline->mOutlineRadius)) { !nsLayoutUtils::HasNonZeroSide(outline->mOutlineRadius)) {
nscoord outlineOffset; nscoord outlineOffset;
outline->GetOutlineOffset(outlineOffset); outline->GetOutlineOffset(outlineOffset);
if (outlineOffset >= 0) { if (outlineOffset >= 0) {
@ -626,7 +597,7 @@ nsDisplayBorder::OptimizeVisibility(nsDisplayListBuilder* aBuilder,
nsRect contentRect = GetBounds(aBuilder); nsRect contentRect = GetBounds(aBuilder);
contentRect.Deflate(border->GetBorder()); contentRect.Deflate(border->GetBorder());
if (contentRect.Contains(aVisibleRegion->GetBounds()) && if (contentRect.Contains(aVisibleRegion->GetBounds()) &&
!HasNonZeroSide(border->mBorderRadius)) { !nsLayoutUtils::HasNonZeroSide(border->mBorderRadius)) {
// the visible region is entirely inside the content rect, and no part // the visible region is entirely inside the content rect, and no part
// of the border is rendered inside the content rect, so we are not // of the border is rendered inside the content rect, so we are not
// visible // visible

Просмотреть файл

@ -65,6 +65,7 @@
#include "gfxRect.h" #include "gfxRect.h"
#include "nsIImage.h" #include "nsIImage.h"
#include "nsIInterfaceRequestorUtils.h" #include "nsIInterfaceRequestorUtils.h"
#include "nsCSSRendering.h"
#ifdef MOZ_SVG_FOREIGNOBJECT #ifdef MOZ_SVG_FOREIGNOBJECT
#include "nsSVGForeignObjectFrame.h" #include "nsSVGForeignObjectFrame.h"
@ -2176,3 +2177,57 @@ nsLayoutUtils::CharsToCoord(const nsStyleCoord& aStyle,
aRenderingContext->GetWidth('M', fontWidth); aRenderingContext->GetWidth('M', fontWidth);
return aStyle.GetIntValue() * fontWidth; return aStyle.GetIntValue() * fontWidth;
} }
static PRBool NonZeroStyleCoord(const nsStyleCoord& aCoord)
{
switch (aCoord.GetUnit()) {
case eStyleUnit_Percent:
return aCoord.GetPercentValue() > 0;
case eStyleUnit_Coord:
return aCoord.GetCoordValue() > 0;
case eStyleUnit_Null:
return PR_FALSE;
default:
return PR_TRUE;
}
}
/* static */ PRBool
nsLayoutUtils::HasNonZeroSide(const nsStyleSides& aSides)
{
nsStyleCoord coord;
aSides.GetTop(coord);
if (NonZeroStyleCoord(coord)) return PR_TRUE;
aSides.GetRight(coord);
if (NonZeroStyleCoord(coord)) return PR_TRUE;
aSides.GetBottom(coord);
if (NonZeroStyleCoord(coord)) return PR_TRUE;
aSides.GetLeft(coord);
if (NonZeroStyleCoord(coord)) return PR_TRUE;
return PR_FALSE;
}
/* static */ PRBool
nsLayoutUtils::FrameHasTransparency(nsIFrame* aFrame) {
if (aFrame->GetStyleContext()->GetStyleDisplay()->mOpacity < 1.0f)
return PR_TRUE;
const nsStyleBorder* border = aFrame->GetStyleContext()->GetStyleBorder();
if (HasNonZeroSide(border->mBorderRadius))
return PR_TRUE;
if (aFrame->IsThemed())
return PR_FALSE;
PRBool isCanvas;
const nsStyleBackground* bg;
if (!nsCSSRendering::FindBackground(aFrame->PresContext(), aFrame, &bg, &isCanvas))
return PR_TRUE;
if (bg->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT)
return PR_TRUE;
if (NS_GET_A(bg->mBackgroundColor) < 255)
return PR_TRUE;
if (bg->mBackgroundClip != NS_STYLE_BG_CLIP_BORDER)
return PR_TRUE;
return PR_FALSE;
}

Просмотреть файл

@ -676,6 +676,20 @@ public:
static nscoord CharsToCoord(const nsStyleCoord& aStyle, static nscoord CharsToCoord(const nsStyleCoord& aStyle,
nsIRenderingContext* aRenderingContext, nsIRenderingContext* aRenderingContext,
nsStyleContext* aStyleContext); nsStyleContext* aStyleContext);
/**
* Determine if any style coordinate is nonzero
* @param aCoord the style sides
* @return PR_TRUE unless all the coordinates are 0%, 0 or null.
*/
static PRBool HasNonZeroSide(const nsStyleSides& aSides);
/**
* Determine if a widget is likely to require transparency or translucency.
* @param aFrame the frame of a <window>, <popup> or <menupopup> element.
* @return a value suitable for passing to SetWindowTranslucency
*/
static PRBool FrameHasTransparency(nsIFrame* aFrame);
}; };
#endif // nsLayoutUtils_h__ #endif // nsLayoutUtils_h__

Просмотреть файл

@ -394,37 +394,10 @@ nsContainerFrame::PositionFrameView(nsIFrame* aKidFrame)
vm->MoveViewTo(view, pt.x, pt.y); vm->MoveViewTo(view, pt.x, pt.y);
} }
// This code is duplicated in nsDisplayList.cpp. We'll remove the duplication
// when we remove all this view sync code.
static PRBool
NonZeroStyleCoord(const nsStyleCoord& aCoord) {
switch (aCoord.GetUnit()) {
case eStyleUnit_Percent:
return aCoord.GetPercentValue() > 0;
case eStyleUnit_Coord:
return aCoord.GetCoordValue() > 0;
case eStyleUnit_Null:
return PR_FALSE;
default:
return PR_TRUE;
}
}
static PRBool static PRBool
HasNonZeroBorderRadius(nsStyleContext* aStyleContext) { HasNonZeroBorderRadius(nsStyleContext* aStyleContext) {
const nsStyleBorder* border = aStyleContext->GetStyleBorder(); const nsStyleBorder* border = aStyleContext->GetStyleBorder();
return nsLayoutUtils::HasNonZeroSide(border->mBorderRadius);
nsStyleCoord coord;
border->mBorderRadius.GetTop(coord);
if (NonZeroStyleCoord(coord)) return PR_TRUE;
border->mBorderRadius.GetRight(coord);
if (NonZeroStyleCoord(coord)) return PR_TRUE;
border->mBorderRadius.GetBottom(coord);
if (NonZeroStyleCoord(coord)) return PR_TRUE;
border->mBorderRadius.GetLeft(coord);
if (NonZeroStyleCoord(coord)) return PR_TRUE;
return PR_FALSE;
} }
static void static void
@ -473,7 +446,7 @@ SyncFrameViewGeometryDependentProperties(nsPresContext* aPresContext,
// don't proceed unless this is the root view // don't proceed unless this is the root view
// (sometimes the non-root-view is a canvas) // (sometimes the non-root-view is a canvas)
if (aView->HasWidget() && aView == rootView) { if (aView->HasWidget() && aView == rootView) {
viewHasTransparentContent = hasBG && (bg->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT); viewHasTransparentContent = nsLayoutUtils::FrameHasTransparency(aFrame);
aView->GetWidget()->SetWindowTranslucency(viewHasTransparentContent); aView->GetWidget()->SetWindowTranslucency(viewHasTransparentContent);
} }
} }

Просмотреть файл

@ -220,14 +220,8 @@ nsMenuPopupFrame::CreateWidgetForView(nsIView* aView)
widgetData.mBorderStyle = eBorderStyle_default; widgetData.mBorderStyle = eBorderStyle_default;
widgetData.clipSiblings = PR_TRUE; widgetData.clipSiblings = PR_TRUE;
PRBool isCanvas; PRBool viewHasTransparentContent = !mInContentShell &&
const nsStyleBackground* bg; nsLayoutUtils::FrameHasTransparency(this);
PRBool hasBG =
nsCSSRendering::FindBackground(PresContext(), this, &bg, &isCanvas);
PRBool viewHasTransparentContent = hasBG &&
(bg->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT) &&
!GetStyleDisplay()->mAppearance && !mInContentShell;
nsIContent* parentContent = GetContent()->GetParent(); nsIContent* parentContent = GetContent()->GetParent();
nsIAtom *tag = nsnull; nsIAtom *tag = nsnull;
if (parentContent) if (parentContent)