Bug 1344971 - Part 4: Don't compute a region for nsDisplayBorder when we only want a rect. r?mstange
MozReview-Commit-ID: Gf44gXXvv1w
--- a/gfx/2d/BaseRect.h
+++ b/gfx/2d/BaseRect.h
@@ -166,16 +166,21 @@ struct BaseRect {
// If both rectangles are empty, sets 'this' to aRect2.
//
// 'this' can be the same object as either aRect1 or aRect2
void UnionRect(const Sub& aRect1, const Sub& aRect2)
{
*static_cast<Sub*>(this) = aRect1.Union(aRect2);
}
+ void OrWith(const Sub& aRect1)
+ {
+ UnionRect(*static_cast<Sub*>(this), aRect1);
+ }
+
// Computes the smallest rectangle that contains both the points (including
// edges) of both aRect1 and aRect2.
// Thus, empty input rectangles are allowed to affect the result.
//
// 'this' can be the same object as either aRect1 or aRect2
void UnionRectEdges(const Sub& aRect1, const Sub& aRect2)
{
*static_cast<Sub*>(this) = aRect1.UnionEdges(aRect2);
--- a/layout/mathml/nsMathMLmtableFrame.cpp
+++ b/layout/mathml/nsMathMLmtableFrame.cpp
@@ -296,17 +296,17 @@ public:
}
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override
{
*aSnap = true;
nsStyleBorder styleBorder = *mFrame->StyleBorder();
nsMathMLmtdFrame* frame = static_cast<nsMathMLmtdFrame*>(mFrame);
ApplyBorderToStyle(frame, styleBorder);
- nsRect bounds = CalculateBounds(styleBorder).GetBounds();
+ nsRect bounds = CalculateBounds<nsRect>(styleBorder);
nsMargin overflow = ComputeBorderOverflow(frame, styleBorder);
bounds.Inflate(overflow);
return bounds;
}
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) override
{
nsStyleBorder styleBorder = *mFrame->StyleBorder();
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -4493,17 +4493,17 @@ nsDisplayCaret::BuildLayer(nsDisplayList
return BuildDisplayItemLayer(aBuilder, aManager, aContainerParameters);
}
nsDisplayBorder::nsDisplayBorder(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
: nsDisplayItem(aBuilder, aFrame)
{
MOZ_COUNT_CTOR(nsDisplayBorder);
- mBounds = CalculateBounds(*mFrame->StyleBorder()).GetBounds();
+ mBounds = CalculateBounds<nsRect>(*mFrame->StyleBorder());
}
bool
nsDisplayBorder::IsInvisibleInRect(const nsRect& aRect)
{
nsRect paddingRect = mFrame->GetPaddingRect() - mFrame->GetPosition() +
ToReferenceFrame();
const nsStyleBorder *styleBorder;
@@ -4673,63 +4673,16 @@ nsDisplayBorder::Paint(nsDisplayListBuil
nsRect
nsDisplayBorder::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
{
*aSnap = true;
return mBounds;
}
-nsRegion
-nsDisplayBorder::CalculateBounds(const nsStyleBorder& aStyleBorder)
-{
- nsRect borderBounds(ToReferenceFrame(), mFrame->GetSize());
- if (aStyleBorder.IsBorderImageLoaded()) {
- borderBounds.Inflate(aStyleBorder.GetImageOutset());
- return borderBounds;
- } else {
- nsMargin border = aStyleBorder.GetComputedBorder();
- nsRegion result;
- if (border.top > 0) {
- result = nsRect(borderBounds.X(), borderBounds.Y(), borderBounds.Width(), border.top);
- }
- if (border.right > 0) {
- result.OrWith(nsRect(borderBounds.XMost() - border.right, borderBounds.Y(), border.right, borderBounds.Height()));
- }
- if (border.bottom > 0) {
- result.OrWith(nsRect(borderBounds.X(), borderBounds.YMost() - border.bottom, borderBounds.Width(), border.bottom));
- }
- if (border.left > 0) {
- result.OrWith(nsRect(borderBounds.X(), borderBounds.Y(), border.left, borderBounds.Height()));
- }
-
- nscoord radii[8];
- if (mFrame->GetBorderRadii(radii)) {
- if (border.left > 0 || border.top > 0) {
- nsSize cornerSize(radii[eCornerTopLeftX], radii[eCornerTopLeftY]);
- result.OrWith(nsRect(borderBounds.TopLeft(), cornerSize));
- }
- if (border.top > 0 || border.right > 0) {
- nsSize cornerSize(radii[eCornerTopRightX], radii[eCornerTopRightY]);
- result.OrWith(nsRect(borderBounds.TopRight() - nsPoint(cornerSize.width, 0), cornerSize));
- }
- if (border.right > 0 || border.bottom > 0) {
- nsSize cornerSize(radii[eCornerBottomRightX], radii[eCornerBottomRightY]);
- result.OrWith(nsRect(borderBounds.BottomRight() - nsPoint(cornerSize.width, cornerSize.height), cornerSize));
- }
- if (border.bottom > 0 || border.left > 0) {
- nsSize cornerSize(radii[eCornerBottomLeftX], radii[eCornerBottomLeftY]);
- result.OrWith(nsRect(borderBounds.BottomLeft() - nsPoint(0, cornerSize.height), cornerSize));
- }
- }
-
- return result;
- }
-}
-
// Given a region, compute a conservative approximation to it as a list
// of rectangles that aren't vertically adjacent (i.e., vertically
// adjacent or overlapping rectangles are combined).
// Right now this is only approximate, some vertically overlapping rectangles
// aren't guaranteed to be combined.
static void
ComputeDisjointRectangles(const nsRegion& aRegion,
nsTArray<nsRect>* aRects) {
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -2893,21 +2893,65 @@ public:
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion* aInvalidRegion) override;
virtual nsRegion GetTightBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override
{
*aSnap = true;
- return CalculateBounds(*mFrame->StyleBorder());
+ return CalculateBounds<nsRegion>(*mFrame->StyleBorder());
}
protected:
- nsRegion CalculateBounds(const nsStyleBorder& aStyleBorder);
+ template<typename T>
+ T CalculateBounds(const nsStyleBorder& aStyleBorder)
+ {
+ nsRect borderBounds(ToReferenceFrame(), mFrame->GetSize());
+ if (aStyleBorder.IsBorderImageLoaded()) {
+ borderBounds.Inflate(aStyleBorder.GetImageOutset());
+ return borderBounds;
+ } else {
+ nsMargin border = aStyleBorder.GetComputedBorder();
+ T result;
+ if (border.top > 0) {
+ result = nsRect(borderBounds.X(), borderBounds.Y(), borderBounds.Width(), border.top);
+ }
+ if (border.right > 0) {
+ result.OrWith(nsRect(borderBounds.XMost() - border.right, borderBounds.Y(), border.right, borderBounds.Height()));
+ }
+ if (border.bottom > 0) {
+ result.OrWith(nsRect(borderBounds.X(), borderBounds.YMost() - border.bottom, borderBounds.Width(), border.bottom));
+ }
+ if (border.left > 0) {
+ result.OrWith(nsRect(borderBounds.X(), borderBounds.Y(), border.left, borderBounds.Height()));
+ }
+
+ nscoord radii[8];
+ if (mFrame->GetBorderRadii(radii)) {
+ if (border.left > 0 || border.top > 0) {
+ nsSize cornerSize(radii[mozilla::eCornerTopLeftX], radii[mozilla::eCornerTopLeftY]);
+ result.OrWith(nsRect(borderBounds.TopLeft(), cornerSize));
+ }
+ if (border.top > 0 || border.right > 0) {
+ nsSize cornerSize(radii[mozilla::eCornerTopRightX], radii[mozilla::eCornerTopRightY]);
+ result.OrWith(nsRect(borderBounds.TopRight() - nsPoint(cornerSize.width, 0), cornerSize));
+ }
+ if (border.right > 0 || border.bottom > 0) {
+ nsSize cornerSize(radii[mozilla::eCornerBottomRightX], radii[mozilla::eCornerBottomRightY]);
+ result.OrWith(nsRect(borderBounds.BottomRight() - nsPoint(cornerSize.width, cornerSize.height), cornerSize));
+ }
+ if (border.bottom > 0 || border.left > 0) {
+ nsSize cornerSize(radii[mozilla::eCornerBottomLeftX], radii[mozilla::eCornerBottomLeftY]);
+ result.OrWith(nsRect(borderBounds.BottomLeft() - nsPoint(0, cornerSize.height), cornerSize));
+ }
+ }
+ return result;
+ }
+ }
mozilla::Array<mozilla::gfx::Color, 4> mColors;
mozilla::Array<mozilla::LayerCoord, 4> mWidths;
mozilla::Array<mozilla::LayerSize, 4> mCorners;
mozilla::Array<uint8_t, 4> mBorderStyles;
mozilla::LayerRect mRect;
nsRect mBounds;