From 6d4bb0f4fd96cc5d623b0d623058ba83aafdc862 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 11 Jul 2014 18:27:26 -0700 Subject: [PATCH] Added Uint8ClampedArray --- examples/Test.js | 2 +- examples/typedArraysUnitTest.js | 19 ++++++++++++++ libraries/script-engine/src/ScriptEngine.cpp | 2 ++ libraries/script-engine/src/TypedArrays.cpp | 27 ++++++++++++++++++++ libraries/script-engine/src/TypedArrays.h | 8 +++++- 5 files changed, 56 insertions(+), 2 deletions(-) diff --git a/examples/Test.js b/examples/Test.js index caecfc5af7..36dee7bd90 100644 --- a/examples/Test.js +++ b/examples/Test.js @@ -80,7 +80,7 @@ UnitTest.prototype.arrayEqual = function(array1, array2, message) { } for (var i = 0; i < array1.length; ++i) { if (array1[i] !== array2[i]) { - throw new AssertionException(array1[i], array2[i], message); + throw new AssertionException(array1[i], array2[i], i + " " + message); } } } diff --git a/examples/typedArraysUnitTest.js b/examples/typedArraysUnitTest.js index a466c9104f..859bc9b9b3 100644 --- a/examples/typedArraysUnitTest.js +++ b/examples/typedArraysUnitTest.js @@ -687,3 +687,22 @@ test('Typed Array getters/setters', function () { this.assertEquals(bytes[1], 0xff); }); + +test('Uint8ClampedArray', function () { + this.assertEquals(Uint8ClampedArray.BYTES_PER_ELEMENT, 1, 'Uint8ClampedArray.BYTES_PER_ELEMENT'); + var a = new Uint8ClampedArray([-Infinity, -Number.MAX_VALUE, -1, -Number.MIN_VALUE, -0, + 0, Number.MIN_VALUE, 1, 1.1, 1.9, 255, 255.1, 255.9, 256, Number.MAX_VALUE, Infinity, + NaN]); + this.assertEquals(a.BYTES_PER_ELEMENT, 1); + this.assertEquals(a.byteOffset, 0); + this.assertEquals(a.byteLength, 17); + this.arrayEqual(a, [0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0], "array test"); +}); + +test('Regression Tests', function() { + // Bug: https://github.com/inexorabletash/polyfill/issues/16 + var minFloat32 = 1.401298464324817e-45; + var truncated = new Float32Array([-minFloat32 / 2 - Math.pow(2, -202)]).get(0); + this.assertEquals(truncated, -minFloat32, 'smallest 32 bit float should not truncate to zero'); +}); + diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 4074beb88e..0279e2ea27 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -100,6 +100,7 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNam new DataViewClass(this); new Int8ArrayClass(this); new Uint8ArrayClass(this); + new Uint8ClampedArrayClass(this); new Int16ArrayClass(this); new Uint16ArrayClass(this); new Int32ArrayClass(this); @@ -141,6 +142,7 @@ ScriptEngine::ScriptEngine(const QUrl& scriptURL, new DataViewClass(this); new Int8ArrayClass(this); new Uint8ArrayClass(this); + new Uint8ClampedArrayClass(this); new Int16ArrayClass(this); new Uint16ArrayClass(this); new Int32ArrayClass(this); diff --git a/libraries/script-engine/src/TypedArrays.cpp b/libraries/script-engine/src/TypedArrays.cpp index 106b824f76..6b461fc6fb 100644 --- a/libraries/script-engine/src/TypedArrays.cpp +++ b/libraries/script-engine/src/TypedArrays.cpp @@ -342,6 +342,33 @@ void Uint8ArrayClass::setProperty(QScriptValue &object, const QScriptString &nam setPropertyHelper(ba, name, id, value); } +Uint8ClampedArrayClass::Uint8ClampedArrayClass(ScriptEngine* scriptEngine) : TypedArray(scriptEngine, UINT_8_CLAMPED_ARRAY_CLASS_NAME) { + setBytesPerElement(sizeof(quint8)); +} + +QScriptValue Uint8ClampedArrayClass::property(const QScriptValue &object, const QScriptString &name, uint id) { + + QByteArray* arrayBuffer = qscriptvalue_cast(object.data().property(_bufferName).data()); + QScriptValue result = propertyHelper(arrayBuffer, name, id); + return (result.isValid()) ? result : TypedArray::property(object, name, id); +} + +void Uint8ClampedArrayClass::setProperty(QScriptValue &object, const QScriptString &name, + uint id, const QScriptValue &value) { + QByteArray *ba = qscriptvalue_cast(object.data().property(_bufferName).data()); + if (ba && value.isNumber()) { + QDataStream stream(ba, QIODevice::ReadWrite); + stream.skipRawData(id); + if (value.toNumber() > 255) { + stream << (quint8)255; + } else if (value.toNumber() < 0) { + stream << (quint8)0; + } else { + stream << (quint8)glm::clamp(qRound(value.toNumber()), 0, 255); + } + } +} + Int16ArrayClass::Int16ArrayClass(ScriptEngine* scriptEngine) : TypedArray(scriptEngine, INT_16_ARRAY_CLASS_NAME) { setBytesPerElement(sizeof(qint16)); } diff --git a/libraries/script-engine/src/TypedArrays.h b/libraries/script-engine/src/TypedArrays.h index 2eff3e84b9..bacb067add 100644 --- a/libraries/script-engine/src/TypedArrays.h +++ b/libraries/script-engine/src/TypedArrays.h @@ -19,6 +19,7 @@ static const QString LENGTH_PROPERTY_NAME = "length"; static const QString INT_8_ARRAY_CLASS_NAME = "Int8Array"; static const QString UINT_8_ARRAY_CLASS_NAME = "Uint8Array"; +static const QString UINT_8_CLAMPED_ARRAY_CLASS_NAME = "Uint8ClampedArray"; static const QString INT_16_ARRAY_CLASS_NAME = "Int16Array"; static const QString UINT_16_ARRAY_CLASS_NAME = "Uint16Array"; static const QString INT_32_ARRAY_CLASS_NAME = "Int32Array"; @@ -98,7 +99,12 @@ public: }; class Uint8ClampedArrayClass : public TypedArray { - // TODO + Q_OBJECT +public: + Uint8ClampedArrayClass(ScriptEngine* scriptEngine); + + QScriptValue property(const QScriptValue &object, const QScriptString &name, uint id); + void setProperty(QScriptValue &object, const QScriptString &name, uint id, const QScriptValue &value); }; class Int16ArrayClass : public TypedArray {