Open main menu

CDOT Wiki β

Changes

User:Dhhodgin

28,068 bytes added, 08:10, 30 September 2010
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==
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 - [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 - wip[http: //dhodgin.wordpress.com/2009/12/15/my-great-white-vs-killer-whale-0-3-patch/ Full Details] blendColor(), blend(), copy(), filter()<br/>
=== Contributions ===
=== Week 1 stuff ===
* Create Zenit Wiki (done)
* Create Blog ([http://dhodgin.wordpress.com done])
* Update wiki (done)
=== Week 2 stuff ===
* Create MDC account (done)
* join Mozilla Fennec mailing list (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)
* 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])
* 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<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 - wipsy - 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: blendColor 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, copyiw1 : 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, filterp.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.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){
return color;
}
=== blendColor() helper functions ===
// helper functions for internal blending modes
// convert rgba color strings to integer
return (n < 0) ? 0 : ((n > 255) ? 255 : n);
}
=== blendColor() blending modes ===
// blending modes
p.modes = {
1
edit