зеркало из https://github.com/mozilla/gecko-dev.git
Bug 550309 - Part a: Tighten up support for fake ImageData objects; r=bz
This commit is contained in:
Родитель
d1b209dd2c
Коммит
c4ac60d8ed
|
@ -0,0 +1,52 @@
|
|||
/* 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 CustomQS_Canvas_h
|
||||
#define CustomQS_Canvas_h
|
||||
|
||||
#include "jsapi.h"
|
||||
|
||||
static bool
|
||||
GetPositiveInt(JSContext* cx, JSObject& obj, const char* name, uint32_t* out)
|
||||
{
|
||||
JS::Value temp;
|
||||
int32_t signedInt;
|
||||
if (!JS_GetProperty(cx, &obj, name, &temp) ||
|
||||
!JS_ValueToECMAInt32(cx, temp, &signedInt)) {
|
||||
return false;
|
||||
}
|
||||
if (signedInt <= 0) {
|
||||
return xpc_qsThrow(cx, NS_ERROR_DOM_TYPE_MISMATCH_ERR);
|
||||
}
|
||||
*out = uint32_t(signedInt);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
GetImageData(JSContext* cx, const JS::Value& imageData,
|
||||
uint32_t* width, uint32_t* height, JS::Anchor<JSObject*>* array)
|
||||
{
|
||||
if (!imageData.isObject()) {
|
||||
return xpc_qsThrow(cx, NS_ERROR_DOM_TYPE_MISMATCH_ERR);
|
||||
}
|
||||
|
||||
JSObject& dataObject = imageData.toObject();
|
||||
|
||||
if (!GetPositiveInt(cx, dataObject, "width", width) ||
|
||||
!GetPositiveInt(cx, dataObject, "height", height)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JS::Value temp;
|
||||
if (!JS_GetProperty(cx, &dataObject, "data", &temp)) {
|
||||
return false;
|
||||
}
|
||||
if (!temp.isObject()) {
|
||||
return xpc_qsThrow(cx, NS_ERROR_DOM_TYPE_MISMATCH_ERR);
|
||||
}
|
||||
array->set(&temp.toObject());
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // CustomQS_Canvas_h
|
|
@ -42,6 +42,7 @@
|
|||
#include "nsIDOMCanvasRenderingContext2D.h"
|
||||
#include "CheckedInt.h"
|
||||
#include "nsMathUtils.h"
|
||||
#include "CustomQS_Canvas.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
|
||||
|
@ -219,32 +220,6 @@ CreateImageData(JSContext* cx,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
GetImageDataDimensions(JSContext *cx, JSObject *dataObject, uint32_t *width, uint32_t *height)
|
||||
{
|
||||
jsval temp;
|
||||
int32_t wi, hi;
|
||||
|
||||
// Need to check that dataObject is ImageData object. That's hard for the moment
|
||||
// because they're just vanilla objects in our implementation.
|
||||
// Let's guess, if the object has valid width and height then it's suitable
|
||||
// for this operation.
|
||||
if (!JS_GetProperty(cx, dataObject, "width", &temp) ||
|
||||
!JS_ValueToECMAInt32(cx, temp, &wi))
|
||||
return false;
|
||||
|
||||
if (!JS_GetProperty(cx, dataObject, "height", &temp) ||
|
||||
!JS_ValueToECMAInt32(cx, temp, &hi))
|
||||
return false;
|
||||
|
||||
if (wi <= 0 || hi <= 0)
|
||||
return xpc_qsThrow(cx, NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||
|
||||
*width = uint32_t(wi);
|
||||
*height = uint32_t(hi);
|
||||
return true;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
nsIDOMCanvasRenderingContext2D_CreateImageData(JSContext *cx, unsigned argc, jsval *vp)
|
||||
{
|
||||
|
@ -258,16 +233,11 @@ nsIDOMCanvasRenderingContext2D_CreateImageData(JSContext *cx, unsigned argc, jsv
|
|||
jsval *argv = JS_ARGV(cx, vp);
|
||||
|
||||
if (argc == 1) {
|
||||
// The specification asks to throw NOT_SUPPORTED if first argument is NULL,
|
||||
// An object is expected, so throw an exception for all primitives.
|
||||
if (JSVAL_IS_PRIMITIVE(argv[0]))
|
||||
return xpc_qsThrow(cx, NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
|
||||
JSObject *dataObject = JSVAL_TO_OBJECT(argv[0]);
|
||||
|
||||
uint32_t data_width, data_height;
|
||||
if (!GetImageDataDimensions(cx, dataObject, &data_width, &data_height))
|
||||
JS::Anchor<JSObject*> darray;
|
||||
if (!GetImageData(cx, argv[0], &data_width, &data_height, &darray)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return CreateImageData(cx, data_width, data_height, NULL, 0, 0, vp);
|
||||
}
|
||||
|
@ -370,10 +340,11 @@ nsIDOMCanvasRenderingContext2D_PutImageData(JSContext *cx, unsigned argc, jsval
|
|||
|
||||
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]);
|
||||
uint32_t w, h;
|
||||
JS::Anchor<JSObject*> darray;
|
||||
if (!GetImageData(cx, argv[0], &w, &h, &darray)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
double xd, yd;
|
||||
if (!JS_ValueToNumber(cx, argv[1], &xd) ||
|
||||
|
@ -388,13 +359,6 @@ nsIDOMCanvasRenderingContext2D_PutImageData(JSContext *cx, unsigned argc, jsval
|
|||
int32_t x = JS_DoubleToInt32(xd);
|
||||
int32_t y = JS_DoubleToInt32(yd);
|
||||
|
||||
// Grab width, height, and the dense array from the dataObject.
|
||||
JS::AutoValueRooter tv(cx);
|
||||
|
||||
uint32_t w, h;
|
||||
if (!GetImageDataDimensions(cx, dataObject, &w, &h))
|
||||
return JS_FALSE;
|
||||
|
||||
// the optional dirty rect
|
||||
bool hasDirtyRect = false;
|
||||
int32_t dirtyX = 0,
|
||||
|
@ -424,24 +388,16 @@ nsIDOMCanvasRenderingContext2D_PutImageData(JSContext *cx, unsigned argc, jsval
|
|||
hasDirtyRect = true;
|
||||
}
|
||||
|
||||
if (!JS_GetProperty(cx, dataObject, "data", tv.jsval_addr()))
|
||||
return JS_FALSE;
|
||||
|
||||
if (JSVAL_IS_PRIMITIVE(tv.jsval_value()))
|
||||
return xpc_qsThrow(cx, NS_ERROR_DOM_TYPE_MISMATCH_ERR);
|
||||
|
||||
JSObject *darray = JSVAL_TO_OBJECT(tv.jsval_value());
|
||||
|
||||
JS::AutoValueRooter tsrc_tvr(cx);
|
||||
|
||||
JSObject *tsrc = NULL;
|
||||
if (js::GetObjectClass(darray) == &js::TypedArray::fastClasses[js::TypedArray::TYPE_UINT8] ||
|
||||
js::GetObjectClass(darray) == &js::TypedArray::fastClasses[js::TypedArray::TYPE_UINT8_CLAMPED])
|
||||
if (js::GetObjectClass(darray.get()) == &js::TypedArray::fastClasses[js::TypedArray::TYPE_UINT8] ||
|
||||
js::GetObjectClass(darray.get()) == &js::TypedArray::fastClasses[js::TypedArray::TYPE_UINT8_CLAMPED])
|
||||
{
|
||||
tsrc = js::TypedArray::getTypedArray(darray);
|
||||
} else if (JS_IsArrayObject(cx, darray) || js_IsTypedArray(darray)) {
|
||||
tsrc = darray.get();
|
||||
} else if (JS_IsArrayObject(cx, darray.get()) || js_IsTypedArray(darray.get())) {
|
||||
// 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);
|
||||
JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_UINT8, darray.get());
|
||||
if (!nobj)
|
||||
return JS_FALSE;
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
#include "jsapi.h"
|
||||
#include "jstypedarray.h"
|
||||
#include "CustomQS_Canvas.h"
|
||||
|
||||
#define GET_INT32_ARG(var, index) \
|
||||
int32_t var; \
|
||||
|
@ -479,33 +480,16 @@ TexImage2DImageDataOrElement(JSContext* cx, T& self, JS::Value* object)
|
|||
|
||||
// Failed to interpret object as an Element, now try to interpret it as
|
||||
// ImageData.
|
||||
JSObject* imageData = &object->toObject();
|
||||
|
||||
jsval js_width, js_height, js_data;
|
||||
if (!JS_GetProperty(cx, imageData, "width", &js_width) ||
|
||||
!JS_GetProperty(cx, imageData, "height", &js_height) ||
|
||||
!JS_GetProperty(cx, imageData, "data", &js_data)) {
|
||||
uint32_t int_width, int_height;
|
||||
JS::Anchor<JSObject*> obj_data;
|
||||
if (!GetImageData(cx, *object, &int_width, &int_height, &obj_data)) {
|
||||
return false;
|
||||
}
|
||||
if (js_width == JSVAL_VOID ||
|
||||
js_height == JSVAL_VOID ||
|
||||
!js_data.isObject())
|
||||
{
|
||||
return xpc_qsThrow(cx, NS_ERROR_FAILURE);
|
||||
}
|
||||
int32_t int_width, int_height;
|
||||
JSObject *obj_data = JSVAL_TO_OBJECT(js_data);
|
||||
if (!JS_ValueToECMAInt32(cx, js_width, &int_width) ||
|
||||
!JS_ValueToECMAInt32(cx, js_height, &int_height))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!js_IsTypedArray(obj_data))
|
||||
{
|
||||
if (!js_IsTypedArray(obj_data.get())) {
|
||||
return xpc_qsThrow(cx, NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
nsresult rv = self.DoCallForImageData(int_width, int_height, obj_data);
|
||||
nsresult rv = self.DoCallForImageData(int_width, int_height, obj_data.get());
|
||||
return NS_SUCCEEDED(rv) || xpc_qsThrow(cx, rv);
|
||||
}
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ LIBRARY_NAME = gkconcvs_s
|
|||
LIBXUL_LIBRARY = 1
|
||||
|
||||
EXPORTS = \
|
||||
CustomQS_Canvas.h \
|
||||
CustomQS_Canvas2D.h \
|
||||
CustomQS_WebGL.h \
|
||||
$(NULL)
|
||||
|
|
|
@ -7681,7 +7681,7 @@ var _thrown = undefined; try {
|
|||
<!-- [[[ test_2d.imageData.create1.zero.html ]]] -->
|
||||
|
||||
<p>Canvas test: 2d.imageData.create1.zero - bug 630040</p>
|
||||
<!-- Testing: createImageData(null) throws NOT_SUPPORTED_ERR -->
|
||||
<!-- Testing: createImageData(null) throws TypeError -->
|
||||
<canvas id="c262a" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
|
||||
<script>
|
||||
|
||||
|
@ -7692,7 +7692,7 @@ var ctx = canvas.getContext('2d');
|
|||
|
||||
var _thrown = undefined; try {
|
||||
ctx.createImageData(null);
|
||||
} catch (e) { _thrown = e }; ok(_thrown && _thrown.code == DOMException.NOT_SUPPORTED_ERR, "should throw NOT_SUPPORTED_ERR");
|
||||
} catch (e) { _thrown = e }; todo(_thrown && _thrown instanceof TypeError, "should throw TypeError");
|
||||
|
||||
|
||||
}
|
||||
|
@ -10790,7 +10790,7 @@ if (ctx.createImageData) {
|
|||
} catch (e) { _thrown = e }; todo(_thrown && _thrown.code == DOMException.NOT_SUPPORTED_ERR, "should throw NOT_SUPPORTED_ERR");
|
||||
var _thrown = undefined; try {
|
||||
ctx.createImageData(1);
|
||||
} catch (e) { _thrown = e }; ok(_thrown && _thrown.code == DOMException.NOT_SUPPORTED_ERR, "should throw NOT_SUPPORTED_ERR");
|
||||
} catch (e) { _thrown = e }; todo(_thrown && _thrown.code == DOMException.NOT_SUPPORTED_ERR, "should throw NOT_SUPPORTED_ERR");
|
||||
}
|
||||
if (ctx.getImageData) {
|
||||
var _thrown = undefined; try {
|
||||
|
|
Загрузка…
Ссылка в новой задаче