Bug 411334. Try optimistically to not use a temporary group for SVG drawing on Mac. If drawing fails we try again with a temporary group. r+sr=vlad
--- a/gfx/thebes/public/gfxContext.h
+++ b/gfx/thebes/public/gfxContext.h
@@ -93,16 +93,21 @@ public:
/**
* Return the raw cairo_t object.
* XXX this should go away at some point.
*/
cairo_t *GetCairo() { return mCairo; }
/**
+ * Returns true if the cairo context is in an error state.
+ */
+ PRBool HasError();
+
+ /**
** State
**/
// XXX document exactly what bits are saved
void Save();
void Restore();
/**
** Paths & Drawing
--- a/gfx/thebes/src/gfxContext.cpp
+++ b/gfx/thebes/src/gfxContext.cpp
@@ -759,8 +759,14 @@ gfxContext::GetUserStrokeExtent()
already_AddRefed<gfxFlattenedPath>
gfxContext::GetFlattenedPath()
{
gfxFlattenedPath *path =
new gfxFlattenedPath(cairo_copy_path_flat(mCairo));
NS_IF_ADDREF(path);
return path;
}
+
+PRBool
+gfxContext::HasError()
+{
+ return cairo_status(mCairo) != CAIRO_STATUS_SUCCESS;
+}
--- a/layout/svg/base/src/nsSVGOuterSVGFrame.cpp
+++ b/layout/svg/base/src/nsSVGOuterSVGFrame.cpp
@@ -151,20 +151,23 @@ NS_NewSVGOuterSVGFrame(nsIPresShell* aPr
NS_ERROR("Can't create frame! Content is not an SVG 'svg' element!");
return nsnull;
}
return new (aPresShell) nsSVGOuterSVGFrame(aContext);
}
nsSVGOuterSVGFrame::nsSVGOuterSVGFrame(nsStyleContext* aContext)
- : nsSVGOuterSVGFrameBase(aContext),
- mRedrawSuspendCount(0),
- mFullZoom(0),
- mViewportInitialized(PR_FALSE)
+ : nsSVGOuterSVGFrameBase(aContext)
+ , mRedrawSuspendCount(0)
+ , mFullZoom(0)
+ , mViewportInitialized(PR_FALSE)
+#ifdef XP_MACOSX
+ , mEnableBitmapFallback(PR_FALSE)
+#endif
{
}
NS_IMETHODIMP
nsSVGOuterSVGFrame::Init(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame* aPrevInFlow)
{
@@ -575,32 +578,55 @@ nsSVGOuterSVGFrame::Paint(nsIRenderingCo
#if defined(DEBUG) && defined(SVG_DEBUG_PAINT_TIMING)
PRTime start = PR_Now();
#endif
dirtyRect.ScaleRoundOut(1.0f / PresContext()->AppUnitsPerDevPixel());
nsSVGRenderState ctx(&aRenderingContext);
- // nquartz fallback paths, which svg tends to trigger, need
- // a non-window context target
#ifdef XP_MACOSX
- ctx.GetGfxContext()->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
+ if (mEnableBitmapFallback) {
+ // nquartz fallback paths, which svg tends to trigger, need
+ // a non-window context target
+ ctx.GetGfxContext()->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
+ }
#endif
// paint children:
for (nsIFrame* kid = mFrames.FirstChild(); kid;
kid = kid->GetNextSibling()) {
nsSVGUtils::PaintChildWithEffects(&ctx, &dirtyRect, kid);
}
-// show the surface we pushed earlier for nquartz fallbacks
#ifdef XP_MACOSX
- ctx.GetGfxContext()->PopGroupToSource();
- ctx.GetGfxContext()->Paint();
+ if (mEnableBitmapFallback) {
+ // show the surface we pushed earlier for fallbacks
+ ctx.GetGfxContext()->PopGroupToSource();
+ ctx.GetGfxContext()->Paint();
+ }
+
+ if (ctx.GetGfxContext()->HasError() && !mEnableBitmapFallback) {
+ mEnableBitmapFallback = PR_TRUE;
+ // It's not really clear what area to invalidate here. We might have
+ // stuffed up rendering for the entire window in this paint pass,
+ // so we can't just invalidate our own rect. Invalidate everything
+ // in sight.
+ // This won't work for printing, by the way, but failure to print the
+ // odd document is probably no worse than printing horribly for all
+ // documents. Better to fix things so we don't need fallback.
+ nsIFrame* frame = this;
+ while (PR_TRUE) {
+ nsIFrame* next = nsLayoutUtils::GetCrossDocParentFrame(frame);
+ if (!next)
+ break;
+ frame = next;
+ }
+ frame->Invalidate(nsRect(nsPoint(0, 0), frame->GetSize()));
+ }
#endif
#if defined(DEBUG) && defined(SVG_DEBUG_PAINT_TIMING)
PRTime end = PR_Now();
printf("SVG Paint Timing: %f ms\n", (end-start)/1000.0);
#endif
aRenderingContext.PopState();
--- a/layout/svg/base/src/nsSVGOuterSVGFrame.h
+++ b/layout/svg/base/src/nsSVGOuterSVGFrame.h
@@ -166,11 +166,14 @@ protected:
// zoom and pan
nsCOMPtr<nsIDOMSVGPoint> mCurrentTranslate;
nsCOMPtr<nsIDOMSVGNumber> mCurrentScale;
float mFullZoom;
PRPackedBool mViewportInitialized;
+#ifdef XP_MACOSX
+ PRPackedBool mEnableBitmapFallback;
+#endif
};
#endif