1
edit
Changes
→About Me
== About Me ==
I'm a 5th 7th Semester BSD student taking DPS909DPS901. Working part time on an ASP.NET c# application.
==Technical Qualifications==
*XHTML/CSS
*JavaScript
*Processing
== FSOSS Research Paper ==
=== Releases ===
0.1 - [http://dhodgin.wordpress.com/2009/10/29/release-0-1-for-my-processing-js-work/ Full Details] shorten(), expand(), nfs(), unhex(), bug fixes on nf() and fill()<br/>
0.2 - work in progress ([http://dhodgin.wordpress.com/2009/11/19/processing-js-0-2-release/ Full Details] nfc(), exp(), log(), map(), asin(), acos(), atan(), tan()<br/>0.3 - [http://dhodgin.wordpress.com/2009/12/15/my-great-white-vs-killer-whale-0-3-patch/ Full Details] blendColor(), blend(), copy(), filter()<br/>
=== Contributions ===
* Created the template for processing.js tests
* Organized 0.1 release code table and project test table areas.
* Wrote GIT tutorial on adding code to GIT from a fresh fork [http://dhodgin.wordpress.com/2009/11/20/a-guide-to-git-for-the-processing-js-community-6-easy-steps/ tutorial]
* Helped Al get Lighthouse setup and got invites sent out to everyone to better prepare for 0.2 release code and bug tracking
* Wrote tutorial on lighthouse, and ticket state explanations [https://processing-js.lighthouseapp.com/projects/41284-processingjs/messages messages]
* Helped with triage on lighthouse tickets
* Helped Anna with PImage copy math which will ultimately be used in my 0.3 copy() code
=== Week 1 stuff ===* Create Zenit Wiki (done)* Create Blog ([http://dhodgin.wordpress.com done])* Blog on introductory readings (done)* Listen in on a [[Overview_of_Mozilla_Communication#Weekly_Calls | Weekly Call]] (done)* Update wiki (done) === Week 2 stuff ===* Create MDC account (done)* join Mozilla Fennec mailing list (done)* week 2 lab (done)* watch learning to be at the festival and blog about it (done) === Week 3 stuff ===* watch online lectures about build system by Paul Reed (done)* build Firefox at school on Linux (fedora) (done)* build Firefox minefield at home on windows 7 (done)* choose subject for project and write project plan on blog (done) === Week 4 stuff ===* spend time searching through MXR and familiarizing myself with it (done)* lab, working with patches (to do) === Week 5 stuff ===* create Bugzilla account (done)* Find 3+ bugs related to your project, and add them to your project wiki page ([http://zenit.senecac.on.ca/wiki/index.php/Fennec_and_@font-face done])* CC yourself on two bugs that relate to your project 517086 476478 (done)* Watch a user in Bugzilla for the week and blog about the experience (blassey) (done)* Be working on your 0.1 release. Ask for help if you're stuck (done)* Register for FSOSS or join as a volunteer. (done) === Week 6 stuff === * work on [http://dhodgin.wordpress.com/2009/10/29/release-0-1-for-my-processing-js-work/ 0.1 release] (done) === Week 7 stuff ===* Firefox tab ordering lab* Watch [http://www.youtube.com/watch?v=hQVTIJBZook JavaScript online talk] (done) === Week 8 stuff ===* Release 0.2 ([http://dhodgin.wordpress.com/2009/11/19/processing-js-0-2-release/ done]) === Week 9 stuff ===* tba ==DPS911 Projects==[[http://zenit.senecac.on.ca/wiki/index.php/Processing.js Processing.js]] - Active project<br /> === Releases ===0.4 - [http://dhodgin.wordpress.com/2010/01/25/0-4-and-triage-for-processing-js/ Full Details] Triage and peer-review of outstanding 0.2 and 0.3 code blocks <br/>0.5 - [http://dhodgin.wordpress.com/2010/02/06/0-5-processing-js-release-contribution/ Full Details] Review of binary() and sort(), rewrote hex(), trim(), some code efficiency cleanup<br />0.6 - wip <br /> === Weekly stuff ===* Update Wiki* Prepare for 0.4 release* schedule demos for Dave in weeks 3, 7, and 10 for 0.4, 0.6, and 0.8 releases.* Demo 1 - Feb 4 (completed) ==Code Blocks ==Here is a list of code blocks I have written for the processing.js project<br />=== trim() ===Trim leading and trailing whitespace from strings as well as tab characters, newlines, and nbsp characters<br/>Commit [http://github.com/dhodgin/processing-js/commit/e7f258eec8f566a0da39c23f964280637e8e2a4b trim() commit]<br />Test available [http://matrix.senecac.on.ca/~dhhodgin/dps911/examples/seneca/trim/trimtest.htm here]<br /> p.trim = function( str ) { var newstr; if (typeof str === "object") { // if str is an array recursivly loop through each element // and drill down into multiple arrays trimming whitespace newstr = new Array(0); for (var i = 0; i < str.length; i++) { newstr[i] = p.trim(str[i]); } } else { // if str is not an array then remove all whitespace, tabs, and returns newstr = str.replace(/^\s*/,'').replace(/\s*$/,'').replace(/\r*$/,''); } return newstr; };=== decimalToHex() ===A helper function used with hex to convert a number passed in to hex and add any specified padding var decimalToHex = function decimalToHex(d, padding) { //if there is no padding value added, default padding to 8 else go into while statement. padding = typeof(padding) === "undefined" || padding === null ? padding = 8 : padding; if (d < 0) { d = 0xFFFFFFFF + d + 1; } var hex = Number(d).toString(16).toUpperCase(); while (hex.length < padding) { hex = "0" + hex; } if (hex.length >= padding){ hex = hex.substring(hex.length - padding, hex.length); } return hex; }; === hex() ===hex(x, y) function for processing. x is a byte, char, int, or color. y is the length of the string to return.<br />Commit [http://github.com/dhodgin/processing-js/commit/d51adccc9acfeb4fa286366c98e06a33ad296524 hex() commit]<br />Test available [http://matrix.senecac.on.ca/~dhhodgin/dps911/hextest.htm here]<br /><br /> // note: since we cannot keep track of byte, char, and int types by default the returned string is 8 chars long // if no 2nd argument is passed. closest compromise we can use to match java implementation Feb 5 2010 // also the char parser has issues with chars that are not digits or letters IE: !@#$%^&* p.hex = function hex(value, len) { var hexstring = ""; var patternRGBa = /^rgba?\((\d{1,3}),(\d{1,3}),(\d{1,3})(,\d?\.?\d*)?\)$/i; //match rgba(20,20,20,0) or rgba(20,20,20) if (arguments.length === 1) { hexstring = hex(value, 8); } else { if (patternRGBa.test(value)) { // its a color hexstring = decimalToHex(p.rgbaToInt(value),len); } else { // its a byte, char, or int hexstring = decimalToHex(value, len); } } return hexstring; }; === copy() === p.copy = function copy(src, sx, sy, sw, sh, dx, dy, dw, dh) { if(arguments.length==8){ p.copy(this, src, sx, sy, sw, sh, dx, dy, dw); } p.blend(src, sx, sy, sw, sh, dx, dy, dw, dh, p.REPLACE); }; === blend() === p.blend = function blend(src, sx, sy, sw, sh, dx, dy, dw, dh, mode){ if(arguments.length==9){ p.blend(this, src, sx, sy, sw, sh, dx, dy, dw, dh); } else if (arguments.length==10){ var sx2 = sx + sw; var sy2 = sy + sh; var dx2 = dx + dw; var dy2 = dy + dh; p.loadPixels(); if (src == this) { if (p.intersect(sx, sy, sx2, sy2, dx, dy, dx2, dy2)) { p.blit_resize(p.get(sx, sy, sx2 - sx, sy2 - sy), // 4 argument get doesnt exist i think 0, 0, sx2 - sx - 1, sy2 - sy - 1, pixels, width, height, dx, dy, dx2, dy2, mode); } else { // same as below, except skip the loadPixels() because it'd be redundant p.blit_resize(src, sx, sy, sx2, sy2, pixels, width, height, dx, dy, dx2, dy2, mode); } } else { src.loadPixels(); p.blit_resize(src, sx, sy, sx2, sy2, pixels, width, height, dx, dy, dx2, dy2, mode); } p.updatePixels(); } }; === blit_resize() ===blit_resize is a helper function for image manipulation used with blend() and copy() /** * Internal blitter/resizer/copier from toxi. * Uses bilinear filtering if smooth() has been enabled * 'mode' determines the blending mode used in the process. * ported from JAVA version */ p.blit_resize = function blit_resize(img, srcX1, srcY1, srcX2, srcY2, destPixels, screenW, screenH, destX1, destY1, destX2, destY2, mode) { if (srcX1 < 0) srcX1 = 0; if (srcY1 < 0) srcY1 = 0; if (srcX2 >= img.width) srcX2 = img.width - 1; if (srcY2 >= img.height) srcY2 = img.height - 1; var srcW = srcX2 - srcX1; var srcH = srcY2 - srcY1; var destW = destX2 - destX1; var destH = destY2 - destY1; var smooth = true; // may as well go with the smoothing these days if (!smooth) { srcW++; srcH++; } if (destW <= 0 || destH <= 0 || srcW <= 0 || srcH <= 0 || destX1 >= screenW || destY1 >= screenH || srcX1 >= img.width || srcY1 >= img.height) { return; } var dx = Math.floor(srcW / destW * p.PRECISIONF); var dy = Math.floor(srcH / destH * p.PRECISIONF); p.shared.srcXOffset = Math.floor(destX1 < 0 ? -destX1 * dx : srcX1 * p.PRECISIONF); p.shared.srcYOffset = Math.floor(destY1 < 0 ? -destY1 * dy : srcY1 * p.PRECISIONF); if (destX1 < 0) { destW += destX1; destX1 = 0; } if (destY1 < 0) { destH += destY1; destY1 = 0; } destW = Math.min(destW, screenW - destX1); destH = Math.min(destH, screenH - destY1); var destOffset = destY1 * screenW + destX1; p.shared.srcBuffer = img.pixels; if (smooth) { // use bilinear filtering p.shared.iw = img.width; p.shared.iw1 = img.width - 1; p.shared.ih1 = img.height - 1; switch (mode) { case p.BLEND: for (var y = 0; y < destH; y++) { p.filter_new_scanline(); for (var x = 0; x < destW; x++) { destPixels[destOffset + x] = p.modes.blend_blend(destPixels[destOffset + x], p.filter_bilinear()); sX += dx; } destOffset += screenW; p.shared.srcYOffset += dy; } break; case p.ADD: for (var y = 0; y < destH; y++) { p.filter_new_scanline(); for (var x = 0; x < destW; x++) { destPixels[destOffset + x] = p.modes.blend_add_pin(destPixels[destOffset + x], p.filter_bilinear()); sX += dx; } destOffset += screenW; srcYOffset += dy; } break; case p.SUBTRACT: for (var y = 0; y < destH; y++) { p.filter_new_scanline(); for (var x = 0; x < destW; x++) { destPixels[destOffset + x] = p.modes.blend_sub_pin(destPixels[destOffset + x], p.filter_bilinear()); sX += dx; } destOffset += screenW; srcYOffset += dy; } break; case p.LIGHTEST: for (var y = 0; y < destH; y++) { p.filter_new_scanline(); for (var x = 0; x < destW; x++) { destPixels[destOffset + x] = p.modes.blend_lightest(destPixels[destOffset + x], p.filter_bilinear()); sX += dx; } destOffset += screenW; srcYOffset += dy; } break; case p.DARKEST: for (var y = 0; y < destH; y++) { p.filter_new_scanline(); for (var x = 0; x < destW; x++) { destPixels[destOffset + x] = p.modes.blend_darkest(destPixels[destOffset + x], p.filter_bilinear()); sX += dx; } destOffset += screenW; srcYOffset += dy; } break; case p.REPLACE: for (var y = 0; y < destH; y++) { p.filter_new_scanline(); for (var x = 0; x < destW; x++) { destPixels[destOffset + x] = p.filter_bilinear(); sX += dx; } destOffset += screenW; srcYOffset += dy; } break; case p.DIFFERENCE: for (var y = 0; y < destH; y++) { p.filter_new_scanline(); for (var x = 0; x < destW; x++) { destPixels[destOffset + x] = p.modes.blend_difference(destPixels[destOffset + x], p.filter_bilinear()); sX += dx; } destOffset += screenW; srcYOffset += dy; } break; case p.EXCLUSION: for (var y = 0; y < destH; y++) { p.filter_new_scanline(); for (var x = 0; x < destW; x++) { destPixels[destOffset + x] = p.modes.blend_exclusion(destPixels[destOffset + x], p.filter_bilinear()); sX += dx; } destOffset += screenW; srcYOffset += dy; } break; case p.MULTIPLY: for (var y = 0; y < destH; y++) { p.filter_new_scanline(); for (var x = 0; x < destW; x++) { destPixels[destOffset + x] = p.modes.blend_multiply(destPixels[destOffset + x], p.filter_bilinear()); sX += dx; } destOffset += screenW; srcYOffset += dy; } break; case p.SCREEN: for (var y = 0; y < destH; y++) { p.filter_new_scanline(); for (var x = 0; x < destW; x++) { destPixels[destOffset + x] = p.modes.blend_screen(destPixels[destOffset + x], p.filter_bilinear()); sX += dx; } destOffset += screenW; srcYOffset += dy; } break; case p.OVERLAY: for (var y = 0; y < destH; y++) { p.filter_new_scanline(); for (var x = 0; x < destW; x++) { destPixels[destOffset + x] = p.modes.blend_overlay(destPixels[destOffset + x], p.filter_bilinear()); sX += dx; } destOffset += screenW; srcYOffset += dy; } break; case p.HARD_LIGHT: for (var y = 0; y < destH; y++) { p.filter_new_scanline(); for (var x = 0; x < destW; x++) { destPixels[destOffset + x] = p.modes.blend_hard_light(destPixels[destOffset + x], p.filter_bilinear()); sX += dx; } destOffset += screenW; srcYOffset += dy; } break; case p.SOFT_LIGHT: for (var y = 0; y < destH; y++) { p.filter_new_scanline(); for (var x = 0; x < destW; x++) { destPixels[destOffset + x] = p.modes.blend_soft_light(destPixels[destOffset + x], p.filter_bilinear()); sX += dx; } destOffset += screenW; srcYOffset += dy; } break; // davbol - proposed 2007-01-09 case p.DODGE: for (var y = 0; y < destH; y++) { p.filter_new_scanline(); for (var x = 0; x < destW; x++) { destPixels[destOffset + x] = p.modes.blend_dodge(destPixels[destOffset + x], p.filter_bilinear()); sX += dx; } destOffset += screenW; srcYOffset += dy; } break; case p.BURN: for (var y = 0; y < destH; y++) { p.filter_new_scanline(); for (var x = 0; x < destW; x++) { destPixels[destOffset + x] = p.modes.blend_burn(destPixels[destOffset + x], p.filter_bilinear()); sX += dx; } destOffset += screenW; srcYOffset += dy; } break; } } else { // nearest neighbour scaling (++fast!) switch (mode) { case p.BLEND: for (var y = 0; y < destH; y++) { sX = srcXOffset; sY = (srcYOffset >> p.PRECISIONB) * img.width; for (var x = 0; x < destW; x++) { // davbol - renamed old blend_multiply to blend_blend destPixels[destOffset + x] = p.modes.blend_blend(destPixels[destOffset + x], srcBuffer[sY + (sX >> p.PRECISIONB)]); sX += dx; } destOffset += screenW; srcYOffset += dy; } break; case p.ADD: for (var y = 0; y < destH; y++) { sX = srcXOffset; sY = (srcYOffset >> p.PRECISIONB) * img.width; for (var x = 0; x < destW; x++) { destPixels[destOffset + x] = p.modes.blend_add_pin(destPixels[destOffset + x], srcBuffer[sY + (sX >> p.PRECISIONB)]); sX += dx; } destOffset += screenW; srcYOffset += dy; } break; case p.SUBTRACT: for (var y = 0; y < destH; y++) { sX = srcXOffset; sY = (srcYOffset >> p.PRECISIONB) * img.width; for (var x = 0; x < destW; x++) { destPixels[destOffset + x] = p.modes.blend_sub_pin(destPixels[destOffset + x], srcBuffer[sY + (sX >> p.PRECISIONB)]); sX += dx; } destOffset += screenW; srcYOffset += dy; } break; case p.LIGHTEST: for (var y = 0; y < destH; y++) { sX = srcXOffset; sY = (srcYOffset >> p.PRECISIONB) * img.width; for (var x = 0; x < destW; x++) { destPixels[destOffset + x] = p.modes.blend_lightest(destPixels[destOffset + x], srcBuffer[sY + (sX >> p.PRECISIONB)]); sX += dx; } destOffset += screenW; srcYOffset += dy; } break; case p.DARKEST: for (var y = 0; y < destH; y++) { sX = srcXOffset; sY = (srcYOffset >> p.PRECISIONB) * img.width; for (var x = 0; x < destW; x++) { destPixels[destOffset + x] = p.modes.blend_darkest(destPixels[destOffset + x], srcBuffer[sY + (sX >> p.PRECISIONB)]); sX += dx; } destOffset += screenW; srcYOffset += dy; } break; case p.REPLACE: for (var y = 0; y < destH; y++) { sX = srcXOffset; sY = (srcYOffset >> p.PRECISIONB) * img.width; for (var x = 0; x < destW; x++) { destPixels[destOffset + x] = srcBuffer[sY + (sX >> p.PRECISIONB)]; sX += dx; } destOffset += screenW; srcYOffset += dy; } break; case p.DIFFERENCE: for (var y = 0; y < destH; y++) { sX = srcXOffset; sY = (srcYOffset >> p.PRECISIONB) * img.width; for (var x = 0; x < destW; x++) { destPixels[destOffset + x] = p.modes.blend_difference(destPixels[destOffset + x], srcBuffer[sY + (sX >> p.PRECISIONB)]); sX += dx; } destOffset += screenW; srcYOffset += dy; } break; case p.EXCLUSION: for (var y = 0; y < destH; y++) { sX = srcXOffset; sY = (srcYOffset >> p.PRECISIONB) * img.width; for (var x = 0; x < destW; x++) { destPixels[destOffset + x] = p.modes.blend_exclusion(destPixels[destOffset + x], srcBuffer[sY + (sX >> p.PRECISIONB)]); sX += dx; } destOffset += screenW; srcYOffset += dy; } break; case p.MULTIPLY: for (var y = 0; y < destH; y++) { sX = srcXOffset; sY = (srcYOffset >> p.PRECISIONB) * img.width; for (var x = 0; x < destW; x++) { destPixels[destOffset + x] = p.modes.blend_multiply(destPixels[destOffset + x], srcBuffer[sY + (sX >> p.PRECISIONB)]); sX += dx; } destOffset += screenW; srcYOffset += dy; } break; case p.SCREEN: for (var y = 0; y < destH; y++) { sX = srcXOffset; sY = (srcYOffset >> p.PRECISIONB) * img.width; for (var x = 0; x < destW; x++) { destPixels[destOffset + x] = p.modes.blend_screen(destPixels[destOffset + x], srcBuffer[sY + (sX >> p.PRECISIONB)]); sX += dx; } destOffset += screenW; srcYOffset += dy; } break; case p.OVERLAY: for (var y = 0; y < destH; y++) { sX = srcXOffset; sY = (srcYOffset >> p.PRECISIONB) * img.width; for (var x = 0; x < destW; x++) { destPixels[destOffset + x] = p.modes.blend_overlay(destPixels[destOffset + x], srcBuffer[sY + (sX >> p.PRECISIONB)]); sX += dx; } destOffset += screenW; srcYOffset += dy; } break; case p.HARD_LIGHT: for (var y = 0; y < destH; y++) { sX =srcXOffset; sY = (srcYOffset >> p.PRECISIONB) * img.width; for (var x = 0; x < destW; x++) { destPixels[destOffset + x] = p.modes.blend_hard_light(destPixels[destOffset + x], srcBuffer[sY + (sX >> p.PRECISIONB)]); sX += dx; } destOffset += screenW; srcYOffset += dy; } break; case p.SOFT_LIGHT: for (var y = 0; y < destH; y++) { sX = srcXOffset; sY = (srcYOffset >> p.PRECISIONB) * img.width; for (var x = 0; x < destW; x++) { destPixels[destOffset + x] = p.modes.blend_soft_light(destPixels[destOffset + x], srcBuffer[sY + (sX >> p.PRECISIONB)]); sX += dx; } destOffset += screenW; srcYOffset += dy; } break; // davbol - proposed 2007-01-09 case p.DODGE: for (var y = 0; y < destH; y++) { sX = srcXOffset; sY = (srcYOffset >> p.PRECISIONB) * img.width; for (var x = 0; x < destW; x++) { destPixels[destOffset + x] = p.modes.blend_dodge(destPixels[destOffset + x], srcBuffer[sY + (sX >> p.PRECISIONB)]); sX += dx; } destOffset += screenW; srcYOffset += dy; } break; case p.BURN: for (var y = 0; y < destH; y++) { sX = srcXOffset; sY = (srcYOffset >> p.PRECISIONB) * img.width; for (var x = 0; x < destW; x++) { destPixels[destOffset + x] = p.modes.blend_burn(destPixels[destOffset + x], srcBuffer[sY + (sX >> p.PRECISIONB)]); sX += dx; } destOffset += screenW; srcYOffset += dy; } break; } } }; === blend() helper functions=== // shared variables for blit_resize(), filter_new_scanline(), filter_bilinear() // change this in the future p.shared = { fracU : 0, ifU : 0, fracV : 0, ifV : 0, u1 : 0, u2 : 0, v1 : 0, v2 : 0, sX : 0, sY : 0, iw : 0, iw1 : 0, ih1 : 0, ul : 0, ll : 0, ur : 0, lr : 0, cUL : 0, cLL : 0, cUR : 0, cLR : 0, srcXOffset : 0, srcYOffset : 0, r : 0, g : 0, b : 0, a : 0,srcBuffer : null }; p.intersect = function intersect(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2) { var sw = sx2 - sx1 + 1; var sh = sy2 - sy1 + 1; var dw = dx2 - dx1 + 1; var dh = dy2 - dy1 + 1; if (dx1 < sx1) { dw += dx1 - sx1; if (dw > sw) { dw = sw; } } else { var w = sw + sx1 - dx1; if (dw > w) { dw = w; } } if (dy1 < sy1) { dh += dy1 - sy1; if (dh > sh) { dh = sh; } } else { var h = sh + sy1 - dy1; if (dh > h) { dh = h; } } return !(dw <= 0 || dh <= 0); }; p.filter_new_scanline = function filter_new_scanline() { p.shared.sX = p.shared.srcXOffset; p.shared.fracV = p.shared.srcYOffset & p.PREC_MAXVAL; p.shared.ifV = p.PREC_MAXVAL - p.shared.fracV; p.shared.v1 = (p.shared.srcYOffset >> p.PRECISIONB) * p.shared.iw; p.shared.v2 = Math.min((p.shared.srcYOffset >> p.PRECISIONB) + 1, p.shared.ih1) * p.shared.iw; }; p.filter_bilinear = function filter_bilinear() { p.shared.fracU = p.shared.sX & p.PREC_MAXVAL; p.shared.ifU = p.PREC_MAXVAL - p.shared.fracU; p.shared.ul = (p.shared.ifU * p.shared.ifV) >> p.PRECISIONB; p.shared.ll = (p.shared.ifU * p.shared.fracV) >> p.PRECISIONB; p.shared.ur = (p.shared.fracU * p.shared.ifV) >> p.PRECISIONB; p.shared.lr = (p.shared.fracU * p.shared.fracV) >> p.PRECISIONB; p.shared.u1 = (p.shared.sX >> p.PRECISIONB); p.shared.u2 = Math.min(p.shared.u1 + 1, p.shared.iw1); // get color values of the 4 neighbouring texels p.shared.cUL = p.shared.srcBuffer[p.shared.v1 + p.shared.u1]; p.shared.cUR = p.shared.srcBuffer[p.shared.v1 + p.shared.u2]; p.shared.cLL = p.shared.srcBuffer[p.shared.v2 + p.shared.u1]; p.shared.cLR = p.shared.srcBuffer[p.shared.v2 + p.shared.u2]; p.shared.r = ((p.shared.ul*((p.shared.cUL&p.RED_MASK)>>16) + p.shared.ll*((p.shared.cLL&p.RED_MASK)>>16) + p.shared.ur*((p.shared.cUR&p.RED_MASK)>>16) + p.shared.lr*((p.shared.cLR&p.RED_MASK)>>16)) << p.PREC_RED_SHIFT) & p.RED_MASK; p.shared.g = ((p.shared.ul*(p.shared.cUL&p.GREEN_MASK) + p.shared.ll*(p.shared.cLL&p.GREEN_MASK) + p.shared.ur*(p.shared.cUR&p.GREEN_MASK) + p.shared.lr*(p.shared.cLR&p.GREEN_MASK)) >>> p.PRECISIONB) & p.GREEN_MASK; p.shared.b = (p.shared.ul*(p.shared.cUL&p.BLUE_MASK) + p.shared.ll*(p.shared.cLL&p.BLUE_MASK) + p.shared.ur*(p.shared.cUR&p.BLUE_MASK) + p.shared.lr*(p.shared.cLR&p.BLUE_MASK)) >>> p.PRECISIONB; p.shared.a = ((p.shared.ul*((p.shared.cUL&p.ALPHA_MASK)>>>24) + p.shared.ll*((p.shared.cLL&p.ALPHA_MASK)>>>24) + p.shared.ur*((p.shared.cUR&p.ALPHA_MASK)>>>24) + p.shared.lr*((p.shared.cLR&p.ALPHA_MASK)>>>24)) << p.PREC_ALPHA_SHIFT) & p.ALPHA_MASK; return p.shared.a | p.shared.r | p.shared.g | p.shared.b; }; === CONSTANTS ADDED === p.ALPHA_MASK = 0xff000000; p.RED_MASK = 0x00ff0000; p.GREEN_MASK = 0x0000ff00; p.BLUE_MASK = 0x000000ff; p.REPLACE = 0; p.BLEND = 1 << 0; p.ADD = 1 << 1; p.SUBTRACT = 1 << 2; p.LIGHTEST = 1 << 3; p.DARKEST = 1 << 4; p.DIFFERENCE = 1 << 5; p.EXCLUSION = 1 << 6; p.MULTIPLY = 1 << 7; p.SCREEN = 1 << 8; p.OVERLAY = 1 << 9; p.HARD_LIGHT = 1 << 10; p.SOFT_LIGHT = 1 << 11; p.DODGE = 1 << 12; p.BURN = 1 << 13; // fixed point precision is limited to 15 bits!! p.PRECISIONB = 15; p.PRECISIONF = 1 << p.PRECISIONB; p.PREC_MAXVAL = p.PRECISIONF-1; p.PREC_ALPHA_SHIFT= 24-p.PRECISIONB; p.PREC_RED_SHIFT = 16-p.PRECISIONB; === blendColor() === p.blendColor = function(c1, c2, mode){ var color = 0; switch(mode){ case p.REPLACE : color = p.modes.replace(c1, c2); break; case p.BLEND : color = p.modes.blend(c1, c2); break; case p.ADD : color = p.modes.add(c1, c2); break; case p.SUBTRACT : color = p.modes.subtract(c1, c2); break; case p.LIGHTEST : color = p.modes.lightest(c1, c2); break; case p.DARKEST : color = p.modes.darkest(c1, c2); break; case p.DIFFERENCE : color = p.modes.difference(c1, c2); break; case p.EXCLUSION : color = p.modes.exclusion(c1, c2); break; case p.MULTIPLY : color = p.modes.multiply(c1, c2); break; case p.SCREEN : color = p.modes.screen(c1, c2); break; case p.HARD_LIGHT : color = p.modes.hard_light(c1, c2); break; case p.SOFT_LIGHT : color = p.modes.soft_light(c1, c2); break; case p.OVERLAY : color = p.modes.overlay(c1, c2); break; case p.DODGE : color = p.modes.dodge(c1, c2); break; case p.BURN : color = p.modes.burn(c1, c2); break; } return color; }=== blendColor() helper functions === // helper functions for internal blending modes // convert rgba color strings to integer p.rgbaToInt = function(color){ var rgbaAry = /\(([^\)]+)\)/.exec(color).slice(1,2)[0].split(','); return (rgbaAry[3] << 24) | (rgbaAry[0] << 16) | (rgbaAry[1] << 8) | (rgbaAry[2]); } p.mix = function(a, b, f) { return a + (((b - a) * f) >> 8); } p.peg = function(n) { return (n < 0) ? 0 : ((n > 255) ? 255 : n); }=== blendColor() blending modes === // blending modes p.modes = { replace: function(a, b){ return p.rgbaToInt(b); }, blend: function(a, b){ var c1 = p.rgbaToInt(a); var c2 = p.rgbaToInt(b); var f = (c2 & p.ALPHA_MASK) >>> 24; return (Math.min(((c1 & p.ALPHA_MASK) >>> 24) + f, 0xff) << 24 | p.mix(c1 & p.RED_MASK, c2 & p.RED_MASK, f) & p.RED_MASK | p.mix(c1 & p.GREEN_MASK, c2 & p.GREEN_MASK, f) & p.GREEN_MASK | p.mix(c1 & p.BLUE_MASK, c2 & p.BLUE_MASK, f)); }, add: function(a, b){ var c1 = p.rgbaToInt(a); var c2 = p.rgbaToInt(b); var f = (c2 & p.ALPHA_MASK) >>> 24; return (Math.min(((c1 & p.ALPHA_MASK) >>> 24) + f, 0xff) << 24 | Math.min(((c1 & p.RED_MASK) + ((c2 & p.RED_MASK) >> 8) * f), p.RED_MASK) & p.RED_MASK | Math.min(((c1 & p.GREEN_MASK) + ((c2 & p.GREEN_MASK) >> 8) * f), p.GREEN_MASK) & p.GREEN_MASK | Math.min((c1 & p.BLUE_MASK) + (((c2 & p.BLUE_MASK) * f) >> 8), p.BLUE_MASK)); }, subtract: function(a, b){ var c1 = p.rgbaToInt(a); var c2 = p.rgbaToInt(b); var f = (c2 & p.ALPHA_MASK) >>> 24; return (Math.min(((c1 & p.ALPHA_MASK) >>> 24) + f, 0xff) << 24 | Math.max(((c1 & p.RED_MASK) - ((c2 & p.RED_MASK) >> 8) * f), p.GREEN_MASK) & p.RED_MASK | Math.max(((c1 & p.GREEN_MASK) - ((c2 & p.GREEN_MASK) >> 8) * f), p.BLUE_MASK) & p.GREEN_MASK | Math.max((c1 & p.BLUE_MASK) - (((c2 & p.BLUE_MASK) * f) >> 8), 0)); }, lightest: function(a, b){ var c1 = p.rgbaToInt(a); var c2 = p.rgbaToInt(b); var f = (c2 & p.ALPHA_MASK) >>> 24; return (Math.min(((c1 & p.ALPHA_MASK) >>> 24) + f, 0xff) << 24 | Math.max(c1 & p.RED_MASK, ((c2 & p.RED_MASK) >> 8) * f) & p.RED_MASK | Math.max(c1 & p.GREEN_MASK, ((c2 & p.GREEN_MASK) >> 8) * f) & p.GREEN_MASK | Math.max(c1 & p.BLUE_MASK, ((c2 & p.BLUE_MASK) * f) >> 8)); }, darkest: function(a, b){ var c1 = p.rgbaToInt(a); var c2 = p.rgbaToInt(b); var f = (c2 & p.ALPHA_MASK) >>> 24; return (Math.min(((c1 & p.ALPHA_MASK) >>> 24) + f, 0xff) << 24 | p.mix(c1 & p.RED_MASK, Math.min(c1 & p.RED_MASK, ((c2 & p.RED_MASK) >> 8) * f), f) & p.RED_MASK | p.mix(c1 & p.GREEN_MASK, Math.min(c1 & p.GREEN_MASK, ((c2 & p.GREEN_MASK) >> 8) * f), f) & p.GREEN_MASK | p.mix(c1 & p.BLUE_MASK, Math.min(c1 & p.BLUE_MASK, ((c2 & p.BLUE_MASK) * f) >> 8), f)); }, difference: function(a, b){ var c1 = p.rgbaToInt(a); var c2 = p.rgbaToInt(b); var f = (c2 & p.ALPHA_MASK) >>> 24; var ar = (c1 & p.RED_MASK) >> 16; var ag = (c1 & p.GREEN_MASK) >> 8; var ab = (c1 & p.BLUE_MASK); var br = (c2 & p.RED_MASK) >> 16; var bg = (c2 & p.GREEN_MASK) >> 8; var bb = (c2 & p.BLUE_MASK); // formula: var cr = (ar > br) ? (ar-br) : (br-ar); var cg = (ag > bg) ? (ag-bg) : (bg-ag); var cb = (ab > bb) ? (ab-bb) : (bb-ab); // alpha blend (this portion will always be the same) return (Math.min(((c1 & p.ALPHA_MASK) >>> 24) + f, 0xff) << 24 | (p.peg(ar + (((cr - ar) * f) >> 8)) << 16) | (p.peg(ag + (((cg - ag) * f) >> 8)) << 8) | (p.peg(ab + (((cb - ab) * f) >> 8)) ) ); }, exclusion: function(a, b){ var c1 = p.rgbaToInt(a); var c2 = p.rgbaToInt(b); var f = (c2 & p.ALPHA_MASK) >>> 24; var ar = (c1 & p.RED_MASK) >> 16; var ag = (c1 & p.GREEN_MASK) >> 8; var ab = (c1 & p.BLUE_MASK); var br = (c2 & p.RED_MASK) >> 16; var bg = (c2 & p.GREEN_MASK) >> 8; var bb = (c2 & p.BLUE_MASK); // formula: var cr = ar + br - ((ar * br) >> 7); var cg = ag + bg - ((ag * bg) >> 7); var cb = ab + bb - ((ab * bb) >> 7); // alpha blend (this portion will always be the same) return (Math.min(((c1 & p.ALPHA_MASK) >>> 24) + f, 0xff) << 24 | (p.peg(ar + (((cr - ar) * f) >> 8)) << 16) | (p.peg(ag + (((cg - ag) * f) >> 8)) << 8) | (p.peg(ab + (((cb - ab) * f) >> 8)) ) ); }, multiply: function(a, b){ var c1 = p.rgbaToInt(a); var c2 = p.rgbaToInt(b); var f = (c2 & p.ALPHA_MASK) >>> 24; var ar = (c1 & p.RED_MASK) >> 16; var ag = (c1 & p.GREEN_MASK) >> 8; var ab = (c1 & p.BLUE_MASK); var br = (c2 & p.RED_MASK) >> 16; var bg = (c2 & p.GREEN_MASK) >> 8; var bb = (c2 & p.BLUE_MASK); // formula: var cr = (ar * br) >> 8; var cg = (ag * bg) >> 8; var cb = (ab * bb) >> 8; // alpha blend (this portion will always be the same) return (Math.min(((c1 & p.ALPHA_MASK) >>> 24) + f, 0xff) << 24 | (p.peg(ar + (((cr - ar) * f) >> 8)) << 16) | (p.peg(ag + (((cg - ag) * f) >> 8)) << 8) | (p.peg(ab + (((cb - ab) * f) >> 8)) ) ); }, screen: function(a, b){ var c1 = p.rgbaToInt(a); var c2 = p.rgbaToInt(b); var f = (c2 & p.ALPHA_MASK) >>> 24; var ar = (c1 & p.RED_MASK) >> 16; var ag = (c1 & p.GREEN_MASK) >> 8; var ab = (c1 & p.BLUE_MASK); var br = (c2 & p.RED_MASK) >> 16; var bg = (c2 & p.GREEN_MASK) >> 8; var bb = (c2 & p.BLUE_MASK); // formula: var cr = 255 - (((255 - ar) * (255 - br)) >> 8); var cg = 255 - (((255 - ag) * (255 - bg)) >> 8); var cb = 255 - (((255 - ab) * (255 - bb)) >> 8); // alpha blend (this portion will always be the same) return (Math.min(((c1 & p.ALPHA_MASK) >>> 24) + f, 0xff) << 24 | (p.peg(ar + (((cr - ar) * f) >> 8)) << 16) | (p.peg(ag + (((cg - ag) * f) >> 8)) << 8) | (p.peg(ab + (((cb - ab) * f) >> 8)) ) ); }, hard_light: function(a, b){ var c1 = p.rgbaToInt(a); var c2 = p.rgbaToInt(b); var f = (c2 & p.ALPHA_MASK) >>> 24; var ar = (c1 & p.RED_MASK) >> 16; var ag = (c1 & p.GREEN_MASK) >> 8; var ab = (c1 & p.BLUE_MASK); var br = (c2 & p.RED_MASK) >> 16; var bg = (c2 & p.GREEN_MASK) >> 8; var bb = (c2 & p.BLUE_MASK); // formula: var cr = (br < 128) ? ((ar*br)>>7) : (255-(((255-ar)*(255-br))>>7)); var cg = (bg < 128) ? ((ag*bg)>>7) : (255-(((255-ag)*(255-bg))>>7)); var cb = (bb < 128) ? ((ab*bb)>>7) : (255-(((255-ab)*(255-bb))>>7)); // alpha blend (this portion will always be the same) return (Math.min(((c1 & p.ALPHA_MASK) >>> 24) + f, 0xff) << 24 | (p.peg(ar + (((cr - ar) * f) >> 8)) << 16) | (p.peg(ag + (((cg - ag) * f) >> 8)) << 8) | (p.peg(ab + (((cb - ab) * f) >> 8)) ) ); }, soft_light: function(a, b){ var c1 = p.rgbaToInt(a); var c2 = p.rgbaToInt(b); var f = (c2 & p.ALPHA_MASK) >>> 24; var ar = (c1 & p.RED_MASK) >> 16; var ag = (c1 & p.GREEN_MASK) >> 8; var ab = (c1 & p.BLUE_MASK); var br = (c2 & p.RED_MASK) >> 16; var bg = (c2 & p.GREEN_MASK) >> 8; var bb = (c2 & p.BLUE_MASK); // formula: var cr = ((ar*br)>>7) + ((ar*ar)>>8) - ((ar*ar*br)>>15); var cg = ((ag*bg)>>7) + ((ag*ag)>>8) - ((ag*ag*bg)>>15); var cb = ((ab*bb)>>7) + ((ab*ab)>>8) - ((ab*ab*bb)>>15); // alpha blend (this portion will always be the same) return (Math.min(((c1 & p.ALPHA_MASK) >>> 24) + f, 0xff) << 24 | (p.peg(ar + (((cr - ar) * f) >> 8)) << 16) | (p.peg(ag + (((cg - ag) * f) >> 8)) << 8) | (p.peg(ab + (((cb - ab) * f) >> 8)) ) ); }, overlay: function(a, b){ var c1 = p.rgbaToInt(a); var c2 = p.rgbaToInt(b); var f = (c2 & p.ALPHA_MASK) >>> 24; var ar = (c1 & p.RED_MASK) >> 16; var ag = (c1 & p.GREEN_MASK) >> 8; var ab = (c1 & p.BLUE_MASK); var br = (c2 & p.RED_MASK) >> 16; var bg = (c2 & p.GREEN_MASK) >> 8; var bb = (c2 & p.BLUE_MASK); // formula: var cr = (ar < 128) ? ((ar*br)>>7) : (255-(((255-ar)*(255-br))>>7)); var cg = (ag < 128) ? ((ag*bg)>>7) : (255-(((255-ag)*(255-bg))>>7)); var cb = (ab < 128) ? ((ab*bb)>>7) : (255-(((255-ab)*(255-bb))>>7)); // alpha blend (this portion will always be the same) return (Math.min(((c1 & p.ALPHA_MASK) >>> 24) + f, 0xff) << 24 | (p.peg(ar + (((cr - ar) * f) >> 8)) << 16) | (p.peg(ag + (((cg - ag) * f) >> 8)) << 8) | (p.peg(ab + (((cb - ab) * f) >> 8)) ) ); }, dodge: function(a, b){ var c1 = p.rgbaToInt(a); var c2 = p.rgbaToInt(b); var f = (c2 & p.ALPHA_MASK) >>> 24; var ar = (c1 & p.RED_MASK) >> 16; var ag = (c1 & p.GREEN_MASK) >> 8; var ab = (c1 & p.BLUE_MASK); var br = (c2 & p.RED_MASK) >> 16; var bg = (c2 & p.GREEN_MASK) >> 8; var bb = (c2 & p.BLUE_MASK); // formula: var cr = (br==255) ? 255 : p.peg((ar << 8) / (255 - br)); // division requires pre-peg()-ing var cg = (bg==255) ? 255 : p.peg((ag << 8) / (255 - bg)); // " var cb = (bb==255) ? 255 : p.peg((ab << 8) / (255 - bb)); // " // alpha blend (this portion will always be the same) return (Math.min(((c1 & p.ALPHA_MASK) >>> 24) + f, 0xff) << 24 | (p.peg(ar + (((cr - ar) * f) >> 8)) << 16) | (p.peg(ag + (((cg - ag) * f) >> 8)) << 8) | (p.peg(ab + (((cb - ab) * f) >> 8)) ) ); }, burn: function(a, b){ var c1 = p.rgbaToInt(a); var c2 = p.rgbaToInt(b); var f = (c2 & p.ALPHA_MASK) >>> 24; var ar = (c1 & p.RED_MASK) >> 16; var ag = (c1 & p.GREEN_MASK) >> 8; var ab = (c1 & p.BLUE_MASK); var br = (c2 & p.RED_MASK) >> 16; var bg = (c2 & p.GREEN_MASK) >> 8; var bb = (c2 & p.BLUE_MASK); // formula: var cr = (br==0) ? 0 : 255 - p.peg(((255 - ar) << 8) / br); // division requires pre-peg()-ing var cg = (bg==0) ? 0 : 255 - p.peg(((255 - ag) << 8) / bg); // " var cb = (bb==0) ? 0 : 255 - p.peg(((255 - ab) << 8) / bb); // " // alpha blend (this portion will always be the same) return (Math.min(((c1 & p.ALPHA_MASK) >>> 24) + f, 0xff) << 24 | (p.peg(ar + (((cr - ar) * f) >> 8)) << 16) | (p.peg(ag + (((cg - ag) * f) >> 8)) << 8) | (p.peg(ab + (((cb - ab) * f) >> 8)) ) ); } };=== screen === p.screen = { width:screen.width, height:screen.height }=== log() === p.log = function( num ) { return Math.log(num > 0 ? num : 0); }=== exp() === p.exp = function( num ){ return Math.exp(num > 0 ? num : 0); }=== asin() === p.asin = function( num ){ return Math.asin(num); }=== acos() === p.acos = function( num ){ return Math.acos(num); }=== atan() === p.atan = function( num ){ return Math.atan(num); }=== tan() === p.tan = function( num ){ return Math.tan(num); }=== map() === p.map = function( value, low1, high1, low2, high2 ){ return (((value-low1)/(high1-low1))*(high2-low2))+low2; }=== nfc() ====
Specification for nfc() in processing [http://processing.org/reference/nfc_.html here].<br />
nfc() is a function used to format numbers with commas every 3rd digit and optionally how many decimal places to show right of the decimal place. It accepts int, int[], float, and float[] types and returns either a single string or array of strings depending on the input.
Example of this function and test is [http://matrix.senecac.on.ca/~dhhodgin/dps909/nfc_test.htm here].<br />
'''Known issues:''' None.
Specification for shorten() in processing [http://processing.org/reference/shorten_.html here].<br />
Arrays in JS have no type, the elements in them can contain any type and do not all have to match. Arrays are also passed by reference which means a reference to the object is passed in not the entire object. so my code creates a new array and then copies the passed in array first and then pops one element off the new array and the newary object is returned. This is built to accept a processing type of String, int, boolean, char, byte, and float. Support for arrays of objects will be added in 0.2.
'''Known issues:''' This has not been tested with arrays of objects. I'm assuming it will copy object elements in an array by reference and not produce a proper deep copy. I plan to fix this by 0.2. (confirmed, needs deep copy support for arrays of objects).
Specification for expand() in processing [http://processing.org/reference/expand_.html here].<br />
Expand takes an array as its argument and returns a copy of the array with its length doubled. There is an optional 2nd parameter to specify the new size of the array as well.
'''Known issues:''' Not yet tested with arrays of objects.
Specification for unhex() in processing [http://processing.org/reference/unhex_.html here].<br />
unhex takes a string representing a 8 digit hex code as its only argument and returns an int representation of the string. JavaScript supports 64 bit floats as var's so it took a little number crunching to make it output an exact replication of the Java implementation with signed int's.
'''Known issues:''' None.
Specification for nfs() in processing [http://processing.org/reference/nfs_.html here].<br />
nfs() is a function used to format numbers as strings with padding of 0's on either the left or right of the decimal place. It accepts int, int[], float, and float[] types and returns either a single string or array of strings depending on the input.
Example of this function and test is [http://matrix.senecac.on.ca/~dhhodgin/dps909/nfs_test.htm here].<br />
'''Known issues:''' None.