Bug 1044102 - Part 2 - Support ImageBitmap as CanvasImageSource. r=smaug

--HG--
extra : rebase_source : e53ca97680dd12e0f1be217b4396a443b04bbeee
This commit is contained in:
Kaku Kuo 2015-07-30 20:49:00 +02:00
Родитель 9c3f995e43
Коммит 976d0f9acf
5 изменённых файлов: 61 добавлений и 33 удалений

Просмотреть файл

@ -76,6 +76,7 @@
#include "mozilla/CheckedInt.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/ImageBitmap.h"
#include "mozilla/dom/ImageData.h"
#include "mozilla/dom/PBrowserParent.h"
#include "mozilla/dom/ToJSValue.h"
@ -1988,7 +1989,7 @@ CanvasRenderingContext2D::CreateRadialGradient(double x0, double y0, double r0,
}
already_AddRefed<CanvasPattern>
CanvasRenderingContext2D::CreatePattern(const HTMLImageOrCanvasOrVideoElement& element,
CanvasRenderingContext2D::CreatePattern(const CanvasImageSource& source,
const nsAString& repeat,
ErrorResult& error)
{
@ -2009,8 +2010,8 @@ CanvasRenderingContext2D::CreatePattern(const HTMLImageOrCanvasOrVideoElement& e
}
Element* htmlElement;
if (element.IsHTMLCanvasElement()) {
HTMLCanvasElement* canvas = &element.GetAsHTMLCanvasElement();
if (source.IsHTMLCanvasElement()) {
HTMLCanvasElement* canvas = &source.GetAsHTMLCanvasElement();
htmlElement = canvas;
nsIntSize size = canvas->GetSize();
@ -2030,16 +2031,29 @@ CanvasRenderingContext2D::CreatePattern(const HTMLImageOrCanvasOrVideoElement& e
return pat.forget();
}
} else if (element.IsHTMLImageElement()) {
HTMLImageElement* img = &element.GetAsHTMLImageElement();
} else if (source.IsHTMLImageElement()) {
HTMLImageElement* img = &source.GetAsHTMLImageElement();
if (img->IntrinsicState().HasState(NS_EVENT_STATE_BROKEN)) {
error.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}
htmlElement = img;
} else if (source.IsHTMLVideoElement()) {
htmlElement = &source.GetAsHTMLVideoElement();
} else {
htmlElement = &element.GetAsHTMLVideoElement();
// Special case for ImageBitmap
ImageBitmap& imgBitmap = source.GetAsImageBitmap();
EnsureTarget();
RefPtr<SourceSurface> srcSurf = imgBitmap.PrepareForDrawTarget(mTarget);
// An ImageBitmap never taints others so we set principalForSecurityCheck to
// nullptr and set CORSUsed to true for passing the security check in
// CanvasUtils::DoDrawImageSecurityCheck().
nsRefPtr<CanvasPattern> pat =
new CanvasPattern(this, srcSurf, repeatMode, nullptr, false, true);
return pat.forget();
}
EnsureTarget();
@ -4238,7 +4252,7 @@ CanvasRenderingContext2D::CachedSurfaceFromElement(Element* aElement)
// are all passed in.
void
CanvasRenderingContext2D::DrawImage(const HTMLImageOrCanvasOrVideoElement& image,
CanvasRenderingContext2D::DrawImage(const CanvasImageSource& image,
double sx, double sy, double sw,
double sh, double dx, double dy,
double dw, double dh,
@ -4265,7 +4279,17 @@ CanvasRenderingContext2D::DrawImage(const HTMLImageOrCanvasOrVideoElement& image
error.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
} else {
} else if (image.IsImageBitmap()) {
ImageBitmap& imageBitmap = image.GetAsImageBitmap();
srcSurf = imageBitmap.PrepareForDrawTarget(mTarget);
if (!srcSurf) {
return;
}
imgSize = gfx::IntSize(imageBitmap.Width(), imageBitmap.Height());
}
else {
if (image.IsHTMLImageElement()) {
HTMLImageElement* img = &image.GetAsHTMLImageElement();
element = img;

Просмотреть файл

@ -37,7 +37,8 @@ class SourceSurface;
} // namespace gl
namespace dom {
class HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement;
class HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmap;
typedef HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmap CanvasImageSource;
class ImageData;
class StringOrCanvasGradientOrCanvasPattern;
class OwningStringOrCanvasGradientOrCanvasPattern;
@ -60,9 +61,6 @@ class CanvasRenderingContext2D final :
public nsICanvasRenderingContextInternal,
public nsWrapperCache
{
typedef HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement
HTMLImageOrCanvasOrVideoElement;
virtual ~CanvasRenderingContext2D();
public:
@ -132,7 +130,7 @@ public:
CreateRadialGradient(double x0, double y0, double r0, double x1, double y1,
double r1, ErrorResult& aError);
already_AddRefed<CanvasPattern>
CreatePattern(const HTMLImageOrCanvasOrVideoElement& element,
CreatePattern(const CanvasImageSource& element,
const nsAString& repeat, ErrorResult& error);
double ShadowOffsetX()
@ -208,20 +206,20 @@ public:
void RemoveHitRegion(const nsAString& id);
void ClearHitRegions();
void DrawImage(const HTMLImageOrCanvasOrVideoElement& image,
void DrawImage(const CanvasImageSource& image,
double dx, double dy, mozilla::ErrorResult& error)
{
DrawImage(image, 0.0, 0.0, 0.0, 0.0, dx, dy, 0.0, 0.0, 0, error);
}
void DrawImage(const HTMLImageOrCanvasOrVideoElement& image,
void DrawImage(const CanvasImageSource& image,
double dx, double dy, double dw, double dh,
mozilla::ErrorResult& error)
{
DrawImage(image, 0.0, 0.0, 0.0, 0.0, dx, dy, dw, dh, 2, error);
}
void DrawImage(const HTMLImageOrCanvasOrVideoElement& image,
void DrawImage(const CanvasImageSource& image,
double sx, double sy, double sw, double sh, double dx,
double dy, double dw, double dh, mozilla::ErrorResult& error)
{
@ -666,7 +664,7 @@ protected:
nsLayoutUtils::SurfaceFromElementResult
CachedSurfaceFromElement(Element* aElement);
void DrawImage(const HTMLImageOrCanvasOrVideoElement &imgElt,
void DrawImage(const CanvasImageSource &imgElt,
double sx, double sy, double sw, double sh,
double dx, double dy, double dw, double dh,
uint8_t optional_argc, mozilla::ErrorResult& error);

Просмотреть файл

@ -29,14 +29,19 @@ using namespace mozilla::gfx;
namespace mozilla {
namespace CanvasUtils {
/**
* This security check utility might be called from an source that never taints
* others. For example, while painting a CanvasPattern, which is created from an
* ImageBitmap, onto a canvas. In this case, the caller could set the CORSUsed
* true in order to pass this check and leave the aPrincipal to be a nullptr
* since the aPrincipal is not going to be used.
*/
void
DoDrawImageSecurityCheck(dom::HTMLCanvasElement *aCanvasElement,
nsIPrincipal *aPrincipal,
bool forceWriteOnly,
bool CORSUsed)
{
NS_PRECONDITION(aPrincipal, "Must have a principal here");
// Callers should ensure that mCanvasElement is non-null before calling this
if (!aCanvasElement) {
NS_WARNING("DoDrawImageSecurityCheck called without canvas element!");
@ -56,6 +61,8 @@ DoDrawImageSecurityCheck(dom::HTMLCanvasElement *aCanvasElement,
if (CORSUsed)
return;
NS_PRECONDITION(aPrincipal, "Must have a principal here");
if (aCanvasElement->NodePrincipal()->Subsumes(aPrincipal)) {
// This canvas has access to that image anyway
return;

Просмотреть файл

@ -45,13 +45,6 @@ using namespace mozilla::gfx;
NS_IMPL_NS_NEW_HTML_ELEMENT(Canvas)
namespace {
typedef mozilla::dom::HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement
HTMLImageOrCanvasOrVideoElement;
} // namespace
namespace mozilla {
namespace dom {
@ -283,10 +276,10 @@ HTMLCanvasElement::CopyInnerTo(Element* aDest)
nsRefPtr<CanvasRenderingContext2D> context2d =
static_cast<CanvasRenderingContext2D*>(cxt.get());
if (context2d && !mPrintCallback) {
HTMLImageOrCanvasOrVideoElement element;
element.SetAsHTMLCanvasElement() = this;
CanvasImageSource source;
source.SetAsHTMLCanvasElement() = this;
ErrorResult err;
context2d->DrawImage(element,
context2d->DrawImage(source,
0.0, 0.0, err);
rv = err.StealNSResult();
}

Просмотреть файл

@ -26,6 +26,11 @@ dictionary HitRegionOptions {
Element? control = null;
};
typedef (HTMLImageElement or
HTMLCanvasElement or
HTMLVideoElement or
ImageBitmap) CanvasImageSource;
interface CanvasRenderingContext2D {
// back-reference to the canvas. Might be null if we're not
@ -64,7 +69,7 @@ interface CanvasRenderingContext2D {
[NewObject, Throws]
CanvasGradient createRadialGradient(double x0, double y0, double r0, double x1, double y1, double r1);
[NewObject, Throws]
CanvasPattern createPattern((HTMLImageElement or HTMLCanvasElement or HTMLVideoElement) image, [TreatNullAs=EmptyString] DOMString repetition);
CanvasPattern createPattern(CanvasImageSource image, [TreatNullAs=EmptyString] DOMString repetition);
// shadows
[LenientFloat]
@ -116,12 +121,13 @@ interface CanvasRenderingContext2D {
// drawing images
// NOT IMPLEMENTED attribute boolean imageSmoothingEnabled; // (default true)
[Throws, LenientFloat]
void drawImage((HTMLImageElement or HTMLCanvasElement or HTMLVideoElement) image, double dx, double dy);
void drawImage(CanvasImageSource image, double dx, double dy);
[Throws, LenientFloat]
void drawImage((HTMLImageElement or HTMLCanvasElement or HTMLVideoElement) image, double dx, double dy, double dw, double dh);
void drawImage(CanvasImageSource image, double dx, double dy, double dw, double dh);
[Throws, LenientFloat]
void drawImage((HTMLImageElement or HTMLCanvasElement or HTMLVideoElement) image, double sx, double sy, double sw, double sh, double dx, double dy, double dw, double dh);
void drawImage(CanvasImageSource image, double sx, double sy, double sw, double sh, double dx, double dy, double dw, double dh);
// hit regions
[Pref="canvas.hitregions.enabled", Throws] void addHitRegion(optional HitRegionOptions options);