From 643971552f00db43fecbf9694550f600529638e2 Mon Sep 17 00:00:00 2001 From: "tor%cs.brown.edu" Date: Wed, 28 Jun 2006 22:04:48 +0000 Subject: [PATCH] Bug 341257 - clipPath not correctly checking for nontrivial situations and not informing children that the CTM has changed. r=scootermorris, sr=roc. --- layout/svg/base/src/nsISVGChildFrame.h | 3 +++ layout/svg/base/src/nsSVGClipPathFrame.cpp | 18 ++++++++++-------- layout/svg/base/src/nsSVGContainerFrame.h | 1 + layout/svg/base/src/nsSVGGlyphFrame.h | 3 ++- layout/svg/base/src/nsSVGPathGeometryFrame.h | 3 ++- .../src/cairo/nsSVGCairoGlyphGeometry.cpp | 8 +++++++- 6 files changed, 25 insertions(+), 11 deletions(-) diff --git a/layout/svg/base/src/nsISVGChildFrame.h b/layout/svg/base/src/nsISVGChildFrame.h index 9c3f24dc4d1f..d112c73d66ce 100644 --- a/layout/svg/base/src/nsISVGChildFrame.h +++ b/layout/svg/base/src/nsISVGChildFrame.h @@ -88,6 +88,9 @@ public: // XXX move this function into interface nsISVGLocatableMetrics NS_IMETHOD GetBBox(nsIDOMSVGRect **_retval)=0; // bbox in local coords + + // Are we a container frame? + NS_IMETHOD_(PRBool) IsDisplayContainer()=0; }; NS_DEFINE_STATIC_IID_ACCESSOR(nsISVGChildFrame, NS_ISVGCHILDFRAME_IID) diff --git a/layout/svg/base/src/nsSVGClipPathFrame.cpp b/layout/svg/base/src/nsSVGClipPathFrame.cpp index 32f125cb83b9..bd9915f28095 100644 --- a/layout/svg/base/src/nsSVGClipPathFrame.cpp +++ b/layout/svg/base/src/nsSVGClipPathFrame.cpp @@ -210,6 +210,7 @@ nsSVGClipPathFrame::ClipPaint(nsISVGRendererCanvas* canvas, nsISVGChildFrame* SVGFrame=nsnull; kid->QueryInterface(NS_GET_IID(nsISVGChildFrame),(void**)&SVGFrame); if (SVGFrame) { + SVGFrame->NotifyCanvasTMChanged(PR_TRUE); SVGFrame->PaintSVG(canvas); } } @@ -273,20 +274,21 @@ NS_IMETHODIMP nsSVGClipPathFrame::IsTrivial(PRBool *aTrivial) { *aTrivial = PR_TRUE; - PRBool foundOne = PR_FALSE; + PRBool foundChild = PR_FALSE; for (nsIFrame* kid = mFrames.FirstChild(); kid; kid = kid->GetNextSibling()) { - nsISVGChildFrame* SVGFrame = nsnull; - kid->QueryInterface(NS_GET_IID(nsISVGChildFrame),(void**)&SVGFrame); - if (SVGFrame) { - nsIFrame *frame = nsnull; - CallQueryInterface(SVGFrame, &frame); - if (foundOne || frame->GetContent()->Tag() == nsSVGAtoms::g) { + nsISVGChildFrame *svgChild = nsnull; + CallQueryInterface(kid, &svgChild); + + if (svgChild) { + // We consider a non-trivial clipPath to be one containing + // either more than one svg child and/or a svg container + if (foundChild || svgChild->IsDisplayContainer()) { *aTrivial = PR_FALSE; return NS_OK; } - foundOne = PR_TRUE; + foundChild = PR_TRUE; } } diff --git a/layout/svg/base/src/nsSVGContainerFrame.h b/layout/svg/base/src/nsSVGContainerFrame.h index 3ed46a67967c..bfae81ce5eb2 100644 --- a/layout/svg/base/src/nsSVGContainerFrame.h +++ b/layout/svg/base/src/nsSVGContainerFrame.h @@ -115,6 +115,7 @@ public: NS_IMETHOD SetMatrixPropagation(PRBool aPropagate) { return NS_ERROR_FAILURE; } NS_IMETHOD SetOverrideCTM(nsIDOMSVGMatrix *aCTM) { return NS_ERROR_FAILURE; } NS_IMETHOD GetBBox(nsIDOMSVGRect **_retval); + NS_IMETHOD_(PRBool) IsDisplayContainer() { return PR_TRUE; } }; #endif diff --git a/layout/svg/base/src/nsSVGGlyphFrame.h b/layout/svg/base/src/nsSVGGlyphFrame.h index 0d6494c61bd7..fa9ea4615733 100644 --- a/layout/svg/base/src/nsSVGGlyphFrame.h +++ b/layout/svg/base/src/nsSVGGlyphFrame.h @@ -111,7 +111,8 @@ public: NS_IMETHOD SetMatrixPropagation(PRBool aPropagate) { return NS_OK; } NS_IMETHOD SetOverrideCTM(nsIDOMSVGMatrix *aCTM) { return NS_ERROR_FAILURE; } NS_IMETHOD GetBBox(nsIDOMSVGRect **_retval); - + NS_IMETHOD_(PRBool) IsDisplayContainer() { return PR_FALSE; } + // nsISVGGeometrySource interface: NS_IMETHOD GetCanvasTM(nsIDOMSVGMatrix * *aCTM); virtual nsresult UpdateGraphic(PRBool suppressInvalidation = PR_FALSE); diff --git a/layout/svg/base/src/nsSVGPathGeometryFrame.h b/layout/svg/base/src/nsSVGPathGeometryFrame.h index 842bad0fca90..0f29d482b1e4 100644 --- a/layout/svg/base/src/nsSVGPathGeometryFrame.h +++ b/layout/svg/base/src/nsSVGPathGeometryFrame.h @@ -120,7 +120,8 @@ protected: NS_IMETHOD SetMatrixPropagation(PRBool aPropagate); NS_IMETHOD SetOverrideCTM(nsIDOMSVGMatrix *aCTM); NS_IMETHOD GetBBox(nsIDOMSVGRect **_retval); - + NS_IMETHOD_(PRBool) IsDisplayContainer() { return PR_FALSE; } + // nsISVGGeometrySource interface: virtual nsresult UpdateGraphic(PRBool suppressInvalidation = PR_FALSE); diff --git a/layout/svg/renderer/src/cairo/nsSVGCairoGlyphGeometry.cpp b/layout/svg/renderer/src/cairo/nsSVGCairoGlyphGeometry.cpp index 22c9ac6d6a47..fed715d08b43 100644 --- a/layout/svg/renderer/src/cairo/nsSVGCairoGlyphGeometry.cpp +++ b/layout/svg/renderer/src/cairo/nsSVGCairoGlyphGeometry.cpp @@ -206,7 +206,13 @@ nsSVGCairoGlyphGeometry::Render(nsSVGGlyphFrame *aSource, else cairo_set_fill_rule(ctx, CAIRO_FILL_RULE_WINDING); - LoopCharacters(ctx, text, cp, cairo_text_path); + if (renderMode == nsISVGRendererCanvas::SVG_RENDER_MODE_CLIP_MASK) { + cairo_set_antialias(ctx, CAIRO_ANTIALIAS_NONE); + cairo_set_source_rgba(ctx, 1.0f, 1.0f, 1.0f, 1.0f); + LoopCharacters(ctx, text, cp, cairo_show_text); + } else { + LoopCharacters(ctx, text, cp, cairo_text_path); + } cairo_set_matrix(ctx, &matrix);