Spaces:
Running
Running
/* Smalltalk from Squeak4.5 with VMMaker 4.13.6 translated as JS source on 3 November 2014 1:52:21 pm */ | |
/* Automatically generated by | |
JSPluginCodeGenerator VMMakerJS-bf.15 uuid: fd4e10f2-3773-4e80-8bb5-c4b471a014e5 | |
from | |
Matrix2x3Plugin VMMaker-bf.353 uuid: 8ae25e7e-8d2c-451e-8277-598b30e9c002 | |
*/ | |
(function Matrix2x3Plugin() { | |
; | |
var VM_PROXY_MAJOR = 1; | |
var VM_PROXY_MINOR = 11; | |
/*** Functions ***/ | |
function CLASSOF(obj) { return typeof obj === "number" ? interpreterProxy.classSmallInteger() : obj.sqClass } | |
function SIZEOF(obj) { return obj.pointers ? obj.pointers.length : obj.words ? obj.words.length : obj.bytes ? obj.bytes.length : 0 } | |
function BYTESIZEOF(obj) { return obj.bytes ? obj.bytes.length : obj.words ? obj.words.length * 4 : 0 } | |
function DIV(a, b) { return Math.floor(a / b) | 0; } // integer division | |
function MOD(a, b) { return a - DIV(a, b) * b | 0; } // signed modulus | |
function SHL(a, b) { return b > 31 ? 0 : a << b; } // fix JS shift | |
function SHR(a, b) { return b > 31 ? 0 : a >>> b; } // fix JS shift | |
function SHIFT(a, b) { return b < 0 ? (b < -31 ? 0 : a >>> (0-b) ) : (b > 31 ? 0 : a << b); } | |
/*** Variables ***/ | |
var interpreterProxy = null; | |
var m23ArgX = 0; | |
var m23ArgY = 0; | |
var m23ResultX = 0; | |
var m23ResultY = 0; | |
var moduleName = "Matrix2x3Plugin 3 November 2014 (e)"; | |
/* Note: This is hardcoded so it can be run from Squeak. | |
The module name is used for validating a module *after* | |
it is loaded to check if it does really contain the module | |
we're thinking it contains. This is important! */ | |
function getModuleName() { | |
return moduleName; | |
} | |
function halt() { | |
; | |
} | |
/* Load the argument matrix */ | |
function loadArgumentMatrix(matrix) { | |
if (interpreterProxy.failed()) { | |
return null; | |
} | |
if (!(interpreterProxy.isWords(matrix) && (SIZEOF(matrix) === 6))) { | |
interpreterProxy.primitiveFail(); | |
return null; | |
} | |
return matrix.wordsAsFloat32Array(); | |
} | |
/* Load the argument point into m23ArgX and m23ArgY */ | |
function loadArgumentPoint(point) { | |
var isInt; | |
var oop; | |
if (interpreterProxy.failed()) { | |
return null; | |
} | |
if (CLASSOF(point) !== interpreterProxy.classPoint()) { | |
return interpreterProxy.primitiveFail(); | |
} | |
oop = interpreterProxy.fetchPointerofObject(0, point); | |
isInt = typeof oop === "number"; | |
if (!(isInt || (oop.isFloat))) { | |
return interpreterProxy.primitiveFail(); | |
} | |
if (isInt) { | |
m23ArgX = oop; | |
} else { | |
m23ArgX = interpreterProxy.floatValueOf(oop); | |
} | |
oop = interpreterProxy.fetchPointerofObject(1, point); | |
isInt = typeof oop === "number"; | |
if (!(isInt || (oop.isFloat))) { | |
return interpreterProxy.primitiveFail(); | |
} | |
if (isInt) { | |
m23ArgY = oop; | |
} else { | |
m23ArgY = interpreterProxy.floatValueOf(oop); | |
} | |
} | |
/* Multiply matrix m1 with m2 and store the result into m3. */ | |
function matrix2x3ComposeMatrixwithinto(m1, m2, m3) { | |
var a11; | |
var a12; | |
var a13; | |
var a21; | |
var a22; | |
var a23; | |
a11 = (m1[0] * m2[0]) + (m1[1] * m2[3]); | |
a12 = (m1[0] * m2[1]) + (m1[1] * m2[4]); | |
a13 = ((m1[0] * m2[2]) + (m1[1] * m2[5])) + m1[2]; | |
a21 = (m1[3] * m2[0]) + (m1[4] * m2[3]); | |
a22 = (m1[3] * m2[1]) + (m1[4] * m2[4]); | |
a23 = ((m1[3] * m2[2]) + (m1[4] * m2[5])) + m1[5]; | |
m3[0] = a11; | |
m3[1] = a12; | |
m3[2] = a13; | |
m3[3] = a21; | |
m3[4] = a22; | |
m3[5] = a23; | |
} | |
/* Invert the pre-loaded argument point by the given matrix */ | |
function matrix2x3InvertPoint(m) { | |
var det; | |
var detX; | |
var detY; | |
var x; | |
var y; | |
x = m23ArgX - m[2]; | |
y = m23ArgY - m[5]; | |
det = (m[0] * m[4]) - (m[1] * m[3]); | |
if (det === 0.0) { | |
return interpreterProxy.primitiveFail(); | |
} | |
det = 1.0 / det; | |
detX = (x * m[4]) - (m[1] * y); | |
detY = (m[0] * y) - (x * m[3]); | |
m23ResultX = detX * det; | |
m23ResultY = detY * det; | |
} | |
/* Transform the pre-loaded argument point by the given matrix */ | |
function matrix2x3TransformPoint(m) { | |
m23ResultX = ((m23ArgX * m[0]) + (m23ArgY * m[1])) + m[2]; | |
m23ResultY = ((m23ArgX * m[3]) + (m23ArgY * m[4])) + m[5]; | |
} | |
function okayIntValue(value) { | |
return (value >= -1073741824) && (m23ResultX <= 1073741823); | |
} | |
function primitiveComposeMatrix(argCount) { | |
var m1; | |
var m2; | |
var m3; | |
var result; | |
; | |
m3 = loadArgumentMatrix((result = interpreterProxy.stackObjectValue(0))); | |
m2 = loadArgumentMatrix(interpreterProxy.stackObjectValue(1)); | |
m1 = loadArgumentMatrix(interpreterProxy.stackObjectValue(2)); | |
if (interpreterProxy.failed()) { | |
return null; | |
} | |
matrix2x3ComposeMatrixwithinto(m1, m2, m3); | |
interpreterProxy.popthenPush(argCount + 1, result); | |
} | |
function primitiveInvertPoint(argCount) { | |
var matrix; | |
loadArgumentPoint(interpreterProxy.stackObjectValue(0)); | |
matrix = loadArgumentMatrix(interpreterProxy.stackObjectValue(1)); | |
if (interpreterProxy.failed()) { | |
return null; | |
} | |
matrix2x3InvertPoint(matrix); | |
if (!interpreterProxy.failed()) { | |
roundAndStoreResultPoint(argCount); | |
} | |
} | |
function primitiveInvertRectInto(argCount) { | |
var cornerX; | |
var cornerY; | |
var dstOop; | |
var matrix; | |
var maxX; | |
var maxY; | |
var minX; | |
var minY; | |
var originX; | |
var originY; | |
var srcOop; | |
dstOop = interpreterProxy.stackObjectValue(0); | |
srcOop = interpreterProxy.stackObjectValue(1); | |
matrix = loadArgumentMatrix(interpreterProxy.stackObjectValue(2)); | |
if (interpreterProxy.failed()) { | |
return null; | |
} | |
if (CLASSOF(srcOop) !== CLASSOF(dstOop)) { | |
return interpreterProxy.primitiveFail(); | |
} | |
if (!interpreterProxy.isPointers(srcOop)) { | |
return interpreterProxy.primitiveFail(); | |
} | |
if (SIZEOF(srcOop) !== 2) { | |
return interpreterProxy.primitiveFail(); | |
} | |
loadArgumentPoint(interpreterProxy.fetchPointerofObject(0, srcOop)); | |
if (interpreterProxy.failed()) { | |
return null; | |
} | |
originX = m23ArgX; | |
originY = m23ArgY; | |
matrix2x3InvertPoint(matrix); | |
minX = (maxX = m23ResultX); | |
/* Load bottom-right point */ | |
minY = (maxY = m23ResultY); | |
loadArgumentPoint(interpreterProxy.fetchPointerofObject(1, srcOop)); | |
if (interpreterProxy.failed()) { | |
return null; | |
} | |
cornerX = m23ArgX; | |
cornerY = m23ArgY; | |
matrix2x3InvertPoint(matrix); | |
minX = Math.min(minX, m23ResultX); | |
maxX = Math.max(maxX, m23ResultX); | |
minY = Math.min(minY, m23ResultY); | |
/* Load top-right point */ | |
maxY = Math.max(maxY, m23ResultY); | |
m23ArgX = cornerX; | |
m23ArgY = originY; | |
matrix2x3InvertPoint(matrix); | |
minX = Math.min(minX, m23ResultX); | |
maxX = Math.max(maxX, m23ResultX); | |
minY = Math.min(minY, m23ResultY); | |
/* Load bottom-left point */ | |
maxY = Math.max(maxY, m23ResultY); | |
m23ArgX = originX; | |
m23ArgY = cornerY; | |
matrix2x3InvertPoint(matrix); | |
minX = Math.min(minX, m23ResultX); | |
maxX = Math.max(maxX, m23ResultX); | |
minY = Math.min(minY, m23ResultY); | |
maxY = Math.max(maxY, m23ResultY); | |
if (!interpreterProxy.failed()) { | |
dstOop = roundAndStoreResultRectx0y0x1y1(dstOop, minX, minY, maxX, maxY); | |
} | |
if (!interpreterProxy.failed()) { | |
interpreterProxy.popthenPush(argCount + 1, dstOop); | |
} | |
} | |
function primitiveIsIdentity(argCount) { | |
var matrix; | |
matrix = loadArgumentMatrix(interpreterProxy.stackObjectValue(0)); | |
if (interpreterProxy.failed()) { | |
return null; | |
} | |
interpreterProxy.pop(1); | |
interpreterProxy.pushBool((((((matrix[0] === 1.0) && (matrix[1] === 0.0)) && (matrix[2] === 0.0)) && (matrix[3] === 0.0)) && (matrix[4] === 1.0)) && (matrix[5] === 0.0)); | |
} | |
function primitiveIsPureTranslation(argCount) { | |
var matrix; | |
matrix = loadArgumentMatrix(interpreterProxy.stackObjectValue(0)); | |
if (interpreterProxy.failed()) { | |
return null; | |
} | |
interpreterProxy.pop(1); | |
interpreterProxy.pushBool((((matrix[0] === 1.0) && (matrix[1] === 0.0)) && (matrix[3] === 0.0)) && (matrix[4] === 1.0)); | |
} | |
function primitiveTransformPoint(argCount) { | |
var matrix; | |
loadArgumentPoint(interpreterProxy.stackObjectValue(0)); | |
matrix = loadArgumentMatrix(interpreterProxy.stackObjectValue(1)); | |
if (interpreterProxy.failed()) { | |
return null; | |
} | |
matrix2x3TransformPoint(matrix); | |
roundAndStoreResultPoint(argCount); | |
} | |
function primitiveTransformRectInto(argCount) { | |
var cornerX; | |
var cornerY; | |
var dstOop; | |
var matrix; | |
var maxX; | |
var maxY; | |
var minX; | |
var minY; | |
var originX; | |
var originY; | |
var srcOop; | |
dstOop = interpreterProxy.stackObjectValue(0); | |
srcOop = interpreterProxy.stackObjectValue(1); | |
matrix = loadArgumentMatrix(interpreterProxy.stackObjectValue(2)); | |
if (interpreterProxy.failed()) { | |
return null; | |
} | |
if (CLASSOF(srcOop) !== CLASSOF(dstOop)) { | |
return interpreterProxy.primitiveFail(); | |
} | |
if (!interpreterProxy.isPointers(srcOop)) { | |
return interpreterProxy.primitiveFail(); | |
} | |
if (SIZEOF(srcOop) !== 2) { | |
return interpreterProxy.primitiveFail(); | |
} | |
loadArgumentPoint(interpreterProxy.fetchPointerofObject(0, srcOop)); | |
if (interpreterProxy.failed()) { | |
return null; | |
} | |
originX = m23ArgX; | |
originY = m23ArgY; | |
matrix2x3TransformPoint(matrix); | |
minX = (maxX = m23ResultX); | |
/* Load bottom-right point */ | |
minY = (maxY = m23ResultY); | |
loadArgumentPoint(interpreterProxy.fetchPointerofObject(1, srcOop)); | |
if (interpreterProxy.failed()) { | |
return null; | |
} | |
cornerX = m23ArgX; | |
cornerY = m23ArgY; | |
matrix2x3TransformPoint(matrix); | |
minX = Math.min(minX, m23ResultX); | |
maxX = Math.max(maxX, m23ResultX); | |
minY = Math.min(minY, m23ResultY); | |
/* Load top-right point */ | |
maxY = Math.max(maxY, m23ResultY); | |
m23ArgX = cornerX; | |
m23ArgY = originY; | |
matrix2x3TransformPoint(matrix); | |
minX = Math.min(minX, m23ResultX); | |
maxX = Math.max(maxX, m23ResultX); | |
minY = Math.min(minY, m23ResultY); | |
/* Load bottom-left point */ | |
maxY = Math.max(maxY, m23ResultY); | |
m23ArgX = originX; | |
m23ArgY = cornerY; | |
matrix2x3TransformPoint(matrix); | |
minX = Math.min(minX, m23ResultX); | |
maxX = Math.max(maxX, m23ResultX); | |
minY = Math.min(minY, m23ResultY); | |
maxY = Math.max(maxY, m23ResultY); | |
dstOop = roundAndStoreResultRectx0y0x1y1(dstOop, minX, minY, maxX, maxY); | |
if (!interpreterProxy.failed()) { | |
interpreterProxy.popthenPush(argCount + 1, dstOop); | |
} | |
} | |
/* Store the result of a previous operation. | |
Fail if we cannot represent the result as SmallInteger */ | |
function roundAndStoreResultPoint(argCount) { | |
m23ResultX += 0.5; | |
m23ResultY += 0.5; | |
if (!okayIntValue(m23ResultX)) { | |
return interpreterProxy.primitiveFail(); | |
} | |
if (!okayIntValue(m23ResultY)) { | |
return interpreterProxy.primitiveFail(); | |
} | |
interpreterProxy.popthenPush(argCount + 1, interpreterProxy.makePointwithxValueyValue((m23ResultX|0), (m23ResultY|0))); | |
} | |
/* Check, round and store the result of a rectangle operation */ | |
function roundAndStoreResultRectx0y0x1y1(dstOop, x0, y0, x1, y1) { | |
var cornerOop; | |
var maxX; | |
var maxY; | |
var minX; | |
var minY; | |
var originOop; | |
var rectOop; | |
minX = x0 + 0.5; | |
if (!okayIntValue(minX)) { | |
return interpreterProxy.primitiveFail(); | |
} | |
maxX = x1 + 0.5; | |
if (!okayIntValue(maxX)) { | |
return interpreterProxy.primitiveFail(); | |
} | |
minY = y0 + 0.5; | |
if (!okayIntValue(minY)) { | |
return interpreterProxy.primitiveFail(); | |
} | |
maxY = y1 + 0.5; | |
if (!okayIntValue(maxY)) { | |
return interpreterProxy.primitiveFail(); | |
} | |
interpreterProxy.pushRemappableOop(dstOop); | |
originOop = interpreterProxy.makePointwithxValueyValue((minX|0), (minY|0)); | |
interpreterProxy.pushRemappableOop(originOop); | |
cornerOop = interpreterProxy.makePointwithxValueyValue((maxX|0), (maxY|0)); | |
originOop = interpreterProxy.popRemappableOop(); | |
rectOop = interpreterProxy.popRemappableOop(); | |
interpreterProxy.storePointerofObjectwithValue(0, rectOop, originOop); | |
interpreterProxy.storePointerofObjectwithValue(1, rectOop, cornerOop); | |
return rectOop; | |
} | |
/* Note: This is coded so that is can be run from Squeak. */ | |
function setInterpreter(anInterpreter) { | |
var ok; | |
interpreterProxy = anInterpreter; | |
ok = interpreterProxy.majorVersion() == VM_PROXY_MAJOR; | |
if (ok === false) { | |
return false; | |
} | |
ok = interpreterProxy.minorVersion() >= VM_PROXY_MINOR; | |
return ok; | |
} | |
function registerPlugin() { | |
if (typeof Squeak === "object" && Squeak.registerExternalModule) { | |
Squeak.registerExternalModule("Matrix2x3Plugin", { | |
primitiveInvertPoint: primitiveInvertPoint, | |
primitiveInvertRectInto: primitiveInvertRectInto, | |
primitiveIsIdentity: primitiveIsIdentity, | |
primitiveComposeMatrix: primitiveComposeMatrix, | |
setInterpreter: setInterpreter, | |
primitiveTransformRectInto: primitiveTransformRectInto, | |
primitiveIsPureTranslation: primitiveIsPureTranslation, | |
getModuleName: getModuleName, | |
primitiveTransformPoint: primitiveTransformPoint, | |
}); | |
} else self.setTimeout(registerPlugin, 100); | |
} | |
registerPlugin(); | |
})(); // Register module/plugin | |