From b47d7ff1136c84fca93c03b614aa6b5632700c36 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 16 Mar 2012 10:44:08 +0100 Subject: [PATCH] Bug 550309 - Part c: Implement ImageData; r=bz --- content/canvas/src/ImageData.cpp | 82 +++++++++++++++++++ content/canvas/src/ImageData.h | 77 +++++++++++++++++ content/canvas/src/Makefile.in | 7 ++ content/canvas/test/test_canvas.html | 44 ++-------- dom/base/nsDOMClassInfo.cpp | 6 ++ dom/base/nsDOMClassInfoClasses.h | 1 + .../canvas/nsIDOMCanvasRenderingContext2D.idl | 8 ++ js/xpconnect/src/dom_quickstubs.qsconf | 18 ++++ 8 files changed, 205 insertions(+), 38 deletions(-) create mode 100644 content/canvas/src/ImageData.cpp create mode 100644 content/canvas/src/ImageData.h diff --git a/content/canvas/src/ImageData.cpp b/content/canvas/src/ImageData.cpp new file mode 100644 index 000000000000..69ed5367d3d3 --- /dev/null +++ b/content/canvas/src/ImageData.cpp @@ -0,0 +1,82 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 et tw=78: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/dom/ImageData.h" + +#include "nsDOMClassInfoID.h" +#include "nsContentUtils.h" + +#include "jsapi.h" + +DOMCI_DATA(ImageData, mozilla::dom::ImageData) + +namespace mozilla { +namespace dom { + +NS_IMPL_CYCLE_COLLECTING_ADDREF(ImageData) +NS_IMPL_CYCLE_COLLECTING_RELEASE(ImageData) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ImageData) + NS_INTERFACE_MAP_ENTRY(nsIDOMImageData) + NS_INTERFACE_MAP_ENTRY(nsISupports) + NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(ImageData) +NS_INTERFACE_MAP_END + +NS_IMPL_CYCLE_COLLECTION_CLASS(ImageData) + +NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ImageData) + NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(tmp->mData, "mData") +NS_IMPL_CYCLE_COLLECTION_TRACE_END + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ImageData) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ImageData) + tmp->DropData(); +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +/* readonly attribute unsigned long width; */ +NS_IMETHODIMP +ImageData::GetWidth(PRUint32* aWidth) +{ + *aWidth = GetWidth(); + return NS_OK; +} + +/* readonly attribute unsigned long height; */ +NS_IMETHODIMP +ImageData::GetHeight(PRUint32* aHeight) +{ + *aHeight = GetHeight(); + return NS_OK; +} + +/* readonly attribute jsval data; */ +NS_IMETHODIMP +ImageData::GetData(JS::Value* aData) +{ + *aData = GetData(); + return NS_OK; +} + +void +ImageData::HoldData() +{ + NS_HOLD_JS_OBJECTS(this, ImageData); +} + +void +ImageData::DropData() +{ + if (mData) { + NS_DROP_JS_OBJECTS(this, ImageData); + mData = NULL; + } +} + +} // namespace dom +} // namespace mozilla diff --git a/content/canvas/src/ImageData.h b/content/canvas/src/ImageData.h new file mode 100644 index 000000000000..c31372b56b07 --- /dev/null +++ b/content/canvas/src/ImageData.h @@ -0,0 +1,77 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 et tw=78: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_ImageData_h +#define mozilla_dom_ImageData_h + +#include "nsIDOMCanvasRenderingContext2D.h" + +#include "mozilla/Attributes.h" +#include "mozilla/StandardInteger.h" + +#include "nsCycleCollectionParticipant.h" +#include "nsTraceRefcnt.h" +#include "xpcpublic.h" + +#include "jsapi.h" + +namespace mozilla { +namespace dom { + +class ImageData MOZ_FINAL : public nsIDOMImageData +{ +public: + ImageData(uint32_t aWidth, uint32_t aHeight, JSObject& aData) + : mWidth(aWidth) + , mHeight(aHeight) + , mData(&aData) + { + MOZ_COUNT_CTOR(ImageData); + HoldData(); + } + + ~ImageData() + { + MOZ_COUNT_DTOR(ImageData); + DropData(); + } + + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_NSIDOMIMAGEDATA + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ImageData) + + uint32_t GetWidth() + { + return mWidth; + } + uint32_t GetHeight() + { + return mHeight; + } + JS::Value GetData() + { + return JS::ObjectOrNullValue(GetDataObject()); + } + JSObject* GetDataObject() + { + xpc_UnmarkGrayObject(mData); + return mData; + } + +private: + void HoldData(); + void DropData(); + + ImageData() MOZ_DELETE; + + uint32_t mWidth, mHeight; + JSObject* mData; +}; + +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_ImageData_h diff --git a/content/canvas/src/Makefile.in b/content/canvas/src/Makefile.in index 97388e6c53d2..f34cb6805308 100644 --- a/content/canvas/src/Makefile.in +++ b/content/canvas/src/Makefile.in @@ -54,6 +54,12 @@ EXPORTS = \ CustomQS_WebGL.h \ $(NULL) +EXPORTS_NAMESPACES = mozilla/dom + +EXPORTS_mozilla/dom = \ + ImageData.h \ + $(NULL) + CPPSRCS = \ CanvasImageCache.cpp \ CanvasUtils.cpp \ @@ -61,6 +67,7 @@ CPPSRCS = \ nsCanvasRenderingContext2DAzure.cpp \ DocumentRendererParent.cpp \ DocumentRendererChild.cpp \ + ImageData.cpp \ $(NULL) ifdef MOZ_WEBGL diff --git a/content/canvas/test/test_canvas.html b/content/canvas/test/test_canvas.html index 45eb618aed51..a3e7440dc45c 100644 --- a/content/canvas/test/test_canvas.html +++ b/content/canvas/test/test_canvas.html @@ -7600,22 +7600,14 @@ function test_2d_imageData_create_type() { var canvas = document.getElementById('c261'); var ctx = canvas.getContext('2d'); -var _thrown_outer = false; -try { - -todo(window.ImageData !== undefined, "window.ImageData !== undefined"); +ok(window.ImageData !== undefined, "window.ImageData !== undefined"); ok(window.Uint8ClampedArray !== undefined, "window.Uint8ClampedArray !== undefined"); window.ImageData.prototype.thisImplementsImageData = true; window.Uint8ClampedArray.prototype.thisImplementsUint8ClampedArray = true; var imgdata = ctx.createImageData(1, 1); -ok(imgdata.thisImplementsImageData, "imgdata.thisImplementsImageData"); +todo(imgdata.thisImplementsImageData, "imgdata.thisImplementsImageData"); ok(imgdata.data.thisImplementsUint8ClampedArray, "imgdata.data.thisImplementsUint8ClampedArray"); -} catch (e) { - _thrown_outer = true; -} -todo(!_thrown_outer, ctx.canvas.id + ' should not throw exception'); - } @@ -7632,10 +7624,7 @@ function test_2d_imageData_create1_type() { var canvas = document.getElementById('c261a'); var ctx = canvas.getContext('2d'); -var _thrown_outer = false; -try { - -todo(window.ImageData !== undefined, "window.ImageData !== undefined"); +ok(window.ImageData !== undefined, "window.ImageData !== undefined"); ok(window.Uint8ClampedArray !== undefined, "window.Uint8ClampedArray !== undefined"); window.ImageData.prototype.thisImplementsImageData = true; window.Uint8ClampedArray.prototype.thisImplementsUint8ClampedArray = true; @@ -7643,11 +7632,6 @@ var imgdata = ctx.createImageData(ctx.createImageData(1, 1)); todo(imgdata.thisImplementsImageData, "imgdata.thisImplementsImageData"); ok(imgdata.data.thisImplementsUint8ClampedArray, "imgdata.data.thisImplementsUint8ClampedArray"); -} catch (e) { - _thrown_outer = true; -} -todo(!_thrown_outer, ctx.canvas.id + ' should not throw exception'); - } @@ -8058,9 +8042,6 @@ function test_2d_imageData_get_source_negative() { var canvas = document.getElementById('c272'); var ctx = canvas.getContext('2d'); -var _thrown_outer = false; -try { - ctx.fillStyle = '#000'; ctx.fillRect(0, 0, 100, 50); ctx.fillStyle = '#fff'; @@ -8082,11 +8063,6 @@ ok(imgdata2.data[1] === 0, "imgdata2.data[\""+(1)+"\"] === 0"); ok(imgdata2.data[2] === 0, "imgdata2.data[\""+(2)+"\"] === 0"); ok(imgdata2.data[3] === 0, "imgdata2.data[\""+(3)+"\"] === 0"); -} catch (e) { - _thrown_outer = true; -} -ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception'); - } @@ -8238,22 +8214,14 @@ function test_2d_imageData_get_type() { var canvas = document.getElementById('c276'); var ctx = canvas.getContext('2d'); -var _thrown_outer = false; -try { - -todo(window.ImageData !== undefined, "window.ImageData !== undefined"); +ok(window.ImageData !== undefined, "window.ImageData !== undefined"); ok(window.Uint8ClampedArray !== undefined, "window.Uint8ClampedArray !== undefined"); window.ImageData.prototype.thisImplementsImageData = true; window.Uint8ClampedArray.prototype.thisImplementsUint8ClampedArray = true; var imgdata = ctx.getImageData(0, 0, 1, 1); -ok(imgdata.thisImplementsImageData, "imgdata.thisImplementsImageData"); +todo(imgdata.thisImplementsImageData, "imgdata.thisImplementsImageData"); ok(imgdata.data.thisImplementsUint8ClampedArray, "imgdata.data.thisImplementsUint8ClampedArray"); -} catch (e) { - _thrown_outer = true; -} -todo(!_thrown_outer, ctx.canvas.id + ' should not throw exception'); - } @@ -8376,7 +8344,7 @@ function test_2d_imageData_object_ctor() { var canvas = document.getElementById('c280'); var ctx = canvas.getContext('2d'); -todo(window.ImageData !== undefined, "window.ImageData !== undefined"); +ok(window.ImageData !== undefined, "window.ImageData !== undefined"); try { var _thrown = false; new window.ImageData(1,1); } catch (e) { _thrown = true; } finally { ok(_thrown, "should throw exception"); } diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index 845f556b5815..e718cd6abd3e 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -1302,6 +1302,8 @@ static nsDOMClassInfoData sClassInfoData[] = { DOM_DEFAULT_SCRIPTABLE_FLAGS) NS_DEFINE_CLASSINFO_DATA(TextMetrics, nsDOMGenericSH, DOM_DEFAULT_SCRIPTABLE_FLAGS) + NS_DEFINE_CLASSINFO_DATA(ImageData, nsDOMGenericSH, + DOM_DEFAULT_SCRIPTABLE_FLAGS) NS_DEFINE_CLASSINFO_DATA(SmartCardEvent, nsDOMGenericSH, DOM_DEFAULT_SCRIPTABLE_FLAGS) @@ -3851,6 +3853,10 @@ nsDOMClassInfo::Init() DOM_CLASSINFO_MAP_ENTRY(nsIDOMTextMetrics) DOM_CLASSINFO_MAP_END + DOM_CLASSINFO_MAP_BEGIN(ImageData, nsIDOMImageData) + DOM_CLASSINFO_MAP_ENTRY(nsIDOMImageData) + DOM_CLASSINFO_MAP_END + DOM_CLASSINFO_MAP_BEGIN(XSLTProcessor, nsIXSLTProcessor) DOM_CLASSINFO_MAP_ENTRY(nsIXSLTProcessor) DOM_CLASSINFO_MAP_ENTRY(nsIXSLTProcessorPrivate) diff --git a/dom/base/nsDOMClassInfoClasses.h b/dom/base/nsDOMClassInfoClasses.h index 311edab11809..da29bb7aca9b 100644 --- a/dom/base/nsDOMClassInfoClasses.h +++ b/dom/base/nsDOMClassInfoClasses.h @@ -350,6 +350,7 @@ DOMCI_CLASS(CanvasRenderingContext2D) DOMCI_CLASS(CanvasGradient) DOMCI_CLASS(CanvasPattern) DOMCI_CLASS(TextMetrics) +DOMCI_CLASS(ImageData) // SmartCard Events DOMCI_CLASS(SmartCardEvent) diff --git a/dom/interfaces/canvas/nsIDOMCanvasRenderingContext2D.idl b/dom/interfaces/canvas/nsIDOMCanvasRenderingContext2D.idl index 4e444de5bcb0..6391d46ae792 100644 --- a/dom/interfaces/canvas/nsIDOMCanvasRenderingContext2D.idl +++ b/dom/interfaces/canvas/nsIDOMCanvasRenderingContext2D.idl @@ -62,6 +62,14 @@ interface nsIDOMTextMetrics : nsISupports readonly attribute float width; }; +[scriptable, builtinclass, uuid(1ea11207-b3e3-4ffc-a256-bf5c7011e806)] +interface nsIDOMImageData : nsISupports +{ + readonly attribute unsigned long width; + readonly attribute unsigned long height; + readonly attribute jsval data; +}; + [scriptable, uuid(274213a8-df51-4b52-bfad-d306a1d5f642)] interface nsIDOMCanvasRenderingContext2D : nsISupports { diff --git a/js/xpconnect/src/dom_quickstubs.qsconf b/js/xpconnect/src/dom_quickstubs.qsconf index 24dbeeab7047..1ff39d308770 100644 --- a/js/xpconnect/src/dom_quickstubs.qsconf +++ b/js/xpconnect/src/dom_quickstubs.qsconf @@ -97,6 +97,7 @@ members = [ 'nsIDOMTextMetrics.*', 'nsIDOMCanvasGradient.*', 'nsIDOMCanvasPattern.*', + 'nsIDOMImageData.*', # dom/interfaces/core 'nsIDOMCharacterData.data', @@ -484,6 +485,7 @@ irregularFilenames = { 'nsIDOMTextMetrics': 'nsIDOMCanvasRenderingContext2D', 'nsIDOMCanvasGradient': 'nsIDOMCanvasRenderingContext2D', 'nsIDOMCanvasPattern': 'nsIDOMCanvasRenderingContext2D', + 'nsIDOMImageData': 'nsIDOMCanvasRenderingContext2D', 'nsIDOMBlob': 'nsIDOMFile', @@ -524,6 +526,7 @@ customIncludes = [ 'nsSVGStylableElement.h', 'nsHTMLDocument.h', 'nsDOMQS.h', + 'mozilla/dom/ImageData.h' ] customQuickStubs = [ @@ -534,6 +537,7 @@ customQuickStubs = [ customReturnInterfaces = [ 'nsIDOMCanvasPattern', 'nsIDOMCanvasGradient', + 'nsIDOMImageData' ] nsIDOMNode_GetChildNodes_customMethodCallCode = """ @@ -1003,5 +1007,19 @@ customMethodCalls = { # Nasty hack to make the ordering of |arc| and |arcTo| correct. # |arc| is not traceable because it has an optional argument. 'nsIDOMCanvasRenderingContext2D_ArcTo' : { 'traceable' : False }, + + 'nsIDOMImageData_GetWidth': { + 'thisType': 'nsIDOMImageData', + 'code': 'uint32_t result = static_cast(self)->GetWidth();', + 'canFail': False + }, + 'nsIDOMImageData_GetHeight': { + 'thisType': 'nsIDOMImageData', + 'code': 'uint32_t result = static_cast(self)->GetHeight();', + 'canFail': False + }, + 'nsIDOMImageData_GetData': { + 'canFail': False + } }