diff --git a/image/private/js-impl.js b/image/private/js-impl.js index 14d1ab6..e57f763 100644 --- a/image/private/js-impl.js +++ b/image/private/js-impl.js @@ -143,6 +143,9 @@ var checkPointsCount = plt.baselib.check.makeCheckArgumentType( "positive integer greater than or equal to 2"); +var checkListofColor = plt.baselib.check.makeCheckListofArgumenType( + isColor, + 'color'); @@ -162,6 +165,57 @@ EXPORTS['image-color?'] = +EXPORTS['mode?'] = + makePrimitiveProcedure( + 'mode?', + 1, + function(MACHINE) { + return isMode(MACHINE.env[MACHINE.env.length - 1]); + }); + +EXPORTS['x-place?'] = + makePrimitiveProcedure( + 'x-place?', + 1, + function(MACHINE) { + return isPlaceX(MACHINE.env[MACHINE.env.length - 1]); + }); + +EXPORTS['y-place?'] = + makePrimitiveProcedure( + 'y-place?', + 1, + function(MACHINE) { + return isPlaceY(MACHINE.env[MACHINE.env.length - 1]); + }); + +EXPORTS['angle?'] = + makePrimitiveProcedure( + 'angle?', + 1, + function(MACHINE) { + return isAngle(MACHINE.env[MACHINE.env.length - 1]); + }); + +EXPORTS['side-count?'] = + makePrimitiveProcedure( + 'side-count?', + 1, + function(MACHINE) { + return isSideCount(MACHINE.env[MACHINE.env.length - 1]); + }); + + +EXPORTS['step-count?'] = + makePrimitiveProcedure( + 'step-count?', + 1, + function(MACHINE) { + return isStepCount(MACHINE.env[MACHINE.env.length - 1]); + }); + + + EXPORTS['text'] = makePrimitiveProcedure( 'text', @@ -914,113 +968,56 @@ EXPORTS['image->color-list'] = }); -// EXPORTS['color-list->image'] = -// makePrimitiveProcedure( -// 'color-list->image', -// ???, -// function(MACHINE) { -// ... -// }); -// EXPORTS['image-width'] = -// makePrimitiveProcedure( -// 'image-width', -// ???, -// function(MACHINE) { -// ... -// }); +EXPORTS['color-list->image'] = + makePrimitiveProcedure( + 'color-list->image', + 5, + function(MACHINE) { + var listOfColors = checkListOfColor(MACHINE, 'color-list->image', 0); + var width = checkNatural(MACHINE, 'color-list->image', 1); + var height = checkNatural(MACHINE, 'color-list->image', 2); + var pinholeX = checkNatural(MACHINE, 'color-list->image', 3); + var pinholeY = checkNatural(MACHINE, 'color-list->image', 4); + + return colorListToImage(listOfColors, + width, + height, + pinholeX, + pinholeY); + }); + + + +EXPORTS['image-width'] = + makePrimitiveProcedure( + 'image-width', + 1, + function(MACHINE) { + var img = checkImage(MACHINE, 'image-width', 0); + return img.getWidth(); + }); + +EXPORTS['image-height'] = + makePrimitiveProcedure( + 'image-height', + 1, + function(MACHINE) { + var img = checkImage(MACHINE, 'image-height', 0); + return img.getHeight(); + }); + +EXPORTS['image-baseline'] = + makePrimitiveProcedure( + 'image-baseline', + 1, + function(MACHINE) { + var img = checkImage(MACHINE, 'image-baseline', 0); + return img.getBaseline(); + }); + + + -// EXPORTS['image-height'] = -// makePrimitiveProcedure( -// 'image-height', -// ???, -// function(MACHINE) { -// ... -// }); - -// EXPORTS['image-baseline'] = -// makePrimitiveProcedure( -// 'image-baseline', -// ???, -// function(MACHINE) { -// ... -// }); - -// EXPORTS['image-color?'] = -// makePrimitiveProcedure( -// 'image-color?', -// ???, -// function(MACHINE) { -// ... -// }); - -// EXPORTS['mode?'] = -// makePrimitiveProcedure( -// 'mode?', -// ???, -// function(MACHINE) { -// ... -// }); - -// EXPORTS['x-place?'] = -// makePrimitiveProcedure( -// 'x-place?', -// ???, -// function(MACHINE) { -// ... -// }); - -// EXPORTS['y-place?'] = -// makePrimitiveProcedure( -// 'y-place?', -// ???, -// function(MACHINE) { -// ... -// }); - -// EXPORTS['angle?'] = -// makePrimitiveProcedure( -// 'angle?', -// ???, -// function(MACHINE) { -// ... -// }); - -// EXPORTS['side-count?'] = -// makePrimitiveProcedure( -// 'side-count?', -// ???, -// function(MACHINE) { -// ... -// }); - -// EXPORTS['image-url'] = -// makePrimitiveProcedure( -// 'image-url', -// ???, -// function(MACHINE) { -// ... -// }); -// EXPORTS['open-image-url'] = -// makePrimitiveProcedure( -// 'open-image-url', -// ???, -// function(MACHINE) { -// ... -// }); -// EXPORTS['color-list->image'] = -// makePrimitiveProcedure( -// 'color-list->image', -// ???, -// function(MACHINE) { -// ... -// }); -// EXPORTS['step-count?'] = -// makePrimitiveProcedure( -// 'step-count?', -// ???, -// function(MACHINE) { -// ... -// }); diff --git a/image/private/kernel.js b/image/private/kernel.js index 909c83c..cce8d58 100644 --- a/image/private/kernel.js +++ b/image/private/kernel.js @@ -11,6 +11,7 @@ var isColor = colorStruct.predicate; var colorRed = function(c) { return colorStruct.accessor(c, 0); }; var colorGreen = function(c) { return colorStruct.accessor(c, 1); }; var colorBlue = function(c) { return colorStruct.accessor(c, 2); }; +var colorAlpha = function(c) { return colorStruct.accessor(c, 3); }; ////////////////////////////////////////////////////////////////////// var heir = plt.baselib.heir; @@ -44,9 +45,9 @@ var isColorOrColorString = function(thing) { var colorString = function(aColor) { return ("rgb(" + - types.colorRed(aColor) + "," + - types.colorGreen(aColor) + ", " + - types.colorBlue(aColor) + ")"); + colorRed(aColor) + "," + + colorGreen(aColor) + ", " + + colorBlue(aColor) + ")"); }; @@ -975,7 +976,7 @@ PolygonImage.prototype.equals = function(other, aUnionFind) { this.step == other.step && this.count == other.count && this.style == other.style && - types.equals(this.color, other.color, aUnionFind)); + plt.baselib.equality.equals(this.color, other.color, aUnionFind)); }; @@ -1087,7 +1088,7 @@ TextImage.prototype.equals = function(other, aUnionFind) { this.style == other.style && this.weight == other.weight && this.underline == other.underline && - types.equals(this.color, other.color, aUnionFind) && + plt.baselib.equality.equals(this.color, other.color, aUnionFind) && this.font == other.font); }; @@ -1144,7 +1145,7 @@ StarImage.prototype.equals = function(other, aUnionFind) { this.outer == other.outer && this.inner == other.inner && this.style == other.style && - types.equals(this.color, other.color, aUnionFind)); + plt.baselib.equality.equals(this.color, other.color, aUnionFind)); }; @@ -1201,7 +1202,7 @@ TriangleImage.prototype.equals = function(other, aUnionFind) { this.side == other.side && this.angle == other.angle && this.style == other.style && - types.equals(this.color, other.color, aUnionFind)); + plt.baselib.equality.equals(this.color, other.color, aUnionFind)); }; ///////////////////////////////////////////////////////////////////// @@ -1247,7 +1248,7 @@ RightTriangleImage.prototype.equals = function(other, aUnionFind) { this.side1 == other.side1 && this.side2 == other.side2 && this.style == other.style && - types.equals(this.color, other.color, aUnionFind)); + plt.baselib.equality.equals(this.color, other.color, aUnionFind)); }; ////////////////////////////////////////////////////////////////////// @@ -1301,7 +1302,7 @@ EllipseImage.prototype.equals = function(other, aUnionFind) { this.width == other.width && this.height == other.height && this.style == other.style && - types.equals(this.color, other.color, aUnionFind)); + plt.baselib.equality.equals(this.color, other.color, aUnionFind)); }; @@ -1373,7 +1374,7 @@ LineImage.prototype.equals = function(other, aUnionFind) { this.pinholeY == other.pinholeY && this.x == other.x && this.y == other.y && - types.equals(this.color, other.color, aUnionFind)); + plt.baselib.equality.equals(this.color, other.color, aUnionFind)); }; @@ -1401,13 +1402,38 @@ var imageToColorList = function(img) { g = data[i+1]; b = data[i+2]; a = data[i+3]; - // FIXME: what to do about the alpha component? - colors.push(types.color(r, g, b)); + colors.push(makeColor(r, g, b, a)); } return plt.baselib.lists.makeList.apply(null, colors); } +var colorListToImage = function(listOfColors, + width, + height, + pinholeX, + pinholeY) { + var canvas = makeCanvas(jsnums.toFixnum(width), + jsnums.toFixnum(height)), + ctx = canvas.getContext("2d"), + imageData = ctx.createImageData(jsnums.toFixnum(width), + jsnums.toFixnum(height)), + data = imageData.data, + aColor, i = 0; + while (listOfColors !== plt.baselib.lists.EMPTY) { + aColor = listOfColors.first; + data[i] = jsnums.toFixnum(colorRed(aColor)); + data[i+1] = jsnums.toFixnum(colorGreen(aColor)); + data[i+2] = jsnums.toFixnum(colorBlue(aColor)); + data[i+3] = jsnums.toFixnum(colorAlpha(aColor)); + + i += 4; + listOfColors = listOfColors.rest; + }; + + return makeImageDataImage(imageData); +}; + @@ -1513,6 +1539,9 @@ var isFileVideo = function(x) { return x instanceof FileVideo; }; /////////////////////////////////////////////////////////////// // Exports +// These functions are available for direct access without the typechecks +// of the Racket-exposed functions. + EXPORTS.makeCanvas = makeCanvas; @@ -1542,9 +1571,6 @@ EXPORTS.StarImage = StarImage; - - - EXPORTS.colorDb = colorDb; EXPORTS.makeSceneImage = makeSceneImage; @@ -1570,7 +1596,7 @@ EXPORTS.makeFileImage = makeFileImage; EXPORTS.makeVideoImage = makeVideoImage; EXPORTS.imageToColorList = imageToColorList; - +EXPORTS.colorListToImage = colorListToImage; EXPORTS.isImage = isImage; @@ -1602,3 +1628,12 @@ EXPORTS.isFlipImage = isFlipImage; EXPORTS.isTextImage = isTextImage; EXPORTS.isFileImage = isFileImage; EXPORTS.isFileVideo = isFileVideo; + + + +EXPORTS.makeColor = makeColor; +EXPORTS.isColor = isColor; +EXPORTS.colorRed = colorRed; +EXPORTS.colorGreen = colorGreen; +EXPORTS.colorBlue = colorBlue; +EXPORTS.colorAlpha = colorAlpha; \ No newline at end of file diff --git a/js-assembler/runtime-src/baselib-check.js b/js-assembler/runtime-src/baselib-check.js index ffb9ce8..4ed658a 100644 --- a/js-assembler/runtime-src/baselib-check.js +++ b/js-assembler/runtime-src/baselib-check.js @@ -4,6 +4,12 @@ var exports = {}; baselib.check = exports; + var EMPTY = plt.baselib.lists.EMPTY; + var isPair = plt.baselib.lists.isPair; + var makeLowLevelEqHash = plt.baselib.hash.makeLowLevelEqHash; + + + ////////////////////////////////////////////////////////////////////// var makeCheckArgumentType = function(predicate, predicateName) { return function(MACHINE, callerName, position) { @@ -19,6 +25,47 @@ }; + var makeCheckListofArgumentType = function(predicate, predicateName) { + var listPredicate = function(x) { + var seen = makeLowLevelEqHash(); + while (true) { + if (x === EMPTY){ + return true; + } + + if (!isPair(x)) { + return false; + } + + if(seen.containsKey(x)) { + // raise an error? we've got a cycle! + return false + } + + if (! predicate(x.first)) { + return false; + } + + seen.put(x, true); + x = x.rest; + } + }; + return function(MACHINE, callerName, position) { + testArgument( + MACHINE, + 'list of ' + predicateName, + listPredicate, + MACHINE.env[MACHINE.env.length - 1 - position], + position, + callerName); + return MACHINE.env[MACHINE.env.length - 1 - position]; + } + }; + + + + + // testArgument: (X -> boolean) X number string string -> boolean // Produces true if val is true, and otherwise raises an error. @@ -131,6 +178,7 @@ exports.testArgument = testArgument; exports.testArity = testArity; exports.makeCheckArgumentType = makeCheckArgumentType; + exports.makeCheckListofArgumentType = makeCheckListofArgumentType; exports.checkOutputPort = checkOutputPort; exports.checkString = checkString;