Bug 1018464 - Add nsDisplayItem::IsInvisibleInRect API to expose holes in display items. r=roc

--HG--
extra : rebase_source : 9f362283113c0ce925ca81c3613ac8c6d19dfebe
This commit is contained in:
Markus Stange 2014-06-03 14:48:16 +02:00
Родитель c26d84b83e
Коммит 81714ca17f
2 изменённых файлов: 53 добавлений и 48 удалений

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

@ -1709,6 +1709,15 @@ nsDisplayItem::ZIndex() const
return 0;
}
bool
nsDisplayItem::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion)
{
return !mVisibleRect.IsEmpty() &&
!IsInvisibleInRect(aVisibleRegion->GetBounds());
}
bool
nsDisplayItem::RecomputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) {
@ -2646,26 +2655,20 @@ nsDisplayOutline::Paint(nsDisplayListBuilder* aBuilder,
}
bool
nsDisplayOutline::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion) {
if (!nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion,
aAllowVisibleRegionExpansion)) {
return false;
}
nsDisplayOutline::IsInvisibleInRect(const nsRect& aRect)
{
const nsStyleOutline* outline = mFrame->StyleOutline();
nsRect borderBox(ToReferenceFrame(), mFrame->GetSize());
if (borderBox.Contains(aVisibleRegion->GetBounds()) &&
if (borderBox.Contains(aRect) &&
!nsLayoutUtils::HasNonZeroCorner(outline->mOutlineRadius)) {
if (outline->mOutlineOffset >= 0) {
// the visible region is entirely inside the border-rect, and the outline
// isn't rendered inside the border-rect, so the outline is not visible
return false;
// aRect is entirely inside the border-rect, and the outline isn't
// rendered inside the border-rect, so the outline is not visible.
return true;
}
}
return true;
return false;
}
void
@ -2725,30 +2728,24 @@ nsDisplayCaret::Paint(nsDisplayListBuilder* aBuilder,
}
bool
nsDisplayBorder::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion) {
if (!nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion,
aAllowVisibleRegionExpansion)) {
return false;
}
nsDisplayBorder::IsInvisibleInRect(const nsRect& aRect)
{
nsRect paddingRect = mFrame->GetPaddingRect() - mFrame->GetPosition() +
ToReferenceFrame();
const nsStyleBorder *styleBorder;
if (paddingRect.Contains(aVisibleRegion->GetBounds()) &&
if (paddingRect.Contains(aRect) &&
!(styleBorder = mFrame->StyleBorder())->IsBorderImageLoaded() &&
!nsLayoutUtils::HasNonZeroCorner(styleBorder->mBorderRadius)) {
// the visible region is entirely inside the content rect, and no part
// aRect is entirely inside the content rect, and no part
// of the border is rendered inside the content rect, so we are not
// visible
// Skip this if there's a border-image (which draws a background
// too) or if there is a border-radius (which makes the border draw
// further in).
return false;
return true;
}
return true;
return false;
}
nsDisplayItemGeometry*
@ -2879,6 +2876,24 @@ nsDisplayBoxShadowOuter::GetBoundsInternal() {
ToReferenceFrame();
}
bool
nsDisplayBoxShadowOuter::IsInvisibleInRect(const nsRect& aRect)
{
nsPoint origin = ToReferenceFrame();
nsRect frameRect(origin, mFrame->GetSize());
if (!frameRect.Contains(aRect))
return false;
// the visible region is entirely inside the border-rect, and box shadows
// never render within the border-rect (unless there's a border radius).
nscoord twipsRadii[8];
bool hasBorderRadii = mFrame->GetBorderRadii(twipsRadii);
if (!hasBorderRadii)
return true;
return RoundedRectContainsRect(frameRect, twipsRadii, aRect);
}
bool
nsDisplayBoxShadowOuter::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
@ -2890,21 +2905,7 @@ nsDisplayBoxShadowOuter::ComputeVisibility(nsDisplayListBuilder* aBuilder,
// Store the actual visible region
mVisibleRegion.And(*aVisibleRegion, mVisibleRect);
nsPoint origin = ToReferenceFrame();
nsRect visibleBounds = aVisibleRegion->GetBounds();
nsRect frameRect(origin, mFrame->GetSize());
if (!frameRect.Contains(visibleBounds))
return true;
// the visible region is entirely inside the border-rect, and box shadows
// never render within the border-rect (unless there's a border radius).
nscoord twipsRadii[8];
bool hasBorderRadii = mFrame->GetBorderRadii(twipsRadii);
if (!hasBorderRadii)
return false;
return !RoundedRectContainsRect(frameRect, twipsRadii, visibleBounds);
return true;
}
void

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

@ -933,6 +933,14 @@ public:
*aSnap = false;
return nsRect(ToReferenceFrame(), Frame()->GetSize());
}
/**
* Returns true if nothing will be rendered inside aRect, false if uncertain.
* aRect is assumed to be contained in this item's bounds.
*/
virtual bool IsInvisibleInRect(const nsRect& aRect)
{
return false;
}
/**
* Returns the result of GetBounds intersected with the item's clip.
* The intersection is approximate since rounded corners are not taking into
@ -1191,8 +1199,7 @@ public:
*/
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion)
{ return !mVisibleRect.IsEmpty(); }
const nsRect& aAllowVisibleRegionExpansion);
/**
* Try to merge with the other item (which is below us in the display
@ -2022,11 +2029,9 @@ public:
}
#endif
virtual bool IsInvisibleInRect(const nsRect& aRect) MOZ_OVERRIDE;
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
NS_DISPLAY_DECL_NAME("Border", TYPE_BORDER)
virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
@ -2344,6 +2349,7 @@ public:
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
virtual bool IsInvisibleInRect(const nsRect& aRect) MOZ_OVERRIDE;
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
@ -2430,11 +2436,9 @@ public:
}
#endif
virtual bool IsInvisibleInRect(const nsRect& aRect) MOZ_OVERRIDE;
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
NS_DISPLAY_DECL_NAME("Outline", TYPE_OUTLINE)
};