From ee86633d81831703c013415fd929c7d1336144af Mon Sep 17 00:00:00 2001 From: Jonathan Watt Date: Mon, 20 Oct 2014 10:55:48 +0100 Subject: [PATCH] Bug 1085160 - Port the code that uses nsRenderingContext::IntersectClip() to Moz2D. r=mattwoodrow --HG-- extra : rebase_source : 54226509a1b16efdc76f92f202cc2be07cf43ab4 --- gfx/src/nsRenderingContext.cpp | 17 ------------ gfx/src/nsRenderingContext.h | 1 - gfx/thebes/gfxContext.cpp | 14 +++++++--- gfx/thebes/gfxContext.h | 3 ++- layout/base/nsCSSRendering.cpp | 14 +++++++--- layout/base/nsDisplayList.cpp | 10 ++++--- layout/forms/nsComboboxControlFrame.cpp | 10 ++++--- layout/forms/nsFieldSetFrame.cpp | 28 +++++++++++--------- layout/generic/nsImageFrame.cpp | 9 ++++--- layout/generic/nsPageFrame.cpp | 14 +++++++--- layout/svg/nsSVGIntegrationUtils.cpp | 8 ++++-- layout/svg/nsSVGUtils.cpp | 6 ++++- layout/xul/nsBoxFrame.h | 1 + layout/xul/nsGroupBoxFrame.cpp | 35 ++++++++++++++----------- layout/xul/tree/nsTreeBodyFrame.cpp | 11 +++++--- 15 files changed, 110 insertions(+), 71 deletions(-) diff --git a/gfx/src/nsRenderingContext.cpp b/gfx/src/nsRenderingContext.cpp index b91fdefca2d..9a07749f4fc 100644 --- a/gfx/src/nsRenderingContext.cpp +++ b/gfx/src/nsRenderingContext.cpp @@ -85,23 +85,6 @@ nsRenderingContext::Init(nsDeviceContext* aContext, // graphics state // -void -nsRenderingContext::IntersectClip(const nsRect& aRect) -{ - mThebes->NewPath(); - gfxRect clipRect(GFX_RECT_FROM_TWIPS_RECT(aRect)); - if (mThebes->UserToDevicePixelSnapped(clipRect, true)) { - gfxMatrix mat(mThebes->CurrentMatrix()); - mat.Invert(); - clipRect = mat.Transform(clipRect); - mThebes->Rectangle(clipRect); - } else { - mThebes->Rectangle(clipRect); - } - - mThebes->Clip(); -} - void nsRenderingContext::SetColor(nscolor aColor) { diff --git a/gfx/src/nsRenderingContext.h b/gfx/src/nsRenderingContext.h index 78ada4e3a07..d85eceac1fb 100644 --- a/gfx/src/nsRenderingContext.h +++ b/gfx/src/nsRenderingContext.h @@ -49,7 +49,6 @@ public: // Graphics state - void IntersectClip(const nsRect& aRect); void SetColor(nscolor aColor); // Text diff --git a/gfx/thebes/gfxContext.cpp b/gfx/thebes/gfxContext.cpp index 927cc3556c6..67cc2934fc4 100644 --- a/gfx/thebes/gfxContext.cpp +++ b/gfx/thebes/gfxContext.cpp @@ -721,13 +721,19 @@ gfxContext::CurrentFillRule() const } // clipping +void +gfxContext::Clip(const Rect& rect) +{ + AzureState::PushedClip clip = { nullptr, rect, mTransform }; + CurrentState().pushedClips.AppendElement(clip); + mDT->PushClipRect(rect); + NewPath(); +} + void gfxContext::Clip(const gfxRect& rect) { - AzureState::PushedClip clip = { nullptr, ToRect(rect), mTransform }; - CurrentState().pushedClips.AppendElement(clip); - mDT->PushClipRect(ToRect(rect)); - NewPath(); + Clip(ToRect(rect)); } void diff --git a/gfx/thebes/gfxContext.h b/gfx/thebes/gfxContext.h index a1a9e1ad6bd..5f95d1d3e28 100644 --- a/gfx/thebes/gfxContext.h +++ b/gfx/thebes/gfxContext.h @@ -40,6 +40,7 @@ class gfxContext MOZ_FINAL { typedef mozilla::gfx::FillRule FillRule; typedef mozilla::gfx::Path Path; typedef mozilla::gfx::Pattern Pattern; + typedef mozilla::gfx::Rect Rect; NS_INLINE_DECL_REFCOUNTING(gfxContext) @@ -531,6 +532,7 @@ public: * Helper functions that will create a rect path and call Clip(). * Any current path will be destroyed by these functions! */ + void Clip(const Rect& rect); void Clip(const gfxRect& rect); // will clip to a rect /** @@ -613,7 +615,6 @@ private: typedef mozilla::gfx::Color Color; typedef mozilla::gfx::StrokeOptions StrokeOptions; typedef mozilla::gfx::Float Float; - typedef mozilla::gfx::Rect Rect; typedef mozilla::gfx::CompositionOp CompositionOp; typedef mozilla::gfx::PathBuilder PathBuilder; typedef mozilla::gfx::SourceSurface SourceSurface; diff --git a/layout/base/nsCSSRendering.cpp b/layout/base/nsCSSRendering.cpp index ed0b87039f9..395ac6a5396 100644 --- a/layout/base/nsCSSRendering.cpp +++ b/layout/base/nsCSSRendering.cpp @@ -683,7 +683,10 @@ nsCSSRendering::PaintBorderWithStyleBorder(nsPresContext* aPresContext, } else { // We're drawing borders around the joined continuation boxes so we need // to clip that to the slice that we want for this frame. - aRenderingContext.IntersectClip(aBorderArea); + aRenderingContext.ThebesContext()-> + Clip(NSRectToRect(aBorderArea, + aForFrame->PresContext()->AppUnitsPerDevPixel(), + *aRenderingContext.GetDrawTarget())); } } else { MOZ_ASSERT(joinedBorderArea.IsEqualEdges(aBorderArea), @@ -1368,7 +1371,10 @@ nsCSSRendering::PaintBoxShadowOuter(nsPresContext* aPresContext, } } } - aRenderingContext.IntersectClip(fragmentClip); + aRenderingContext.ThebesContext()-> + Clip(NSRectToRect(fragmentClip, + aForFrame->PresContext()->AppUnitsPerDevPixel(), + *aRenderingContext.GetDrawTarget())); gfxCornerSizes clipRectRadii; if (hasBorderRadius) { @@ -3207,7 +3213,9 @@ DrawBorderImage(nsPresContext* aPresContext, nsRect clip = aBorderArea; clip.Inflate(imageOutset); autoSR.EnsureSaved(aRenderingContext.ThebesContext()); - aRenderingContext.IntersectClip(clip); + aRenderingContext.ThebesContext()-> + Clip(NSRectToRect(clip, aForFrame->PresContext()->AppUnitsPerDevPixel(), + *aRenderingContext.GetDrawTarget())); } } else { borderImgArea = aBorderArea; diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 7f3db0a27fe..26895c46978 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -3062,12 +3062,16 @@ nsDisplayBoxShadowInner::Paint(nsDisplayListBuilder* aBuilder, PROFILER_LABEL("nsDisplayBoxShadowInner", "Paint", js::ProfileEntry::Category::GRAPHICS); + DrawTarget* drawTarget = aCtx->GetDrawTarget(); + gfxContext* gfx = aCtx->ThebesContext(); + int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel(); + for (uint32_t i = 0; i < rects.Length(); ++i) { - aCtx->ThebesContext()->Save(); - aCtx->IntersectClip(rects[i]); + gfx->Save(); + gfx->Clip(NSRectToRect(rects[i], appUnitsPerDevPixel, *drawTarget)); nsCSSRendering::PaintBoxShadowInner(presContext, *aCtx, mFrame, borderRect, rects[i]); - aCtx->ThebesContext()->Restore(); + gfx->Restore(); } } diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp index b182f3846ca..ce13584a304 100644 --- a/layout/forms/nsComboboxControlFrame.cpp +++ b/layout/forms/nsComboboxControlFrame.cpp @@ -1505,9 +1505,13 @@ void nsComboboxControlFrame::PaintFocus(nsRenderingContext& aRenderingContext, if (eventStates.HasState(NS_EVENT_STATE_DISABLED) || sFocused != this) return; - aRenderingContext.ThebesContext()->Save(); + gfxContext* gfx = aRenderingContext.ThebesContext(); + + gfx->Save(); nsRect clipRect = mDisplayFrame->GetRect() + aPt; - aRenderingContext.IntersectClip(clipRect); + gfx->Clip(NSRectToRect(clipRect, + PresContext()->AppUnitsPerDevPixel(), + *aRenderingContext.GetDrawTarget())); // REVIEW: Why does the old code paint mDisplayFrame again? We've // already painted it in the children above. So clipping it here won't do @@ -1527,7 +1531,7 @@ void nsComboboxControlFrame::PaintFocus(nsRenderingContext& aRenderingContext, StrokeSnappedEdgesOfRect(r, *aRenderingContext.GetDrawTarget(), color, strokeOptions); - aRenderingContext.ThebesContext()->Restore(); + gfx->Restore(); } //--------------------------------------------------------- diff --git a/layout/forms/nsFieldSetFrame.cpp b/layout/forms/nsFieldSetFrame.cpp index 0a8ed8bd2d8..9c7737ba90e 100644 --- a/layout/forms/nsFieldSetFrame.cpp +++ b/layout/forms/nsFieldSetFrame.cpp @@ -5,7 +5,9 @@ #include "nsFieldSetFrame.h" +#include "mozilla/gfx/2D.h" #include "nsCSSAnonBoxes.h" +#include "nsLayoutUtils.h" #include "nsLegendFrame.h" #include "nsCSSRendering.h" #include @@ -21,6 +23,7 @@ #include "mozilla/Maybe.h" using namespace mozilla; +using namespace mozilla::gfx; using namespace mozilla::layout; nsContainerFrame* @@ -219,12 +222,15 @@ nsFieldSetFrame::PaintBorderBackground(nsRenderingContext& aRenderingContext, clipRect.width = legendRect.x - rect.x; clipRect.height = topBorder; - aRenderingContext.ThebesContext()->Save(); - aRenderingContext.IntersectClip(clipRect); + DrawTarget* drawTarget = aRenderingContext.GetDrawTarget(); + gfxContext* gfx = aRenderingContext.ThebesContext(); + int32_t appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel(); + + gfx->Save(); + gfx->Clip(NSRectToRect(clipRect, appUnitsPerDevPixel, *drawTarget)); nsCSSRendering::PaintBorder(presContext, aRenderingContext, this, aDirtyRect, rect, mStyleContext); - - aRenderingContext.ThebesContext()->Restore(); + gfx->Restore(); // draw right side @@ -233,12 +239,11 @@ nsFieldSetFrame::PaintBorderBackground(nsRenderingContext& aRenderingContext, clipRect.width = rect.XMost() - legendRect.XMost(); clipRect.height = topBorder; - aRenderingContext.ThebesContext()->Save(); - aRenderingContext.IntersectClip(clipRect); + gfx->Save(); + gfx->Clip(NSRectToRect(clipRect, appUnitsPerDevPixel, *drawTarget)); nsCSSRendering::PaintBorder(presContext, aRenderingContext, this, aDirtyRect, rect, mStyleContext); - - aRenderingContext.ThebesContext()->Restore(); + gfx->Restore(); // draw bottom @@ -246,12 +251,11 @@ nsFieldSetFrame::PaintBorderBackground(nsRenderingContext& aRenderingContext, clipRect.y += topBorder; clipRect.height = mRect.height - (yoff + topBorder); - aRenderingContext.ThebesContext()->Save(); - aRenderingContext.IntersectClip(clipRect); + gfx->Save(); + gfx->Clip(NSRectToRect(clipRect, appUnitsPerDevPixel, *drawTarget)); nsCSSRendering::PaintBorder(presContext, aRenderingContext, this, aDirtyRect, rect, mStyleContext); - - aRenderingContext.ThebesContext()->Restore(); + gfx->Restore(); } else { nsCSSRendering::PaintBorder(presContext, aRenderingContext, this, diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index ac638ba2196..7acdccae3d0 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -1220,9 +1220,13 @@ nsImageFrame::DisplayAltFeedback(nsRenderingContext& aRenderingContext, return; } + DrawTarget* drawTarget = aRenderingContext.GetDrawTarget(); + gfxContext* gfx = aRenderingContext.ThebesContext(); + // Clip so we don't render outside the inner rect - aRenderingContext.ThebesContext()->Save(); - aRenderingContext.IntersectClip(inner); + gfx->Save(); + gfx->Clip(NSRectToRect(inner, PresContext()->AppUnitsPerDevPixel(), + *drawTarget)); // Check if we should display image placeholders if (gIconLoad->mPrefShowPlaceholders) { @@ -1261,7 +1265,6 @@ nsImageFrame::DisplayAltFeedback(nsRenderingContext& aRenderingContext, // just draw some graffiti in the mean time if (!iconUsed) { ColorPattern color(ToDeviceColor(Color(1.f, 0.f, 0.f, 1.f))); - DrawTarget* drawTarget = aRenderingContext.GetDrawTarget(); nscoord iconXPos = (vis->mDirection == NS_STYLE_DIRECTION_RTL) ? inner.XMost() - size : inner.x; diff --git a/layout/generic/nsPageFrame.cpp b/layout/generic/nsPageFrame.cpp index 249bb4d6a7b..b0176979158 100644 --- a/layout/generic/nsPageFrame.cpp +++ b/layout/generic/nsPageFrame.cpp @@ -4,6 +4,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsPageFrame.h" + +#include "mozilla/gfx/2D.h" +#include "nsLayoutUtils.h" #include "nsPresContext.h" #include "nsRenderingContext.h" #include "nsGkAtoms.h" @@ -25,6 +28,7 @@ extern PRLogModuleInfo *GetLayoutPrintingLog(); #endif using namespace mozilla; +using namespace mozilla::gfx; nsPageFrame* NS_NewPageFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) @@ -372,12 +376,16 @@ nsPageFrame::DrawHeaderFooter(nsRenderingContext& aRenderingContext, y = aRect.YMost() - aHeight - mPD->mEdgePaperMargin.bottom; } + DrawTarget* drawTarget = aRenderingContext.GetDrawTarget(); + gfxContext* gfx = aRenderingContext.ThebesContext(); + // set up new clip and draw the text - aRenderingContext.ThebesContext()->Save(); + gfx->Save(); + gfx->Clip(NSRectToRect(aRect, PresContext()->AppUnitsPerDevPixel(), + *drawTarget)); aRenderingContext.SetColor(NS_RGB(0,0,0)); - aRenderingContext.IntersectClip(aRect); nsLayoutUtils::DrawString(this, &aRenderingContext, str.get(), str.Length(), nsPoint(x, y + aAscent)); - aRenderingContext.ThebesContext()->Restore(); + gfx->Restore(); } } diff --git a/layout/svg/nsSVGIntegrationUtils.cpp b/layout/svg/nsSVGIntegrationUtils.cpp index b0e523adbc1..4a83ea82350 100644 --- a/layout/svg/nsSVGIntegrationUtils.cpp +++ b/layout/svg/nsSVGIntegrationUtils.cpp @@ -473,6 +473,7 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(nsRenderingContext* aCtx, bool isTrivialClip = clipPathFrame ? clipPathFrame->IsTrivial() : true; + DrawTarget* drawTarget = aCtx->GetDrawTarget(); gfxContext* gfx = aCtx->ThebesContext(); gfxContextMatrixAutoSaveRestore matrixAutoSaveRestore(gfx); @@ -519,8 +520,11 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(nsRenderingContext* aCtx, || aFrame->StyleDisplay()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) { complexEffects = true; gfx->Save(); - aCtx->IntersectClip(aFrame->GetVisualOverflowRectRelativeToSelf() + - toUserSpace); + nsRect clipRect = + aFrame->GetVisualOverflowRectRelativeToSelf() + toUserSpace; + gfx->Clip(NSRectToRect(clipRect, + aFrame->PresContext()->AppUnitsPerDevPixel(), + *drawTarget)); gfx->PushGroup(gfxContentType::COLOR_ALPHA); } diff --git a/layout/svg/nsSVGUtils.cpp b/layout/svg/nsSVGUtils.cpp index 4da936afaad..fbbcc120783 100644 --- a/layout/svg/nsSVGUtils.cpp +++ b/layout/svg/nsSVGUtils.cpp @@ -28,6 +28,7 @@ #include "nsIFrame.h" #include "nsIPresShell.h" #include "nsISVGChildFrame.h" +#include "nsLayoutUtils.h" #include "nsPresContext.h" #include "nsRenderingContext.h" #include "nsStyleCoord.h" @@ -556,6 +557,7 @@ nsSVGUtils::PaintFrameWithEffects(nsIFrame *aFrame, if (opacity != 1.0f && CanOptimizeOpacity(aFrame)) opacity = 1.0f; + DrawTarget* drawTarget = aContext->GetDrawTarget(); gfxContext *gfx = aContext->ThebesContext(); bool complexEffects = false; @@ -587,7 +589,9 @@ nsSVGUtils::PaintFrameWithEffects(nsIFrame *aFrame, // GetCanvasTM(). overflowRect = overflowRect + aFrame->GetPosition(); } - aContext->IntersectClip(overflowRect); + gfx->Clip(NSRectToRect(overflowRect, + aFrame->PresContext()->AppUnitsPerDevPixel(), + *drawTarget)); } gfx->PushGroup(gfxContentType::COLOR_ALPHA); } diff --git a/layout/xul/nsBoxFrame.h b/layout/xul/nsBoxFrame.h index 47b24a39403..0fc5c9ec301 100644 --- a/layout/xul/nsBoxFrame.h +++ b/layout/xul/nsBoxFrame.h @@ -36,6 +36,7 @@ nsIFrame* NS_NewBoxFrame(nsIPresShell* aPresShell, class nsBoxFrame : public nsContainerFrame { +protected: typedef mozilla::gfx::DrawTarget DrawTarget; public: diff --git a/layout/xul/nsGroupBoxFrame.cpp b/layout/xul/nsGroupBoxFrame.cpp index 808fa0dfe50..44a52e5325b 100644 --- a/layout/xul/nsGroupBoxFrame.cpp +++ b/layout/xul/nsGroupBoxFrame.cpp @@ -6,11 +6,17 @@ // YY need to pass isMultiple before create called #include "nsBoxFrame.h" + +#include "mozilla/gfx/2D.h" #include "nsCSSRendering.h" +#include "nsLayoutUtils.h" #include "nsRenderingContext.h" #include "nsStyleContext.h" #include "nsDisplayList.h" +using namespace mozilla; +using namespace mozilla::gfx; + class nsGroupBoxFrame : public nsBoxFrame { public: NS_DECL_FRAMEARENA_HELPERS @@ -123,6 +129,10 @@ nsGroupBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, void nsGroupBoxFrame::PaintBorderBackground(nsRenderingContext& aRenderingContext, nsPoint aPt, const nsRect& aDirtyRect) { + + DrawTarget* drawTarget = aRenderingContext.GetDrawTarget(); + gfxContext* gfx = aRenderingContext.ThebesContext(); + Sides skipSides; const nsStyleBorder* borderStyleData = StyleBorder(); const nsMargin& border = borderStyleData->GetComputedBorder(); @@ -152,6 +162,7 @@ nsGroupBoxFrame::PaintBorderBackground(nsRenderingContext& aRenderingContext, nsCSSRendering::PAINTBG_SYNC_DECODE_IMAGES); if (groupBox) { + int32_t appUnitsPerDevPixel = PresContext()->AppUnitsPerDevPixel(); // we should probably use PaintBorderEdges to do this but for now just use clipping // to achieve the same effect. @@ -161,13 +172,11 @@ nsGroupBoxFrame::PaintBorderBackground(nsRenderingContext& aRenderingContext, clipRect.width = groupRect.x - rect.x; clipRect.height = border.top; - aRenderingContext.ThebesContext()->Save(); - aRenderingContext.IntersectClip(clipRect); + gfx->Save(); + gfx->Clip(NSRectToRect(clipRect, appUnitsPerDevPixel, *drawTarget)); nsCSSRendering::PaintBorder(presContext, aRenderingContext, this, aDirtyRect, rect, mStyleContext, skipSides); - - aRenderingContext.ThebesContext()->Restore(); - + gfx->Restore(); // draw right side clipRect = rect; @@ -175,14 +184,11 @@ nsGroupBoxFrame::PaintBorderBackground(nsRenderingContext& aRenderingContext, clipRect.width = rect.XMost() - groupRect.XMost(); clipRect.height = border.top; - aRenderingContext.ThebesContext()->Save(); - aRenderingContext.IntersectClip(clipRect); + gfx->Save(); + gfx->Clip(NSRectToRect(clipRect, appUnitsPerDevPixel, *drawTarget)); nsCSSRendering::PaintBorder(presContext, aRenderingContext, this, aDirtyRect, rect, mStyleContext, skipSides); - - aRenderingContext.ThebesContext()->Restore(); - - + gfx->Restore(); // draw bottom @@ -190,12 +196,11 @@ nsGroupBoxFrame::PaintBorderBackground(nsRenderingContext& aRenderingContext, clipRect.y += border.top; clipRect.height = mRect.height - (yoff + border.top); - aRenderingContext.ThebesContext()->Save(); - aRenderingContext.IntersectClip(clipRect); + gfx->Save(); + gfx->Clip(NSRectToRect(clipRect, appUnitsPerDevPixel, *drawTarget)); nsCSSRendering::PaintBorder(presContext, aRenderingContext, this, aDirtyRect, rect, mStyleContext, skipSides); - - aRenderingContext.ThebesContext()->Restore(); + gfx->Restore(); } else { nsCSSRendering::PaintBorder(presContext, aRenderingContext, this, diff --git a/layout/xul/tree/nsTreeBodyFrame.cpp b/layout/xul/tree/nsTreeBodyFrame.cpp index 82af450a09b..9be16c9d0b1 100644 --- a/layout/xul/tree/nsTreeBodyFrame.cpp +++ b/layout/xul/tree/nsTreeBodyFrame.cpp @@ -2797,8 +2797,13 @@ nsTreeBodyFrame::PaintTreeBody(nsRenderingContext& aRenderingContext, { // Update our available height and our page count. CalcInnerBox(); - aRenderingContext.ThebesContext()->Save(); - aRenderingContext.IntersectClip(mInnerBox + aPt); + + DrawTarget* drawTarget = aRenderingContext.GetDrawTarget(); + gfxContext* gfx = aRenderingContext.ThebesContext(); + + gfx->Save(); + gfx->Clip(NSRectToRect(mInnerBox + aPt, PresContext()->AppUnitsPerDevPixel(), + *drawTarget)); int32_t oldPageCount = mPageLength; if (!mHasFixedRowCount) mPageLength = mInnerBox.height/mRowHeight; @@ -2856,7 +2861,7 @@ nsTreeBodyFrame::PaintTreeBody(nsRenderingContext& aRenderingContext, PaintDropFeedback(feedbackRect, PresContext(), aRenderingContext, aDirtyRect, aPt); } } - aRenderingContext.ThebesContext()->Restore(); + gfx->Restore(); }