diff --git a/layout/svg/base/src/nsSVGOuterSVGFrame.cpp b/layout/svg/base/src/nsSVGOuterSVGFrame.cpp index 31ebe8de3bd..07023074325 100644 --- a/layout/svg/base/src/nsSVGOuterSVGFrame.cpp +++ b/layout/svg/base/src/nsSVGOuterSVGFrame.cpp @@ -505,10 +505,70 @@ nsDisplaySVG::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, void nsDisplaySVG::Paint(nsDisplayListBuilder* aBuilder, - nsRenderingContext* aCtx) + nsRenderingContext* aContext) { - static_cast(mFrame)-> - Paint(aBuilder, aCtx, mVisibleRect, ToReferenceFrame()); + nsSVGOuterSVGFrame *frame = static_cast(mFrame); + + if (frame->GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD) + return; + +#if defined(DEBUG) && defined(SVG_DEBUG_PAINT_TIMING) + PRTime start = PR_Now(); +#endif + + aContext->PushState(); + +#ifdef XP_MACOSX + if (frame->BitmapFallbackEnabled()) { + // nquartz fallback paths, which svg tends to trigger, need + // a non-window context target + aContext->ThebesContext()->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA); + } +#endif + + frame->Paint(aBuilder, aContext, mVisibleRect, ToReferenceFrame()); + +#ifdef XP_MACOSX + if (frame->BitmapFallbackEnabled()) { + // show the surface we pushed earlier for fallbacks + aContext->ThebesContext()->PopGroupToSource(); + aContext->ThebesContext()->Paint(); + } + + if (aContext->ThebesContext()->HasError() && !frame->BitmapFallbackEnabled()) { + frame->SetBitmapFallbackEnabled(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* ancestor = frame; + PRUint32 flags = 0; + while (true) { + nsIFrame* next = nsLayoutUtils::GetCrossDocParentFrame(ancestor); + if (!next) + break; + if (ancestor->GetParent() != next) { + // We're crossing a document boundary. Logically, the invalidation is + // being triggered by a subdocument of the root document. This will + // prevent an untrusted root document being told about invalidation + // that happened because a child was using SVG... + flags |= nsIFrame::INVALIDATE_CROSS_DOC; + } + ancestor = next; + } + ancestor->InvalidateWithFlags(nsRect(nsPoint(0, 0), ancestor->GetSize()), flags); + } +#endif + + aContext->PopState(); + +#if defined(DEBUG) && defined(SVG_DEBUG_PAINT_TIMING) + PRTime end = PR_Now(); + printf("SVG Paint Timing: %f ms\n", (end-start)/1000.0); +#endif } // helper @@ -588,12 +648,6 @@ nsSVGOuterSVGFrame::Paint(const nsDisplayListBuilder* aBuilder, nsRenderingContext* aContext, const nsRect& aDirtyRect, nsPoint aPt) { - if (GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD) - return; - - // initialize Mozilla rendering context - aContext->PushState(); - nsRect viewportRect = GetContentRect(); nsPoint viewportOffset = aPt + viewportRect.TopLeft() - GetPosition(); viewportRect.MoveTo(viewportOffset); @@ -604,10 +658,6 @@ nsSVGOuterSVGFrame::Paint(const nsDisplayListBuilder* aBuilder, aContext->Translate(viewportRect.TopLeft()); nsRect dirtyRect = clipRect - viewportOffset; -#if defined(DEBUG) && defined(SVG_DEBUG_PAINT_TIMING) - PRTime start = PR_Now(); -#endif - nsIntRect dirtyPxRect = dirtyRect.ToOutsidePixels(PresContext()->AppUnitsPerDevPixel()); // Create an SVGAutoRenderState so we can call SetPaintingToWindow on @@ -618,57 +668,7 @@ nsSVGOuterSVGFrame::Paint(const nsDisplayListBuilder* aBuilder, state.SetPaintingToWindow(true); } -#ifdef XP_MACOSX - if (mEnableBitmapFallback) { - // nquartz fallback paths, which svg tends to trigger, need - // a non-window context target - aContext->ThebesContext()->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA); - } -#endif - nsSVGUtils::PaintFrameWithEffects(aContext, &dirtyPxRect, this); - -#ifdef XP_MACOSX - if (mEnableBitmapFallback) { - // show the surface we pushed earlier for fallbacks - aContext->ThebesContext()->PopGroupToSource(); - aContext->ThebesContext()->Paint(); - } - - if (aContext->ThebesContext()->HasError() && !mEnableBitmapFallback) { - mEnableBitmapFallback = 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; - PRUint32 flags = 0; - while (true) { - nsIFrame* next = nsLayoutUtils::GetCrossDocParentFrame(frame); - if (!next) - break; - if (frame->GetParent() != next) { - // We're crossing a document boundary. Logically, the invalidation is - // being triggered by a subdocument of the root document. This will - // prevent an untrusted root document being told about invalidation - // that happened because a child was using SVG... - flags |= INVALIDATE_CROSS_DOC; - } - frame = next; - } - frame->InvalidateWithFlags(nsRect(nsPoint(0, 0), frame->GetSize()), flags); - } -#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 - - aContext->PopState(); } nsSplittableType diff --git a/layout/svg/base/src/nsSVGOuterSVGFrame.h b/layout/svg/base/src/nsSVGOuterSVGFrame.h index 69ee54256e1..2283705820e 100644 --- a/layout/svg/base/src/nsSVGOuterSVGFrame.h +++ b/layout/svg/base/src/nsSVGOuterSVGFrame.h @@ -140,6 +140,16 @@ public: void RegisterForeignObject(nsSVGForeignObjectFrame* aFrame); void UnregisterForeignObject(nsSVGForeignObjectFrame* aFrame); +#ifdef XP_MACOSX + bool BitmapFallbackEnabled() const { + return mEnableBitmapFallback; + } + void SetBitmapFallbackEnabled(bool aVal) { + NS_NOTREACHED("don't think me need this any more"); // comment in bug 732429 if we do + mEnableBitmapFallback = aVal; + } +#endif + protected: /* Returns true if our content is the document element and our document is