diff --git a/scripts/javascript/examples/colorwheel.pjs b/scripts/javascript/examples/colorwheel.pjs new file mode 100644 index 00000000..8336ca1b --- /dev/null +++ b/scripts/javascript/examples/colorwheel.pjs @@ -0,0 +1,66 @@ +// All Examples Written by Casey Reas and Ben Fry +// unless otherwise stated. +int segs = 12; +int steps = 6; +float rotAdjust = radians(360.0/segs/2.0); +float radius = 95.0; +float segWidth = radius/steps; +float interval = TWO_PI/segs; +int SHADE = 0; +int TINT = 1; + +void setup(){ + size(200, 200); + background(127); + smooth(); + ellipseMode(CENTER_RADIUS); + noStroke(); + // you can substitue TINT for SHADE argument + createWheel(width/2, height/2, SHADE); +} + +void createWheel(int x, int y, int valueShift){ + if (valueShift == SHADE){ + for (int j=0; j 1) { + level = level - 1; + int num = int(random(2, 6)); + for(int i=0; i= 4 ){ redRange = range1; greenRange = range2; blueRange = range3; } + if( arguments.length >= 4 ){ + redRange = range1; + greenRange = range2; + blueRange = range3; + } if( arguments.length == 5 ){ opacityRange = range4; } - if( arguments.length == 2 ){ p.colorMode( mode, range1, range1, range1, range1 ); } + if( arguments.length == 2 ){ + p.colorMode( mode, range1, range1, range1, range1 ); + } }; @@ -723,11 +711,11 @@ // Canvas-Matrix manipulation //////////////////////////////////////////////////////////////////////////// - p.translate = function translate( x, y ){ curContext.translate( x, y ); }; - p.scale = function scale( x, y ) { curContext.scale( x, y || x ); }; - p.rotate = function rotate( aAngle ) { curContext.rotate( aAngle ); }; - p.pushMatrix = function pushMatrix() { curContext.save(); }; - p.popMatrix = function popMatrix() { curContext.restore(); }; + p.translate = function translate( x, y ){ p.context.translate( x, y ); }; + p.scale = function scale( x, y ) { p.context.scale( x, y || x ); }; + p.rotate = function rotate( aAngle ) { p.context.rotate( aAngle ); }; + p.pushMatrix = function pushMatrix() { p.context.save(); }; + p.popMatrix = function popMatrix() { p.context.restore(); }; p.ortho = function ortho(){}; @@ -759,28 +747,19 @@ p.loop = function loop(){ if( loopStarted ){ return; } - - looping = setInterval( function(){ - - try { - try{ - p.focused = document.hasFocus(); - }catch(e){} - p.redraw(); - } - catch( e ){ - clearInterval( looping ); - throw e; - } - }, curMsPerFrame ); - - loopStarted = true; - + + looping = new TriggerController(); + register_controller(looping) + looping.frame = function() { + p.redraw(); + } + loopStarter = true; }; p.frameRate = function frameRate( aRate ){ - curFrameRate = aRate; - curMsPerFrame = 1000 / curFrameRate; + // curFrameRate = aRate; + // curMsPerFrame = 1000 / curFrameRate; + set_fps( aRate ); }; p.exit = function exit(){ @@ -797,19 +776,13 @@ p.beginDraw = function beginDraw(){}; p.endDraw = function endDraw(){}; - p.ajax = ajax; - - // Imports an external Processing.js library - p.Import = function Import( lib ){ - eval( p.ajax( lib ) ); - } - p.disableContextMenu = function disableContextMenu(){ - curElement.addEventListener( 'contextmenu', function( e ){ - e.preventDefault(); - e.stopPropagation(); - }, false ); - } + // p.disableContextMenu = function disableContextMenu(){ + // curElement.addEventListener( 'contextmenu', function( e ){ + // e.preventDefault(); + // e.stopPropagation(); + // }, false ); + // } @@ -890,7 +863,8 @@ //function i use to convert RGB to hex values p.RGB2HTML = function RGB2HTML(red, green, blue) { var char = "0123456789ABCDEF"; - return String(char.charAt(Math.floor(rgb / 16))) + String(char.charAt(rgb - (Math.floor(rgb / 16) * 16))); + rgb_div = Math.floor(rgb / 16); + return String( char.charAt(rgb_div) ) + String(char.charAt(rgb - (rgb_div * 16))); } //function i use to convert decimals to a padded hex value @@ -1129,23 +1103,24 @@ // Math functions //////////////////////////////////////////////////////////////////////////// - p.sq = function sq ( aNumber ){ return aNumber * aNumber; }; - p.sqrt = function sqrt ( aNumber ){ return Math.sqrt( aNumber ); }; - p.int = function int ( aNumber ){ return Math.floor( aNumber ); }; - p.min = function min ( aNumber, aNumber2 ){ return Math.min( aNumber, aNumber2 ); }; - p.max = function max ( aNumber, aNumber2 ){ return Math.max( aNumber, aNumber2 ); }; - p.floor = function floor ( aNumber ){ return Math.floor( aNumber ); }; - p.float = function float ( aNumber ){ return parseFloat( aNumber ); }; - p.ceil = function ceil ( aNumber ){ return Math.ceil( aNumber ); }; - p.round = function round ( aNumber ){ return Math.round( aNumber ); }; - p.lerp = function lerp ( value1, value2, amt ){ return ( ( value2 - value1 ) * amt ) + value1; }; - p.abs = function abs ( aNumber ){ return Math.abs( aNumber ); }; - p.cos = function cos ( aNumber ){ return Math.cos( aNumber ); }; - p.sin = function sin ( aNumber ){ return Math.sin( aNumber ); }; - p.pow = function pow ( aNumber, aExponent ){ return Math.pow( aNumber, aExponent ); }; - p.sqrt = function sqrt ( aNumber ){ return Math.sqrt( aNumber ); }; - p.atan2 = function atan2 ( aNumber, aNumber2 ){ return Math.atan2( aNumber, aNumber2 ); }; - p.radians = function radians( aAngle ){ return ( aAngle / 180 ) * p.PI; }; + p.sq = function sq ( aNumber ){ return aNumber * aNumber; }; + p.sqrt = function sqrt ( aNumber ){ return Math.sqrt( aNumber ); }; + p.int = function int ( aNumber ){ return Math.floor( aNumber ); }; + p.min = function min ( aNumber, aNumber2 ){ return Math.min( aNumber, aNumber2 ); }; + p.max = function max ( aNumber, aNumber2 ){ return Math.max( aNumber, aNumber2 ); }; + p.floor = function floor ( aNumber ){ return Math.floor( aNumber ); }; + p.float = function float ( aNumber ){ return parseFloat( aNumber ); }; + p.ceil = function ceil ( aNumber ){ return Math.ceil( aNumber ); }; + p.round = function round ( aNumber ){ return Math.round( aNumber ); }; + p.lerp = function lerp ( value1, value2, amt ){ + return ( ( value2 - value1 ) * amt ) + value1; }; + p.abs = function abs ( aNumber ){ return Math.abs( aNumber ); }; + p.cos = function cos ( aNumber ){ return Math.cos( aNumber ); }; + p.sin = function sin ( aNumber ){ return Math.sin( aNumber ); }; + p.pow = function pow ( aNumber, aExponent ){ return Math.pow( aNumber, aExponent );}; + p.sqrt = function sqrt ( aNumber ){ return Math.sqrt( aNumber ); }; + p.atan2 = function atan2 ( aNumber, aNumber2 ){ return Math.atan2( aNumber, aNumber2 );}; + p.radians = function radians( aAngle ){ return ( aAngle / 180 ) * p.PI; }; p.dist = function dist( x1, y1, x2, y2 ){ return Math.sqrt( Math.pow( x2 - x1, 2 ) + Math.pow( y2 - y1, 2 ) ); @@ -1285,16 +1260,29 @@ // Changes the size of the Canvas ( this resets context properties like 'lineCap', etc. p.size = function size( aWidth, aHeight ){ - - var props = { fillStyle : curContext.fillStyle, - strokeStyle : curContext.strokeStyle, - lineCap : curContext.lineCap - } // More to be added... - - curElement.width = p.width = aWidth; - curElement.height = p.height = aHeight; - for( var i in props ){ curContext[ i ] = props[ i ] }; + p.context = new VectorLayer(aWidth, aHeight); + + p.context.start(); + + add_layer(p.context); + + p.width = aWidth; + p.height = aHeight; + + srand(); + + var props = { fillStyle : p.context.fillStyle, + strokeStyle : p.context.strokeStyle, + lineCap : p.context.lineCap + } // More to be added... + + // curElement.width = p.width = aWidth; + // curElement.height = p.height = aHeight; + + // for( var i in props ){ + // p.context[ i ] = props[ i ] + // }; }; // PVector instantiation @@ -1486,18 +1474,33 @@ p.smooth = function smooth() {}; p.noSmooth = function noSmooth() {}; - p.fill = function fill(){ - doFill = true; - curContext.fillStyle = p.color.apply( this, arguments ); + p.fill = function(){ + if(arguments.length) + p.context.set_color.apply(p.context, arguments); + // p.context.fillStyle = p.context.set_color.apply( this, arguments ); + doFill = true; + p.endShape(); }; - p.stroke = function stroke(){ - doStroke = true; - curContext.strokeStyle = p.color.apply( this, arguments ); - }; + p.stroke = function() { + if(arguments.length) { + p.context.set_color.apply(p.context, arguments); + } + // p.context.strokeStyle = p.context.set_color.apply( this, arguments ); + doStroke = true; + p.endShape(); + } + + // echo ("STROKE args: " + arguments); + // doStroke = true; + // doStrokeArgs = arguments + // // our own freej color function -jrml + // // p.context.color.apply(p.context, arguments); + + // }; p.strokeWeight = function strokeWeight( w ){ - curContext.lineWidth = w; + p.context.lineWidth = w; }; @@ -1515,10 +1518,10 @@ }; p.point = function point( x, y ){ - var oldFill = curContext.fillStyle; - curContext.fillStyle = curContext.strokeStyle; - curContext.fillRect( Math.round( x ), Math.round( y ), 1, 1 ); - curContext.fillStyle = oldFill; + var oldFill = p.context.fillStyle; + p.context.fillStyle = p.context.strokeStyle; + p.context.fillRect( Math.round( x ), Math.round( y ), 1, 1 ); + p.context.fillStyle = oldFill; }; p.beginShape = function beginShape( type ){ @@ -1531,11 +1534,11 @@ if( curShapeCount != 0 ){ - if( close || doFill ){ curContext.lineTo( firstX, firstY ); } - if( doFill ){ curContext.fill(); } - if( doStroke ){ curContext.stroke(); } + if( close || doFill ){ p.context.lineTo( firstX, firstY ); } + if( doFill ){ p.context.fill(); } + if( doStroke ){ p.context.stroke(); } - curContext.closePath(); + p.context.closePath(); curShapeCount = 0; pathOpen = false; @@ -1543,10 +1546,10 @@ if( pathOpen ){ - if ( doFill ){ curContext.fill(); } - if ( doStroke ){ curContext.stroke(); } + if ( doFill ){ p.context.fill(); } + if ( doStroke ){ p.context.stroke(); } - curContext.closePath(); + p.context.closePath(); curShapeCount = 0; pathOpen = false; @@ -1559,8 +1562,8 @@ if( curShapeCount == 0 && curShape != p.POINTS ){ pathOpen = true; - curContext.beginPath(); - curContext.moveTo( x, y ); + p.context.beginPath(); + p.context.moveTo( x, y ); firstX = x; firstY = y; @@ -1574,7 +1577,7 @@ if( curShape != p.QUAD_STRIP || curShapeCount != 2 ){ - curContext.lineTo( x, y ); + p.context.lineTo( x, y ); } @@ -1585,11 +1588,11 @@ // finish shape p.endShape( p.CLOSE ); pathOpen = true; - curContext.beginPath(); + p.context.beginPath(); // redraw last line to start next shape - curContext.moveTo( prevX, prevY ); - curContext.lineTo( x, y ); + p.context.moveTo( prevX, prevY ); + p.context.lineTo( x, y ); curShapeCount = 1; } @@ -1604,11 +1607,11 @@ // finish shape p.endShape( p.CLOSE) ; pathOpen = true; - curContext.beginPath(); + p.context.beginPath(); // redraw last line to start next shape - curContext.moveTo( firstX, firstY ); - curContext.lineTo( x, y ); + p.context.moveTo( firstX, firstY ); + p.context.lineTo( x, y ); curShapeCount = 1; } @@ -1616,14 +1619,14 @@ if( curShape == p.QUAD_STRIP && curShapeCount == 3 ){ // finish shape - curContext.lineTo( prevX, prevY ); + p.context.lineTo( prevX, prevY ); p.endShape(p.CLOSE); pathOpen = true; - curContext.beginPath(); + p.context.beginPath(); // redraw lines to start next shape - curContext.moveTo( prevX, prevY ); - curContext.lineTo( x, y ); + p.context.moveTo( prevX, prevY ); + p.context.lineTo( x, y ); curShapeCount = 1; } @@ -1641,15 +1644,15 @@ if( curShapeCount > 1 ){ - curContext.moveTo( prevX, prevY ); - curContext.quadraticCurveTo( firstX, firstY, x, y ); + p.context.moveTo( prevX, prevY ); + p.context.quadraticCurveTo( firstX, firstY, x, y ); curShapeCount = 1; } }else if( arguments.length == 6 ){ - curContext.bezierCurveTo( x, y, x2, y2, x3, y3 ); + p.context.bezierCurveTo( x, y, x2, y2, x3, y3 ); } } @@ -1689,8 +1692,10 @@ curvePoints.push( [ x, y ] ); b[ 0 ] = [ curvePoints[ 1 ][ 0 ], curvePoints[ 1 ][ 1 ] ]; - b[ 1 ] = [ curvePoints[ 1 ][ 0 ] + ( s * curvePoints[ 2 ][ 0 ] - s * curvePoints[ 0 ][ 0 ] ) / 6, curvePoints[ 1 ][ 1 ] + ( s * curvePoints[ 2 ][ 1 ] - s * curvePoints[ 0 ][ 1 ] ) / 6 ]; - b[ 2 ] = [ curvePoints[ 2 ][ 0 ] + ( s * curvePoints[ 1 ][ 0 ] - s * curvePoints[ 3 ][ 0 ] ) / 6, curvePoints[ 2 ][ 1 ] + ( s * curvePoints[ 1 ][ 1 ] - s * curvePoints[ 3 ][ 1 ] ) / 6 ]; + b[ 1 ] = [ curvePoints[ 1 ][ 0 ] + ( s * curvePoints[ 2 ][ 0 ] - s * curvePoints[ 0 ][ 0 ] ) / 6, + curvePoints[ 1 ][ 1 ] + ( s * curvePoints[ 2 ][ 1 ] - s * curvePoints[ 0 ][ 1 ] ) / 6 ]; + b[ 2 ] = [ curvePoints[ 2 ][ 0 ] + ( s * curvePoints[ 1 ][ 0 ] - s * curvePoints[ 3 ][ 0 ] ) / 6, + curvePoints[ 2 ][ 1 ] + ( s * curvePoints[ 1 ][ 1 ] - s * curvePoints[ 3 ][ 1 ] ) / 6 ]; b[ 3 ] = [ curvePoints[ 2 ][ 0 ], curvePoints[ 2 ][ 1 ] ]; if( !pathOpen ){ @@ -1730,34 +1735,35 @@ y += height / 2; } - curContext.moveTo( x, y ); - curContext.beginPath(); - curContext.arc( x, y, curEllipseMode == p.CENTER_RADIUS ? width : width/2, start, stop, false ); + p.context.moveTo( x, y ); + p.context.beginPath(); + p.context.arc( x, y, curEllipseMode == p.CENTER_RADIUS ? width : width/2, start, stop, false ); - if( doStroke ){ curContext.stroke(); } - curContext.lineTo( x, y ); + if( doStroke ){ p.context.stroke(); } + p.context.lineTo( x, y ); - if( doFill ){ curContext.fill(); } - curContext.closePath(); + if( doFill ){ p.context.fill(); } + p.context.closePath(); }; - + + // QUAAA optimize by implementing these iterations in C++ p.line = function line( x1, y1, x2, y2 ){ - curContext.lineCap = "round"; - curContext.beginPath(); - curContext.moveTo( x1 || 0, y1 || 0 ); - curContext.lineTo( x2 || 0, y2 || 0 ); - curContext.stroke(); - curContext.closePath(); + p.context.lineCap = "round"; + p.context.beginPath(); + p.context.moveTo( x1, y1 ); + p.context.lineTo( x2, y2 ); + p.context.stroke(); + p.context.closePath(); }; p.bezier = function bezier( x1, y1, x2, y2, x3, y3, x4, y4 ){ - curContext.lineCap = "butt"; - curContext.beginPath(); - curContext.moveTo( x1, y1 ); - curContext.bezierCurveTo( x2, y2, x3, y3, x4, y4 ); - curContext.stroke(); - curContext.closePath(); + p.context.lineCap = "butt"; + p.context.beginPath(); + p.context.moveTo( x1, y1 ); + p.context.bezierCurveTo( x2, y2, x3, y3, x4, y4 ); + p.context.stroke(); + p.context.closePath(); }; p.triangle = function triangle( x1, y1, x2, y2, x3, y3 ){ @@ -1769,7 +1775,7 @@ }; p.quad = function quad( x1, y1, x2, y2, x3, y3, x4, y4 ){ - curContext.lineCap = "square"; + p.context.lineCap = "square"; p.beginShape(); p.vertex( x1, y1 ); p.vertex( x2, y2 ); @@ -1782,7 +1788,7 @@ if( !( width + height ) ){ return; } - curContext.beginPath(); + p.context.beginPath(); var offsetStart = 0; var offsetEnd = 0; @@ -1802,17 +1808,17 @@ y -= height / 2; } - curContext.rect( + p.context.rect( Math.round( x ) - offsetStart, Math.round( y ) - offsetStart, Math.round( width ) + offsetEnd, Math.round( height ) + offsetEnd ); - if( doFill ){ curContext.fill(); } - if( doStroke ){ curContext.stroke() }; + if( doFill ){ p.context.fill(); } + if( doStroke ){ p.context.stroke() }; - curContext.closePath(); + p.context.closePath(); }; @@ -1823,7 +1829,7 @@ if( width <= 0 && height <= 0 ){ return; } - curContext.beginPath(); + p.context.beginPath(); if( curEllipseMode == p.RADIUS ){ width *= 2; @@ -1835,7 +1841,7 @@ // Shortcut for drawing a circle if( width == height ){ - curContext.arc( x - offsetStart, y - offsetStart, width / 2, 0, p.TWO_PI, false ); + p.context.arc( x - offsetStart, y - offsetStart, width / 2, 0, p.TWO_PI, false ); }else{ @@ -1846,18 +1852,18 @@ c_y = C * h; //! Do we still need this? I hope the Canvas arc() more capable by now? - curContext.moveTo( x + w, y ); - curContext.bezierCurveTo( x+w , y-c_y , x+c_x , y-h , x , y-h ); - curContext.bezierCurveTo( x-c_x , y-h , x-w , y-c_y , x-w , y ); - curContext.bezierCurveTo( x-w , y+c_y , x-c_x , y+h, x, y+h ); - curContext.bezierCurveTo( x+c_x , y+h , x+w , y+c_y , x+w , y ); + p.context.moveTo( x + w, y ); + p.context.bezierCurveTo( x+w , y-c_y , x+c_x , y-h , x , y-h ); + p.context.bezierCurveTo( x-c_x , y-h , x-w , y-c_y , x-w , y ); + p.context.bezierCurveTo( x-w , y+c_y , x-c_x , y+h, x, y+h ); + p.context.bezierCurveTo( x+c_x , y+h , x+w , y+c_y , x+w , y ); } - if( doFill ){ curContext.fill(); } - if( doStroke ){ curContext.stroke(); } + if( doFill ){ p.context.fill(); } + if( doStroke ){ p.context.stroke(); } - curContext.closePath(); + p.context.closePath(); }; @@ -1898,32 +1904,32 @@ }; // Gets a single pixel or block of pixels from the current Canvas Context - p.get = function get( x, y ){ + // p.get = function get( x, y ){ - if( !arguments.length ){ - var c = p.createGraphics( p.width, p.height ); - c.image( curContext, 0, 0 ); - return c; - } + // if( !arguments.length ){ + // var c = p.createGraphics( p.width, p.height ); + // c.image( p.context, 0, 0 ); + // return c; + // } - if( !getLoaded ){ - getLoaded = buildImageObject( curContext.getImageData( 0, 0, p.width, p.height ) ); - } + // if( !getLoaded ){ + // getLoaded = buildImageObject( p.context.getImageData( 0, 0, p.width, p.height ) ); + // } - return getLoaded.get( x, y ); + // return getLoaded.get( x, y ); - }; + // }; - // Creates a new Processing instance and passes it back for... processing - p.createGraphics = function createGraphics( w, h ){ + // // Creates a new Processing instance and passes it back for... processing + // p.createGraphics = function createGraphics( w, h ){ - var canvas = document.createElement( "canvas" ); - var ret = buildProcessing( canvas ); - ret.size( w, h ); - ret.canvas = canvas; - return ret; + // var canvas = document.createElement( "canvas" ); + // var ret = buildProcessing( canvas ); + // ret.size( w, h ); + // ret.canvas = canvas; + // return ret; - }; + // }; // Paints a pixel array into the canvas p.set = function set( x, y, obj ){ @@ -1934,12 +1940,12 @@ }else{ - var oldFill = curContext.fillStyle, + var oldFill = p.context.fillStyle, color = obj; - curContext.fillStyle = color; - curContext.fillRect( Math.round( x ), Math.round( y ), 1, 1 ); - curContext.fillStyle = oldFill; + p.context.fillStyle = color; + p.context.fillRect( Math.round( x ), Math.round( y ), 1, 1 ); + p.context.fillStyle = oldFill; } @@ -1947,7 +1953,7 @@ // Gets a 1-Dimensional pixel array from Canvas p.loadPixels = function(){ - p.pixels = buildImageObject( curContext.getImageData(0, 0, p.width, p.height) ).pixels; + p.pixels = buildImageObject( p.context.getImageData(0, 0, p.width, p.height) ).pixels; }; // Draws a 1-Dimensional pixel array to Canvas @@ -1960,8 +1966,8 @@ pixels.height = p.height; pixels.data = []; - if( curContext.createImageData ){ - pixels = curContext.createImageData( p.width, p.height ); + if( p.context.createImageData ){ + pixels = p.context.createImageData( p.width, p.height ); } var data = pixels.data, @@ -1980,36 +1986,38 @@ } - curContext.putImageData( pixels, 0, 0 ); + p.context.putImageData( pixels, 0, 0 ); }; // Draw an image or a color to the background p.background = function background( img ) { - - if( arguments.length ){ - - if( img.data && img.data.img ){ - curBackground = img.data; - }else{ - curBackground = p.color.apply( this, arguments ); - } - - } - if( curBackground.img ){ - - p.image( img, 0, 0 ); - - }else{ + if( arguments.length ){ + + if( img.data && img.data.img ){ + curBackground = img.data; + }else{ + p.context.set_color.apply(p.context, arguments); + // curBackground = p.color.apply( this, arguments ); + } + + } - var oldFill = curContext.fillStyle; - curContext.fillStyle = curBackground + ""; - curContext.fillRect( 0, 0, p.width, p.height ); - curContext.fillStyle = oldFill; - - } - + if( curBackground.img ){ + + p.image( img, 0, 0 ); + + }else{ + + // var oldFill = p.context.fillStyle; + // p.context.fillStyle = curBackground + ""; + p.context.set_color(0); + p.context.fillRect( 0, 0, p.width, p.height ); + // p.context.fillStyle = oldFill; + + } + }; p.AniSprite = function( prefix, frames ){ @@ -2087,8 +2095,8 @@ data.height = h; data.data = []; - if( curContext.createImageData ) { - data = curContext.createImageData( w, h ); + if( p.context.createImageData ) { + data = p.context.createImageData( w, h ); } data.pixels = new Array( w * h ); @@ -2179,22 +2187,22 @@ y = y || 0; var obj = getImage( img ); if( curTint >= 0 ){ - var oldAlpha = curContext.globalAlpha; - curContext.globalAlpha = curTint / opacityRange; + var oldAlpha = p.context.globalAlpha; + p.context.globalAlpha = curTint / opacityRange; } if( arguments.length == 3 ){ - curContext.drawImage( obj, x, y ); + p.context.drawImage( obj, x, y ); }else{ - curContext.drawImage( obj, x, y, w, h ); + p.context.drawImage( obj, x, y, w, h ); } if( curTint >= 0 ){ - curContext.globalAlpha = oldAlpha; + p.context.globalAlpha = oldAlpha; } if( img._mask ){ - var oldComposite = curContext.globalCompositeOperation; - curContext.globalCompositeOperation = "darker"; + var oldComposite = p.context.globalCompositeOperation; + p.context.globalCompositeOperation = "darker"; p.image( img._mask, x, y ); - curContext.globalCompositeOperation = oldComposite; + p.context.globalCompositeOperation = oldComposite; } }; @@ -2209,25 +2217,25 @@ var obj = getImage( img.data || img.canvas ); if( curTint >= 0 ){ - var oldAlpha = curContext.globalAlpha; - curContext.globalAlpha = curTint / opacityRange; + var oldAlpha = p.context.globalAlpha; + p.context.globalAlpha = curTint / opacityRange; } if( arguments.length == 3 ){ - curContext.drawImage( obj, x, y ); + p.context.drawImage( obj, x, y ); }else{ - curContext.drawImage( obj, x, y, w, h ); + p.context.drawImage( obj, x, y, w, h ); } if( curTint >= 0 ){ - curContext.globalAlpha = oldAlpha; + p.context.globalAlpha = oldAlpha; } if( img._mask ){ - var oldComposite = curContext.globalCompositeOperation; - curContext.globalCompositeOperation = "darker"; + var oldComposite = p.context.globalCompositeOperation; + p.context.globalCompositeOperation = "darker"; p.image( img._mask, x, y ); - curContext.globalCompositeOperation = oldComposite; + p.context.globalCompositeOperation = oldComposite; } } @@ -2241,9 +2249,9 @@ // Clears a rectangle in the Canvas element or the whole Canvas p.clear = function clear ( x, y, width, height ) { if( arguments.length == 0 ){ - curContext.clearRect( 0, 0, p.width, p.height ); + p.context.clearRect( 0, 0, p.width, p.height ); }else{ - curContext.clearRect( x, y, width, height ); + p.context.clearRect( x, y, width, height ); } } @@ -2265,8 +2273,8 @@ return { name: name, width: function( str ){ - if( curContext.mozMeasureText ){ - return curContext.mozMeasureText( + if( p.context.mozMeasureText ){ + return p.context.mozMeasureText( typeof str == "number" ? String.fromCharCode( str ) : str @@ -2382,16 +2390,16 @@ // If the font is a standard Canvas font... if( !curTextFont.glyph ){ - if( str && curContext.mozDrawText ){ + if( str && p.context.mozDrawText ){ - curContext.save(); - curContext.mozTextStyle = curTextSize + "px " + curTextFont.name; - curContext.translate( x, y ); - curContext.mozDrawText( + p.context.save(); + p.context.mozTextStyle = curTextSize + "px " + curTextFont.name; + p.context.translate( x, y ); + p.context.mozDrawText( typeof str == "number" ? String.fromCharCode( str ) : str ) ; - curContext.restore(); + p.context.restore(); } @@ -2399,13 +2407,13 @@ // If the font is a Batik SVG font... var font = p.glyphTable[ curTextFont.name ]; - curContext.save(); - curContext.translate( x, y + curTextSize ); + p.context.save(); + p.context.translate( x, y + curTextSize ); var upem = font[ "units_per_em" ], newScale = 1 / upem * curTextSize; - curContext.scale( newScale, newScale ); + p.context.scale( newScale, newScale ); var len = str.length; @@ -2415,7 +2423,7 @@ catch( e ){ ; } } - curContext.restore(); + p.context.restore(); } }; @@ -2499,7 +2507,7 @@ var c = regex( "[A-Za-z][0-9\- ]+|Z", d ); // Begin storing path object - var path = "var path={draw:function(){curContext.beginPath();curContext.save();"; + var path = "var path={draw:function(){p.context.beginPath();p.context.save();"; var x = 0, y = 0, @@ -2520,30 +2528,30 @@ switch( com[ 0 ] ){ - case "M": //curContext.moveTo(x,-y); + case "M": //p.context.moveTo(x,-y); x = parseFloat( xy[ 0 ][ 0 ] ); y = parseFloat( xy[ 1 ][ 0 ] ); //! Brackets needed on (-y)? - path += "curContext.moveTo("+ x +","+ (-y) +");"; + path += "p.context.moveTo("+ x +","+ (-y) +");"; break; - case "L": //curContext.lineTo(x,-y); + case "L": //p.context.lineTo(x,-y); x = parseFloat( xy[ 0 ][ 0 ] ); y = parseFloat( xy[ 1 ][ 0 ] ); - path += "curContext.lineTo("+ x +","+ (-y) +");"; + path += "p.context.lineTo("+ x +","+ (-y) +");"; break; - case "H"://curContext.lineTo(x,-y) + case "H"://p.context.lineTo(x,-y) x = parseFloat( xy[ 0 ][ 0 ] ); - path += "curContext.lineTo("+ x +","+ (-y) +");"; + path += "p.context.lineTo("+ x +","+ (-y) +");"; break; - case "V"://curContext.lineTo(x,-y); + case "V"://p.context.lineTo(x,-y); y = parseFloat( xy[ 0 ][ 0 ] ); - path += "curContext.lineTo("+ x +","+ (-y) +");"; + path += "p.context.lineTo("+ x +","+ (-y) +");"; break; - case "T"://curContext.quadraticCurveTo(cx,-cy,nx,-ny); + case "T"://p.context.quadraticCurveTo(cx,-cy,nx,-ny); nx = parseFloat( xy[ 0 ][ 0 ] ); ny = parseFloat( xy[ 1 ][ 0 ] ); @@ -2559,23 +2567,23 @@ cy = y; } - path += "curContext.quadraticCurveTo("+ cx +","+ (-cy) +","+ nx +","+ (-ny) +");"; + path += "p.context.quadraticCurveTo("+ cx +","+ (-cy) +","+ nx +","+ (-ny) +");"; x = nx; y = ny; break; - case "Q"://curContext.quadraticCurveTo(cx,-cy,nx,-ny); + case "Q"://p.context.quadraticCurveTo(cx,-cy,nx,-ny); cx = parseFloat( xy[ 0 ][ 0 ] ); cy = parseFloat( xy[ 1 ][ 0 ] ); nx = parseFloat( xy[ 2 ][ 0 ] ); ny = parseFloat( xy[ 3 ][ 0 ] ); - path += "curContext.quadraticCurveTo("+ cx +","+ (-cy) +","+ nx +","+ (-ny) +");"; + path += "p.context.quadraticCurveTo("+ cx +","+ (-cy) +","+ nx +","+ (-ny) +");"; x = nx; y = ny; break; - case "Z"://curContext.closePath(); - path += "curContext.closePath();"; + case "Z"://p.context.closePath(); + path += "p.context.closePath();"; break; } @@ -2584,10 +2592,10 @@ } - path += "doStroke?curContext.stroke():0;"; - path += "doFill?curContext.fill():0;"; - path += "curContext.restore();"; - path += "curContext.translate("+ horiz_adv_x +",0);"; + path += "doStroke?p.context.stroke():0;"; + path += "doFill?p.context.fill():0;"; + path += "p.context.restore();"; + path += "p.context.translate("+ horiz_adv_x +",0);"; path += "}}"; return path; @@ -2677,14 +2685,16 @@ p.init = function init(code){ - p.stroke( 0 ); - p.fill( 255 ); + // p.stroke( 0 ); + // p.fill( 255 ); // Canvas has trouble rendering single pixel stuff on whole-pixel // counts, so we slightly offset it (this is super lame). - curContext.translate( 0.5, 0.5 ); + // p.context.translate( 0.5, 0.5 ); + // luckily enough FreeJ is not-so-lame... + // The fun bit! if( code ){ (function( Processing ){ @@ -2713,7 +2723,7 @@ ////////////////////////////////////////////////////////////////////////// // Event handling ////////////////////////////////////////////////////////////////////////// - + /* attach( curElement, "mousemove" , function(e){ var scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset; @@ -2749,7 +2759,7 @@ if( typeof p.mousePressed != "function" ){ p.mousePressed = false; } if( p.mouseReleased ){ p.mouseReleased(); } }); - + /* attach( document, "keydown", function( e ){ keyPressed = true; p.key = e.keyCode + 32; @@ -2777,10 +2787,10 @@ }); function attach(elem, type, fn) { - if( elem.addEventListener ){ elem.addEventListener( type, fn, false ); } - else{ elem.attachEvent( "on" + type, fn ); } + // if( elem.addEventListener ){ elem.addEventListener( type, fn, false ); } + // else{ elem.attachEvent( "on" + type, fn ); } } - + */ }; return p; diff --git a/src/Makefile.am b/src/Makefile.am index bcb78f96..12df6a09 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -17,7 +17,7 @@ SOURCES = \ filter.cpp parameter.cpp \ jutils.cpp fastmemcpy.cpp \ ringbuffer.cpp convertvid.cpp \ - logging.cpp geometry.cpp \ + logging.cpp geometry.cpp color.cpp \ \ v4l_layer.cpp tvfreq.c unicap_layer.cpp \ video_layer.cpp image_layer.cpp \ diff --git a/src/audio_collector_js.cpp b/src/audio_collector_js.cpp index 9a295593..35a2445b 100644 --- a/src/audio_collector_js.cpp +++ b/src/audio_collector_js.cpp @@ -54,15 +54,14 @@ JS(js_audio_jack_constructor) { char excp_msg[MAX_ERR_MSG + 1]; char *port; - + JS_CHECK_ARGC(3); - JS_ARG_STRING(port,0); - JS_ARG_NUMBER(sample,1); - JS_ARG_NUMBER(rate,2); + JS_ARG_INT(sample,1); + JS_ARG_INT(rate,2); - AudioCollector *audio = new AudioCollector(port, (int)sample, (int)rate); + AudioCollector *audio = new AudioCollector(port, sample, rate); if( ! JS_SetPrivate(cx, obj, (void*)audio) ) { sprintf(excp_msg, "failed assigning audio jack to javascript"); @@ -121,7 +120,7 @@ JS(js_audio_jack_get_harmonic) { JS_CHECK_ARGC(1); - JS_ARG_NUMBER(hc,0); + JS_ARG_INT(hc,0); AudioCollector *audio = (AudioCollector*)JS_GetPrivate(cx, obj); if(!audio) { @@ -129,7 +128,7 @@ JS(js_audio_jack_get_harmonic) { goto error; } - harmonic = audio->GetHarmonic((int)hc); + harmonic = audio->GetHarmonic(hc); return JS_NewNumberValue(cx, (double)harmonic, rval); diff --git a/src/cairo_layer.cpp b/src/cairo_layer.cpp index f2cc5f03..6443176f 100644 --- a/src/cairo_layer.cpp +++ b/src/cairo_layer.cpp @@ -32,12 +32,17 @@ // our objects are allowed to be created trough the factory engine FACTORY_REGISTER_INSTANTIATOR(Layer, CairoLayer, VectorLayer, cairo); +CairoColor::CairoColor(cairo_t *cai) :Color() { cairo = cai; } +CairoColor::~CairoColor() { } +void CairoColor::set() { cairo_set_source_rgba(cairo, r, g, b, a); }; + CairoLayer::CairoLayer() :Layer() { surf = NULL; cairo = NULL; + color = NULL; pixels = NULL; set_name("VEC"); @@ -50,7 +55,7 @@ CairoLayer::~CairoLayer() { if(cairo) cairo_destroy(cairo); if(surf) cairo_surface_destroy(surf); if(pixels) free(pixels); - + if(color) free(color); } bool CairoLayer::_init() { @@ -66,6 +71,8 @@ bool CairoLayer::_init() { // cairo_surface_destroy() on it if you don't need to maintain a // separate reference to it. + color = new CairoColor( cairo ); + // test cairo_set_line_width(cairo, 0.1 ); cairo_set_source_rgb(cairo, 1.0, 1.0, 0.0); @@ -99,17 +106,17 @@ void CairoLayer::new_path() { cairo_new_path(cairo); } void CairoLayer::close_path() { cairo_close_path(cairo); } void CairoLayer::scale(double xx, double yy) { cairo_scale(cairo, xx, yy); } void CairoLayer::rotate(double angle) { cairo_rotate(cairo, angle); } -void CairoLayer::translate(double xx, double yy) { cairo_translate(cairo, xx, yy); } +void CairoLayer::translate(int xx, int yy) { cairo_translate(cairo, xx, yy); } void CairoLayer::move_to(double xx, double yy) { cairo_move_to(cairo, xx, yy); } void CairoLayer::line_to(double xx, double yy) { cairo_line_to(cairo, xx, yy); } -void CairoLayer::curve_to(double x1, double y1, double x2, double y2, double x3, double y3) { +void CairoLayer::curve_to(int x1, int y1, int x2, int y2, int x3, int y3) { cairo_curve_to(cairo, x1, y1, x2, y2, x3, y3); } void CairoLayer::arc(double xc, double yc, double radius, double angle1, double angle2) { cairo_arc(cairo, xc, yc, radius, angle1, angle2); } void CairoLayer::fill() { cairo_fill(cairo); } void CairoLayer::stroke() { cairo_stroke(cairo); } void CairoLayer::set_line_width(double wid) { cairo_set_line_width(cairo, wid); } -double CairoLayer::get_line_width() { return cairo_get_line_width(cairo); } +int CairoLayer::get_line_width() { return cairo_get_line_width(cairo); } // Mozilla's GFX compatibility API void CairoLayer::quad_curve_to(double x1, double y1, double x2, double y2) { diff --git a/src/cairo_layer_js.cpp b/src/cairo_layer_js.cpp index 394c7ce3..8c1417d5 100644 --- a/src/cairo_layer_js.cpp +++ b/src/cairo_layer_js.cpp @@ -34,6 +34,7 @@ DECLARE_CLASS_GC("VectorLayer", vector_layer_class, vector_layer_constructor, js JSFunctionSpec vector_layer_methods[] = { ENTRY_METHODS, + { "set_color", vector_layer_color, 4 }, { "translate", vector_layer_translate, 2 }, { "scale", vector_layer_scale, 2 }, { "rotate", vector_layer_rotate, 1 }, @@ -46,9 +47,9 @@ JSFunctionSpec vector_layer_methods[] = { { "bezierCurveTo", vector_layer_beziercurveto, 6 }, { "arc", vector_layer_arc, 5 }, { "closePath", vector_layer_closepath, 0 }, - { "fill", vector_layer_fill, 0 }, + { "fill", vector_layer_fill, 4 }, { "fillRect", vector_layer_fillrect, 4 }, - { "stroke", vector_layer_stroke, 0 }, + { "stroke", vector_layer_stroke, 4 }, {0} }; @@ -72,9 +73,9 @@ JS_CONSTRUCTOR("VectorLayer", vector_layer_constructor, CairoLayer); static inline void js_debug_property(JSContext *cx, jsval *vp) { - func("vp mem address %p", vp); + func(" vp mem address %p", vp); int tag = JSVAL_TAG(*vp); - func("type tag is %i: %s",tag, + func(" type tag is %i: %s",tag, (tag==0x0)?"object": (tag==0x1)?"integer": (tag==0x2)?"double": @@ -89,32 +90,32 @@ static inline void js_debug_property(JSContext *cx, jsval *vp) { jsval val; if( JS_IsArrayObject(cx, obj) ) { jsuint len; JS_GetArrayLength(cx, obj, &len); - func("object is an array of %u elements", len); + func(" object is an array of %u elements", len); for(jsuint c = 0; cset_gray(g); + return JS_TRUE; + + } else if(argc==2) { + + JS_ARG_INT(g, idx); + JS_ARG_INT(a, idx+1); + + // g is a double + // a is a signed integer + func("%s gray [%i] alpha [%i]", __FUNCTION__, g, a); + // js_debug_property(cx, &argv[idx]); + // js_debug_property(cx, &argv[idx+1]); + + color->set_gray_alpha(g,a); + return JS_TRUE; + + } else if(argc==3) { + JS_ARG_INT(r, idx); + JS_ARG_INT(g, idx+1); + JS_ARG_INT(b, idx+2); + + func("%s r[%i] g[%i] b[%i]", __FUNCTION__, r, g, b); + // js_debug_property(cx, &argv[idx]); + // js_debug_property(cx, &argv[idx+1]); + // js_debug_property(cx, &argv[idx+2]); + + color->set_rgb(r, g, b); + return JS_TRUE; + + } else if(argc==4) { + + JS_ARG_INT(r, idx); + JS_ARG_INT(g, idx+1); + JS_ARG_INT(b, idx+2); + JS_ARG_INT(a, idx+3); + + func("%s r[%i] g[%i] b[%i] a[%i]", __FUNCTION__, r, g, b, a); + // js_debug_property(cx, &argv[idx]); + // js_debug_property(cx, &argv[idx+1]); + // js_debug_property(cx, &argv[idx+2]); + // js_debug_property(cx, &argv[idx+3]); + + color->set_rgba(r, g, b, a); + return JS_TRUE; + + } + + error("usage of color with %u args not (yet?) supported",argc); + + return JS_FALSE; +} + +JS(vector_layer_color) { + + GET_LAYER(CairoLayer); + + lay->set_color(cx, argc, argv, 0); + return JS_TRUE; +} JS(vector_layer_translate) { @@ -149,10 +217,10 @@ JS(vector_layer_translate) { GET_LAYER(CairoLayer); - JS_ARG_NUMBER(tx, 0); - JS_ARG_NUMBER(ty, 1); + JS_ARG_INT(tx, 0); + JS_ARG_INT(ty, 1); - func("%s x[%.2f] y[%.2f]", __FUNCTION__, tx, ty); + func("%s x[%i] y[%i]", __FUNCTION__, tx, ty); lay->translate(tx, ty); @@ -164,8 +232,8 @@ JS(vector_layer_scale) { GET_LAYER(CairoLayer); - JS_ARG_NUMBER(sx, 0); - JS_ARG_NUMBER(sy, 1); + JS_ARG_DOUBLE(sx, 0); + JS_ARG_DOUBLE(sy, 1); func("%s x[%.2f] y[%.2f]", __FUNCTION__, sx, sy ); @@ -180,7 +248,7 @@ JS(vector_layer_rotate) { GET_LAYER(CairoLayer); - JS_ARG_NUMBER(angle, 0); + JS_ARG_DOUBLE(angle, 0); func("%s angle[%.2f]", __FUNCTION__, angle); @@ -207,10 +275,10 @@ JS(vector_layer_lineto) { GET_LAYER(CairoLayer); - JS_ARG_NUMBER(x, 0); - JS_ARG_NUMBER(y, 1); + JS_ARG_DOUBLE(x, 0); + JS_ARG_DOUBLE(y, 1); - func("%s x[%.2f] y[%.2f]", __FUNCTION__ , x, y ); + func("%s x[%.4f] y[%.4f]", __FUNCTION__ , x, y ); lay->line_to(x, y); @@ -234,10 +302,10 @@ JS(vector_layer_moveto) { GET_LAYER(CairoLayer); - JS_ARG_NUMBER(x, 0); - JS_ARG_NUMBER(y, 1); + JS_ARG_DOUBLE(x, 0); + JS_ARG_DOUBLE(y, 1); - func("%s x[%.2f] y[%.2f]", __FUNCTION__, x, y ); + func("%s x[%.4f] y[%.4f]", __FUNCTION__, x, y ); lay->move_to(x, y); @@ -249,11 +317,11 @@ JS(vector_layer_quadcurveto) { JS_CHECK_ARGC(4); GET_LAYER(CairoLayer); - JS_ARG_NUMBER(x1, 0); - JS_ARG_NUMBER(y1, 1); + JS_ARG_INT(x1, 0); + JS_ARG_INT(y1, 1); - JS_ARG_NUMBER(x2, 2); - JS_ARG_NUMBER(y2, 3); + JS_ARG_INT(x2, 2); + JS_ARG_INT(y2, 3); lay->quad_curve_to( x1, y1, x2, y2) ; @@ -266,14 +334,14 @@ JS(vector_layer_beziercurveto) { GET_LAYER(CairoLayer); - JS_ARG_NUMBER(x1, 0); - JS_ARG_NUMBER(y1, 1); + JS_ARG_DOUBLE(x1, 0); + JS_ARG_DOUBLE(y1, 1); - JS_ARG_NUMBER(x2, 2); - JS_ARG_NUMBER(y2, 3); + JS_ARG_DOUBLE(x2, 2); + JS_ARG_DOUBLE(y2, 3); - JS_ARG_NUMBER(x3, 4); - JS_ARG_NUMBER(y3, 5); + JS_ARG_DOUBLE(x3, 4); + JS_ARG_DOUBLE(y3, 5); func("Vector bezier curve :: x1[%.2f] y1[%.2f] x2[%.2f] y2[%.2f] x3[%.2f] y3[%.2f]", x1, y1, x2, y2, x3, y3 ); @@ -289,13 +357,13 @@ JS(vector_layer_arc) { GET_LAYER(CairoLayer); - JS_ARG_NUMBER(xc, 0); - JS_ARG_NUMBER(yc, 1); + JS_ARG_DOUBLE(xc, 0); + JS_ARG_DOUBLE(yc, 1); - JS_ARG_NUMBER(radius, 2); + JS_ARG_DOUBLE(radius, 2); - JS_ARG_NUMBER(angle1, 3); - JS_ARG_NUMBER(angle2, 4); + JS_ARG_DOUBLE(angle1, 3); + JS_ARG_DOUBLE(angle2, 4); func("Vector arc :: x[%.2f] y[%.2f] rad[%.2f] angle1[%.2f] angle2[%.2f]", xc, yc, radius, angle1, angle2 ); @@ -311,11 +379,11 @@ JS(vector_layer_fillrect) { GET_LAYER(CairoLayer); - JS_ARG_NUMBER(x1, 0); - JS_ARG_NUMBER(y1, 1); + JS_ARG_DOUBLE(x1, 0); + JS_ARG_DOUBLE(y1, 1); - JS_ARG_NUMBER(x2, 2); - JS_ARG_NUMBER(y2, 3); + JS_ARG_DOUBLE(x2, 2); + JS_ARG_DOUBLE(y2, 3); lay->fill_rect(x1, y1, x2, y2); @@ -324,13 +392,22 @@ JS(vector_layer_fillrect) { JS(vector_layer_fill) { func("%s",__FUNCTION__); - GET_LAYER(CairoLayer); + GET_LAYER(CairoLayer); + + if(argc>0) + lay->set_color(cx, argc, argv, 0); + lay->fill(); return JS_TRUE; } JS(vector_layer_stroke) { func("%s",__FUNCTION__); GET_LAYER(CairoLayer); + + if(argc>0) { + lay->set_color(cx, argc, argv, 0); + } + lay->stroke(); return JS_TRUE; } @@ -338,7 +415,7 @@ JS(vector_layer_stroke) { JSP(vector_layer_fillstyle_g) { func("%s",__FUNCTION__); - js_debug_property(cx, vp); + // js_debug_property(cx, vp); // GET_LAYER(CairoLayer); @@ -346,7 +423,7 @@ JSP(vector_layer_fillstyle_g) { } JSP(vector_layer_fillstyle_s) { func("%s",__FUNCTION__); - js_debug_property(cx, vp); + // js_debug_property(cx, vp); GET_LAYER(CairoLayer); @@ -367,17 +444,17 @@ JSP(vector_layer_fillstyle_s) { JSP(vector_layer_strokestyle_g) { func("%s",__FUNCTION__); - js_debug_property(cx, vp); + // js_debug_property(cx, vp); return JS_TRUE; } JSP(vector_layer_strokestyle_s) { func("%s",__FUNCTION__); - js_debug_property(cx, vp); + // js_debug_property(cx, vp); // GET_LAYER(CairoLayer); - // JS_PROP_NUMBER(num, *vp); + // JS_PROP_NUMBER(num, vp); // func("num is %f", num); // if( JSVAL_IS_OBJECT(*vp) ) @@ -391,12 +468,11 @@ JSP(vector_layer_strokestyle_s) { JSP(vector_layer_linecap_g) { func("%s",__FUNCTION__); - js_debug_property(cx, vp); + // js_debug_property(cx, vp); return JS_TRUE; } JSP(vector_layer_linecap_s) { - func("%s",__FUNCTION__); // js_debug_property(cx, vp); GET_LAYER(CairoLayer); @@ -404,6 +480,9 @@ JSP(vector_layer_linecap_s) { char *cap = NULL; JS_PROP_STRING(cap); + func("Vector linecap set :: %s",cap); + if(!cap) return JS_TRUE; // we don't stop the flow + switch(cap[0]) { // we parse fast, using only first letter // [b]utt, [r]ound, [s]quare case 'b': @@ -425,7 +504,7 @@ JSP(vector_layer_linecap_s) { JSP(vector_layer_linewidth_g) { func("%s",__FUNCTION__); - js_debug_property(cx, vp); + // js_debug_property(cx, vp); GET_LAYER(CairoLayer); @@ -439,7 +518,7 @@ JSP(vector_layer_linewidth_s) { GET_LAYER(CairoLayer); - JS_PROP_NUMBER(wid, *vp); + JS_PROP_DOUBLE(wid, vp); lay->set_line_width(wid); diff --git a/src/callbacks_js.cpp b/src/callbacks_js.cpp index 90944a58..ca2b0d59 100644 --- a/src/callbacks_js.cpp +++ b/src/callbacks_js.cpp @@ -26,11 +26,15 @@ #include #include #include +#include + #include // spidermonkey header // include exception messags #include +#include + JSErrorFormatString jsFreej_ErrorFormatString[JSFreejErr_Limit] = { #if JS_HAS_DFLT_MSG_STRINGS #define MSG_DEF(name, number, count, exception, format) \ @@ -76,6 +80,109 @@ JSBool js_static_branch_callback(JSContext* Context) return JS_TRUE; } +jsint js_get_int(jsval *val) { + jsint res = 0; + + int tag = JSVAL_TAG(*val); + switch(tag) { + case 0x0: + error("argument %p is a JS Object, should be integer", val); + break; + + case 0x1: + res = JSVAL_TO_INT(*val); + func("argument %p is %i",val, res); + break; + + case 0x2: + res = (int)floor( *JSVAL_TO_DOUBLE(*val) ); + warning("argument %p is a double, but should be int, got value %i",val, res); + break; + + case 0x4: + error("argument %p is a string, should be integer", val); + break; + + case 0x6: + error("argument %p is a boolean, shoul be integer", val); + break; + + default: + if(!val) { + warning("argument is NULL"); + break; + } + double *tmp = JSVAL_TO_DOUBLE(*val); + if(!tmp) { + warning("argument %p is of unknown type, got null",val); + } + // else { + // res = (int)floor( *tmp ); + // warning("argument %p is of unknown type, but should be int, got value %i",val, res); + // } + + // JS_ReportErrorNumber( env->js->global_context, JSFreej_GetErrorMessage, NULL, + // JSSMSG_FJ_WICKED,__FUNCTION__, "invalid value"); + + // res = *JSVAL_TO_DOUBLE(*val); + // func("argument %p is %.4f",val, res); + break; + } + + return res; +} + +jsdouble js_get_double(jsval *val) { + jsdouble res = 0.0; + + int tag = JSVAL_TAG(*val); + switch(tag) { + case 0x0: + error("argument %p is a JS Object, should be double", val); + break; + + case 0x1: + res = (double)JSVAL_TO_INT(*val); + warning("argument %p is an integer, but should be double, got value %.4f",val, res); + break; + + case 0x2: + res = *JSVAL_TO_DOUBLE(*val); + func("argument %p is %.4f",val, res); + break; + + case 0x4: + error("argument %p is a string, should be double", val); + break; + + case 0x6: + error("argument %p is a boolean, shoul be double", val); + break; + + default: + if(!val) { + warning("argument is NULL"); + break; + } + double *tmp = JSVAL_TO_DOUBLE(*val); + if(!tmp) { + warning("argument %p is of unknown type, got null",val); + } + // else { + // res = *tmp; + // warning("argument %p is of unknown type, but should be int, got value %.4f",val, res); + // } + // JS_ReportErrorNumber( env->js->global_context, JSFreej_GetErrorMessage, NULL, + // JSSMSG_FJ_WICKED,__FUNCTION__, "invalid value"); + + // res = *JSVAL_TO_DOUBLE(*val); + // func("argument %p is %.4f",val, res); + break; + } + + return res; +} + void js_error_reporter(JSContext* Context, const char *Message, JSErrorReport *Report) { ::func("JS Error Reporter called"); if(Report->filename) diff --git a/src/color.cpp b/src/color.cpp new file mode 100644 index 00000000..3ae00a95 --- /dev/null +++ b/src/color.cpp @@ -0,0 +1,52 @@ +/* FreeJ + * (c) Copyright 2010 Denis Roio + * + * This source code is free software; you can redistribute it and/or + * modify it under the terms of the GNU Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Please refer + * to the GNU Public License for more details. + * + * You should have received a copy of the GNU Public License along + * with this source code; if not, write to: Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include + +#include + +Color::Color() { + // defaults to black + r = 0; + g = 0; + b = 0; + a = 0; + // set(); +} + +Color::~Color() { } + + +void Color::set_rgb(int nr, int ng, int nb) { + r = nr; + g = ng; + b = nb; + set(); +} + +void Color::set_rgba(int nr, int ng, int nb, int na) { + r = nr; + g = ng; + b = nb; + a = na; + set(); +} + +void Color::set_gray(double g) { set_rgb(g, g, g); } +void Color::set_gray_alpha(double g, int a) { set_rgba(g, g, g, a); } diff --git a/src/context_js.cpp b/src/context_js.cpp index 17801915..593211cb 100644 --- a/src/context_js.cpp +++ b/src/context_js.cpp @@ -63,6 +63,7 @@ JSFunctionSpec global_functions[] = { {"strstr", freej_strstr, 2}, // {"stream_start", stream_start, 0}, // {"stream_stop", stream_stop, 0}, + {"read_file", read_file, 1}, {"file_to_strings", file_to_strings, 1}, {"register_controller", register_controller, 1}, {"rem_controller", rem_controller, 1}, @@ -297,17 +298,17 @@ JS(unset_clear_all) { JS(set_fps) { func("%u:%s:%s",__LINE__,__FILE__,__FUNCTION__); - JS_ARG_NUMBER(fps, 0); + JS_ARG_INT(fps, 0); - global_environment->fps.set((int)fps); + global_environment->fps.set(fps); return JS_TRUE; } JS(js_set_debug) { JSBool ret = JS_NewNumberValue(cx, get_debug(), rval); if(argc==1) { - JS_ARG_NUMBER(level, 0); - set_debug((int)level); + JS_ARG_INT(level, 0); + set_debug(level); } return ret; } @@ -426,6 +427,50 @@ JS(freej_strstr) { return JS_NewNumberValue(cx, intval, rval); } +JS(read_file) { + func("%u:%s:%s",__LINE__,__FILE__,__FUNCTION__); + + JS_CHECK_ARGC(1); + + JSString *str; + jsval val; + + FILE *fd; + + int len; + char *buf; + + char *file; + JS_ARG_STRING(file,0); + + // try to open the file + fd = ::fopen(file,"r"); + if(!fd) { + error("read_file failed for %s: %s",file, strerror(errno) ); + *rval = JSVAL_NULL; + return JS_TRUE; + } + + // read it all in *buf + fseek(fd,0,SEEK_END); + len = ftell(fd); + rewind(fd); + buf = (char*)calloc(len,sizeof(char)); + fread(buf,len,1,fd); + fclose(fd); + // file is now read in memory + + // create the new string + str = JS_NewStringCopyN(cx, buf, len); + // cast it into a js return value + *rval = STRING_TO_JSVAL(str); + + act("file loaded: %s",file); + + return JS_TRUE; +} + + JS(file_to_strings) { func("%u:%s:%s",__LINE__,__FILE__,__FUNCTION__); @@ -545,8 +590,8 @@ JS(srand) { if(argc<1) seed = time(NULL); else { - JS_ARG_NUMBER(r,0); - seed = (int)r; + JS_ARG_INT(r,0); + seed = r; } randval = seed; diff --git a/src/controller.cpp b/src/controller.cpp index cb5aab3d..4623155b 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -73,7 +73,7 @@ JS(controller_activate) { *rval = BOOLEAN_TO_JSVAL(ctrl->active); if (argc == 1) { - JS_ARG_NUMBER(var,0); + JS_ARG_INT(var,0); ctrl->active = var; } return JS_TRUE; diff --git a/src/filter_js.cpp b/src/filter_js.cpp index ec0fee63..9f7a962e 100644 --- a/src/filter_js.cpp +++ b/src/filter_js.cpp @@ -74,7 +74,7 @@ JS(filter_activate) { *rval = BOOLEAN_TO_JSVAL(duo->instance->active); if (argc == 1) { - JS_ARG_NUMBER(var,0); + JS_ARG_INT(var,0); duo->instance->active = (bool)var; } diff --git a/src/geo_layer_js.cpp b/src/geo_layer_js.cpp index 3b801509..81f90b33 100644 --- a/src/geo_layer_js.cpp +++ b/src/geo_layer_js.cpp @@ -97,8 +97,8 @@ JS(geometry_layer_color) { if(argc == 1) { - JS_ARG_NUMBER(hex,0); - lay->set_color((uint32_t)hex); + JS_ARG_INT(hex,0); + lay->set_color(hex); } else { JS_ValueToUint16(cx, argv[0], &r); diff --git a/src/goom_layer_js.cpp b/src/goom_layer_js.cpp index e16477cf..0c852575 100644 --- a/src/goom_layer_js.cpp +++ b/src/goom_layer_js.cpp @@ -54,7 +54,7 @@ JS(goom_layer_mode) { GET_LAYER(GoomLayer); - JS_ARG_NUMBER(mod,0); + JS_ARG_INT(mod,0); if(mod>9) mod = 9; if(mod<0) mod = 0; @@ -71,7 +71,7 @@ JS(goom_layer_speed) { GET_LAYER(GoomLayer); - JS_ARG_NUMBER(spd,0); + JS_ARG_INT(spd,0); if(spd>256) spd = 256; if(spd<0) spd = 0; @@ -88,8 +88,8 @@ JS(goom_layer_middle) { GET_LAYER(GoomLayer); - JS_ARG_NUMBER(x,0); - JS_ARG_NUMBER(y,1); + JS_ARG_INT(x,0); + JS_ARG_INT(y,1); lay->goom->update.zoomFilterData.middleX = x; lay->goom->update.zoomFilterData.middleY = y; @@ -105,8 +105,8 @@ JS(goom_layer_plane) { GET_LAYER(GoomLayer); - JS_ARG_NUMBER(h,0); - JS_ARG_NUMBER(v,1); + JS_ARG_INT(h,0); + JS_ARG_INT(v,1); lay->goom->update.zoomFilterData.hPlaneEffect = h; lay->goom->update.zoomFilterData.vPlaneEffect = v; @@ -122,7 +122,7 @@ JS(goom_layer_reverse) { GET_LAYER(GoomLayer); - JS_ARG_NUMBER(rev,0); + JS_ARG_INT(rev,0); lay->goom->update.zoomFilterData.reverse = (char)rev; @@ -136,7 +136,7 @@ JS(goom_layer_noise) { GET_LAYER(GoomLayer); - JS_ARG_NUMBER(noi,0); + JS_ARG_INT(noi,0); lay->goom->update.zoomFilterData.noisify = (char)noi; @@ -150,7 +150,7 @@ JS(goom_layer_hypercos) { GET_LAYER(GoomLayer); - JS_ARG_NUMBER(hyp,0); + JS_ARG_DOUBLE(hyp,0); lay->goom->update.zoomFilterData.hypercosEffect = hyp; // TODO @@ -164,7 +164,7 @@ JS(goom_layer_wave) { GET_LAYER(GoomLayer); - JS_ARG_NUMBER(wav,0); + JS_ARG_DOUBLE(wav,0); lay->goom->update.zoomFilterData.waveEffect = wav; // TODO diff --git a/src/include/audio_collector.h b/src/include/audio_collector.h index 6a7741ca..6a7c4365 100644 --- a/src/include/audio_collector.h +++ b/src/include/audio_collector.h @@ -62,8 +62,8 @@ public: void get_audio(void *buffer); - unsigned int samplerate; - unsigned int buffersize; + int samplerate; + int buffersize; bool attached; JackClient *Jack; diff --git a/src/include/cairo_layer.h b/src/include/cairo_layer.h index 608a1779..16f396d2 100644 --- a/src/include/cairo_layer.h +++ b/src/include/cairo_layer.h @@ -22,8 +22,23 @@ #include #ifdef WITH_CAIRO +#include + #include +class CairoColor: public Color { + + public: + CairoColor(cairo_t *cai); + ~CairoColor(); + + protected: + void set(); + + private: + cairo_t *cairo; + +}; class CairoLayer: public Layer { @@ -37,6 +52,9 @@ class CairoLayer: public Layer { cairo_t *cairo; + Color *color; + JSBool set_color(JSContext *cx, uintN argc, jsval *argv, int idx); + /////////////////////////////////////////////// // public methods exported to language bindings @@ -49,13 +67,13 @@ class CairoLayer: public Layer { void stroke(); void scale(double xx, double yy); void rotate(double angle); - void translate(double xx, double yy); + void translate(int xx, int yy); void line_to(double xx, double yy); void move_to(double xx, double yy); - void curve_to(double x1, double y1, double x2, double y2, double x3, double y3); + void curve_to(int x1, int y1, int x2, int y2, int x3, int y3); void arc(double xc, double yc, double radius, double angle1, double angle2); void set_line_width(double wid); - double get_line_width(); + int get_line_width(); // Mozilla's GFX compatibility API void quad_curve_to(double x1, double y1, double x2, double y2); diff --git a/src/include/callbacks_js.h b/src/include/callbacks_js.h index 838734de..a41410da 100644 --- a/src/include/callbacks_js.h +++ b/src/include/callbacks_js.h @@ -76,6 +76,14 @@ const JSErrorFormatString * JSFreej_GetErrorMessage(void *userRef, const char *l #define JSP(fun) \ JSBool fun(JSContext *cx, JSObject *obj, jsval idval, jsval *vp) +#define JS_ERROR(str) { \ + ::error(str); \ + JS_ReportErrorNumber(cx, JSFreej_GetErrorMessage, NULL, \ + JSSMSG_FJ_WICKED, \ + __FUNCTION__,str); \ + return JS_FALSE; \ + } + #define JS_CHECK_ARGC(num) \ if(argc + * + * This source code is free software; you can redistribute it and/or + * modify it under the terms of the GNU Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Please refer + * to the GNU Public License for more details. + * + * You should have received a copy of the GNU Public License along + * with this source code; if not, write to: Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __FREEJ_COLOR_H__ +#define __FREEJ_COLOR_H__ + +#include + +#include + + +class Color { + + public: + + Color(); + virtual ~Color(); + + uint8_t r; + uint8_t g; + uint8_t b; + uint8_t a; + + void set_rgb(int nr, int ng, int nb); + void set_rgba(int nr, int ng, int nb, int na); + + void set_gray(double g); + void set_gray_alpha(double g, int a); + + /* void set_hsb(double h, double s, double b); */ + + /* void set_hex(uint32_t h); */ + /* void set_hex_alpha(uint32_t h, uint8_t a); */ + + virtual void set() =0; + +}; + +#endif + diff --git a/src/include/jsparser_data.h b/src/include/jsparser_data.h index d45f6d3c..7532f583 100644 --- a/src/include/jsparser_data.h +++ b/src/include/jsparser_data.h @@ -276,6 +276,7 @@ JS(freej_scandir); JS(freej_echo); JS(freej_echo_func); JS(freej_strstr); +JS(read_file); JS(file_to_strings); JS(register_controller); JS(rem_controller); @@ -402,6 +403,7 @@ JS(geometry_layer_trigon_fill); //////////////////////////////// // Vector layer methods #ifdef WITH_CAIRO +JS(vector_layer_color); JS(vector_layer_translate); JS(vector_layer_scale); JS(vector_layer_rotate); diff --git a/src/layer_js.cpp b/src/layer_js.cpp index 2b689810..b3375d6f 100644 --- a/src/layer_js.cpp +++ b/src/layer_js.cpp @@ -166,7 +166,7 @@ JS(layer_set_fps) { int fps_old = lay->fps.get(); if(argc==1) { - JS_ARG_NUMBER(fps, 0); + JS_ARG_INT(fps, 0); fps_old = lay->fps.set(fps); } @@ -382,10 +382,10 @@ JS(layer_set_position) { GET_LAYER(Layer); - JS_ARG_NUMBER(x,0); - JS_ARG_NUMBER(y,1); + JS_ARG_INT(x,0); + JS_ARG_INT(y,1); - lay->set_position((int)x, (int)y); + lay->set_position(x, y); return JS_TRUE; } @@ -423,7 +423,7 @@ JS(layer_set_blit_value) { func("%u:%s:%s",__LINE__,__FILE__,__FUNCTION__); if(argc<1) JS_ERROR("missing argument"); - JS_ARG_NUMBER(value,0); + JS_ARG_DOUBLE(value,0); GET_LAYER(Layer); @@ -448,8 +448,8 @@ JS(layer_fade_blit_value) { func("%u:%s:%s",__LINE__,__FILE__,__FUNCTION__); if(argc<2) JS_ERROR("missing argument"); - JS_ARG_NUMBER(value,0); - JS_ARG_NUMBER(step,1); + JS_ARG_DOUBLE(value,0); + JS_ARG_DOUBLE(step,1); GET_LAYER(Layer); @@ -544,7 +544,7 @@ JS(layer_rotate) { func("%u:%s:%s",__LINE__,__FILE__,__FUNCTION__); if(argc<1) JS_ERROR("missing argument"); - JS_ARG_NUMBER(degrees,0); + JS_ARG_DOUBLE(degrees,0); GET_LAYER(Layer); @@ -557,8 +557,8 @@ JS(layer_zoom) { if(argc<1) JS_ERROR("missing argument"); // take ymang=xmagn on .zoom(val) - JS_ARG_NUMBER(xmagn,0); - JS_ARG_NUMBER(ymagn,argc == 1 ? 0 : 1); + JS_ARG_DOUBLE(xmagn,0); + JS_ARG_DOUBLE(ymagn,argc == 1 ? 0 : 1); GET_LAYER(Layer); diff --git a/src/midi_ctrl.cpp b/src/midi_ctrl.cpp index a57bc7dc..af8f3d73 100644 --- a/src/midi_ctrl.cpp +++ b/src/midi_ctrl.cpp @@ -97,9 +97,9 @@ JS(midi_connect_from) { } // int snd_seq_connect_to(snd_seq_t * seq, int myport, int dest_client, int dest_port) - JS_ARG_NUMBER(myport, 0); - JS_ARG_NUMBER(dest_client, 1); - JS_ARG_NUMBER(dest_port, 2); + JS_ARG_INT(myport, 0); + JS_ARG_INT(dest_client, 1); + JS_ARG_INT(dest_port, 2); res = midi->connect_from(int(myport), int(dest_client), int(dest_port)); return JS_NewNumberValue(cx, res, rval); diff --git a/src/mouse_ctrl.cpp b/src/mouse_ctrl.cpp index 0163cdd2..8139bcee 100644 --- a/src/mouse_ctrl.cpp +++ b/src/mouse_ctrl.cpp @@ -63,7 +63,7 @@ JSFunctionSpec js_mouse_ctrl_methods[] = { JS(js_mouse_grab) { JS_CHECK_ARGC(1); - JS_ARG_NUMBER(state,0); + JS_ARG_INT(state,0); MouseController *mouse = (MouseController *) JS_GetPrivate(cx,obj); if(!mouse) { diff --git a/src/osc_ctrl.cpp b/src/osc_ctrl.cpp index 6937c367..6739b9ae 100644 --- a/src/osc_ctrl.cpp +++ b/src/osc_ctrl.cpp @@ -336,14 +336,14 @@ JS(js_osc_ctrl_send) { switch(type[c]) { case 'i': { - JS_ARG_NUMBER(i,c); - func("OSC add message arg %u with value %u",c,i); - lo_message_add_int32(osc->outmsg,(int32_t)i); + JS_ARG_INT(i,c); + func("OSC add message arg %i with value %i",c,i); + lo_message_add_int32(osc->outmsg,i); } break; case 'f': { - JS_ARG_NUMBER(f,c); + JS_ARG_DOUBLE(f,c); func("OSC add message arg %u with value %.2f",c,f); lo_message_add_float(osc->outmsg,(float)f); } diff --git a/src/screen_js.cpp b/src/screen_js.cpp index 563059ce..3c49d4a9 100644 --- a/src/screen_js.cpp +++ b/src/screen_js.cpp @@ -77,11 +77,10 @@ JS(screen_constructor) { JS(screen_init) { func("%s",__PRETTY_FUNCTION__); - JS_CHECK_ARGC(2) - - uint16_t w,h; - JS_ValueToUint16(cx, argv[0], &w); - JS_ValueToUint16(cx, argv[1], &h); + JS_CHECK_ARGC(2); + + JS_ARG_INT(w, 0); + JS_ARG_INT(h, 1); ViewPort *screen = (ViewPort*)JS_GetPrivate(cx,obj); if(!screen) { diff --git a/src/text_layer_js.cpp b/src/text_layer_js.cpp index 6cfcc741..f6f40ad8 100644 --- a/src/text_layer_js.cpp +++ b/src/text_layer_js.cpp @@ -97,9 +97,9 @@ JS(txt_layer_size) { GET_LAYER(TextLayer); - JS_ARG_NUMBER(size,0); + JS_ARG_INT(size,0); - lay->set_fontsize((int)size); + lay->set_fontsize(size); return JS_TRUE; } diff --git a/src/video_encoder_js.cpp b/src/video_encoder_js.cpp index 8a969b35..7ebb4219 100644 --- a/src/video_encoder_js.cpp +++ b/src/video_encoder_js.cpp @@ -244,9 +244,9 @@ JS(stream_port) { return JS_FALSE; } - JS_ARG_NUMBER(port, 0); + JS_ARG_INT(port, 0); - if(shout_set_port(enc->ice, (short unsigned int)port)) + if(shout_set_port(enc->ice, port)) error("shout_set_port: %s", shout_get_error(enc->ice)); return JS_TRUE; diff --git a/src/xgrab_layer.cpp b/src/xgrab_layer.cpp index 7605de73..fb40e92a 100644 --- a/src/xgrab_layer.cpp +++ b/src/xgrab_layer.cpp @@ -370,8 +370,8 @@ JS(js_xgrab_constructor) { delete xg; return JS_FALSE; } if (argc == 1) { - JS_ARG_NUMBER(winid, 0); - if(!JS_NewNumberValue(cx, xg->open((uint32_t)winid), rval)) { + JS_ARG_INT(winid, 0); + if(!JS_NewNumberValue(cx, xg->open(winid), rval)) { error("failed initializing xgrab controller"); delete xg; return JS_FALSE; } @@ -394,8 +394,8 @@ JS(js_xgrab_open) { } if (argc == 1) { - JS_ARG_NUMBER(winid, 0); - return JS_NewNumberValue(cx, lay->open((uint32_t)winid), rval); + JS_ARG_INT(winid, 0); + return JS_NewNumberValue(cx, lay->open(winid), rval); } JS_ERROR("Wrong number of arguments"); }