Bug 1085160 - Port the code that uses nsRenderingContext::IntersectClip() to Moz2D. r=mattwoodrow

--HG--
extra : rebase_source : 54226509a1b16efdc76f92f202cc2be07cf43ab4
This commit is contained in:
Jonathan Watt 2014-10-20 10:55:48 +01:00
parent 5ddc4c01d7
commit ee86633d81
15 changed files with 110 additions and 71 deletions

View File

@ -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)
{

View File

@ -49,7 +49,6 @@ public:
// Graphics state
void IntersectClip(const nsRect& aRect);
void SetColor(nscolor aColor);
// Text

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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();
}
}

View File

@ -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();
}
//---------------------------------------------------------

View File

@ -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 <algorithm>
@ -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,

View File

@ -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;

View File

@ -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();
}
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -36,6 +36,7 @@ nsIFrame* NS_NewBoxFrame(nsIPresShell* aPresShell,
class nsBoxFrame : public nsContainerFrame
{
protected:
typedef mozilla::gfx::DrawTarget DrawTarget;
public:

View File

@ -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,

View File

@ -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();
}