From cdc32f1c635d2c4ba8f345657cea6c532b39fee5 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Sat, 3 Dec 2011 22:50:16 +0100 Subject: [PATCH] Bug 704088 - Pass dom::Element to nsLayoutUtils::SurfaceFromElement; r=bz --- content/canvas/src/WebGLContextGL.cpp | 18 +++++++------- .../canvas/src/nsCanvasRenderingContext2D.cpp | 19 ++++++++------- .../src/nsCanvasRenderingContext2DAzure.cpp | 15 ++++++------ .../html/content/public/nsHTMLVideoElement.h | 8 +++++++ .../html/content/src/nsHTMLMediaElement.cpp | 11 ++++----- dom/base/nsDOMWindowUtils.cpp | 12 ++++++++-- layout/base/nsCSSRendering.cpp | 5 ++-- layout/base/nsLayoutUtils.cpp | 24 +++++++------------ layout/base/nsLayoutUtils.h | 8 ++++++- 9 files changed, 67 insertions(+), 53 deletions(-) diff --git a/content/canvas/src/WebGLContextGL.cpp b/content/canvas/src/WebGLContextGL.cpp index d13ccb63c648..a82fb379f7e9 100644 --- a/content/canvas/src/WebGLContextGL.cpp +++ b/content/canvas/src/WebGLContextGL.cpp @@ -3993,7 +3993,10 @@ nsresult WebGLContext::DOMElementToImageSurface(nsIDOMElement *imageOrCanvas, gfxImageSurface **imageOut, int *format) { - gfxImageSurface *surf = nsnull; + nsCOMPtr content = do_QueryInterface(imageOrCanvas); + if (!content) { + return NS_ERROR_FAILURE; + } PRUint32 flags = nsLayoutUtils::SFE_WANT_NEW_SURFACE | @@ -4005,7 +4008,7 @@ WebGLContext::DOMElementToImageSurface(nsIDOMElement *imageOrCanvas, flags |= nsLayoutUtils::SFE_NO_PREMULTIPLY_ALPHA; nsLayoutUtils::SurfaceFromElementResult res = - nsLayoutUtils::SurfaceFromElement(imageOrCanvas, flags); + nsLayoutUtils::SurfaceFromElement(content->AsElement(), flags); if (!res.mSurface) return NS_ERROR_FAILURE; if (res.mSurface->GetType() != gfxASurface::SurfaceTypeImage) { @@ -4034,11 +4037,10 @@ WebGLContext::DOMElementToImageSurface(nsIDOMElement *imageOrCanvas, } } - // part 2: if the DOM element is a canvas, check that it's not write-only. That would indicate a tainted canvas, - // i.e. a canvas that could contain cross-domain image data. - nsCOMPtr maybeDOMCanvas = do_QueryInterface(imageOrCanvas); - if (maybeDOMCanvas && maybeDOMCanvas->IsHTML(nsGkAtoms::canvas)) { - nsHTMLCanvasElement *canvas = static_cast(maybeDOMCanvas.get()); + // part 2: if the DOM element is a canvas, check that it's not write-only. + // That would indicate a tainted canvas, i.e. a canvas that could contain + // cross-domain image data. + if (nsHTMLCanvasElement* canvas = nsHTMLCanvasElement::FromContent(content)) { if (canvas->IsWriteOnly()) { LogMessageIfVerbose("The canvas used as source for texImage2D here is tainted (write-only). It is forbidden " "to load a WebGL texture from a tainted canvas. A Canvas becomes tainted for example " @@ -4052,7 +4054,7 @@ WebGLContext::DOMElementToImageSurface(nsIDOMElement *imageOrCanvas, // Notice that there is never a need to mark the WebGL canvas as write-only, since we reject write-only/cross-domain // texture sources in the first place. - surf = static_cast(res.mSurface.get()); + gfxImageSurface* surf = static_cast(res.mSurface.get()); res.mSurface.forget(); *imageOut = surf; diff --git a/content/canvas/src/nsCanvasRenderingContext2D.cpp b/content/canvas/src/nsCanvasRenderingContext2D.cpp index f28c7cfbdc0c..d5d6d4bc5bdd 100644 --- a/content/canvas/src/nsCanvasRenderingContext2D.cpp +++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp @@ -1813,11 +1813,12 @@ nsCanvasRenderingContext2D::CreatePattern(nsIDOMHTMLElement *image, const nsAString& repeat, nsIDOMCanvasPattern **_retval) { - if (!image) { + nsCOMPtr content = do_QueryInterface(image); + if (!content) { return NS_ERROR_DOM_TYPE_MISMATCH_ERR; } - gfxPattern::GraphicsExtend extend; + gfxPattern::GraphicsExtend extend; if (repeat.IsEmpty() || repeat.EqualsLiteral("repeat")) { extend = gfxPattern::EXTEND_REPEAT; } else if (repeat.EqualsLiteral("repeat-x")) { @@ -1833,7 +1834,6 @@ nsCanvasRenderingContext2D::CreatePattern(nsIDOMHTMLElement *image, return NS_ERROR_DOM_SYNTAX_ERR; } - nsCOMPtr content = do_QueryInterface(image); nsHTMLCanvasElement* canvas = nsHTMLCanvasElement::FromContent(content); if (canvas) { nsIntSize size = canvas->GetSize(); @@ -1845,8 +1845,8 @@ nsCanvasRenderingContext2D::CreatePattern(nsIDOMHTMLElement *image, // The canvas spec says that createPattern should use the first frame // of animated images nsLayoutUtils::SurfaceFromElementResult res = - nsLayoutUtils::SurfaceFromElement(image, nsLayoutUtils::SFE_WANT_FIRST_FRAME | - nsLayoutUtils::SFE_WANT_NEW_SURFACE); + nsLayoutUtils::SurfaceFromElement(content->AsElement(), + nsLayoutUtils::SFE_WANT_FIRST_FRAME | nsLayoutUtils::SFE_WANT_NEW_SURFACE); if (!res.mSurface) return NS_ERROR_NOT_AVAILABLE; @@ -3399,11 +3399,11 @@ nsCanvasRenderingContext2D::DrawImage(nsIDOMElement *imgElt, float a1, if (!EnsureSurface()) return NS_ERROR_FAILURE; - if (!imgElt) { + nsCOMPtr content = do_QueryInterface(imgElt); + if (!content) { return NS_ERROR_DOM_TYPE_MISMATCH_ERR; } - nsCOMPtr content = do_QueryInterface(imgElt); nsHTMLCanvasElement* canvas = nsHTMLCanvasElement::FromContent(content); if (canvas) { nsIntSize size = canvas->GetSize(); @@ -3423,7 +3423,7 @@ nsCanvasRenderingContext2D::DrawImage(nsIDOMElement *imgElt, float a1, // of animated images PRUint32 sfeFlags = nsLayoutUtils::SFE_WANT_FIRST_FRAME; nsLayoutUtils::SurfaceFromElementResult res = - nsLayoutUtils::SurfaceFromElement(imgElt, sfeFlags); + nsLayoutUtils::SurfaceFromElement(content->AsElement(), sfeFlags); if (!res.mSurface) { // Spec says to silently do nothing if the element is still loading. return res.mIsStillLoading ? NS_OK : NS_ERROR_NOT_AVAILABLE; @@ -3433,7 +3433,8 @@ nsCanvasRenderingContext2D::DrawImage(nsIDOMElement *imgElt, float a1, // as a source to work around some Cairo self-copy semantics issues. if (res.mSurface == mSurface) { sfeFlags |= nsLayoutUtils::SFE_WANT_NEW_SURFACE; - res = nsLayoutUtils::SurfaceFromElement(imgElt, sfeFlags); + res = nsLayoutUtils::SurfaceFromElement(content->AsElement(), + sfeFlags); if (!res.mSurface) return NS_ERROR_NOT_AVAILABLE; } diff --git a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp index 849519f5a5af..a856c6bba89d 100644 --- a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp +++ b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp @@ -1889,7 +1889,8 @@ nsCanvasRenderingContext2DAzure::CreatePattern(nsIDOMHTMLElement *image, const nsAString& repeat, nsIDOMCanvasPattern **_retval) { - if (!image) { + nsCOMPtr content = do_QueryInterface(image); + if (!content) { return NS_ERROR_DOM_TYPE_MISMATCH_ERR; } @@ -1908,9 +1909,7 @@ nsCanvasRenderingContext2DAzure::CreatePattern(nsIDOMHTMLElement *image, return NS_ERROR_DOM_SYNTAX_ERR; } - nsCOMPtr content = do_QueryInterface(image); nsHTMLCanvasElement* canvas = nsHTMLCanvasElement::FromContent(content); - if (canvas) { nsIntSize size = canvas->GetSize(); if (size.width == 0 || size.height == 0) { @@ -1939,8 +1938,8 @@ nsCanvasRenderingContext2DAzure::CreatePattern(nsIDOMHTMLElement *image, // The canvas spec says that createPattern should use the first frame // of animated images nsLayoutUtils::SurfaceFromElementResult res = - nsLayoutUtils::SurfaceFromElement(image, nsLayoutUtils::SFE_WANT_FIRST_FRAME | - nsLayoutUtils::SFE_WANT_NEW_SURFACE); + nsLayoutUtils::SurfaceFromElement(content->AsElement(), + nsLayoutUtils::SFE_WANT_FIRST_FRAME | nsLayoutUtils::SFE_WANT_NEW_SURFACE); if (!res.mSurface) { return NS_ERROR_NOT_AVAILABLE; @@ -3570,7 +3569,8 @@ nsCanvasRenderingContext2DAzure::DrawImage(nsIDOMElement *imgElt, float a1, float a6, float a7, float a8, PRUint8 optional_argc) { - if (!imgElt) { + nsCOMPtr content = do_QueryInterface(imgElt); + if (!content) { return NS_ERROR_DOM_TYPE_MISMATCH_ERR; } @@ -3591,7 +3591,6 @@ nsCanvasRenderingContext2DAzure::DrawImage(nsIDOMElement *imgElt, float a1, double sx,sy,sw,sh; double dx,dy,dw,dh; - nsCOMPtr content = do_QueryInterface(imgElt); nsHTMLCanvasElement* canvas = nsHTMLCanvasElement::FromContent(content); if (canvas) { nsIntSize size = canvas->GetSize(); @@ -3643,7 +3642,7 @@ nsCanvasRenderingContext2DAzure::DrawImage(nsIDOMElement *imgElt, float a1, // of animated images PRUint32 sfeFlags = nsLayoutUtils::SFE_WANT_FIRST_FRAME; nsLayoutUtils::SurfaceFromElementResult res = - nsLayoutUtils::SurfaceFromElement(imgElt, sfeFlags); + nsLayoutUtils::SurfaceFromElement(content->AsElement(), sfeFlags); if (!res.mSurface) { // Spec says to silently do nothing if the element is still loading. diff --git a/content/html/content/public/nsHTMLVideoElement.h b/content/html/content/public/nsHTMLVideoElement.h index 7891d3850a0c..bd6acb68585e 100644 --- a/content/html/content/public/nsHTMLVideoElement.h +++ b/content/html/content/public/nsHTMLVideoElement.h @@ -48,6 +48,14 @@ public: nsHTMLVideoElement(already_AddRefed aNodeInfo); virtual ~nsHTMLVideoElement(); + static nsHTMLVideoElement* FromContent(nsIContent* aPossibleVideo) + { + if (!aPossibleVideo || !aPossibleVideo->IsHTML(nsGkAtoms::video)) { + return NULL; + } + return static_cast(aPossibleVideo); + } + // nsISupports NS_DECL_ISUPPORTS_INHERITED diff --git a/content/html/content/src/nsHTMLMediaElement.cpp b/content/html/content/src/nsHTMLMediaElement.cpp index 5c159aeda259..515980813cc3 100644 --- a/content/html/content/src/nsHTMLMediaElement.cpp +++ b/content/html/content/src/nsHTMLMediaElement.cpp @@ -2687,18 +2687,17 @@ nsHTMLMediaElement::CopyInnerTo(nsGenericElement* aDest) const dest->mMediaSize = mMediaSize; } else { nsIFrame* frame = GetPrimaryFrame(); - nsCOMPtr elem; + Element* element; if (frame && frame->GetType() == nsGkAtoms::HTMLVideoFrame && static_cast(frame)->ShouldDisplayPoster()) { - elem = do_QueryInterface(static_cast(frame)-> - GetPosterImage()); + nsIContent* content = static_cast(frame)->GetPosterImage(); + element = content ? content->AsElement() : NULL; } else { - elem = do_QueryInterface( - static_cast(const_cast(this))); + element = const_cast(this); } nsLayoutUtils::SurfaceFromElementResult res = - nsLayoutUtils::SurfaceFromElement(elem, + nsLayoutUtils::SurfaceFromElement(element, nsLayoutUtils::SFE_WANT_NEW_SURFACE); dest->mPrintSurface = res.mSurface; dest->mMediaSize = nsIntSize(res.mSize.width, res.mSize.height); diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 5ae971245d3c..0e2d87bd88b5 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -869,10 +869,18 @@ nsDOMWindowUtils::NodesFromRect(float aX, float aY, } static already_AddRefed -CanvasToImageSurface(nsIDOMHTMLCanvasElement *canvas) +CanvasToImageSurface(nsIDOMHTMLCanvasElement* aCanvas) { + nsCOMPtr node = do_QueryInterface(aCanvas); + if (!node) { + return nsnull; + } + + NS_ABORT_IF_FALSE(node->IsElement(), + "An nsINode that implements nsIDOMHTMLCanvasElement should " + "be an element."); nsLayoutUtils::SurfaceFromElementResult result = - nsLayoutUtils::SurfaceFromElement(canvas, + nsLayoutUtils::SurfaceFromElement(node->AsElement(), nsLayoutUtils::SFE_WANT_IMAGE_SURFACE); return static_cast(result.mSurface.forget().get()); } diff --git a/layout/base/nsCSSRendering.cpp b/layout/base/nsCSSRendering.cpp index 64c09f189f3b..0dc431ae6b55 100644 --- a/layout/base/nsCSSRendering.cpp +++ b/layout/base/nsCSSRendering.cpp @@ -3836,9 +3836,8 @@ ImageRenderer::PrepareImage() // If the referenced element doesn't have a frame we might still be able // to paint it if it's an , , or