зеркало из https://github.com/mozilla/gecko-dev.git
b=534467; implement Uint8ClampedArray for CanvasPixelArray; part 3, DOM-side implementation; r=bz
This commit is contained in:
Родитель
85abed396c
Коммит
90b432f3ea
|
@ -1,5 +1,6 @@
|
||||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
/* ***** BEGIN LICENSE BLOCK *****
|
*
|
||||||
|
* ***** BEGIN LICENSE BLOCK *****
|
||||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
*
|
*
|
||||||
* The contents of this file are subject to the Mozilla Public License Version
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
@ -12,10 +13,10 @@
|
||||||
* for the specific language governing rights and limitations under the
|
* for the specific language governing rights and limitations under the
|
||||||
* License.
|
* License.
|
||||||
*
|
*
|
||||||
* The Original Code is mozilla.org code.
|
* The Original Code is Gecko code.
|
||||||
*
|
*
|
||||||
* The Initial Developer of the Original Code is
|
* The Initial Developer of the Original Code is
|
||||||
* Mozilla Corporation.
|
* Mozilla Corporation
|
||||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||||
* the Initial Developer. All Rights Reserved.
|
* the Initial Developer. All Rights Reserved.
|
||||||
*
|
*
|
||||||
|
@ -23,8 +24,8 @@
|
||||||
* Vladimir Vukicevic <vladimir@pobox.com> (original author)
|
* Vladimir Vukicevic <vladimir@pobox.com> (original author)
|
||||||
*
|
*
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
* of those above. If you wish to allow use of your version of this file only
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
@ -36,6 +37,7 @@
|
||||||
*
|
*
|
||||||
* ***** END LICENSE BLOCK ***** */
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#include "nsDOMError.h"
|
||||||
#include "nsIDOMCanvasRenderingContext2D.h"
|
#include "nsIDOMCanvasRenderingContext2D.h"
|
||||||
|
|
||||||
typedef nsresult (NS_STDCALL nsIDOMCanvasRenderingContext2D::*CanvasStyleSetterType)(const nsAString &, nsISupports *);
|
typedef nsresult (NS_STDCALL nsIDOMCanvasRenderingContext2D::*CanvasStyleSetterType)(const nsAString &, nsISupports *);
|
||||||
|
@ -142,3 +144,216 @@ nsIDOMCanvasRenderingContext2D_GetFillStyle(JSContext *cx, JSObject *obj, jsval
|
||||||
{
|
{
|
||||||
return Canvas2D_GetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::GetFillStyle_multi);
|
return Canvas2D_GetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::GetFillStyle_multi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static JSBool
|
||||||
|
nsIDOMCanvasRenderingContext2D_CreateImageData(JSContext *cx, uintN argc, jsval *vp)
|
||||||
|
{
|
||||||
|
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
||||||
|
|
||||||
|
/* Note: this doesn't need JS_THIS_OBJECT */
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
|
||||||
|
|
||||||
|
jsval *argv = JS_ARGV(cx, vp);
|
||||||
|
|
||||||
|
int32 wi, hi;
|
||||||
|
if (!JS_ValueToECMAInt32(cx, argv[0], &wi) ||
|
||||||
|
!JS_ValueToECMAInt32(cx, argv[1], &hi))
|
||||||
|
return JS_FALSE;
|
||||||
|
|
||||||
|
if (wi <= 0 || hi <= 0)
|
||||||
|
return xpc_qsThrow(cx, NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||||
|
|
||||||
|
uint32 w = (uint32) wi;
|
||||||
|
uint32 h = (uint32) hi;
|
||||||
|
|
||||||
|
/* Sanity check w * h here */
|
||||||
|
uint32 len0 = w * h;
|
||||||
|
if (len0 / w != (uint32) h)
|
||||||
|
return xpc_qsThrow(cx, NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||||
|
|
||||||
|
uint32 len = len0 * 4;
|
||||||
|
if (len / 4 != len0)
|
||||||
|
return xpc_qsThrow(cx, NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||||
|
|
||||||
|
// create the fast typed array; it's initialized to 0 by default
|
||||||
|
JSObject *darray = js_CreateTypedArray(cx, js::TypedArray::TYPE_UINT8_CLAMPED, len);
|
||||||
|
JSAutoTempValueRooter rd(cx, darray);
|
||||||
|
if (!darray)
|
||||||
|
return JS_FALSE;
|
||||||
|
|
||||||
|
// Do JS_NewObject after CreateTypedArray, so that gc will get
|
||||||
|
// triggered here if necessary
|
||||||
|
JSObject *result = JS_NewObject(cx, NULL, NULL, NULL);
|
||||||
|
JSAutoTempValueRooter rr(cx, result);
|
||||||
|
if (!result)
|
||||||
|
return JS_FALSE;
|
||||||
|
|
||||||
|
if (!JS_DefineProperty(cx, result, "width", INT_TO_JSVAL(w), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT) ||
|
||||||
|
!JS_DefineProperty(cx, result, "height", INT_TO_JSVAL(h), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT) ||
|
||||||
|
!JS_DefineProperty(cx, result, "data", OBJECT_TO_JSVAL(darray), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT))
|
||||||
|
return JS_FALSE;
|
||||||
|
|
||||||
|
*vp = OBJECT_TO_JSVAL(result);
|
||||||
|
return JS_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSBool
|
||||||
|
nsIDOMCanvasRenderingContext2D_GetImageData(JSContext *cx, uintN argc, jsval *vp)
|
||||||
|
{
|
||||||
|
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
||||||
|
|
||||||
|
JSObject *obj = JS_THIS_OBJECT(cx, vp);
|
||||||
|
if (!obj)
|
||||||
|
return JS_FALSE;
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
nsIDOMCanvasRenderingContext2D *self;
|
||||||
|
xpc_qsSelfRef selfref;
|
||||||
|
JSAutoTempValueRooter tvr(cx);
|
||||||
|
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull))
|
||||||
|
return JS_FALSE;
|
||||||
|
|
||||||
|
if (argc < 4)
|
||||||
|
return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
|
||||||
|
|
||||||
|
jsval *argv = JS_ARGV(cx, vp);
|
||||||
|
|
||||||
|
int32 x, y;
|
||||||
|
int32 wi, hi;
|
||||||
|
if (!JS_ValueToECMAInt32(cx, argv[0], &x) ||
|
||||||
|
!JS_ValueToECMAInt32(cx, argv[1], &y) ||
|
||||||
|
!JS_ValueToECMAInt32(cx, argv[2], &wi) ||
|
||||||
|
!JS_ValueToECMAInt32(cx, argv[3], &hi))
|
||||||
|
return JS_FALSE;
|
||||||
|
|
||||||
|
if (wi <= 0 || hi <= 0)
|
||||||
|
return xpc_qsThrow(cx, NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||||
|
|
||||||
|
uint32 w = (uint32) wi;
|
||||||
|
uint32 h = (uint32) hi;
|
||||||
|
|
||||||
|
// Sanity check w * h here
|
||||||
|
uint32 len0 = w * h;
|
||||||
|
if (len0 / w != (uint32) h)
|
||||||
|
return xpc_qsThrow(cx, NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||||
|
|
||||||
|
uint32 len = len0 * 4;
|
||||||
|
if (len / 4 != len0)
|
||||||
|
return xpc_qsThrow(cx, NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||||
|
|
||||||
|
// create the fast typed array
|
||||||
|
JSObject *darray = js_CreateTypedArray(cx, js::TypedArray::TYPE_UINT8_CLAMPED, len);
|
||||||
|
JSAutoTempValueRooter rd(cx, darray);
|
||||||
|
if (!darray)
|
||||||
|
return JS_FALSE;
|
||||||
|
|
||||||
|
js::TypedArray *tdest = js::TypedArray::fromJSObject(darray);
|
||||||
|
|
||||||
|
// make the call
|
||||||
|
rv = self->GetImageData_explicit(x, y, w, h, (PRUint8*) tdest->data, tdest->byteLength);
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
return xpc_qsThrowMethodFailed(cx, rv, vp);
|
||||||
|
|
||||||
|
// Do JS_NewObject after CreateTypedArray, so that gc will get
|
||||||
|
// triggered here if necessary
|
||||||
|
JSObject *result = JS_NewObject(cx, NULL, NULL, NULL);
|
||||||
|
JSAutoTempValueRooter rr(cx, result);
|
||||||
|
if (!result)
|
||||||
|
return JS_FALSE;
|
||||||
|
|
||||||
|
if (!JS_DefineProperty(cx, result, "width", INT_TO_JSVAL(w), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT) ||
|
||||||
|
!JS_DefineProperty(cx, result, "height", INT_TO_JSVAL(h), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT) ||
|
||||||
|
!JS_DefineProperty(cx, result, "data", OBJECT_TO_JSVAL(darray), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT))
|
||||||
|
return JS_FALSE;
|
||||||
|
|
||||||
|
*vp = OBJECT_TO_JSVAL(result);
|
||||||
|
return JS_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSBool
|
||||||
|
nsIDOMCanvasRenderingContext2D_PutImageData(JSContext *cx, uintN argc, jsval *vp)
|
||||||
|
{
|
||||||
|
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
||||||
|
|
||||||
|
JSObject *obj = JS_THIS_OBJECT(cx, vp);
|
||||||
|
if (!obj)
|
||||||
|
return JS_FALSE;
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
nsIDOMCanvasRenderingContext2D *self;
|
||||||
|
xpc_qsSelfRef selfref;
|
||||||
|
JSAutoTempValueRooter tvr(cx);
|
||||||
|
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.addr(), nsnull))
|
||||||
|
return JS_FALSE;
|
||||||
|
|
||||||
|
if (argc < 3)
|
||||||
|
return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
|
||||||
|
|
||||||
|
jsval *argv = JS_ARGV(cx, vp);
|
||||||
|
|
||||||
|
if (JSVAL_IS_PRIMITIVE(argv[0]))
|
||||||
|
return xpc_qsThrow(cx, NS_ERROR_DOM_TYPE_MISMATCH_ERR);
|
||||||
|
|
||||||
|
JSObject *dataObject = JSVAL_TO_OBJECT(argv[0]);
|
||||||
|
int32 x, y;
|
||||||
|
if (!JS_ValueToECMAInt32(cx, argv[1], &x) ||
|
||||||
|
!JS_ValueToECMAInt32(cx, argv[2], &y))
|
||||||
|
return JS_FALSE;
|
||||||
|
|
||||||
|
int32 wi, hi;
|
||||||
|
JSObject *darray;
|
||||||
|
|
||||||
|
// grab width, height, and the dense array from the dataObject
|
||||||
|
JSAutoTempValueRooter tv(cx);
|
||||||
|
|
||||||
|
if (!JS_GetProperty(cx, dataObject, "width", tv.addr()) ||
|
||||||
|
!JS_ValueToECMAInt32(cx, tv.value(), &wi))
|
||||||
|
return JS_FALSE;
|
||||||
|
|
||||||
|
if (!JS_GetProperty(cx, dataObject, "height", tv.addr()) ||
|
||||||
|
!JS_ValueToECMAInt32(cx, tv.value(), &hi))
|
||||||
|
return JS_FALSE;
|
||||||
|
|
||||||
|
if (wi <= 0 || hi <= 0)
|
||||||
|
return xpc_qsThrow(cx, NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||||
|
|
||||||
|
uint32 w = (uint32) wi;
|
||||||
|
uint32 h = (uint32) hi;
|
||||||
|
|
||||||
|
if (!JS_GetProperty(cx, dataObject, "data", tv.addr()) ||
|
||||||
|
JSVAL_IS_PRIMITIVE(tv.value()))
|
||||||
|
return JS_FALSE;
|
||||||
|
darray = JSVAL_TO_OBJECT(tv.value());
|
||||||
|
|
||||||
|
JSAutoTempValueRooter tsrc_tvr(cx);
|
||||||
|
|
||||||
|
js::TypedArray *tsrc = NULL;
|
||||||
|
if (darray->getClass() == &js::TypedArray::fastClasses[js::TypedArray::TYPE_UINT8] ||
|
||||||
|
darray->getClass() == &js::TypedArray::fastClasses[js::TypedArray::TYPE_UINT8_CLAMPED])
|
||||||
|
{
|
||||||
|
tsrc = js::TypedArray::fromJSObject(darray);
|
||||||
|
} else if (JS_IsArrayObject(cx, darray) || js_IsTypedArray(darray)) {
|
||||||
|
// ugh, this isn't a uint8 typed array, someone made their own object; convert it to a typed array
|
||||||
|
JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_UINT8, darray);
|
||||||
|
if (!nobj)
|
||||||
|
return JS_FALSE;
|
||||||
|
|
||||||
|
*tsrc_tvr.addr() = OBJECT_TO_JSVAL(nobj);
|
||||||
|
tsrc = js::TypedArray::fromJSObject(nobj);
|
||||||
|
} else {
|
||||||
|
// yeah, no.
|
||||||
|
return xpc_qsThrow(cx, NS_ERROR_DOM_TYPE_MISMATCH_ERR);
|
||||||
|
}
|
||||||
|
|
||||||
|
// make the call
|
||||||
|
rv = self->PutImageData_explicit(x, y, w, h, (PRUint8*) tsrc->data, tsrc->byteLength);
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
return xpc_qsThrowMethodFailed(cx, rv, vp);
|
||||||
|
|
||||||
|
*vp = JSVAL_VOID;
|
||||||
|
return JS_TRUE;
|
||||||
|
}
|
||||||
|
|
|
@ -3426,9 +3426,16 @@ nsCanvasRenderingContext2D::EnsureUnpremultiplyTable() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ImageData getImageData (in float x, in float y, in float width, in float height);
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsCanvasRenderingContext2D::GetImageData()
|
nsCanvasRenderingContext2D::GetImageData()
|
||||||
|
{
|
||||||
|
/* Should never be called -- GetImageData_explicit is the QS entry point */
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsCanvasRenderingContext2D::GetImageData_explicit(PRInt32 x, PRInt32 y, PRUint32 w, PRUint32 h,
|
||||||
|
PRUint8 *aData, PRUint32 aDataLen)
|
||||||
{
|
{
|
||||||
if (!mValid)
|
if (!mValid)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
@ -3438,42 +3445,15 @@ nsCanvasRenderingContext2D::GetImageData()
|
||||||
return NS_ERROR_DOM_SECURITY_ERR;
|
return NS_ERROR_DOM_SECURITY_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsAXPCNativeCallContext *ncc = nsnull;
|
|
||||||
nsresult rv = nsContentUtils::XPConnect()->
|
|
||||||
GetCurrentNativeCallContext(&ncc);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (!ncc)
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
JSContext *ctx = nsnull;
|
|
||||||
|
|
||||||
rv = ncc->GetJSContext(&ctx);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
PRUint32 argc;
|
|
||||||
jsval *argv = nsnull;
|
|
||||||
|
|
||||||
ncc->GetArgc(&argc);
|
|
||||||
ncc->GetArgvPtr(&argv);
|
|
||||||
|
|
||||||
JSAutoRequest ar(ctx);
|
|
||||||
|
|
||||||
int32 x, y, w, h;
|
|
||||||
if (!JS_ConvertArguments (ctx, argc, argv, "jjjj", &x, &y, &w, &h))
|
|
||||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
|
||||||
|
|
||||||
if (!CanvasUtils::CheckSaneSubrectSize (x, y, w, h, mWidth, mHeight))
|
if (!CanvasUtils::CheckSaneSubrectSize (x, y, w, h, mWidth, mHeight))
|
||||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||||
|
|
||||||
nsAutoArrayPtr<PRUint8> surfaceData (new (std::nothrow) PRUint8[w * h * 4]);
|
PRUint32 len = w * h * 4;
|
||||||
int surfaceDataStride = w*4;
|
if (aDataLen != len)
|
||||||
int surfaceDataOffset = 0;
|
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||||
|
|
||||||
if (!surfaceData)
|
/* Copy the surface contents to the buffer */
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
nsRefPtr<gfxImageSurface> tmpsurf = new gfxImageSurface(aData,
|
||||||
|
|
||||||
nsRefPtr<gfxImageSurface> tmpsurf = new gfxImageSurface(surfaceData,
|
|
||||||
gfxIntSize(w, h),
|
gfxIntSize(w, h),
|
||||||
w * 4,
|
w * 4,
|
||||||
gfxASurface::ImageFormatARGB32);
|
gfxASurface::ImageFormatARGB32);
|
||||||
|
@ -3489,99 +3469,39 @@ nsCanvasRenderingContext2D::GetImageData()
|
||||||
tmpctx->SetSource(mSurface, gfxPoint(-(int)x, -(int)y));
|
tmpctx->SetSource(mSurface, gfxPoint(-(int)x, -(int)y));
|
||||||
tmpctx->Paint();
|
tmpctx->Paint();
|
||||||
|
|
||||||
tmpctx = nsnull;
|
// make sure sUnpremultiplyTable has been created
|
||||||
tmpsurf = nsnull;
|
|
||||||
|
|
||||||
PRUint32 len = w * h * 4;
|
|
||||||
if (len > (((PRUint32)0xfff00000)/sizeof(jsval)))
|
|
||||||
return NS_ERROR_INVALID_ARG;
|
|
||||||
|
|
||||||
jsval *dest;
|
|
||||||
JSObject *dataArray = js_NewArrayObjectWithCapacity(ctx, len, &dest);
|
|
||||||
if (!dataArray)
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
nsAutoGCRoot arrayGCRoot(&dataArray, &rv);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
EnsureUnpremultiplyTable();
|
EnsureUnpremultiplyTable();
|
||||||
|
|
||||||
PRUint8 *row;
|
// NOTE! dst is the same as src, and this relies on reading
|
||||||
|
// from src and advancing that ptr before writing to dst.
|
||||||
|
PRUint8 *src = aData;
|
||||||
|
PRUint8 *dst = aData;
|
||||||
|
|
||||||
for (int j = 0; j < h; j++) {
|
for (int j = 0; j < h; j++) {
|
||||||
row = surfaceData + surfaceDataOffset + (surfaceDataStride * j);
|
|
||||||
for (int i = 0; i < w; i++) {
|
for (int i = 0; i < w; i++) {
|
||||||
|
// XXX Is there some useful swizzle MMX we can use here?
|
||||||
#ifdef IS_LITTLE_ENDIAN
|
#ifdef IS_LITTLE_ENDIAN
|
||||||
PRUint8 b = *row++;
|
PRUint8 b = *src++;
|
||||||
PRUint8 g = *row++;
|
PRUint8 g = *src++;
|
||||||
PRUint8 r = *row++;
|
PRUint8 r = *src++;
|
||||||
PRUint8 a = *row++;
|
PRUint8 a = *src++;
|
||||||
#else
|
#else
|
||||||
PRUint8 a = *row++;
|
PRUint8 a = *src++;
|
||||||
PRUint8 r = *row++;
|
PRUint8 r = *src++;
|
||||||
PRUint8 g = *row++;
|
PRUint8 g = *src++;
|
||||||
PRUint8 b = *row++;
|
PRUint8 b = *src++;
|
||||||
#endif
|
#endif
|
||||||
// Convert to non-premultiplied color
|
// Convert to non-premultiplied color
|
||||||
|
*dst++ = sUnpremultiplyTable[a][r];
|
||||||
*dest++ = INT_TO_JSVAL(sUnpremultiplyTable[a][r]);
|
*dst++ = sUnpremultiplyTable[a][g];
|
||||||
*dest++ = INT_TO_JSVAL(sUnpremultiplyTable[a][g]);
|
*dst++ = sUnpremultiplyTable[a][b];
|
||||||
*dest++ = INT_TO_JSVAL(sUnpremultiplyTable[a][b]);
|
*dst++ = a;
|
||||||
*dest++ = INT_TO_JSVAL(a);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate result object after array, so if we have to trigger gc
|
|
||||||
// we do it now.
|
|
||||||
JSObject *result = JS_NewObject(ctx, NULL, NULL, NULL);
|
|
||||||
if (!result)
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
nsAutoGCRoot resultGCRoot(&result, &rv);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (!JS_DefineProperty(ctx, result, "width", INT_TO_JSVAL(w), NULL, NULL, 0) ||
|
|
||||||
!JS_DefineProperty(ctx, result, "height", INT_TO_JSVAL(h), NULL, NULL, 0) ||
|
|
||||||
!JS_DefineProperty(ctx, result, "data", OBJECT_TO_JSVAL(dataArray), NULL, NULL, 0))
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
jsval *retvalPtr;
|
|
||||||
ncc->GetRetValPtr(&retvalPtr);
|
|
||||||
*retvalPtr = OBJECT_TO_JSVAL(result);
|
|
||||||
ncc->SetReturnValueWasSet(PR_TRUE);
|
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline PRUint8 ToUint8(jsint aInput)
|
|
||||||
{
|
|
||||||
if (PRUint32(aInput) > 255)
|
|
||||||
return (aInput < 0) ? 0 : 255;
|
|
||||||
return PRUint8(aInput);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline PRUint8 ToUint8(double aInput)
|
|
||||||
{
|
|
||||||
if (!(aInput >= 0)) /* Not < so that NaN coerces to 0 */
|
|
||||||
return 0;
|
|
||||||
if (aInput > 255)
|
|
||||||
return 255;
|
|
||||||
double toTruncate = aInput + 0.5;
|
|
||||||
PRUint8 retval = PRUint8(toTruncate);
|
|
||||||
|
|
||||||
// now retval is rounded to nearest, ties rounded up. We want
|
|
||||||
// rounded to nearest ties to even, so check whether we had a tie.
|
|
||||||
if (retval == toTruncate) {
|
|
||||||
// It was a tie (since adding 0.5 gave us the exact integer we want).
|
|
||||||
// Since we rounded up, we either already have an even number or we
|
|
||||||
// have an odd number but the number we want is one less. So just
|
|
||||||
// unconditionally masking out the ones bit should do the trick to get
|
|
||||||
// us the value we want.
|
|
||||||
return (retval & ~1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nsCanvasRenderingContext2D::EnsurePremultiplyTable() {
|
nsCanvasRenderingContext2D::EnsurePremultiplyTable() {
|
||||||
if (sPremultiplyTable)
|
if (sPremultiplyTable)
|
||||||
|
@ -3604,163 +3524,60 @@ nsCanvasRenderingContext2D::EnsurePremultiplyTable() {
|
||||||
// void putImageData (in ImageData d, in float x, in float y);
|
// void putImageData (in ImageData d, in float x, in float y);
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsCanvasRenderingContext2D::PutImageData()
|
nsCanvasRenderingContext2D::PutImageData()
|
||||||
|
{
|
||||||
|
/* Should never be called -- PutImageData_explicit is the QS entry point */
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsCanvasRenderingContext2D::PutImageData_explicit(PRInt32 x, PRInt32 y, PRUint32 w, PRUint32 h,
|
||||||
|
unsigned char *aData, PRUint32 aDataLen)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
if (!mValid)
|
if (!mValid)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
nsAXPCNativeCallContext *ncc = nsnull;
|
|
||||||
rv = nsContentUtils::XPConnect()->
|
|
||||||
GetCurrentNativeCallContext(&ncc);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (!ncc)
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
JSContext *ctx = nsnull;
|
|
||||||
|
|
||||||
rv = ncc->GetJSContext(&ctx);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
PRUint32 argc;
|
|
||||||
jsval *argv = nsnull;
|
|
||||||
|
|
||||||
ncc->GetArgc(&argc);
|
|
||||||
ncc->GetArgvPtr(&argv);
|
|
||||||
|
|
||||||
JSAutoRequest ar(ctx);
|
|
||||||
|
|
||||||
JSObject *dataObject;
|
|
||||||
int32 x, y;
|
|
||||||
|
|
||||||
if (!JS_ConvertArguments (ctx, argc, argv, "ojj", &dataObject, &x, &y))
|
|
||||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
|
||||||
|
|
||||||
if (!dataObject)
|
|
||||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
|
||||||
|
|
||||||
int32 w, h;
|
|
||||||
JSObject *dataArray;
|
|
||||||
jsval v;
|
|
||||||
|
|
||||||
if (!JS_GetProperty(ctx, dataObject, "width", &v) ||
|
|
||||||
!JS_ValueToInt32(ctx, v, &w))
|
|
||||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
|
||||||
|
|
||||||
if (!JS_GetProperty(ctx, dataObject, "height", &v) ||
|
|
||||||
!JS_ValueToInt32(ctx, v, &h))
|
|
||||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
|
||||||
|
|
||||||
if (!JS_GetProperty(ctx, dataObject, "data", &v) ||
|
|
||||||
!JSVAL_IS_OBJECT(v))
|
|
||||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
|
||||||
dataArray = JSVAL_TO_OBJECT(v);
|
|
||||||
|
|
||||||
if (!CanvasUtils::CheckSaneSubrectSize (x, y, w, h, mWidth, mHeight))
|
if (!CanvasUtils::CheckSaneSubrectSize (x, y, w, h, mWidth, mHeight))
|
||||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||||
|
|
||||||
jsuint arrayLen;
|
PRUint32 len = w * h * 4;
|
||||||
if (!JS_IsArrayObject(ctx, dataArray) ||
|
if (aDataLen != len)
|
||||||
!JS_GetArrayLength(ctx, dataArray, &arrayLen) ||
|
|
||||||
arrayLen < (jsuint)(w * h * 4))
|
|
||||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||||
|
|
||||||
nsAutoArrayPtr<PRUint8> imageBuffer(new (std::nothrow) PRUint8[w * h * 4]);
|
nsRefPtr<gfxImageSurface> imgsurf = new gfxImageSurface(gfxIntSize(w, h),
|
||||||
if (!imageBuffer)
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
PRUint8 *imgPtr = imageBuffer.get();
|
|
||||||
|
|
||||||
EnsurePremultiplyTable();
|
|
||||||
|
|
||||||
JSBool canFastPath =
|
|
||||||
js_CoerceArrayToCanvasImageData(dataArray, 0, w*h*4, imageBuffer);
|
|
||||||
|
|
||||||
// no fast path? go slow. We sadly need this for now, instead of just
|
|
||||||
// throwing, because dataArray might not be dense in case someone stuck
|
|
||||||
// their own array on the imageData.
|
|
||||||
// FIXME: it'd be awfully nice if we could prevent such modification of
|
|
||||||
// imageData objects, since it's likely the spec won't allow it anyway.
|
|
||||||
// Bug 497110 covers this.
|
|
||||||
if (!canFastPath) {
|
|
||||||
jsval vr, vg, vb, va;
|
|
||||||
PRUint8 ir, ig, ib, ia;
|
|
||||||
for (int32 j = 0; j < h; j++) {
|
|
||||||
int32 lineOffset = (j*w*4);
|
|
||||||
for (int32 i = 0; i < w; i++) {
|
|
||||||
int32 pixelOffset = lineOffset + i*4;
|
|
||||||
if (!JS_GetElement(ctx, dataArray, pixelOffset + 0, &vr) ||
|
|
||||||
!JS_GetElement(ctx, dataArray, pixelOffset + 1, &vg) ||
|
|
||||||
!JS_GetElement(ctx, dataArray, pixelOffset + 2, &vb) ||
|
|
||||||
!JS_GetElement(ctx, dataArray, pixelOffset + 3, &va))
|
|
||||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
|
||||||
|
|
||||||
if (JSVAL_IS_INT(vr)) ir = ToUint8(JSVAL_TO_INT(vr));
|
|
||||||
else if (JSVAL_IS_DOUBLE(vr)) ir = ToUint8(*JSVAL_TO_DOUBLE(vr));
|
|
||||||
else return NS_ERROR_DOM_SYNTAX_ERR;
|
|
||||||
|
|
||||||
if (JSVAL_IS_INT(vg)) ig = ToUint8(JSVAL_TO_INT(vg));
|
|
||||||
else if (JSVAL_IS_DOUBLE(vg)) ig = ToUint8(*JSVAL_TO_DOUBLE(vg));
|
|
||||||
else return NS_ERROR_DOM_SYNTAX_ERR;
|
|
||||||
|
|
||||||
if (JSVAL_IS_INT(vb)) ib = ToUint8(JSVAL_TO_INT(vb));
|
|
||||||
else if (JSVAL_IS_DOUBLE(vb)) ib = ToUint8(*JSVAL_TO_DOUBLE(vb));
|
|
||||||
else return NS_ERROR_DOM_SYNTAX_ERR;
|
|
||||||
|
|
||||||
if (JSVAL_IS_INT(va)) ia = ToUint8(JSVAL_TO_INT(va));
|
|
||||||
else if (JSVAL_IS_DOUBLE(va)) ia = ToUint8(*JSVAL_TO_DOUBLE(va));
|
|
||||||
else return NS_ERROR_DOM_SYNTAX_ERR;
|
|
||||||
|
|
||||||
// Convert to premultiplied color (losslessly if the input came from getImageData)
|
|
||||||
ir = sPremultiplyTable[ia][ir];
|
|
||||||
ig = sPremultiplyTable[ia][ig];
|
|
||||||
ib = sPremultiplyTable[ia][ib];
|
|
||||||
|
|
||||||
#ifdef IS_LITTLE_ENDIAN
|
|
||||||
*imgPtr++ = ib;
|
|
||||||
*imgPtr++ = ig;
|
|
||||||
*imgPtr++ = ir;
|
|
||||||
*imgPtr++ = ia;
|
|
||||||
#else
|
|
||||||
*imgPtr++ = ia;
|
|
||||||
*imgPtr++ = ir;
|
|
||||||
*imgPtr++ = ig;
|
|
||||||
*imgPtr++ = ib;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* Walk through and premultiply and swap rgba */
|
|
||||||
PRUint8 ir, ig, ib, ia;
|
|
||||||
PRUint8 *ptr = imgPtr;
|
|
||||||
for (int32 i = 0; i < w*h; i++) {
|
|
||||||
ir = ptr[0];
|
|
||||||
ig = ptr[1];
|
|
||||||
ib = ptr[2];
|
|
||||||
ia = ptr[3];
|
|
||||||
|
|
||||||
#ifdef IS_LITTLE_ENDIAN
|
|
||||||
ptr[0] = sPremultiplyTable[ia][ib];
|
|
||||||
ptr[1] = sPremultiplyTable[ia][ig];
|
|
||||||
ptr[2] = sPremultiplyTable[ia][ir];
|
|
||||||
#else
|
|
||||||
ptr[0] = ia;
|
|
||||||
ptr[1] = sPremultiplyTable[ia][ir];
|
|
||||||
ptr[2] = sPremultiplyTable[ia][ig];
|
|
||||||
ptr[3] = sPremultiplyTable[ia][ib];
|
|
||||||
#endif
|
|
||||||
ptr += 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRefPtr<gfxImageSurface> imgsurf = new gfxImageSurface(imageBuffer.get(),
|
|
||||||
gfxIntSize(w, h),
|
|
||||||
w * 4,
|
|
||||||
gfxASurface::ImageFormatARGB32);
|
gfxASurface::ImageFormatARGB32);
|
||||||
if (!imgsurf || imgsurf->CairoStatus())
|
if (!imgsurf || imgsurf->CairoStatus())
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
// ensure premultiply table has been created
|
||||||
|
EnsurePremultiplyTable();
|
||||||
|
|
||||||
|
PRUint8 *src = aData;
|
||||||
|
PRUint8 *dst = imgsurf->Data();
|
||||||
|
|
||||||
|
for (int j = 0; j < h; j++) {
|
||||||
|
for (int i = 0; i < w; i++) {
|
||||||
|
PRUint8 r = *src++;
|
||||||
|
PRUint8 g = *src++;
|
||||||
|
PRUint8 b = *src++;
|
||||||
|
PRUint8 a = *src++;
|
||||||
|
|
||||||
|
// Convert to premultiplied color (losslessly if the input came from getImageData)
|
||||||
|
#ifdef IS_LITTLE_ENDIAN
|
||||||
|
*dst++ = sPremultiplyTable[a][b];
|
||||||
|
*dst++ = sPremultiplyTable[a][g];
|
||||||
|
*dst++ = sPremultiplyTable[a][r];
|
||||||
|
*dst++ = a;
|
||||||
|
#else
|
||||||
|
*dst++ = a;
|
||||||
|
*dst++ = sPremultiplyTable[a][r];
|
||||||
|
*dst++ = sPremultiplyTable[a][g];
|
||||||
|
*dst++ = sPremultiplyTable[a][b];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gfxContextPathAutoSaveRestore pathSR(mThebes);
|
gfxContextPathAutoSaveRestore pathSR(mThebes);
|
||||||
gfxContextAutoSaveRestore autoSR(mThebes);
|
gfxContextAutoSaveRestore autoSR(mThebes);
|
||||||
|
|
||||||
|
@ -3775,7 +3592,7 @@ nsCanvasRenderingContext2D::PutImageData()
|
||||||
mThebes->SetOperator(gfxContext::OPERATOR_SOURCE);
|
mThebes->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||||
mThebes->Fill();
|
mThebes->Fill();
|
||||||
|
|
||||||
return Redraw();
|
return Redraw(gfxRect(x, y, w, h));
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -3795,79 +3612,8 @@ nsCanvasRenderingContext2D::GetThebesSurface(gfxASurface **surface)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsCanvasRenderingContext2D::CreateImageData()
|
nsCanvasRenderingContext2D::CreateImageData()
|
||||||
{
|
{
|
||||||
if (!mValid)
|
/* Should never be called; handled entirely in the quickstub */
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
|
||||||
nsAXPCNativeCallContext *ncc = nsnull;
|
|
||||||
nsresult rv = nsContentUtils::XPConnect()->
|
|
||||||
GetCurrentNativeCallContext(&ncc);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (!ncc)
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
JSContext *ctx = nsnull;
|
|
||||||
|
|
||||||
rv = ncc->GetJSContext(&ctx);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
PRUint32 argc;
|
|
||||||
jsval *argv = nsnull;
|
|
||||||
|
|
||||||
ncc->GetArgc(&argc);
|
|
||||||
ncc->GetArgvPtr(&argv);
|
|
||||||
|
|
||||||
JSAutoRequest ar(ctx);
|
|
||||||
|
|
||||||
int32 width, height;
|
|
||||||
if (!JS_ConvertArguments (ctx, argc, argv, "jj", &width, &height))
|
|
||||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
|
||||||
|
|
||||||
if (width <= 0 || height <= 0)
|
|
||||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
|
||||||
|
|
||||||
PRUint32 w = (PRUint32) width;
|
|
||||||
PRUint32 h = (PRUint32) height;
|
|
||||||
|
|
||||||
// check for overflow when calculating len
|
|
||||||
PRUint32 len0 = w * h;
|
|
||||||
if (len0 / w != (PRUint32) h)
|
|
||||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
|
||||||
PRUint32 len = len0 * 4;
|
|
||||||
if (len / 4 != len0)
|
|
||||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
|
||||||
|
|
||||||
jsval *dest;
|
|
||||||
JSObject *dataArray = js_NewArrayObjectWithCapacity(ctx, len, &dest);
|
|
||||||
if (!dataArray)
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
nsAutoGCRoot arrayGCRoot(&dataArray, &rv);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
for (PRUint32 i = 0; i < len; i++)
|
|
||||||
*dest++ = JSVAL_ZERO;
|
|
||||||
|
|
||||||
// Allocate result object after array, so if we have to trigger gc
|
|
||||||
// we do it now.
|
|
||||||
JSObject *result = JS_NewObject(ctx, NULL, NULL, NULL);
|
|
||||||
if (!result)
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
nsAutoGCRoot resultGCRoot(&result, &rv);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (!JS_DefineProperty(ctx, result, "width", INT_TO_JSVAL(w), NULL, NULL, 0) ||
|
|
||||||
!JS_DefineProperty(ctx, result, "height", INT_TO_JSVAL(h), NULL, NULL, 0) ||
|
|
||||||
!JS_DefineProperty(ctx, result, "data", OBJECT_TO_JSVAL(dataArray), NULL, NULL, 0))
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
jsval *retvalPtr;
|
|
||||||
ncc->GetRetValPtr(&retvalPtr);
|
|
||||||
*retvalPtr = OBJECT_TO_JSVAL(result);
|
|
||||||
ncc->SetReturnValueWasSet(PR_TRUE);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
|
|
@ -182,10 +182,22 @@ enum CanvasMultiGetterType {
|
||||||
// void putImageData (in ImageData d, in float x, in float y);
|
// void putImageData (in ImageData d, in float x, in float y);
|
||||||
// ImageData = { width: #, height: #, data: [r, g, b, a, ...] }
|
// ImageData = { width: #, height: #, data: [r, g, b, a, ...] }
|
||||||
|
|
||||||
|
// These are just dummy functions; for JS, they are implemented as quickstubs
|
||||||
|
// that call the _explicit methods below. Native callers should use the _explit
|
||||||
|
// methods directly.
|
||||||
void getImageData();
|
void getImageData();
|
||||||
void putImageData();
|
void putImageData();
|
||||||
|
|
||||||
|
// dataLen must be == width*height*4 in both of these calls
|
||||||
|
[noscript] void getImageData_explicit(in long x, in long y, in unsigned long width, in unsigned long height,
|
||||||
|
[array, size_is(dataLen)] in octet dataPtr, in unsigned long dataLen);
|
||||||
|
[noscript] void putImageData_explicit(in long x, in long y, in unsigned long width, in unsigned long height,
|
||||||
|
[array, size_is(dataLen)] in octet dataPtr, in unsigned long dataLen);
|
||||||
|
|
||||||
// ImageData createImageData(in float w, in float h);
|
// ImageData createImageData(in float w, in float h);
|
||||||
|
// Note: this is basically script-only (and really, quickstub-only). Native callers
|
||||||
|
// should just use the noscript 'explicit' get/put methods above, instead of using
|
||||||
|
// a separate ImageData object.
|
||||||
void createImageData();
|
void createImageData();
|
||||||
|
|
||||||
// image smoothing mode -- if disabled, images won't be smoothed
|
// image smoothing mode -- if disabled, images won't be smoothed
|
||||||
|
|
|
@ -12089,6 +12089,7 @@ TraceRecorder::setElem(int lval_spindex, int idx_spindex, int v_spindex)
|
||||||
case js::TypedArray::TYPE_UINT8_CLAMPED:
|
case js::TypedArray::TYPE_UINT8_CLAMPED:
|
||||||
addr_ins = lir->ins2(LIR_piadd, data_ins, pidx_ins);
|
addr_ins = lir->ins2(LIR_piadd, data_ins, pidx_ins);
|
||||||
lir->insStore(LIR_stb, lir->insCall(&js_TypedArray_uint8_clamp_double_ci, &v_ins), addr_ins, 0);
|
lir->insStore(LIR_stb, lir->insCall(&js_TypedArray_uint8_clamp_double_ci, &v_ins), addr_ins, 0);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
JS_NOT_REACHED("Unknown typed array type in tracer");
|
JS_NOT_REACHED("Unknown typed array type in tracer");
|
||||||
}
|
}
|
||||||
|
|
|
@ -520,9 +520,18 @@ class TypedArrayTemplate
|
||||||
jsuint index;
|
jsuint index;
|
||||||
// We can't just chain to js_SetProperty, because we're not a normal object.
|
// We can't just chain to js_SetProperty, because we're not a normal object.
|
||||||
if (!tarray->isArrayIndex(cx, id, &index)) {
|
if (!tarray->isArrayIndex(cx, id, &index)) {
|
||||||
|
#if 0
|
||||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||||
JSMSG_TYPED_ARRAY_BAD_INDEX);
|
JSMSG_TYPED_ARRAY_BAD_INDEX);
|
||||||
return false;
|
return false;
|
||||||
|
#endif
|
||||||
|
// Silent ignore is better than an exception here, because
|
||||||
|
// at some point we may want to support other properties on
|
||||||
|
// these objects. This is especially true when these arrays
|
||||||
|
// are used to implement HTML Canvas 2D's PixelArray objects,
|
||||||
|
// which used to be plain old arrays.
|
||||||
|
*vp = JSVAL_VOID;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (JSVAL_IS_INT(*vp)) {
|
if (JSVAL_IS_INT(*vp)) {
|
||||||
|
|
|
@ -92,11 +92,6 @@ members = [
|
||||||
'nsIDOMTextMetrics.*',
|
'nsIDOMTextMetrics.*',
|
||||||
'nsIDOMCanvasGradient.*',
|
'nsIDOMCanvasGradient.*',
|
||||||
'nsIDOMCanvasPattern.*',
|
'nsIDOMCanvasPattern.*',
|
||||||
# NOTE: createImageDate(), getImageData(), and putImageData() use
|
|
||||||
# GetCurrentNativeCallContext
|
|
||||||
'-nsIDOMCanvasRenderingContext2D.createImageData',
|
|
||||||
'-nsIDOMCanvasRenderingContext2D.getImageData',
|
|
||||||
'-nsIDOMCanvasRenderingContext2D.putImageData',
|
|
||||||
|
|
||||||
# dom/interfaces/core
|
# dom/interfaces/core
|
||||||
'nsIDOMCharacterData.data',
|
'nsIDOMCharacterData.data',
|
||||||
|
@ -625,6 +620,10 @@ customMethodCalls = {
|
||||||
'nsICanvasRenderingContextWebGL_VertexAttrib1fv': CUSTOM_QS,
|
'nsICanvasRenderingContextWebGL_VertexAttrib1fv': CUSTOM_QS,
|
||||||
'nsICanvasRenderingContextWebGL_VertexAttrib2fv': CUSTOM_QS,
|
'nsICanvasRenderingContextWebGL_VertexAttrib2fv': CUSTOM_QS,
|
||||||
'nsICanvasRenderingContextWebGL_VertexAttrib3fv': CUSTOM_QS,
|
'nsICanvasRenderingContextWebGL_VertexAttrib3fv': CUSTOM_QS,
|
||||||
'nsICanvasRenderingContextWebGL_VertexAttrib4fv': CUSTOM_QS
|
'nsICanvasRenderingContextWebGL_VertexAttrib4fv': CUSTOM_QS,
|
||||||
|
# Canvas 2D
|
||||||
|
'nsIDOMCanvasRenderingContext2D_CreateImageData': CUSTOM_QS,
|
||||||
|
'nsIDOMCanvasRenderingContext2D_GetImageData': CUSTOM_QS,
|
||||||
|
'nsIDOMCanvasRenderingContext2D_PutImageData': CUSTOM_QS,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче