зеркало из https://github.com/mozilla/pjs.git
Bug 602757. Part 3: Change IsOpaque to GetOpaqueRegion so we can get useful opaque regions for content that uses border-radius. r=tnikkel,sr=dbaron,a=blocking
This commit is contained in:
Родитель
360d34a263
Коммит
e7ff7b3a5f
|
@ -1486,8 +1486,10 @@ namespace {
|
||||||
nsRect nsRegion::GetLargestRectangle () const {
|
nsRect nsRegion::GetLargestRectangle () const {
|
||||||
nsRect bestRect;
|
nsRect bestRect;
|
||||||
|
|
||||||
if (!mRectCount)
|
if (mRectCount <= 1) {
|
||||||
|
bestRect = mBoundRect;
|
||||||
return bestRect;
|
return bestRect;
|
||||||
|
}
|
||||||
|
|
||||||
AxisPartition xaxis, yaxis;
|
AxisPartition xaxis, yaxis;
|
||||||
|
|
||||||
|
|
|
@ -186,7 +186,8 @@ protected:
|
||||||
void Accumulate(nsDisplayListBuilder* aBuilder,
|
void Accumulate(nsDisplayListBuilder* aBuilder,
|
||||||
nsDisplayItem* aItem,
|
nsDisplayItem* aItem,
|
||||||
const nsIntRect& aVisibleRect,
|
const nsIntRect& aVisibleRect,
|
||||||
const nsIntRect& aDrawRect);
|
const nsIntRect& aDrawRect,
|
||||||
|
const FrameLayerBuilder::Clip& aClip);
|
||||||
nsIFrame* GetActiveScrolledRoot() { return mActiveScrolledRoot; }
|
nsIFrame* GetActiveScrolledRoot() { return mActiveScrolledRoot; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -307,6 +308,7 @@ protected:
|
||||||
already_AddRefed<ThebesLayer> FindThebesLayerFor(nsDisplayItem* aItem,
|
already_AddRefed<ThebesLayer> FindThebesLayerFor(nsDisplayItem* aItem,
|
||||||
const nsIntRect& aVisibleRect,
|
const nsIntRect& aVisibleRect,
|
||||||
const nsIntRect& aDrawRect,
|
const nsIntRect& aDrawRect,
|
||||||
|
const FrameLayerBuilder::Clip& aClip,
|
||||||
nsIFrame* aActiveScrolledRoot);
|
nsIFrame* aActiveScrolledRoot);
|
||||||
ThebesLayerData* GetTopThebesLayerData()
|
ThebesLayerData* GetTopThebesLayerData()
|
||||||
{
|
{
|
||||||
|
@ -922,7 +924,8 @@ void
|
||||||
ContainerState::ThebesLayerData::Accumulate(nsDisplayListBuilder* aBuilder,
|
ContainerState::ThebesLayerData::Accumulate(nsDisplayListBuilder* aBuilder,
|
||||||
nsDisplayItem* aItem,
|
nsDisplayItem* aItem,
|
||||||
const nsIntRect& aVisibleRect,
|
const nsIntRect& aVisibleRect,
|
||||||
const nsIntRect& aDrawRect)
|
const nsIntRect& aDrawRect,
|
||||||
|
const FrameLayerBuilder::Clip& aClip)
|
||||||
{
|
{
|
||||||
nscolor uniformColor;
|
nscolor uniformColor;
|
||||||
if (aItem->IsUniform(aBuilder, &uniformColor)) {
|
if (aItem->IsUniform(aBuilder, &uniformColor)) {
|
||||||
|
@ -947,18 +950,25 @@ ContainerState::ThebesLayerData::Accumulate(nsDisplayListBuilder* aBuilder,
|
||||||
mDrawRegion.SimplifyOutward(4);
|
mDrawRegion.SimplifyOutward(4);
|
||||||
|
|
||||||
PRBool forceTransparentSurface = PR_FALSE;
|
PRBool forceTransparentSurface = PR_FALSE;
|
||||||
if (aItem->IsOpaque(aBuilder, &forceTransparentSurface)) {
|
nsRegion opaque = aItem->GetOpaqueRegion(aBuilder, &forceTransparentSurface);
|
||||||
// We don't use SimplifyInward here since it's not defined exactly
|
if (!opaque.IsEmpty()) {
|
||||||
// what it will discard. For our purposes the most important case
|
nsRegionRectIterator iter(opaque);
|
||||||
// is a large opaque background at the bottom of z-order (e.g.,
|
nscoord appUnitsPerDevPixel = AppUnitsPerDevPixel(aItem);
|
||||||
// a canvas background), so we need to make sure that the first rect
|
for (const nsRect* r = iter.Next(); r; r = iter.Next()) {
|
||||||
// we see doesn't get discarded.
|
// We don't use SimplifyInward here since it's not defined exactly
|
||||||
nsIntRegion tmp;
|
// what it will discard. For our purposes the most important case
|
||||||
tmp.Or(mOpaqueRegion, aDrawRect);
|
// is a large opaque background at the bottom of z-order (e.g.,
|
||||||
if (tmp.GetNumRects() <= 4) {
|
// a canvas background), so we need to make sure that the first rect
|
||||||
mOpaqueRegion = tmp;
|
// we see doesn't get discarded.
|
||||||
|
nsIntRect rect = aClip.ApproximateIntersect(*r).ToNearestPixels(appUnitsPerDevPixel);
|
||||||
|
nsIntRegion tmp;
|
||||||
|
tmp.Or(mOpaqueRegion, rect);
|
||||||
|
if (tmp.GetNumRects() <= 4) {
|
||||||
|
mOpaqueRegion = tmp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (aItem->HasText()) {
|
}
|
||||||
|
if (aItem->HasText()) {
|
||||||
if (!mOpaqueRegion.Contains(aVisibleRect)) {
|
if (!mOpaqueRegion.Contains(aVisibleRect)) {
|
||||||
if (SuppressComponentAlpha(aBuilder, aItem)) {
|
if (SuppressComponentAlpha(aBuilder, aItem)) {
|
||||||
aItem->DisableComponentAlpha();
|
aItem->DisableComponentAlpha();
|
||||||
|
@ -974,6 +984,7 @@ already_AddRefed<ThebesLayer>
|
||||||
ContainerState::FindThebesLayerFor(nsDisplayItem* aItem,
|
ContainerState::FindThebesLayerFor(nsDisplayItem* aItem,
|
||||||
const nsIntRect& aVisibleRect,
|
const nsIntRect& aVisibleRect,
|
||||||
const nsIntRect& aDrawRect,
|
const nsIntRect& aDrawRect,
|
||||||
|
const FrameLayerBuilder::Clip& aClip,
|
||||||
nsIFrame* aActiveScrolledRoot)
|
nsIFrame* aActiveScrolledRoot)
|
||||||
{
|
{
|
||||||
PRInt32 i;
|
PRInt32 i;
|
||||||
|
@ -1028,7 +1039,7 @@ ContainerState::FindThebesLayerFor(nsDisplayItem* aItem,
|
||||||
layer = thebesLayerData->mLayer;
|
layer = thebesLayerData->mLayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
thebesLayerData->Accumulate(mBuilder, aItem, aVisibleRect, aDrawRect);
|
thebesLayerData->Accumulate(mBuilder, aItem, aVisibleRect, aDrawRect, aClip);
|
||||||
return layer.forget();
|
return layer.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1175,7 +1186,7 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<ThebesLayer> thebesLayer =
|
nsRefPtr<ThebesLayer> thebesLayer =
|
||||||
FindThebesLayerFor(item, itemVisibleRect, itemDrawRect,
|
FindThebesLayerFor(item, itemVisibleRect, itemDrawRect, aClip,
|
||||||
activeScrolledRoot);
|
activeScrolledRoot);
|
||||||
|
|
||||||
InvalidateForLayerChange(item, thebesLayer);
|
InvalidateForLayerChange(item, thebesLayer);
|
||||||
|
@ -1814,4 +1825,20 @@ FrameLayerBuilder::Clip::ApplyTo(gfxContext* aContext,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsRect
|
||||||
|
FrameLayerBuilder::Clip::ApproximateIntersect(const nsRect& aRect) const
|
||||||
|
{
|
||||||
|
nsRect r = aRect;
|
||||||
|
if (mHaveClipRect) {
|
||||||
|
r.IntersectRect(r, mClipRect);
|
||||||
|
}
|
||||||
|
for (PRUint32 i = 0, iEnd = mRoundedClipRects.Length();
|
||||||
|
i < iEnd; ++i) {
|
||||||
|
const Clip::RoundedRect &rr = mRoundedClipRects[i];
|
||||||
|
nsRegion rgn = nsLayoutUtils::RoundedRectIntersectRect(rr.mRect, rr.mRadii, r);
|
||||||
|
r = rgn.GetLargestRectangle();
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -317,6 +317,11 @@ public:
|
||||||
// or clearing of other clips must be done by the caller.
|
// or clearing of other clips must be done by the caller.
|
||||||
void ApplyTo(gfxContext* aContext, nsPresContext* aPresContext);
|
void ApplyTo(gfxContext* aContext, nsPresContext* aPresContext);
|
||||||
|
|
||||||
|
// Return a rectangle contained in the intersection of aRect with this
|
||||||
|
// clip region. Tries to return the largest possible rectangle, but may
|
||||||
|
// not succeed.
|
||||||
|
nsRect ApproximateIntersect(const nsRect& aRect) const;
|
||||||
|
|
||||||
bool operator==(const Clip& aOther) const {
|
bool operator==(const Clip& aOther) const {
|
||||||
return mHaveClipRect == aOther.mHaveClipRect &&
|
return mHaveClipRect == aOther.mHaveClipRect &&
|
||||||
(!mHaveClipRect || mClipRect == aOther.mClipRect) &&
|
(!mHaveClipRect || mClipRect == aOther.mClipRect) &&
|
||||||
|
|
|
@ -174,6 +174,9 @@ void
|
||||||
nsDisplayListBuilder::SubtractFromVisibleRegion(nsRegion* aVisibleRegion,
|
nsDisplayListBuilder::SubtractFromVisibleRegion(nsRegion* aVisibleRegion,
|
||||||
const nsRegion& aRegion)
|
const nsRegion& aRegion)
|
||||||
{
|
{
|
||||||
|
if (aRegion.IsEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
nsRegion tmp;
|
nsRegion tmp;
|
||||||
tmp.Sub(*aVisibleRegion, aRegion);
|
tmp.Sub(*aVisibleRegion, aRegion);
|
||||||
// Don't let *aVisibleRegion get too complex, but don't let it fluff out
|
// Don't let *aVisibleRegion get too complex, but don't let it fluff out
|
||||||
|
@ -310,19 +313,19 @@ nsDisplayList::ComputeVisibilityForRoot(nsDisplayListBuilder* aBuilder,
|
||||||
return ComputeVisibilityForSublist(aBuilder, aVisibleRegion, r.GetBounds());
|
return ComputeVisibilityForSublist(aBuilder, aVisibleRegion, r.GetBounds());
|
||||||
}
|
}
|
||||||
|
|
||||||
static PRBool
|
static nsRegion
|
||||||
TreatAsOpaque(nsDisplayItem* aItem, nsDisplayListBuilder* aBuilder,
|
TreatAsOpaque(nsDisplayItem* aItem, nsDisplayListBuilder* aBuilder,
|
||||||
PRBool* aTransparentBackground)
|
PRBool* aTransparentBackground)
|
||||||
{
|
{
|
||||||
if (aItem->IsOpaque(aBuilder, aTransparentBackground))
|
nsRegion opaque = aItem->GetOpaqueRegion(aBuilder, aTransparentBackground);
|
||||||
return PR_TRUE;
|
|
||||||
if (aBuilder->IsForPluginGeometry()) {
|
if (aBuilder->IsForPluginGeometry()) {
|
||||||
// Treat all chrome items as opaque
|
// Treat all chrome items as opaque
|
||||||
nsIFrame* f = aItem->GetUnderlyingFrame();
|
nsIFrame* f = aItem->GetUnderlyingFrame();
|
||||||
if (f && f->PresContext()->IsChrome())
|
if (f && f->PresContext()->IsChrome()) {
|
||||||
return PR_TRUE;
|
opaque = aItem->GetBounds(aBuilder);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return PR_FALSE;
|
return opaque;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool
|
PRBool
|
||||||
|
@ -362,10 +365,9 @@ nsDisplayList::ComputeVisibilityForSublist(nsDisplayListBuilder* aBuilder,
|
||||||
if (item->ComputeVisibility(aBuilder, aVisibleRegion)) {
|
if (item->ComputeVisibility(aBuilder, aVisibleRegion)) {
|
||||||
anyVisible = PR_TRUE;
|
anyVisible = PR_TRUE;
|
||||||
PRBool transparentBackground = PR_FALSE;
|
PRBool transparentBackground = PR_FALSE;
|
||||||
if (TreatAsOpaque(item, aBuilder, &transparentBackground)) {
|
nsRegion opaque = TreatAsOpaque(item, aBuilder, &transparentBackground);
|
||||||
// Subtract opaque item from the visible region
|
// Subtract opaque item from the visible region
|
||||||
aBuilder->SubtractFromVisibleRegion(aVisibleRegion, nsRegion(bounds));
|
aBuilder->SubtractFromVisibleRegion(aVisibleRegion, opaque);
|
||||||
}
|
|
||||||
forceTransparentSurface = forceTransparentSurface || transparentBackground;
|
forceTransparentSurface = forceTransparentSurface || transparentBackground;
|
||||||
}
|
}
|
||||||
AppendToBottom(item);
|
AppendToBottom(item);
|
||||||
|
@ -686,9 +688,8 @@ PRBool nsDisplayItem::RecomputeVisibility(nsDisplayListBuilder* aBuilder,
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
|
|
||||||
PRBool forceTransparentBackground;
|
PRBool forceTransparentBackground;
|
||||||
if (TreatAsOpaque(this, aBuilder, &forceTransparentBackground)) {
|
nsRegion opaque = TreatAsOpaque(this, aBuilder, &forceTransparentBackground);
|
||||||
aVisibleRegion->Sub(*aVisibleRegion, bounds);
|
aVisibleRegion->Sub(*aVisibleRegion, opaque);
|
||||||
}
|
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -834,25 +835,8 @@ RoundedBorderIntersectsRect(nsIFrame* aFrame,
|
||||||
static PRBool RoundedRectContainsRect(const nsRect& aRoundedRect,
|
static PRBool RoundedRectContainsRect(const nsRect& aRoundedRect,
|
||||||
const nscoord aRadii[8],
|
const nscoord aRadii[8],
|
||||||
const nsRect& aContainedRect) {
|
const nsRect& aContainedRect) {
|
||||||
// rectFullHeight and rectFullWidth together will approximately contain
|
nsRegion rgn = nsLayoutUtils::RoundedRectIntersectRect(aRoundedRect, aRadii, aContainedRect);
|
||||||
// the total area of the frame minus the rounded corners.
|
return rgn.Contains(aContainedRect);
|
||||||
nsRect rectFullHeight = aRoundedRect;
|
|
||||||
nscoord xDiff = NS_MAX(aRadii[NS_CORNER_TOP_LEFT_X], aRadii[NS_CORNER_BOTTOM_LEFT_X]);
|
|
||||||
rectFullHeight.x += xDiff;
|
|
||||||
rectFullHeight.width -= NS_MAX(aRadii[NS_CORNER_TOP_RIGHT_X],
|
|
||||||
aRadii[NS_CORNER_BOTTOM_RIGHT_X]) + xDiff;
|
|
||||||
if (rectFullHeight.Contains(aContainedRect))
|
|
||||||
return PR_TRUE;
|
|
||||||
|
|
||||||
nsRect rectFullWidth = aRoundedRect;
|
|
||||||
nscoord yDiff = NS_MAX(aRadii[NS_CORNER_TOP_LEFT_Y], aRadii[NS_CORNER_TOP_RIGHT_Y]);
|
|
||||||
rectFullWidth.y += yDiff;
|
|
||||||
rectFullWidth.height -= NS_MAX(aRadii[NS_CORNER_BOTTOM_LEFT_Y],
|
|
||||||
aRadii[NS_CORNER_BOTTOM_RIGHT_Y]) + yDiff;
|
|
||||||
if (rectFullWidth.Contains(aContainedRect))
|
|
||||||
return PR_TRUE;
|
|
||||||
|
|
||||||
return PR_FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -888,9 +872,10 @@ nsDisplayBackground::ComputeVisibility(nsDisplayListBuilder* aBuilder,
|
||||||
nsCSSRendering::FindBackground(mFrame->PresContext(), mFrame, &bgSC);
|
nsCSSRendering::FindBackground(mFrame->PresContext(), mFrame, &bgSC);
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool
|
nsRegion
|
||||||
nsDisplayBackground::IsOpaque(nsDisplayListBuilder* aBuilder,
|
nsDisplayBackground::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
|
||||||
PRBool* aForceTransparentSurface) {
|
PRBool* aForceTransparentSurface) {
|
||||||
|
nsRegion result;
|
||||||
if (aForceTransparentSurface) {
|
if (aForceTransparentSurface) {
|
||||||
*aForceTransparentSurface = PR_FALSE;
|
*aForceTransparentSurface = PR_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -901,27 +886,34 @@ nsDisplayBackground::IsOpaque(nsDisplayListBuilder* aBuilder,
|
||||||
*aForceTransparentSurface = disp->mAppearance == NS_THEME_WIN_BORDERLESS_GLASS ||
|
*aForceTransparentSurface = disp->mAppearance == NS_THEME_WIN_BORDERLESS_GLASS ||
|
||||||
disp->mAppearance == NS_THEME_WIN_GLASS;
|
disp->mAppearance == NS_THEME_WIN_GLASS;
|
||||||
}
|
}
|
||||||
return mThemeTransparency == nsITheme::eOpaque;
|
if (mThemeTransparency == nsITheme::eOpaque) {
|
||||||
|
result = GetBounds(aBuilder);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsStyleContext* bgSC;
|
nsStyleContext* bgSC;
|
||||||
if (!nsCSSRendering::FindBackground(mFrame->PresContext(), mFrame, &bgSC))
|
if (!nsCSSRendering::FindBackground(mFrame->PresContext(), mFrame, &bgSC))
|
||||||
return PR_FALSE;
|
return result;
|
||||||
const nsStyleBackground* bg = bgSC->GetStyleBackground();
|
const nsStyleBackground* bg = bgSC->GetStyleBackground();
|
||||||
|
|
||||||
const nsStyleBackground::Layer& bottomLayer = bg->BottomLayer();
|
const nsStyleBackground::Layer& bottomLayer = bg->BottomLayer();
|
||||||
|
|
||||||
// bottom layer's clip is used for the color
|
// bottom layer's clip is used for the color
|
||||||
if (bottomLayer.mClip != NS_STYLE_BG_CLIP_BORDER ||
|
if (bottomLayer.mClip != NS_STYLE_BG_CLIP_BORDER ||
|
||||||
nsLayoutUtils::HasNonZeroCorner(mFrame->GetStyleBorder()->mBorderRadius))
|
nsLayoutUtils::HasNonZeroCorner(mFrame->GetStyleBorder()->mBorderRadius))
|
||||||
return PR_FALSE;
|
return result;
|
||||||
|
|
||||||
if (NS_GET_A(bg->mBackgroundColor) == 255 &&
|
if (NS_GET_A(bg->mBackgroundColor) == 255 &&
|
||||||
!nsCSSRendering::IsCanvasFrame(mFrame))
|
!nsCSSRendering::IsCanvasFrame(mFrame)) {
|
||||||
return PR_TRUE;
|
result = GetBounds(aBuilder);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
return bottomLayer.mRepeat == NS_STYLE_BG_REPEAT_XY &&
|
if (bottomLayer.mRepeat == NS_STYLE_BG_REPEAT_XY &&
|
||||||
bottomLayer.mImage.IsOpaque();
|
bottomLayer.mImage.IsOpaque()) {
|
||||||
|
result = GetBounds(aBuilder);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool
|
PRBool
|
||||||
|
@ -1283,13 +1275,17 @@ nsDisplayWrapList::ComputeVisibility(nsDisplayListBuilder* aBuilder,
|
||||||
mVisibleRect);
|
mVisibleRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool
|
nsRegion
|
||||||
nsDisplayWrapList::IsOpaque(nsDisplayListBuilder* aBuilder,
|
nsDisplayWrapList::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
|
||||||
PRBool* aForceTransparentSurface) {
|
PRBool* aForceTransparentSurface) {
|
||||||
if (aForceTransparentSurface) {
|
if (aForceTransparentSurface) {
|
||||||
*aForceTransparentSurface = PR_FALSE;
|
*aForceTransparentSurface = PR_FALSE;
|
||||||
}
|
}
|
||||||
return mList.IsOpaque();
|
nsRegion result;
|
||||||
|
if (mList.IsOpaque()) {
|
||||||
|
result = GetBounds(aBuilder);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool nsDisplayWrapList::IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) {
|
PRBool nsDisplayWrapList::IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) {
|
||||||
|
@ -1427,14 +1423,14 @@ nsDisplayOpacity::~nsDisplayOpacity() {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PRBool nsDisplayOpacity::IsOpaque(nsDisplayListBuilder* aBuilder,
|
nsRegion nsDisplayOpacity::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
|
||||||
PRBool* aForceTransparentSurface) {
|
PRBool* aForceTransparentSurface) {
|
||||||
if (aForceTransparentSurface) {
|
if (aForceTransparentSurface) {
|
||||||
*aForceTransparentSurface = PR_FALSE;
|
*aForceTransparentSurface = PR_FALSE;
|
||||||
}
|
}
|
||||||
// We are never opaque, if our opacity was < 1 then we wouldn't have
|
// We are never opaque, if our opacity was < 1 then we wouldn't have
|
||||||
// been created.
|
// been created.
|
||||||
return PR_FALSE;
|
return nsRegion();
|
||||||
}
|
}
|
||||||
|
|
||||||
// nsDisplayOpacity uses layers for rendering
|
// nsDisplayOpacity uses layers for rendering
|
||||||
|
@ -1601,13 +1597,14 @@ nsDisplayClipRoundedRect::~nsDisplayClipRoundedRect()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PRBool nsDisplayClipRoundedRect::IsOpaque(nsDisplayListBuilder* aBuilder,
|
nsRegion
|
||||||
|
nsDisplayClipRoundedRect::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
|
||||||
PRBool* aForceTransparentSurface)
|
PRBool* aForceTransparentSurface)
|
||||||
{
|
{
|
||||||
if (aForceTransparentSurface) {
|
if (aForceTransparentSurface) {
|
||||||
*aForceTransparentSurface = PR_FALSE;
|
*aForceTransparentSurface = PR_FALSE;
|
||||||
}
|
}
|
||||||
return PR_FALSE;
|
return nsRegion();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -2021,8 +2018,8 @@ nsRect nsDisplayTransform::GetBounds(nsDisplayListBuilder *aBuilder)
|
||||||
* mStoredList.GetVisibleRect().Contains(untransformedVisible), then it
|
* mStoredList.GetVisibleRect().Contains(untransformedVisible), then it
|
||||||
* certainly contains the actual (non-axis-aligned) untransformed rect.
|
* certainly contains the actual (non-axis-aligned) untransformed rect.
|
||||||
*/
|
*/
|
||||||
PRBool nsDisplayTransform::IsOpaque(nsDisplayListBuilder *aBuilder,
|
nsRegion nsDisplayTransform::GetOpaqueRegion(nsDisplayListBuilder *aBuilder,
|
||||||
PRBool* aForceTransparentSurface)
|
PRBool* aForceTransparentSurface)
|
||||||
{
|
{
|
||||||
if (aForceTransparentSurface) {
|
if (aForceTransparentSurface) {
|
||||||
*aForceTransparentSurface = PR_FALSE;
|
*aForceTransparentSurface = PR_FALSE;
|
||||||
|
@ -2030,14 +2027,17 @@ PRBool nsDisplayTransform::IsOpaque(nsDisplayListBuilder *aBuilder,
|
||||||
const nsStyleDisplay* disp = mFrame->GetStyleDisplay();
|
const nsStyleDisplay* disp = mFrame->GetStyleDisplay();
|
||||||
nsRect untransformedVisible =
|
nsRect untransformedVisible =
|
||||||
UntransformRect(mVisibleRect, mFrame, ToReferenceFrame());
|
UntransformRect(mVisibleRect, mFrame, ToReferenceFrame());
|
||||||
return disp->mTransform.GetMainMatrixEntry(1) == 0.0f &&
|
nsRegion result;
|
||||||
disp->mTransform.GetMainMatrixEntry(2) == 0.0f &&
|
if (disp->mTransform.GetMainMatrixEntry(1) == 0.0f &&
|
||||||
mStoredList.GetVisibleRect().Contains(untransformedVisible) &&
|
disp->mTransform.GetMainMatrixEntry(2) == 0.0f &&
|
||||||
mStoredList.IsOpaque(aBuilder);
|
mStoredList.GetOpaqueRegion(aBuilder).Contains(untransformedVisible)) {
|
||||||
|
result = mVisibleRect;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The transform is uniform if it fills the entire bounding rect and the
|
/* The transform is uniform if it fills the entire bounding rect and the
|
||||||
* wrapped list is uniform. See IsOpaque for discussion of why this
|
* wrapped list is uniform. See GetOpaqueRegion for discussion of why this
|
||||||
* works.
|
* works.
|
||||||
*/
|
*/
|
||||||
PRBool nsDisplayTransform::IsUniform(nsDisplayListBuilder *aBuilder, nscolor* aColor)
|
PRBool nsDisplayTransform::IsUniform(nsDisplayListBuilder *aBuilder, nscolor* aColor)
|
||||||
|
@ -2161,13 +2161,13 @@ nsDisplaySVGEffects::~nsDisplaySVGEffects()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PRBool nsDisplaySVGEffects::IsOpaque(nsDisplayListBuilder* aBuilder,
|
nsRegion nsDisplaySVGEffects::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
|
||||||
PRBool* aForceTransparentSurface)
|
PRBool* aForceTransparentSurface)
|
||||||
{
|
{
|
||||||
if (aForceTransparentSurface) {
|
if (aForceTransparentSurface) {
|
||||||
*aForceTransparentSurface = PR_FALSE;
|
*aForceTransparentSurface = PR_FALSE;
|
||||||
}
|
}
|
||||||
return PR_FALSE;
|
return nsRegion();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -559,16 +559,16 @@ public:
|
||||||
return nsRect(ToReferenceFrame(), GetUnderlyingFrame()->GetSize());
|
return nsRect(ToReferenceFrame(), GetUnderlyingFrame()->GetSize());
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @return PR_TRUE if the item is definitely opaque --- i.e., paints
|
* @return a region of the item that is opaque --- every pixel painted
|
||||||
* every pixel within its bounds opaquely
|
* with an opaque color.
|
||||||
*/
|
*/
|
||||||
virtual PRBool IsOpaque(nsDisplayListBuilder* aBuilder,
|
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
|
||||||
PRBool* aForceTransparentSurface = nsnull)
|
PRBool* aForceTransparentSurface = nsnull)
|
||||||
{
|
{
|
||||||
if (aForceTransparentSurface) {
|
if (aForceTransparentSurface) {
|
||||||
*aForceTransparentSurface = PR_FALSE;
|
*aForceTransparentSurface = PR_FALSE;
|
||||||
}
|
}
|
||||||
return PR_FALSE;
|
return nsRegion();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* If this returns true, then aColor is set to the uniform color
|
* If this returns true, then aColor is set to the uniform color
|
||||||
|
@ -641,11 +641,10 @@ public:
|
||||||
* On entry, aVisibleRegion contains the region (relative to ReferenceFrame())
|
* On entry, aVisibleRegion contains the region (relative to ReferenceFrame())
|
||||||
* which may be visible. If the display item opaquely covers an area, it
|
* which may be visible. If the display item opaquely covers an area, it
|
||||||
* can remove that area from aVisibleRegion before returning.
|
* can remove that area from aVisibleRegion before returning.
|
||||||
* nsDisplayList::ComputeVisibility automatically subtracts the bounds
|
* nsDisplayList::ComputeVisibility automatically subtracts the region
|
||||||
* of items that return true from IsOpaque(), and automatically
|
* returned by GetOpaqueRegion, and automatically removes items whose bounds
|
||||||
* removes items whose bounds do not intersect the visible area,
|
* do not intersect the visible area, so implementations of
|
||||||
* so implementations of nsDisplayItem::ComputeVisibility do not
|
* nsDisplayItem::ComputeVisibility do not need to do these things.
|
||||||
* need to do these things.
|
|
||||||
* nsDisplayList::ComputeVisibility will already have set mVisibleRect on
|
* nsDisplayList::ComputeVisibility will already have set mVisibleRect on
|
||||||
* this item to the intersection of *aVisibleRegion and this item's bounds.
|
* this item to the intersection of *aVisibleRegion and this item's bounds.
|
||||||
* We rely on that, so this should only be called by
|
* We rely on that, so this should only be called by
|
||||||
|
@ -1360,12 +1359,16 @@ public:
|
||||||
|
|
||||||
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) { return mBounds; }
|
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) { return mBounds; }
|
||||||
|
|
||||||
virtual PRBool IsOpaque(nsDisplayListBuilder* aBuilder,
|
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
|
||||||
PRBool* aOutTransparentBackground = nsnull) {
|
PRBool* aOutTransparentBackground = nsnull) {
|
||||||
if (aOutTransparentBackground) {
|
if (aOutTransparentBackground) {
|
||||||
*aOutTransparentBackground = PR_FALSE;
|
*aOutTransparentBackground = PR_FALSE;
|
||||||
}
|
}
|
||||||
return (NS_GET_A(mColor) == 255);
|
nsRegion result;
|
||||||
|
if (NS_GET_A(mColor) == 255) {
|
||||||
|
result = GetBounds(aBuilder);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual PRBool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor)
|
virtual PRBool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor)
|
||||||
|
@ -1400,8 +1403,8 @@ public:
|
||||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
|
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
|
||||||
virtual PRBool ComputeVisibility(nsDisplayListBuilder* aBuilder,
|
virtual PRBool ComputeVisibility(nsDisplayListBuilder* aBuilder,
|
||||||
nsRegion* aVisibleRegion);
|
nsRegion* aVisibleRegion);
|
||||||
virtual PRBool IsOpaque(nsDisplayListBuilder* aBuilder,
|
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
|
||||||
PRBool* aForceTransparentSurface = nsnull);
|
PRBool* aForceTransparentSurface = nsnull);
|
||||||
virtual PRBool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
|
virtual PRBool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
|
||||||
nsIFrame* aFrame);
|
nsIFrame* aFrame);
|
||||||
virtual PRBool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor);
|
virtual PRBool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor);
|
||||||
|
@ -1536,8 +1539,8 @@ public:
|
||||||
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
|
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
|
||||||
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
|
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
|
||||||
virtual PRBool IsOpaque(nsDisplayListBuilder* aBuilder,
|
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
|
||||||
PRBool* aForceTransparentSurface = nsnull);
|
PRBool* aForceTransparentSurface = nsnull);
|
||||||
virtual PRBool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor);
|
virtual PRBool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor);
|
||||||
virtual PRBool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
|
virtual PRBool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
|
||||||
nsIFrame* aFrame);
|
nsIFrame* aFrame);
|
||||||
|
@ -1620,8 +1623,8 @@ public:
|
||||||
virtual ~nsDisplayOpacity();
|
virtual ~nsDisplayOpacity();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
virtual PRBool IsOpaque(nsDisplayListBuilder* aBuilder,
|
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
|
||||||
PRBool* aForceTransparentSurface = nsnull);
|
PRBool* aForceTransparentSurface = nsnull);
|
||||||
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
|
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||||
LayerManager* aManager);
|
LayerManager* aManager);
|
||||||
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
|
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||||
|
@ -1718,8 +1721,8 @@ public:
|
||||||
virtual ~nsDisplayClipRoundedRect();
|
virtual ~nsDisplayClipRoundedRect();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
virtual PRBool IsOpaque(nsDisplayListBuilder* aBuilder,
|
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
|
||||||
PRBool* aForceTransparentSurface = nsnull);
|
PRBool* aForceTransparentSurface = nsnull);
|
||||||
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
|
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
|
||||||
virtual PRBool ComputeVisibility(nsDisplayListBuilder* aBuilder,
|
virtual PRBool ComputeVisibility(nsDisplayListBuilder* aBuilder,
|
||||||
|
@ -1788,8 +1791,8 @@ public:
|
||||||
virtual ~nsDisplaySVGEffects();
|
virtual ~nsDisplaySVGEffects();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
virtual PRBool IsOpaque(nsDisplayListBuilder* aBuilder,
|
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
|
||||||
PRBool* aForceTransparentSurface = nsnull);
|
PRBool* aForceTransparentSurface = nsnull);
|
||||||
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
|
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
|
||||||
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) {
|
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) {
|
||||||
|
@ -1847,8 +1850,8 @@ public:
|
||||||
virtual void HitTest(nsDisplayListBuilder *aBuilder, const nsRect& aRect,
|
virtual void HitTest(nsDisplayListBuilder *aBuilder, const nsRect& aRect,
|
||||||
HitTestState *aState, nsTArray<nsIFrame*> *aOutFrames);
|
HitTestState *aState, nsTArray<nsIFrame*> *aOutFrames);
|
||||||
virtual nsRect GetBounds(nsDisplayListBuilder *aBuilder);
|
virtual nsRect GetBounds(nsDisplayListBuilder *aBuilder);
|
||||||
virtual PRBool IsOpaque(nsDisplayListBuilder *aBuilder,
|
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder *aBuilder,
|
||||||
PRBool* aForceTransparentSurface = nsnull);
|
PRBool* aForceTransparentSurface = nsnull);
|
||||||
virtual PRBool IsUniform(nsDisplayListBuilder *aBuilder, nscolor* aColor);
|
virtual PRBool IsUniform(nsDisplayListBuilder *aBuilder, nscolor* aColor);
|
||||||
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
|
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||||
LayerManager* aManager);
|
LayerManager* aManager);
|
||||||
|
|
|
@ -178,11 +178,15 @@ PrintDisplayListTo(nsDisplayListBuilder* aBuilder, const nsDisplayList& aList,
|
||||||
nscolor color;
|
nscolor color;
|
||||||
nsRect vis = i->GetVisibleRect();
|
nsRect vis = i->GetVisibleRect();
|
||||||
nsDisplayList* list = i->GetList();
|
nsDisplayList* list = i->GetList();
|
||||||
|
nsRegion opaque;
|
||||||
|
if (!list || list->DidComputeVisibility()) {
|
||||||
|
opaque = i->GetOpaqueRegion(aBuilder);
|
||||||
|
}
|
||||||
fprintf(aOutput, "%s %p(%s) (%d,%d,%d,%d)(%d,%d,%d,%d)%s%s\n",
|
fprintf(aOutput, "%s %p(%s) (%d,%d,%d,%d)(%d,%d,%d,%d)%s%s\n",
|
||||||
i->Name(), (void*)f, NS_ConvertUTF16toUTF8(fName).get(),
|
i->Name(), (void*)f, NS_ConvertUTF16toUTF8(fName).get(),
|
||||||
rect.x, rect.y, rect.width, rect.height,
|
rect.x, rect.y, rect.width, rect.height,
|
||||||
vis.x, vis.y, vis.width, vis.height,
|
vis.x, vis.y, vis.width, vis.height,
|
||||||
((!list || list->DidComputeVisibility()) && i->IsOpaque(aBuilder)) ? " opaque" : "",
|
opaque.IsEmpty() ? "" : " opaque",
|
||||||
i->IsUniform(aBuilder, &color) ? " uniform" : "");
|
i->IsUniform(aBuilder, &color) ? " uniform" : "");
|
||||||
if (list) {
|
if (list) {
|
||||||
PrintDisplayListTo(aBuilder, *list, aIndent + 4, aOutput);
|
PrintDisplayListTo(aBuilder, *list, aIndent + 4, aOutput);
|
||||||
|
|
|
@ -923,6 +923,35 @@ nsLayoutUtils::RoundGfxRectToAppRect(const gfxRect &aRect, float aFactor)
|
||||||
nscoord(scaledRect.size.width), nscoord(scaledRect.size.height));
|
nscoord(scaledRect.size.width), nscoord(scaledRect.size.height));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
nsRegion
|
||||||
|
nsLayoutUtils::RoundedRectIntersectRect(const nsRect& aRoundedRect,
|
||||||
|
const nscoord aRadii[8],
|
||||||
|
const nsRect& aContainedRect)
|
||||||
|
{
|
||||||
|
// rectFullHeight and rectFullWidth together will approximately contain
|
||||||
|
// the total area of the frame minus the rounded corners.
|
||||||
|
nsRect rectFullHeight = aRoundedRect;
|
||||||
|
nscoord xDiff = NS_MAX(aRadii[NS_CORNER_TOP_LEFT_X], aRadii[NS_CORNER_BOTTOM_LEFT_X]);
|
||||||
|
rectFullHeight.x += xDiff;
|
||||||
|
rectFullHeight.width -= NS_MAX(aRadii[NS_CORNER_TOP_RIGHT_X],
|
||||||
|
aRadii[NS_CORNER_BOTTOM_RIGHT_X]) + xDiff;
|
||||||
|
nsRect r1;
|
||||||
|
r1.IntersectRect(rectFullHeight, aContainedRect);
|
||||||
|
|
||||||
|
nsRect rectFullWidth = aRoundedRect;
|
||||||
|
nscoord yDiff = NS_MAX(aRadii[NS_CORNER_TOP_LEFT_Y], aRadii[NS_CORNER_TOP_RIGHT_Y]);
|
||||||
|
rectFullWidth.y += yDiff;
|
||||||
|
rectFullWidth.height -= NS_MAX(aRadii[NS_CORNER_BOTTOM_LEFT_Y],
|
||||||
|
aRadii[NS_CORNER_BOTTOM_RIGHT_Y]) + yDiff;
|
||||||
|
nsRect r2;
|
||||||
|
r2.IntersectRect(rectFullWidth, aContainedRect);
|
||||||
|
|
||||||
|
nsRegion result;
|
||||||
|
result.Or(r1, r2);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
nsRect
|
nsRect
|
||||||
nsLayoutUtils::MatrixTransformRect(const nsRect &aBounds,
|
nsLayoutUtils::MatrixTransformRect(const nsRect &aBounds,
|
||||||
const gfxMatrix &aMatrix, float aFactor)
|
const gfxMatrix &aMatrix, float aFactor)
|
||||||
|
|
|
@ -512,6 +512,15 @@ public:
|
||||||
*/
|
*/
|
||||||
static nsRect RoundGfxRectToAppRect(const gfxRect &aRect, float aFactor);
|
static nsRect RoundGfxRectToAppRect(const gfxRect &aRect, float aFactor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a subrectangle of aContainedRect that is entirely inside the rounded
|
||||||
|
* rect. Complex cases are handled conservatively by returning a smaller
|
||||||
|
* rect than necessary.
|
||||||
|
*/
|
||||||
|
static nsRegion RoundedRectIntersectRect(const nsRect& aRoundedRect,
|
||||||
|
const nscoord aRadii[8],
|
||||||
|
const nsRect& aContainedRect);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PAINT_IN_TRANSFORM = 0x01,
|
PAINT_IN_TRANSFORM = 0x01,
|
||||||
PAINT_SYNC_DECODE_IMAGES = 0x02,
|
PAINT_SYNC_DECODE_IMAGES = 0x02,
|
||||||
|
|
|
@ -177,14 +177,15 @@ public:
|
||||||
return NS_GET_A(mExtraBackgroundColor) > 0 ||
|
return NS_GET_A(mExtraBackgroundColor) > 0 ||
|
||||||
nsDisplayBackground::ComputeVisibility(aBuilder, aVisibleRegion);
|
nsDisplayBackground::ComputeVisibility(aBuilder, aVisibleRegion);
|
||||||
}
|
}
|
||||||
virtual PRBool IsOpaque(nsDisplayListBuilder* aBuilder,
|
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
|
||||||
PRBool* aForceTransparentSurface = nsnull)
|
PRBool* aForceTransparentSurface = nsnull)
|
||||||
{
|
{
|
||||||
if (aForceTransparentSurface) {
|
if (aForceTransparentSurface) {
|
||||||
*aForceTransparentSurface = PR_FALSE;
|
*aForceTransparentSurface = PR_FALSE;
|
||||||
}
|
}
|
||||||
return NS_GET_A(mExtraBackgroundColor) == 255 ||
|
if (NS_GET_A(mExtraBackgroundColor) == 255)
|
||||||
nsDisplayBackground::IsOpaque(aBuilder);
|
return nsRegion(GetBounds(aBuilder));
|
||||||
|
return nsDisplayBackground::GetOpaqueRegion(aBuilder);
|
||||||
}
|
}
|
||||||
virtual PRBool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor)
|
virtual PRBool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor)
|
||||||
{
|
{
|
||||||
|
|
|
@ -77,14 +77,18 @@ public:
|
||||||
|
|
||||||
NS_DISPLAY_DECL_NAME("nsDisplayCanvas", TYPE_CANVAS)
|
NS_DISPLAY_DECL_NAME("nsDisplayCanvas", TYPE_CANVAS)
|
||||||
|
|
||||||
virtual PRBool IsOpaque(nsDisplayListBuilder* aBuilder,
|
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
|
||||||
PRBool* aForceTransparentSurface = nsnull) {
|
PRBool* aForceTransparentSurface = nsnull) {
|
||||||
if (aForceTransparentSurface) {
|
if (aForceTransparentSurface) {
|
||||||
*aForceTransparentSurface = PR_FALSE;
|
*aForceTransparentSurface = PR_FALSE;
|
||||||
}
|
}
|
||||||
nsIFrame* f = GetUnderlyingFrame();
|
nsIFrame* f = GetUnderlyingFrame();
|
||||||
nsHTMLCanvasElement *canvas = CanvasElementFromContent(f->GetContent());
|
nsHTMLCanvasElement *canvas = CanvasElementFromContent(f->GetContent());
|
||||||
return canvas->GetIsOpaque();
|
nsRegion result;
|
||||||
|
if (canvas->GetIsOpaque()) {
|
||||||
|
result = GetBounds(aBuilder);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) {
|
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) {
|
||||||
|
|
|
@ -1290,13 +1290,14 @@ nsDisplayPlugin::ComputeVisibility(nsDisplayListBuilder* aBuilder,
|
||||||
return nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion);
|
return nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool
|
nsRegion
|
||||||
nsDisplayPlugin::IsOpaque(nsDisplayListBuilder* aBuilder,
|
nsDisplayPlugin::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
|
||||||
PRBool* aForceTransparentSurface)
|
PRBool* aForceTransparentSurface)
|
||||||
{
|
{
|
||||||
if (aForceTransparentSurface) {
|
if (aForceTransparentSurface) {
|
||||||
*aForceTransparentSurface = PR_FALSE;
|
*aForceTransparentSurface = PR_FALSE;
|
||||||
}
|
}
|
||||||
|
nsRegion result;
|
||||||
nsObjectFrame* f = static_cast<nsObjectFrame*>(mFrame);
|
nsObjectFrame* f = static_cast<nsObjectFrame*>(mFrame);
|
||||||
if (!aBuilder->IsForPluginGeometry()) {
|
if (!aBuilder->IsForPluginGeometry()) {
|
||||||
nsIWidget* widget = f->GetWidget();
|
nsIWidget* widget = f->GetWidget();
|
||||||
|
@ -1310,11 +1311,14 @@ nsDisplayPlugin::IsOpaque(nsDisplayListBuilder* aBuilder,
|
||||||
// Something has clipped us unexpectedly. Perhaps there is a translucent
|
// Something has clipped us unexpectedly. Perhaps there is a translucent
|
||||||
// chrome element overlaying us that forced us to be clipped away. Treat
|
// chrome element overlaying us that forced us to be clipped away. Treat
|
||||||
// us as non-opaque since we may have holes.
|
// us as non-opaque since we may have holes.
|
||||||
return PR_FALSE;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return f->IsOpaque();
|
if (f->IsOpaque()) {
|
||||||
|
result = GetBounds(aBuilder);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -316,8 +316,8 @@ public:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
|
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
|
||||||
virtual PRBool IsOpaque(nsDisplayListBuilder* aBuilder,
|
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
|
||||||
PRBool* aForceTransparentSurface = nsnull);
|
PRBool* aForceTransparentSurface = nsnull);
|
||||||
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
||||||
nsIRenderingContext* aCtx);
|
nsIRenderingContext* aCtx);
|
||||||
virtual PRBool ComputeVisibility(nsDisplayListBuilder* aBuilder,
|
virtual PRBool ComputeVisibility(nsDisplayListBuilder* aBuilder,
|
||||||
|
|
|
@ -375,10 +375,10 @@ public:
|
||||||
|
|
||||||
NS_DISPLAY_DECL_NAME("Video", TYPE_VIDEO)
|
NS_DISPLAY_DECL_NAME("Video", TYPE_VIDEO)
|
||||||
|
|
||||||
// It would be great if we could override IsOpaque to return false here,
|
// It would be great if we could override GetOpaqueRegion to return nonempty here,
|
||||||
// but it's probably not safe to do so in general. Video frames are
|
// but it's probably not safe to do so in general. Video frames are
|
||||||
// updated asynchronously from decoder threads, and it's possible that
|
// updated asynchronously from decoder threads, and it's possible that
|
||||||
// we might have an opaque video frame when IsOpaque is called, but
|
// we might have an opaque video frame when GetOpaqueRegion is called, but
|
||||||
// when we come to paint, the video frame is transparent or has gone
|
// when we come to paint, the video frame is transparent or has gone
|
||||||
// away completely (e.g. because of a decoder error). The problem would
|
// away completely (e.g. because of a decoder error). The problem would
|
||||||
// be especially acute if we have off-main-thread rendering.
|
// be especially acute if we have off-main-thread rendering.
|
||||||
|
|
|
@ -280,7 +280,7 @@ struct nsStyleImage {
|
||||||
// rect is non-trivial since each side value can be specified with
|
// rect is non-trivial since each side value can be specified with
|
||||||
// percentage unit, which can not be evaluated until the source image size
|
// percentage unit, which can not be evaluated until the source image size
|
||||||
// is available. Therefore, we currently postpone the evaluation of crop
|
// is available. Therefore, we currently postpone the evaluation of crop
|
||||||
// rect until the actual rendering time --- alternatively until IsOpaque()
|
// rect until the actual rendering time --- alternatively until GetOpaqueRegion()
|
||||||
// is called.
|
// is called.
|
||||||
return mType == eStyleImageType_Null;
|
return mType == eStyleImageType_Null;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче