Propchange: ofbiz/trunk/framework/images/webapp/images/flotr/flotr.js
------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/flotr/flotr.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/flotr/lib/base64.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/flotr/lib/base64.js?rev=945044&view=auto ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/flotr/lib/base64.js (added) +++ ofbiz/trunk/framework/images/webapp/images/flotr/lib/base64.js Mon May 17 09:29:38 2010 @@ -0,0 +1,113 @@ +/* Copyright (C) 1999 Masanao Izumo <[hidden email]> + * Version: 1.0 + * LastModified: Dec 25 1999 + * This library is free. You can redistribute it and/or modify it. + */ + +/* + * Interfaces: + * b64 = base64encode(data); + * data = base64decode(b64); + */ + +(function() { + +var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +var base64DecodeChars = [ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1]; + +function base64encode(str) { + var out, i, len; + var c1, c2, c3; + + len = str.length; + i = 0; + out = ""; + while(i < len) { + c1 = str.charCodeAt(i++) & 0xff; + if(i == len) + { + out += base64EncodeChars.charAt(c1 >> 2); + out += base64EncodeChars.charAt((c1 & 0x3) << 4); + out += "=="; + break; + } + c2 = str.charCodeAt(i++); + if(i == len) + { + out += base64EncodeChars.charAt(c1 >> 2); + out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)); + out += base64EncodeChars.charAt((c2 & 0xF) << 2); + out += "="; + break; + } + c3 = str.charCodeAt(i++); + out += base64EncodeChars.charAt(c1 >> 2); + out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)); + out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)); + out += base64EncodeChars.charAt(c3 & 0x3F); + } + return out; +} + +function base64decode(str) { + var c1, c2, c3, c4; + var i, len, out; + + len = str.length; + i = 0; + out = ""; + while(i < len) { + /* c1 */ + do { + c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff]; + } while(i < len && c1 == -1); + if(c1 == -1) + break; + + /* c2 */ + do { + c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff]; + } while(i < len && c2 == -1); + if(c2 == -1) + break; + + out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4)); + + /* c3 */ + do { + c3 = str.charCodeAt(i++) & 0xff; + if(c3 == 61) + return out; + c3 = base64DecodeChars[c3]; + } while(i < len && c3 == -1); + if(c3 == -1) + break; + + out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2)); + + /* c4 */ + do { + c4 = str.charCodeAt(i++) & 0xff; + if(c4 == 61) + return out; + c4 = base64DecodeChars[c4]; + } while(i < len && c4 == -1); + if(c4 == -1) + break; + out += String.fromCharCode(((c3 & 0x03) << 6) | c4); + } + return out; +} + +if (!window.btoa) window.btoa = base64encode; +if (!window.atob) window.atob = base64decode; + +})(); \ No newline at end of file Propchange: ofbiz/trunk/framework/images/webapp/images/flotr/lib/base64.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/flotr/lib/base64.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/flotr/lib/base64.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/flotr/lib/canvas2image.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/flotr/lib/canvas2image.js?rev=945044&view=auto ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/flotr/lib/canvas2image.js (added) +++ ofbiz/trunk/framework/images/webapp/images/flotr/lib/canvas2image.js Mon May 17 09:29:38 2010 @@ -0,0 +1,198 @@ +/* + * Canvas2Image v0.1 + * Copyright (c) 2008 Jacob Seidelin, [hidden email] + * MIT License [http://www.opensource.org/licenses/mit-license.php] + */ + +var Canvas2Image = (function() { + // check if we have canvas support + var oCanvas = document.createElement("canvas"), + sc = String.fromCharCode, + strDownloadMime = "image/octet-stream", + bReplaceDownloadMime = false; + + // no canvas, bail out. + if (!oCanvas.getContext) { + return { + saveAsBMP : function(){}, + saveAsPNG : function(){}, + saveAsJPEG : function(){} + } + } + + var bHasImageData = !!(oCanvas.getContext("2d").getImageData), + bHasDataURL = !!(oCanvas.toDataURL), + bHasBase64 = !!(window.btoa); + + // ok, we're good + var readCanvasData = function(oCanvas) { + var iWidth = parseInt(oCanvas.width), + iHeight = parseInt(oCanvas.height); + return oCanvas.getContext("2d").getImageData(0,0,iWidth,iHeight); + } + + // base64 encodes either a string or an array of charcodes + var encodeData = function(data) { + var i, aData, strData = ""; + + if (typeof data == "string") { + strData = data; + } else { + aData = data; + for (i = 0; i < aData.length; i++) { + strData += sc(aData[i]); + } + } + return btoa(strData); + } + + // creates a base64 encoded string containing BMP data takes an imagedata object as argument + var createBMP = function(oData) { + var strHeader = '', + iWidth = oData.width, + iHeight = oData.height; + + strHeader += 'BM'; + + var iFileSize = iWidth*iHeight*4 + 54; // total header size = 54 bytes + strHeader += sc(iFileSize % 256); iFileSize = Math.floor(iFileSize / 256); + strHeader += sc(iFileSize % 256); iFileSize = Math.floor(iFileSize / 256); + strHeader += sc(iFileSize % 256); iFileSize = Math.floor(iFileSize / 256); + strHeader += sc(iFileSize % 256); + + strHeader += sc(0, 0, 0, 0, 54, 0, 0, 0); // data offset + strHeader += sc(40, 0, 0, 0); // info header size + + var iImageWidth = iWidth; + strHeader += sc(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth / 256); + strHeader += sc(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth / 256); + strHeader += sc(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth / 256); + strHeader += sc(iImageWidth % 256); + + var iImageHeight = iHeight; + strHeader += sc(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight / 256); + strHeader += sc(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight / 256); + strHeader += sc(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight / 256); + strHeader += sc(iImageHeight % 256); + + strHeader += sc(1, 0, 32, 0); // num of planes & num of bits per pixel + strHeader += sc(0, 0, 0, 0); // compression = none + + var iDataSize = iWidth*iHeight*4; + strHeader += sc(iDataSize % 256); iDataSize = Math.floor(iDataSize / 256); + strHeader += sc(iDataSize % 256); iDataSize = Math.floor(iDataSize / 256); + strHeader += sc(iDataSize % 256); iDataSize = Math.floor(iDataSize / 256); + strHeader += sc(iDataSize % 256); + + strHeader += sc(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); // these bytes are not used + + var aImgData = oData.data, + strPixelData = "", + c, x, y = iHeight, + iOffsetX, iOffsetY, strPixelRow; + + do { + iOffsetY = iWidth*(y-1)*4; + strPixelRow = ""; + for (x = 0; x < iWidth; x++) { + iOffsetX = 4*x; + strPixelRow += sc( + aImgData[iOffsetY + iOffsetX + 2], // B + aImgData[iOffsetY + iOffsetX + 1], // G + aImgData[iOffsetY + iOffsetX], // R + aImgData[iOffsetY + iOffsetX + 3] // A + ); + } + strPixelData += strPixelRow; + } while (--y); + + return encodeData(strHeader + strPixelData); + } + + // sends the generated file to the client + var saveFile = function(strData) { + if (!window.open(strData)) { + document.location.href = strData; + } + } + + var makeDataURI = function(strData, strMime) { + return "data:" + strMime + ";base64," + strData; + } + + // generates a <img> object containing the imagedata + var makeImageObject = function(strSource) { + var oImgElement = document.createElement("img"); + oImgElement.src = strSource; + return oImgElement; + } + + var scaleCanvas = function(oCanvas, iWidth, iHeight) { + if (iWidth && iHeight) { + var oSaveCanvas = document.createElement("canvas"); + + oSaveCanvas.width = iWidth; + oSaveCanvas.height = iHeight; + oSaveCanvas.style.width = iWidth+"px"; + oSaveCanvas.style.height = iHeight+"px"; + + var oSaveCtx = oSaveCanvas.getContext("2d"); + + oSaveCtx.drawImage(oCanvas, 0, 0, oCanvas.width, oCanvas.height, 0, 0, iWidth, iWidth); + + return oSaveCanvas; + } + return oCanvas; + } + + return { + saveAsPNG : function(oCanvas, bReturnImg, iWidth, iHeight) { + if (!bHasDataURL) return false; + + var oScaledCanvas = scaleCanvas(oCanvas, iWidth, iHeight), + strMime = "image/png", + strData = oScaledCanvas.toDataURL(strMime); + + if (bReturnImg) { + return makeImageObject(strData); + } else { + saveFile(bReplaceDownloadMime ? strData.replace(strMime, strDownloadMime) : strData); + } + return true; + }, + + saveAsJPEG : function(oCanvas, bReturnImg, iWidth, iHeight) { + if (!bHasDataURL) return false; + + var oScaledCanvas = scaleCanvas(oCanvas, iWidth, iHeight), + strMime = "image/jpeg", + strData = oScaledCanvas.toDataURL(strMime); + + // check if browser actually supports jpeg by looking for the mime type in the data uri. if not, return false + if (strData.indexOf(strMime) != 5) return false; + + if (bReturnImg) { + return makeImageObject(strData); + } else { + saveFile(bReplaceDownloadMime ? strData.replace(strMime, strDownloadMime) : strData); + } + return true; + }, + + saveAsBMP : function(oCanvas, bReturnImg, iWidth, iHeight) { + if (!(bHasDataURL && bHasImageData && bHasBase64)) return false; + + var oScaledCanvas = scaleCanvas(oCanvas, iWidth, iHeight), + strMime = "image/bmp", + oData = readCanvasData(oScaledCanvas), + strImgData = createBMP(oData); + + if (bReturnImg) { + return makeImageObject(makeDataURI(strImgData, strMime)); + } else { + saveFile(makeDataURI(strImgData, strMime)); + } + return true; + } + }; +})(); \ No newline at end of file Propchange: ofbiz/trunk/framework/images/webapp/images/flotr/lib/canvas2image.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/flotr/lib/canvas2image.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/flotr/lib/canvas2image.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/flotr/lib/canvastext.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/flotr/lib/canvastext.js?rev=945044&view=auto ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/flotr/lib/canvastext.js (added) +++ ofbiz/trunk/framework/images/webapp/images/flotr/lib/canvastext.js Mon May 17 09:29:38 2010 @@ -0,0 +1,429 @@ +/** + * This code is released to the public domain by Jim Studt, 2007. + * He may keep some sort of up to date copy at http://www.federated.com/~jim/canvastext/ + * It as been modified by Fabien Ménager to handle font style like size, weight, color and rotation. + * A partial support for special characters has been added too. + */ +var CanvasText = { + /** The letters definition. It is a list of letters, + * with their width, and the coordinates of points compositing them. + * The syntax for the points is : [x, y], null value means "pen up" + */ + letters: { + '\n':{ width: -1, points: [] }, + ' ': { width: 10, points: [] }, + '!': { width: 10, points: [[5,21],[5,7],null,[5,2],[4,1],[5,0],[6,1],[5,2]] }, + '"': { width: 16, points: [[4,21],[4,14],null,[12,21],[12,14]] }, + '#': { width: 21, points: [[11,25],[4,-7],null,[17,25],[10,-7],null,[4,12],[18,12],null,[3,6],[17,6]] }, + '$': { width: 20, points: [[8,25],[8,-4],null,[12,25],[12,-4],null,[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]] }, + '%': { width: 24, points: [[21,21],[3,0],null,[8,21],[10,19],[10,17],[9,15],[7,14],[5,14],[3,16],[3,18],[4,20],[6,21],[8,21],null,[17,7],[15,6],[14,4],[14,2],[16,0],[18,0],[20,1],[21,3],[21,5],[19,7],[17,7]] }, + '&': { width: 26, points: [[23,12],[23,13],[22,14],[21,14],[20,13],[19,11],[17,6],[15,3],[13,1],[11,0],[7,0],[5,1],[4,2],[3,4],[3,6],[4,8],[5,9],[12,13],[13,14],[14,16],[14,18],[13,20],[11,21],[9,20],[8,18],[8,16],[9,13],[11,10],[16,3],[18,1],[20,0],[22,0],[23,1],[23,2]] }, + '\'':{ width: 10, points: [[5,19],[4,20],[5,21],[6,20],[6,18],[5,16],[4,15]] }, + '(': { width: 14, points: [[11,25],[9,23],[7,20],[5,16],[4,11],[4,7],[5,2],[7,-2],[9,-5],[11,-7]] }, + ')': { width: 14, points: [[3,25],[5,23],[7,20],[9,16],[10,11],[10,7],[9,2],[7,-2],[5,-5],[3,-7]] }, + '*': { width: 16, points: [[8,21],[8,9],null,[3,18],[13,12],null,[13,18],[3,12]] }, + '+': { width: 26, points: [[13,18],[13,0],null,[4,9],[22,9]] }, + ',': { width: 10, points: [[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]] }, + '-': { width: 26, points: [[4,9],[22,9]] }, + '.': { width: 10, points: [[5,2],[4,1],[5,0],[6,1],[5,2]] }, + '/': { width: 22, points: [[20,25],[2,-7]] }, + '0': { width: 20, points: [[9,21],[6,20],[4,17],[3,12],[3,9],[4,4],[6,1],[9,0],[11,0],[14,1],[16,4],[17,9],[17,12],[16,17],[14,20],[11,21],[9,21]] }, + '1': { width: 20, points: [[6,17],[8,18],[11,21],[11,0]] }, + '2': { width: 20, points: [[4,16],[4,17],[5,19],[6,20],[8,21],[12,21],[14,20],[15,19],[16,17],[16,15],[15,13],[13,10],[3,0],[17,0]] }, + '3': { width: 20, points: [[5,21],[16,21],[10,13],[13,13],[15,12],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]] }, + '4': { width: 20, points: [[13,21],[3,7],[18,7],null,[13,21],[13,0]] }, + '5': { width: 20, points: [[15,21],[5,21],[4,12],[5,13],[8,14],[11,14],[14,13],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]] }, + '6': { width: 20, points: [[16,18],[15,20],[12,21],[10,21],[7,20],[5,17],[4,12],[4,7],[5,3],[7,1],[10,0],[11,0],[14,1],[16,3],[17,6],[17,7],[16,10],[14,12],[11,13],[10,13],[7,12],[5,10],[4,7]] }, + '7': { width: 20, points: [[17,21],[7,0],null,[3,21],[17,21]] }, + '8': { width: 20, points: [[8,21],[5,20],[4,18],[4,16],[5,14],[7,13],[11,12],[14,11],[16,9],[17,7],[17,4],[16,2],[15,1],[12,0],[8,0],[5,1],[4,2],[3,4],[3,7],[4,9],[6,11],[9,12],[13,13],[15,14],[16,16],[16,18],[15,20],[12,21],[8,21]] }, + '9': { width: 20, points: [[16,14],[15,11],[13,9],[10,8],[9,8],[6,9],[4,11],[3,14],[3,15],[4,18],[6,20],[9,21],[10,21],[13,20],[15,18],[16,14],[16,9],[15,4],[13,1],[10,0],[8,0],[5,1],[4,3]] }, + ':': { width: 10, points: [[5,14],[4,13],[5,12],[6,13],[5,14],null,[5,2],[4,1],[5,0],[6,1],[5,2]] }, + ';': { width: 10, points: [[5,14],[4,13],[5,12],[6,13],[5,14],null,[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]] }, + '<': { width: 24, points: [[20,18],[4,9],[20,0]] }, + '=': { width: 26, points: [[4,12],[22,12],null,[4,6],[22,6]] }, + '>': { width: 24, points: [[4,18],[20,9],[4,0]] }, + '?': { width: 18, points: [[3,16],[3,17],[4,19],[5,20],[7,21],[11,21],[13,20],[14,19],[15,17],[15,15],[14,13],[13,12],[9,10],[9,7],null,[9,2],[8,1],[9,0],[10,1],[9,2]] }, + '@': { width: 27, points: [[18,13],[17,15],[15,16],[12,16],[10,15],[9,14],[8,11],[8,8],[9,6],[11,5],[14,5],[16,6],[17,8],null,[12,16],[10,14],[9,11],[9,8],[10,6],[11,5],null,[18,16],[17,8],[17,6],[19,5],[21,5],[23,7],[24,10],[24,12],[23,15],[22,17],[20,19],[18,20],[15,21],[12,21],[9,20],[7,19],[5,17],[4,15],[3,12],[3,9],[4,6],[5,4],[7,2],[9,1],[12,0],[15,0],[18,1],[20,2],[21,3],null,[19,16],[18,8],[18,6],[19,5]] }, + 'A': { width: 18, points: [[9,21],[1,0],null,[9,21],[17,0],null,[4,7],[14,7]] }, + 'B': { width: 21, points: [[4,21],[4,0],null,[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],null,[4,11],[13,11],[16,10],[17,9],[18,7],[18,4],[17,2],[16,1],[13,0],[4,0]] }, + 'C': { width: 21, points: [[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5]] }, + 'D': { width: 21, points: [[4,21],[4,0],null,[4,21],[11,21],[14,20],[16,18],[17,16],[18,13],[18,8],[17,5],[16,3],[14,1],[11,0],[4,0]] }, + 'E': { width: 19, points: [[4,21],[4,0],null,[4,21],[17,21],null,[4,11],[12,11],null,[4,0],[17,0]] }, + 'F': { width: 18, points: [[4,21],[4,0],null,[4,21],[17,21],null,[4,11],[12,11]] }, + 'G': { width: 21, points: [[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[18,8],null,[13,8],[18,8]] }, + 'H': { width: 22, points: [[4,21],[4,0],null,[18,21],[18,0],null,[4,11],[18,11]] }, + 'I': { width: 8, points: [[4,21],[4,0]] }, + 'J': { width: 16, points: [[12,21],[12,5],[11,2],[10,1],[8,0],[6,0],[4,1],[3,2],[2,5],[2,7]] }, + 'K': { width: 21, points: [[4,21],[4,0],null,[18,21],[4,7],null,[9,12],[18,0]] }, + 'L': { width: 17, points: [[4,21],[4,0],null,[4,0],[16,0]] }, + 'M': { width: 24, points: [[4,21],[4,0],null,[4,21],[12,0],null,[20,21],[12,0],null,[20,21],[20,0]] }, + 'N': { width: 22, points: [[4,21],[4,0],null,[4,21],[18,0],null,[18,21],[18,0]] }, + 'O': { width: 22, points: [[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21]] }, + 'P': { width: 21, points: [[4,21],[4,0],null,[4,21],[13,21],[16,20],[17,19],[18,17],[18,14],[17,12],[16,11],[13,10],[4,10]] }, + 'Q': { width: 22, points: [[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21],null,[12,4],[18,-2]] }, + 'R': { width: 21, points: [[4,21],[4,0],null,[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[4,11],null,[11,11],[18,0]] }, + 'S': { width: 20, points: [[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]] }, + 'T': { width: 16, points: [[8,21],[8,0],null,[1,21],[15,21]] }, + 'U': { width: 22, points: [[4,21],[4,6],[5,3],[7,1],[10,0],[12,0],[15,1],[17,3],[18,6],[18,21]] }, + 'V': { width: 18, points: [[1,21],[9,0],null,[17,21],[9,0]] }, + 'W': { width: 24, points: [[2,21],[7,0],null,[12,21],[7,0],null,[12,21],[17,0],null,[22,21],[17,0]] }, + 'X': { width: 20, points: [[3,21],[17,0],null,[17,21],[3,0]] }, + 'Y': { width: 18, points: [[1,21],[9,11],[9,0],null,[17,21],[9,11]] }, + 'Z': { width: 20, points: [[17,21],[3,0],null,[3,21],[17,21],null,[3,0],[17,0]] }, + '[': { width: 14, points: [[4,25],[4,-7],null,[5,25],[5,-7],null,[4,25],[11,25],null,[4,-7],[11,-7]] }, + '\\':{ width: 14, points: [[0,21],[14,-3]] }, + ']': { width: 14, points: [[9,25],[9,-7],null,[10,25],[10,-7],null,[3,25],[10,25],null,[3,-7],[10,-7]] }, + '^': { width: 14, points: [[3,10],[8,18],[13,10]] }, + '_': { width: 16, points: [[0,-2],[16,-2]] }, + '`': { width: 10, points: [[6,21],[5,20],[4,18],[4,16],[5,15],[6,16],[5,17]] }, + 'a': { width: 19, points: [[15,14],[15,0],null,[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, + 'b': { width: 19, points: [[4,21],[4,0],null,[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]] }, + 'c': { width: 18, points: [[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, + 'd': { width: 19, points: [[15,21],[15,0],null,[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, + 'e': { width: 18, points: [[3,8],[15,8],[15,10],[14,12],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, + 'f': { width: 12, points: [[10,21],[8,21],[6,20],[5,17],[5,0],null,[2,14],[9,14]] }, + 'g': { width: 19, points: [[15,14],[15,-2],[14,-5],[13,-6],[11,-7],[8,-7],[6,-6],null,[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, + 'h': { width: 19, points: [[4,21],[4,0],null,[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]] }, + 'i': { width: 8, points: [[3,21],[4,20],[5,21],[4,22],[3,21],null,[4,14],[4,0]] }, + 'j': { width: 10, points: [[5,21],[6,20],[7,21],[6,22],[5,21],null,[6,14],[6,-3],[5,-6],[3,-7],[1,-7]] }, + 'k': { width: 17, points: [[4,21],[4,0],null,[14,14],[4,4],null,[8,8],[15,0]] }, + 'l': { width: 8, points: [[4,21],[4,0]] }, + 'm': { width: 30, points: [[4,14],[4,0],null,[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0],null,[15,10],[18,13],[20,14],[23,14],[25,13],[26,10],[26,0]] }, + 'n': { width: 19, points: [[4,14],[4,0],null,[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]] }, + 'o': { width: 19, points: [[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3],[16,6],[16,8],[15,11],[13,13],[11,14],[8,14]] }, + 'p': { width: 19, points: [[4,14],[4,-7],null,[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]] }, + 'q': { width: 19, points: [[15,14],[15,-7],null,[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, + 'r': { width: 13, points: [[4,14],[4,0],null,[4,8],[5,11],[7,13],[9,14],[12,14]] }, + 's': { width: 17, points: [[14,11],[13,13],[10,14],[7,14],[4,13],[3,11],[4,9],[6,8],[11,7],[13,6],[14,4],[14,3],[13,1],[10,0],[7,0],[4,1],[3,3]] }, + 't': { width: 12, points: [[5,21],[5,4],[6,1],[8,0],[10,0],null,[2,14],[9,14]] }, + 'u': { width: 19, points: [[4,14],[4,4],[5,1],[7,0],[10,0],[12,1],[15,4],null,[15,14],[15,0]] }, + 'v': { width: 16, points: [[2,14],[8,0],null,[14,14],[8,0]] }, + 'w': { width: 22, points: [[3,14],[7,0],null,[11,14],[7,0],null,[11,14],[15,0],null,[19,14],[15,0]] }, + 'x': { width: 17, points: [[3,14],[14,0],null,[14,14],[3,0]] }, + 'y': { width: 16, points: [[2,14],[8,0],null,[14,14],[8,0],[6,-4],[4,-6],[2,-7],[1,-7]] }, + 'z': { width: 17, points: [[14,14],[3,0],null,[3,14],[14,14],null,[3,0],[14,0]] }, + '{': { width: 14, points: [[9,25],[7,24],[6,23],[5,21],[5,19],[6,17],[7,16],[8,14],[8,12],[6,10],null,[7,24],[6,22],[6,20],[7,18],[8,17],[9,15],[9,13],[8,11],[4,9],[8,7],[9,5],[9,3],[8,1],[7,0],[6,-2],[6,-4],[7,-6],null,[6,8],[8,6],[8,4],[7,2],[6,1],[5,-1],[5,-3],[6,-5],[7,-6],[9,-7]] }, + '|': { width: 8, points: [[4,25],[4,-7]] }, + '}': { width: 14, points: [[5,25],[7,24],[8,23],[9,21],[9,19],[8,17],[7,16],[6,14],[6,12],[8,10],null,[7,24],[8,22],[8,20],[7,18],[6,17],[5,15],[5,13],[6,11],[10,9],[6,7],[5,5],[5,3],[6,1],[7,0],[8,-2],[8,-4],[7,-6],null,[8,8],[6,6],[6,4],[7,2],[8,1],[9,-1],[9,-3],[8,-5],[7,-6],[5,-7]] }, + '~': { width: 24, points: [[3,6],[3,8],[4,11],[6,12],[8,12],[10,11],[14,8],[16,7],[18,7],[20,8],[21,10],null,[3,8],[4,10],[6,11],[8,11],[10,10],[14,7],[16,6],[18,6],[20,7],[21,10],[21,12]] }, + + // Lower case Latin-1 + 'à': { diacritic: '`', letter: 'a' }, + 'á': { diacritic: '´', letter: 'a' }, + 'â': { diacritic: '^', letter: 'a' }, + 'ä': { diacritic: '¨', letter: 'a' }, + 'ã': { diacritic: '~', letter: 'a' }, + + 'è': { diacritic: '`', letter: 'e' }, + 'é': { diacritic: '´', letter: 'e' }, + 'ê': { diacritic: '^', letter: 'e' }, + 'ë': { diacritic: '¨', letter: 'e' }, + + 'ì': { diacritic: '`', letter: 'i' }, + 'í': { diacritic: '´', letter: 'i' }, + 'î': { diacritic: '^', letter: 'i' }, + 'ï': { diacritic: '¨', letter: 'i' }, + + 'ò': { diacritic: '`', letter: 'o' }, + 'ó': { diacritic: '´', letter: 'o' }, + 'ô': { diacritic: '^', letter: 'o' }, + 'ö': { diacritic: '¨', letter: 'o' }, + 'õ': { diacritic: '~', letter: 'o' }, + + 'ù': { diacritic: '`', letter: 'u' }, + 'ú': { diacritic: '´', letter: 'u' }, + 'û': { diacritic: '^', letter: 'u' }, + 'ü': { diacritic: '¨', letter: 'u' }, + + 'ý': { diacritic: '´', letter: 'y' }, + 'ÿ': { diacritic: '¨', letter: 'y' }, + + 'ç': { diacritic: '¸', letter: 'c' }, + 'ñ': { diacritic: '~', letter: 'n' }, + + // Upper case Latin-1 + 'À': { diacritic: '`', letter: 'A' }, + 'Á': { diacritic: '´', letter: 'A' }, + 'Â': { diacritic: '^', letter: 'A' }, + 'Ä': { diacritic: '¨', letter: 'A' }, + 'Ã': { diacritic: '~', letter: 'A' }, + + 'È': { diacritic: '`', letter: 'E' }, + 'É': { diacritic: '´', letter: 'E' }, + 'Ê': { diacritic: '^', letter: 'E' }, + 'Ë': { diacritic: '¨', letter: 'E' }, + + 'Ì': { diacritic: '`', letter: 'I' }, + 'Í': { diacritic: '´', letter: 'I' }, + 'Î': { diacritic: '^', letter: 'I' }, + 'Ï': { diacritic: '¨', letter: 'I' }, + + 'Ò': { diacritic: '`', letter: 'O' }, + 'Ó': { diacritic: '´', letter: 'O' }, + 'Ô': { diacritic: '^', letter: 'O' }, + 'Ö': { diacritic: '¨', letter: 'O' }, + 'Õ': { diacritic: '~', letter: 'O' }, + + 'Ù': { diacritic: '`', letter: 'U' }, + 'Ú': { diacritic: '´', letter: 'U' }, + 'Û': { diacritic: '^', letter: 'U' }, + 'Ü': { diacritic: '¨', letter: 'U' }, + + 'Ý': { diacritic: '´', letter: 'Y' }, + + 'Ç': { diacritic: '¸', letter: 'C' }, + 'Ñ': { diacritic: '~', letter: 'N' } + }, + + specialchars: { + 'pi': { width: 19, points: [[6,14],[6,0],null,[14,14],[14,0],null,[2,13],[6,16],[13,13],[17,16]] } + }, + + /** Diacritics, used to draw accentuated letters */ + diacritics: { + '¸': { entity: 'cedil', points: [[6,-4],[4,-6],[2,-7],[1,-7]] }, + '´': { entity: 'acute', points: [[8,19],[13,22]] }, + '`': { entity: 'grave', points: [[7,22],[12,19]] }, + '^': { entity: 'circ', points: [[5.5,19],[9.5,23],[12.5,19]] }, + '¨': { entity: 'trema', points: [[5,21],[6,20],[7,21],[6,22],[5,21],null,[12,21],[13,20],[14,21],[13,22],[12,21]] }, + '~': { entity: 'tilde', points: [[4,18],[7,22],[10,18],[13,22]] } + }, + + /** The default font styling */ + style: { + size: 8, // font height in pixels + font: null, // not yet implemented + color: '#000000', // font color + weight: 1, // float, 1 for 'normal' + textAlign: 'left', // left, right, center + textBaseline: 'bottom', // top, middle, bottom + adjustAlign: false, // modifies the alignments if the angle is different from 0 to make the spin point always at the good position + angle: 0, // in radians, anticlockwise + tracking: 1, // space between the letters, float, 1 for 'normal' + boundingBoxColor: '#ff0000', // color of the bounding box (null to hide), can be used for debug and font drawing + originPointColor: '#000000' // color of the bounding box (null to hide), can be used for debug and font drawing + }, + + debug: false, + _bufferLexemes: {}, + + extend: function(dest, src) { + for (var property in src) { + if (property in dest) continue; + dest[property] = src[property]; + } + return dest; + }, + + /** Get the letter data corresponding to a char + * @param {String} ch - The char + */ + letter: function(ch) { + return CanvasText.letters[ch]; + }, + + parseLexemes: function(str) { + if (CanvasText._bufferLexemes[str]) + return CanvasText._bufferLexemes[str]; + + var i, c, matches = str.match(/&[A-Za-z]{2,5};|\s|./g), + result = [], chars = []; + + for (i = 0; i < matches.length; i++) { + c = matches[i]; + if (c.length == 1) + chars.push(c); + else { + var entity = c.substring(1, c.length-1); + if (CanvasText.specialchars[entity]) + chars.push(entity); + else + chars = chars.concat(c.toArray()); + } + } + for (i = 0; i < chars.length; i++) { + c = chars[i]; + if (c = CanvasText.letters[c] || CanvasText.specialchars[c]) result.push(c); + } + for (i = 0; i < result.length; i++) { + if (result === null || typeof result === 'undefined') + delete result[i]; + } + return CanvasText._bufferLexemes[str] = result; + }, + + /** Get the font ascent for a given style + * @param {Object} style - The reference style + */ + ascent: function(style) { + style = style || CanvasText.style; + return (style.size || CanvasText.style.size); + }, + + /** Get the font descent for a given style + * @param {Object} style - The reference style + * */ + descent: function(style) { + style = style || CanvasText.style; + return 7.0*(style.size || CanvasText.style.size)/25.0; + }, + + /** Measure the text horizontal size + * @param {String} str - The text + * @param {Object} style - Text style + * */ + measure: function(str, style) { + if (!str) return; + style = style || CanvasText.style; + + var i, width, lexemes = CanvasText.parseLexemes(str), + total = 0; + + for (i = lexemes.length-1; i > -1; --i) { + c = lexemes[i]; + width = (c.diacritic) ? CanvasText.letter(c.letter).width : c.width; + total += width * (style.tracking || CanvasText.style.tracking) * (style.size || CanvasText.style.size) / 25.0; + } + return total; + }, + + getDimensions: function(str, style) { + style = style || CanvasText.style; + + var width = CanvasText.measure(str, style), + height = style.size || CanvasText.style.size, + angle = style.angle || CanvasText.style.angle; + + if (style.angle == 0) return {width: width, height: height}; + return { + width: Math.abs(Math.cos(angle) * width) + Math.abs(Math.sin(angle) * height), + height: Math.abs(Math.sin(angle) * width) + Math.abs(Math.cos(angle) * height) + } + }, + + /** Draws serie of points at given coordinates + * @param {Canvas context} ctx - The canvas context + * @param {Array} points - The points to draw + * @param {Number} x - The X coordinate + * @param {Number} y - The Y coordinate + * @param {Number} mag - The scale + */ + drawPoints: function (ctx, points, x, y, mag, offset) { + var i, a, penUp = true, needStroke = 0; + offset = offset || {x:0, y:0}; + + ctx.beginPath(); + for (i = 0; i < points.length; i++) { + a = points[i]; + if (!a) { + penUp = true; + continue; + } + if (penUp) { + ctx.moveTo(x + a[0]*mag + offset.x, y - a[1]*mag + offset.y); + penUp = false; + } + else { + ctx.lineTo(x + a[0]*mag + offset.x, y - a[1]*mag + offset.y); + } + } + ctx.stroke(); + ctx.closePath(); + }, + + /** Draws a text at given coordinates and with a given style + * @param {String} str - The text to draw + * @param {Number} xOrig - The X coordinate + * @param {Number} yOrig - The Y coordinate + * @param {Object} style - The font style + */ + draw: function(str, xOrig, yOrig, style) { + if (!str) return; + CanvasText.extend(style, CanvasText.style); + + var i, c, total = 0, + mag = style.size / 25.0, + x = 0, y = 0, + lexemes = CanvasText.parseLexemes(str), + offset = {x: 0, y: 0}, + measure = CanvasText.measure(str, style), + align; + + if (style.adjustAlign) { + align = CanvasText.getBestAlign(style.angle, style); + CanvasText.extend(style, align); + } + + switch (style.textAlign) { + case 'left': break; + case 'center': offset.x = -measure / 2; break; + case 'right': offset.x = -measure; break; + } + + switch (style.textBaseline) { + case 'bottom': break; + case 'middle': offset.y = style.size / 2; break; + case 'top': offset.y = style.size; break; + } + + this.save(); + this.translate(xOrig, yOrig); + this.rotate(style.angle); + this.lineCap = "round"; + this.lineWidth = 2.0 * mag * (style.weight || CanvasText.style.weight); + this.strokeStyle = style.color || CanvasText.style.color; + + for (i = 0; i < lexemes.length; i++) { + c = lexemes[i]; + if (c.width == -1) { + x = 0; + y = style.size * 1.4; + continue; + } + + var points = c.points, + width = c.width; + + if (c.diacritic) { + var dia = CanvasText.diacritics[c.diacritic], + character = CanvasText.letter(c.letter); + + CanvasText.drawPoints(this, dia.points, x, y - (c.letter.toUpperCase() == c.letter ? 3 : 0), mag, offset); + points = character.points; + width = character.width; + } + + CanvasText.drawPoints(this, points, x, y, mag, offset); + + if (CanvasText.debug) { + this.save(); + this.lineJoin = "miter"; + this.lineWidth = 0.5; + this.strokeStyle = (style.boundingBoxColor || CanvasText.style.boundingBoxColor); + this.strokeRect(x+offset.x, y+offset.y, width*mag, -style.size); + + this.fillStyle = (style.originPointColor || CanvasText.style.originPointColor); + this.beginPath(); + this.arc(0, 0, 1.5, 0, Math.PI*2, true); + this.fill(); + this.closePath(); + this.restore(); + } + + x += width*mag*(style.tracking || CanvasText.style.tracking); + } + this.restore(); + return total; + } +}; + +/** The text functions are bound to the CanvasRenderingContext2D prototype */ +CanvasText.proto = window.CanvasRenderingContext2D ? window.CanvasRenderingContext2D.prototype : document.createElement('canvas').getContext('2d').__proto__; + +if (CanvasText.proto) { + CanvasText.proto.drawText = CanvasText.draw; + CanvasText.proto.measure = CanvasText.measure; + CanvasText.proto.getTextBounds = CanvasText.getDimensions; + CanvasText.proto.fontAscent = CanvasText.ascent; + CanvasText.proto.fontDescent = CanvasText.descent; +} \ No newline at end of file Propchange: ofbiz/trunk/framework/images/webapp/images/flotr/lib/canvastext.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/flotr/lib/canvastext.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/flotr/lib/canvastext.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/flotr/lib/excanvas.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/flotr/lib/excanvas.js?rev=945044&view=auto ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/flotr/lib/excanvas.js (added) +++ ofbiz/trunk/framework/images/webapp/images/flotr/lib/excanvas.js Mon May 17 09:29:38 2010 @@ -0,0 +1,1420 @@ +// Copyright 2006 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// Known Issues: +// +// * Patterns only support repeat. +// * Radial gradient are not implemented. The VML version of these look very +// different from the canvas one. +// * Clipping paths are not implemented. +// * Coordsize. The width and height attribute have higher priority than the +// width and height style values which isn't correct. +// * Painting mode isn't implemented. +// * Canvas width/height should is using content-box by default. IE in +// Quirks mode will draw the canvas using border-box. Either change your +// doctype to HTML5 +// (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype) +// or use Box Sizing Behavior from WebFX +// (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html) +// * Non uniform scaling does not correctly scale strokes. +// * Optimize. There is always room for speed improvements. + +// Only add this code if we do not already have a canvas implementation +if (!document.createElement('canvas').getContext) { + +(function() { + + // alias some functions to make (compiled) code shorter + var m = Math; + var mr = m.round; + var ms = m.sin; + var mc = m.cos; + var abs = m.abs; + var sqrt = m.sqrt; + + // this is used for sub pixel precision + var Z = 10; + var Z2 = Z / 2; + + var IE_VERSION = +navigator.userAgent.match(/MSIE ([\d.]+)?/)[1]; + + /** + * This funtion is assigned to the <canvas> elements as element.getContext(). + * @this {HTMLElement} + * @return {CanvasRenderingContext2D_} + */ + function getContext() { + return this.context_ || + (this.context_ = new CanvasRenderingContext2D_(this)); + } + + var slice = Array.prototype.slice; + + /** + * Binds a function to an object. The returned function will always use the + * passed in {@code obj} as {@code this}. + * + * Example: + * + * g = bind(f, obj, a, b) + * g(c, d) // will do f.call(obj, a, b, c, d) + * + * @param {Function} f The function to bind the object to + * @param {Object} obj The object that should act as this when the function + * is called + * @param {*} var_args Rest arguments that will be used as the initial + * arguments when the function is called + * @return {Function} A new function that has bound this + */ + function bind(f, obj, var_args) { + var a = slice.call(arguments, 2); + return function() { + return f.apply(obj, a.concat(slice.call(arguments))); + }; + } + + function encodeHtmlAttribute(s) { + return String(s).replace(/&/g, '&').replace(/"/g, '"'); + } + + function addNamespace(doc, prefix, urn) { + if (!doc.namespaces[prefix]) { + doc.namespaces.add(prefix, urn, '#default#VML'); + } + } + + function addNamespacesAndStylesheet(doc) { + addNamespace(doc, 'g_vml_', 'urn:schemas-microsoft-com:vml'); + addNamespace(doc, 'g_o_', 'urn:schemas-microsoft-com:office:office'); + + // Setup default CSS. Only add one style sheet per document + if (!doc.styleSheets['ex_canvas_']) { + var ss = doc.createStyleSheet(); + ss.owningElement.id = 'ex_canvas_'; + ss.cssText = 'canvas{display:inline-block;overflow:hidden;' + + // default size is 300x150 in Gecko and Opera + 'text-align:left;width:300px;height:150px}'; + } + } + + // Add namespaces and stylesheet at startup. + addNamespacesAndStylesheet(document); + + var G_vmlCanvasManager_ = { + init: function(opt_doc) { + var doc = opt_doc || document; + // Create a dummy element so that IE will allow canvas elements to be + // recognized. + doc.createElement('canvas'); + doc.attachEvent('onreadystatechange', bind(this.init_, this, doc)); + }, + + init_: function(doc) { + // find all canvas elements + var els = doc.getElementsByTagName('canvas'); + for (var i = 0; i < els.length; i++) { + this.initElement(els[i]); + } + }, + + /** + * Public initializes a canvas element so that it can be used as canvas + * element from now on. This is called automatically before the page is + * loaded but if you are creating elements using createElement you need to + * make sure this is called on the element. + * @param {HTMLElement} el The canvas element to initialize. + * @return {HTMLElement} the element that was created. + */ + initElement: function(el) { + if (!el.getContext) { + el.getContext = getContext; + + // Add namespaces and stylesheet to document of the element. + addNamespacesAndStylesheet(el.ownerDocument); + + // Remove fallback content. There is no way to hide text nodes so we + // just remove all childNodes. We could hide all elements and remove + // text nodes but who really cares about the fallback content. + el.innerHTML = ''; + + // do not use inline function because that will leak memory + el.attachEvent('onpropertychange', onPropertyChange); + el.attachEvent('onresize', onResize); + + var attrs = el.attributes; + if (attrs.width && attrs.width.specified) { + // TODO: use runtimeStyle and coordsize + // el.getContext().setWidth_(attrs.width.nodeValue); + el.style.width = attrs.width.nodeValue + 'px'; + } else { + el.width = el.clientWidth; + } + if (attrs.height && attrs.height.specified) { + // TODO: use runtimeStyle and coordsize + // el.getContext().setHeight_(attrs.height.nodeValue); + el.style.height = attrs.height.nodeValue + 'px'; + } else { + el.height = el.clientHeight; + } + //el.getContext().setCoordsize_() + } + return el; + } + }; + + function onPropertyChange(e) { + var el = e.srcElement; + + switch (e.propertyName) { + case 'width': + el.getContext().clearRect(); + el.style.width = el.attributes.width.nodeValue + 'px'; + // In IE8 this does not trigger onresize. + if (el.firstChild) { + el.firstChild.style.width = el.clientWidth + 'px'; + } + break; + case 'height': + el.getContext().clearRect(); + el.style.height = el.attributes.height.nodeValue + 'px'; + if (el.firstChild) { + el.firstChild.style.height = el.clientHeight + 'px'; + } + break; + } + } + + function onResize(e) { + var el = e.srcElement; + if (el.firstChild) { + el.firstChild.style.width = el.clientWidth + 'px'; + el.firstChild.style.height = el.clientHeight + 'px'; + } + } + + G_vmlCanvasManager_.init(); + + // precompute "00" to "FF" + var decToHex = []; + for (var i = 0; i < 16; i++) { + for (var j = 0; j < 16; j++) { + decToHex[i * 16 + j] = i.toString(16) + j.toString(16); + } + } + + function createMatrixIdentity() { + return [ + [1, 0, 0], + [0, 1, 0], + [0, 0, 1] + ]; + } + + function matrixMultiply(m1, m2) { + var result = createMatrixIdentity(); + + for (var x = 0; x < 3; x++) { + for (var y = 0; y < 3; y++) { + var sum = 0; + + for (var z = 0; z < 3; z++) { + sum += m1[x][z] * m2[z][y]; + } + + result[x][y] = sum; + } + } + return result; + } + + function copyState(o1, o2) { + o2.fillStyle = o1.fillStyle; + o2.lineCap = o1.lineCap; + o2.lineJoin = o1.lineJoin; + o2.lineWidth = o1.lineWidth; + o2.miterLimit = o1.miterLimit; + o2.shadowBlur = o1.shadowBlur; + o2.shadowColor = o1.shadowColor; + o2.shadowOffsetX = o1.shadowOffsetX; + o2.shadowOffsetY = o1.shadowOffsetY; + o2.strokeStyle = o1.strokeStyle; + o2.globalAlpha = o1.globalAlpha; + o2.font = o1.font; + o2.textAlign = o1.textAlign; + o2.textBaseline = o1.textBaseline; + o2.arcScaleX_ = o1.arcScaleX_; + o2.arcScaleY_ = o1.arcScaleY_; + o2.lineScale_ = o1.lineScale_; + } + + var colorData = { + aliceblue: '#F0F8FF', + antiquewhite: '#FAEBD7', + aquamarine: '#7FFFD4', + azure: '#F0FFFF', + beige: '#F5F5DC', + bisque: '#FFE4C4', + black: '#000000', + blanchedalmond: '#FFEBCD', + blueviolet: '#8A2BE2', + brown: '#A52A2A', + burlywood: '#DEB887', + cadetblue: '#5F9EA0', + chartreuse: '#7FFF00', + chocolate: '#D2691E', + coral: '#FF7F50', + cornflowerblue: '#6495ED', + cornsilk: '#FFF8DC', + crimson: '#DC143C', + cyan: '#00FFFF', + darkblue: '#00008B', + darkcyan: '#008B8B', + darkgoldenrod: '#B8860B', + darkgray: '#A9A9A9', + darkgreen: '#006400', + darkgrey: '#A9A9A9', + darkkhaki: '#BDB76B', + darkmagenta: '#8B008B', + darkolivegreen: '#556B2F', + darkorange: '#FF8C00', + darkorchid: '#9932CC', + darkred: '#8B0000', + darksalmon: '#E9967A', + darkseagreen: '#8FBC8F', + darkslateblue: '#483D8B', + darkslategray: '#2F4F4F', + darkslategrey: '#2F4F4F', + darkturquoise: '#00CED1', + darkviolet: '#9400D3', + deeppink: '#FF1493', + deepskyblue: '#00BFFF', + dimgray: '#696969', + dimgrey: '#696969', + dodgerblue: '#1E90FF', + firebrick: '#B22222', + floralwhite: '#FFFAF0', + forestgreen: '#228B22', + gainsboro: '#DCDCDC', + ghostwhite: '#F8F8FF', + gold: '#FFD700', + goldenrod: '#DAA520', + grey: '#808080', + greenyellow: '#ADFF2F', + honeydew: '#F0FFF0', + hotpink: '#FF69B4', + indianred: '#CD5C5C', + indigo: '#4B0082', + ivory: '#FFFFF0', + khaki: '#F0E68C', + lavender: '#E6E6FA', + lavenderblush: '#FFF0F5', + lawngreen: '#7CFC00', + lemonchiffon: '#FFFACD', + lightblue: '#ADD8E6', + lightcoral: '#F08080', + lightcyan: '#E0FFFF', + lightgoldenrodyellow: '#FAFAD2', + lightgreen: '#90EE90', + lightgrey: '#D3D3D3', + lightpink: '#FFB6C1', + lightsalmon: '#FFA07A', + lightseagreen: '#20B2AA', + lightskyblue: '#87CEFA', + lightslategray: '#778899', + lightslategrey: '#778899', + lightsteelblue: '#B0C4DE', + lightyellow: '#FFFFE0', + limegreen: '#32CD32', + linen: '#FAF0E6', + magenta: '#FF00FF', + mediumaquamarine: '#66CDAA', + mediumblue: '#0000CD', + mediumorchid: '#BA55D3', + mediumpurple: '#9370DB', + mediumseagreen: '#3CB371', + mediumslateblue: '#7B68EE', + mediumspringgreen: '#00FA9A', + mediumturquoise: '#48D1CC', + mediumvioletred: '#C71585', + midnightblue: '#191970', + mintcream: '#F5FFFA', + mistyrose: '#FFE4E1', + moccasin: '#FFE4B5', + navajowhite: '#FFDEAD', + oldlace: '#FDF5E6', + olivedrab: '#6B8E23', + orange: '#FFA500', + orangered: '#FF4500', + orchid: '#DA70D6', + palegoldenrod: '#EEE8AA', + palegreen: '#98FB98', + paleturquoise: '#AFEEEE', + palevioletred: '#DB7093', + papayawhip: '#FFEFD5', + peachpuff: '#FFDAB9', + peru: '#CD853F', + pink: '#FFC0CB', + plum: '#DDA0DD', + powderblue: '#B0E0E6', + rosybrown: '#BC8F8F', + royalblue: '#4169E1', + saddlebrown: '#8B4513', + salmon: '#FA8072', + sandybrown: '#F4A460', + seagreen: '#2E8B57', + seashell: '#FFF5EE', + sienna: '#A0522D', + skyblue: '#87CEEB', + slateblue: '#6A5ACD', + slategray: '#708090', + slategrey: '#708090', + snow: '#FFFAFA', + springgreen: '#00FF7F', + steelblue: '#4682B4', + tan: '#D2B48C', + thistle: '#D8BFD8', + tomato: '#FF6347', + turquoise: '#40E0D0', + violet: '#EE82EE', + wheat: '#F5DEB3', + whitesmoke: '#F5F5F5', + yellowgreen: '#9ACD32' + }; + + + function getRgbHslContent(styleString) { + var start = styleString.indexOf('(', 3); + var end = styleString.indexOf(')', start + 1); + var parts = styleString.substring(start + 1, end).split(','); + // add alpha if needed + if (parts.length != 4 || styleString.charAt(3) != 'a') { + parts[3] = 1; + } + return parts; + } + + function percent(s) { + return parseFloat(s) / 100; + } + + function clamp(v, min, max) { + return Math.min(max, Math.max(min, v)); + } + + function hslToRgb(parts){ + var r, g, b, h, s, l; + h = parseFloat(parts[0]) / 360 % 360; + if (h < 0) + h++; + s = clamp(percent(parts[1]), 0, 1); + l = clamp(percent(parts[2]), 0, 1); + if (s == 0) { + r = g = b = l; // achromatic + } else { + var q = l < 0.5 ? l * (1 + s) : l + s - l * s; + var p = 2 * l - q; + r = hueToRgb(p, q, h + 1 / 3); + g = hueToRgb(p, q, h); + b = hueToRgb(p, q, h - 1 / 3); + } + + return '#' + decToHex[Math.floor(r * 255)] + + decToHex[Math.floor(g * 255)] + + decToHex[Math.floor(b * 255)]; + } + + function hueToRgb(m1, m2, h) { + if (h < 0) + h++; + if (h > 1) + h--; + + if (6 * h < 1) + return m1 + (m2 - m1) * 6 * h; + else if (2 * h < 1) + return m2; + else if (3 * h < 2) + return m1 + (m2 - m1) * (2 / 3 - h) * 6; + else + return m1; + } + + var processStyleCache = {}; + + function processStyle(styleString) { + if (styleString in processStyleCache) { + return processStyleCache[styleString]; + } + + var str, alpha = 1; + + styleString = String(styleString); + if (styleString.charAt(0) == '#') { + str = styleString; + } else if (/^rgb/.test(styleString)) { + var parts = getRgbHslContent(styleString); + var str = '#', n; + for (var i = 0; i < 3; i++) { + if (parts[i].indexOf('%') != -1) { + n = Math.floor(percent(parts[i]) * 255); + } else { + n = +parts[i]; + } + str += decToHex[clamp(n, 0, 255)]; + } + alpha = +parts[3]; + } else if (/^hsl/.test(styleString)) { + var parts = getRgbHslContent(styleString); + str = hslToRgb(parts); + alpha = parts[3]; + } else { + str = colorData[styleString] || styleString; + } + return processStyleCache[styleString] = {color: str, alpha: alpha}; + } + + var DEFAULT_STYLE = { + style: 'normal', + variant: 'normal', + weight: 'normal', + size: 10, + family: 'sans-serif' + }; + + // Internal text style cache + var fontStyleCache = {}; + + function processFontStyle(styleString) { + if (fontStyleCache[styleString]) { + return fontStyleCache[styleString]; + } + + var el = document.createElement('div'); + var style = el.style; + try { + style.font = styleString; + } catch (ex) { + // Ignore failures to set to invalid font. + } + + return fontStyleCache[styleString] = { + style: style.fontStyle || DEFAULT_STYLE.style, + variant: style.fontVariant || DEFAULT_STYLE.variant, + weight: style.fontWeight || DEFAULT_STYLE.weight, + size: style.fontSize || DEFAULT_STYLE.size, + family: style.fontFamily || DEFAULT_STYLE.family + }; + } + + function getComputedStyle(style, element) { + var computedStyle = {}; + + for (var p in style) { + computedStyle[p] = style[p]; + } + + // Compute the size + var canvasFontSize = parseFloat(element.currentStyle.fontSize), + fontSize = parseFloat(style.size); + + if (typeof style.size == 'number') { + computedStyle.size = style.size; + } else if (style.size.indexOf('px') != -1) { + computedStyle.size = fontSize; + } else if (style.size.indexOf('em') != -1) { + computedStyle.size = canvasFontSize * fontSize; + } else if(style.size.indexOf('%') != -1) { + computedStyle.size = (canvasFontSize / 100) * fontSize; + } else if (style.size.indexOf('pt') != -1) { + computedStyle.size = fontSize / .75; + } else { + computedStyle.size = canvasFontSize; + } + + // Different scaling between normal text and VML text. This was found using + // trial and error to get the same size as non VML text. + //computedStyle.size *= 0.981; + + return computedStyle; + } + + function buildStyle(style) { + return style.style + ' ' + style.variant + ' ' + style.weight + ' ' + + style.size + 'px ' + style.family; + } + + var lineCapMap = { + 'butt': 'flat', + 'round': 'round' + }; + + function processLineCap(lineCap) { + return lineCapMap[lineCap] || 'square'; + } + + /** + * This class implements CanvasRenderingContext2D interface as described by + * the WHATWG. + * @param {HTMLElement} canvasElement The element that the 2D context should + * be associated with + */ + function CanvasRenderingContext2D_(canvasElement) { + this.m_ = createMatrixIdentity(); + + this.mStack_ = []; + this.aStack_ = []; + this.currentPath_ = []; + + // Canvas context properties + this.strokeStyle = '#000'; + this.fillStyle = '#000'; + + this.lineWidth = 1; + this.lineJoin = 'miter'; + this.lineCap = 'butt'; + this.miterLimit = Z * 1; + this.globalAlpha = 1; + this.font = '10px sans-serif'; + this.textAlign = 'left'; + this.textBaseline = 'alphabetic'; + this.canvas = canvasElement; + + var cssText = 'width:' + canvasElement.clientWidth + 'px;height:' + + canvasElement.clientHeight + 'px;overflow:hidden;position:absolute'; + var el = canvasElement.ownerDocument.createElement('div'); + el.style.cssText = cssText; + canvasElement.appendChild(el); + + var overlayEl = el.cloneNode(false); + // Use a non transparent background. + overlayEl.style.backgroundColor = 'red'; + overlayEl.style.filter = 'alpha(opacity=0)'; + canvasElement.appendChild(overlayEl); + + this.element_ = el; + this.arcScaleX_ = 1; + this.arcScaleY_ = 1; + this.lineScale_ = 1; + } + + var contextPrototype = CanvasRenderingContext2D_.prototype; + contextPrototype.clearRect = function() { + if (this.textMeasureEl_) { + this.textMeasureEl_.removeNode(true); + this.textMeasureEl_ = null; + } + this.element_.innerHTML = ''; + }; + + contextPrototype.beginPath = function() { + // TODO: Branch current matrix so that save/restore has no effect + // as per safari docs. + this.currentPath_ = []; + }; + + contextPrototype.moveTo = function(aX, aY) { + var p = getCoords(this, aX, aY); + this.currentPath_.push({type: 'moveTo', x: p.x, y: p.y}); + this.currentX_ = p.x; + this.currentY_ = p.y; + }; + + contextPrototype.lineTo = function(aX, aY) { + var p = getCoords(this, aX, aY); + this.currentPath_.push({type: 'lineTo', x: p.x, y: p.y}); + + this.currentX_ = p.x; + this.currentY_ = p.y; + }; + + contextPrototype.bezierCurveTo = function(aCP1x, aCP1y, + aCP2x, aCP2y, + aX, aY) { + var p = getCoords(this, aX, aY); + var cp1 = getCoords(this, aCP1x, aCP1y); + var cp2 = getCoords(this, aCP2x, aCP2y); + bezierCurveTo(this, cp1, cp2, p); + }; + + // Helper function that takes the already fixed cordinates. + function bezierCurveTo(self, cp1, cp2, p) { + self.currentPath_.push({ + type: 'bezierCurveTo', + cp1x: cp1.x, + cp1y: cp1.y, + cp2x: cp2.x, + cp2y: cp2.y, + x: p.x, + y: p.y + }); + self.currentX_ = p.x; + self.currentY_ = p.y; + } + + contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) { + // the following is lifted almost directly from + // http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes + + var cp = getCoords(this, aCPx, aCPy); + var p = getCoords(this, aX, aY); + + var cp1 = { + x: this.currentX_ + 2.0 / 3.0 * (cp.x - this.currentX_), + y: this.currentY_ + 2.0 / 3.0 * (cp.y - this.currentY_) + }; + var cp2 = { + x: cp1.x + (p.x - this.currentX_) / 3.0, + y: cp1.y + (p.y - this.currentY_) / 3.0 + }; + + bezierCurveTo(this, cp1, cp2, p); + }; + + contextPrototype.arc = function(aX, aY, aRadius, + aStartAngle, aEndAngle, aClockwise) { + aRadius *= Z; + var arcType = aClockwise ? 'at' : 'wa'; + + var xStart = aX + mc(aStartAngle) * aRadius - Z2; + var yStart = aY + ms(aStartAngle) * aRadius - Z2; + + var xEnd = aX + mc(aEndAngle) * aRadius - Z2; + var yEnd = aY + ms(aEndAngle) * aRadius - Z2; + + // IE won't render arches drawn counter clockwise if xStart == xEnd. + if (xStart == xEnd && !aClockwise) { + xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something + // that can be represented in binary + } + + var p = getCoords(this, aX, aY); + var pStart = getCoords(this, xStart, yStart); + var pEnd = getCoords(this, xEnd, yEnd); + + this.currentPath_.push({type: arcType, + x: p.x, + y: p.y, + radius: aRadius, + xStart: pStart.x, + yStart: pStart.y, + xEnd: pEnd.x, + yEnd: pEnd.y}); + + }; + + contextPrototype.rect = function(aX, aY, aWidth, aHeight) { + this.moveTo(aX, aY); + this.lineTo(aX + aWidth, aY); + this.lineTo(aX + aWidth, aY + aHeight); + this.lineTo(aX, aY + aHeight); + this.closePath(); + }; + + contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) { + var oldPath = this.currentPath_; + this.beginPath(); + + this.moveTo(aX, aY); + this.lineTo(aX + aWidth, aY); + this.lineTo(aX + aWidth, aY + aHeight); + this.lineTo(aX, aY + aHeight); + this.closePath(); + this.stroke(); + + this.currentPath_ = oldPath; + }; + + contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) { + var oldPath = this.currentPath_; + this.beginPath(); + + this.moveTo(aX, aY); + this.lineTo(aX + aWidth, aY); + this.lineTo(aX + aWidth, aY + aHeight); + this.lineTo(aX, aY + aHeight); + this.closePath(); + this.fill(); + + this.currentPath_ = oldPath; + }; + + contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) { + var gradient = new CanvasGradient_('gradient'); + gradient.x0_ = aX0; + gradient.y0_ = aY0; + gradient.x1_ = aX1; + gradient.y1_ = aY1; + return gradient; + }; + + contextPrototype.createRadialGradient = function(aX0, aY0, aR0, + aX1, aY1, aR1) { + var gradient = new CanvasGradient_('gradientradial'); + gradient.x0_ = aX0; + gradient.y0_ = aY0; + gradient.r0_ = aR0; + gradient.x1_ = aX1; + gradient.y1_ = aY1; + gradient.r1_ = aR1; + return gradient; + }; + + contextPrototype.drawImage = function(image, var_args) { + var dx, dy, dw, dh, sx, sy, sw, sh; + + // to find the original width we overide the width and height + var oldRuntimeWidth = image.runtimeStyle.width; + var oldRuntimeHeight = image.runtimeStyle.height; + image.runtimeStyle.width = 'auto'; + image.runtimeStyle.height = 'auto'; + + // get the original size + var w = image.width; + var h = image.height; + + // and remove overides + image.runtimeStyle.width = oldRuntimeWidth; + image.runtimeStyle.height = oldRuntimeHeight; + + if (arguments.length == 3) { + dx = arguments[1]; + dy = arguments[2]; + sx = sy = 0; + sw = dw = w; + sh = dh = h; + } else if (arguments.length == 5) { + dx = arguments[1]; + dy = arguments[2]; + dw = arguments[3]; + dh = arguments[4]; + sx = sy = 0; + sw = w; + sh = h; + } else if (arguments.length == 9) { + sx = arguments[1]; + sy = arguments[2]; + sw = arguments[3]; + sh = arguments[4]; + dx = arguments[5]; + dy = arguments[6]; + dw = arguments[7]; + dh = arguments[8]; + } else { + throw Error('Invalid number of arguments'); + } + + var d = getCoords(this, dx, dy); + + var w2 = sw / 2; + var h2 = sh / 2; + + var vmlStr = []; + + var W = 10; + var H = 10; + + // For some reason that I've now forgotten, using divs didn't work + vmlStr.push(' <g_vml_:group', + ' coordsize="', Z * W, ',', Z * H, '"', + ' coordorigin="0,0"' , + ' style="width:', W, 'px;height:', H, 'px;position:absolute;'); + + // If filters are necessary (rotation exists), create them + // filters are bog-slow, so only create them if abbsolutely necessary + // The following check doesn't account for skews (which don't exist + // in the canvas spec (yet) anyway. + + if (this.m_[0][0] != 1 || this.m_[0][1] || + this.m_[1][1] != 1 || this.m_[1][0]) { + var filter = []; + + // Note the 12/21 reversal + filter.push('M11=', this.m_[0][0], ',', + 'M12=', this.m_[1][0], ',', + 'M21=', this.m_[0][1], ',', + 'M22=', this.m_[1][1], ',', + 'Dx=', mr(d.x / Z), ',', + 'Dy=', mr(d.y / Z), ''); + + // Bounding box calculation (need to minimize displayed area so that + // filters don't waste time on unused pixels. + var max = d; + var c2 = getCoords(this, dx + dw, dy); + var c3 = getCoords(this, dx, dy + dh); + var c4 = getCoords(this, dx + dw, dy + dh); + + max.x = m.max(max.x, c2.x, c3.x, c4.x); + max.y = m.max(max.y, c2.y, c3.y, c4.y); + + vmlStr.push('padding:0 ', mr(max.x / Z), 'px ', mr(max.y / Z), + 'px 0;filter:progid:DXImageTransform.Microsoft.Matrix(', + filter.join(''), ", sizingmethod='clip');"); + + } else { + vmlStr.push('top:', mr(d.y / Z), 'px;left:', mr(d.x / Z), 'px;'); + } + + vmlStr.push(' ">' , + '<g_vml_:image src="', image.src, '"', + ' style="width:', Z * dw, 'px;', + ' height:', Z * dh, 'px"', + ' cropleft="', sx / w, '"', + ' croptop="', sy / h, '"', + ' cropright="', (w - sx - sw) / w, '"', + ' cropbottom="', (h - sy - sh) / h, '"', + ' />', + '</g_vml_:group>'); + + this.element_.insertAdjacentHTML('BeforeEnd', vmlStr.join('')); + }; + + contextPrototype.stroke = function(aFill) { + var lineStr = []; + var lineOpen = false; + + var W = 10; + var H = 10; + + lineStr.push('<g_vml_:shape', + ' filled="', !!aFill, '"', + ' style="position:absolute;width:', W, 'px;height:', H, 'px;"', + ' coordorigin="0,0"', + ' coordsize="', Z * W, ',', Z * H, '"', + ' stroked="', !aFill, '"', + ' path="'); + + var newSeq = false; + var min = {x: null, y: null}; + var max = {x: null, y: null}; + + for (var i = 0; i < this.currentPath_.length; i++) { + var p = this.currentPath_[i]; + var c; + + switch (p.type) { + case 'moveTo': + c = p; + lineStr.push(' m ', mr(p.x), ',', mr(p.y)); + break; + case 'lineTo': + lineStr.push(' l ', mr(p.x), ',', mr(p.y)); + break; + case 'close': + lineStr.push(' x '); + p = null; + break; + case 'bezierCurveTo': + lineStr.push(' c ', + mr(p.cp1x), ',', mr(p.cp1y), ',', + mr(p.cp2x), ',', mr(p.cp2y), ',', + mr(p.x), ',', mr(p.y)); + break; + case 'at': + case 'wa': + lineStr.push(' ', p.type, ' ', + mr(p.x - this.arcScaleX_ * p.radius), ',', + mr(p.y - this.arcScaleY_ * p.radius), ' ', + mr(p.x + this.arcScaleX_ * p.radius), ',', + mr(p.y + this.arcScaleY_ * p.radius), ' ', + mr(p.xStart), ',', mr(p.yStart), ' ', + mr(p.xEnd), ',', mr(p.yEnd)); + break; + } + + + // TODO: Following is broken for curves due to + // move to proper paths. + + // Figure out dimensions so we can do gradient fills + // properly + if (p) { + if (min.x == null || p.x < min.x) { + min.x = p.x; + } + if (max.x == null || p.x > max.x) { + max.x = p.x; + } + if (min.y == null || p.y < min.y) { + min.y = p.y; + } + if (max.y == null || p.y > max.y) { + max.y = p.y; + } + } + } + lineStr.push(' ">'); + + if (!aFill) { + appendStroke(this, lineStr); + } else { + appendFill(this, lineStr, min, max); + } + + lineStr.push('</g_vml_:shape>'); + + this.element_.insertAdjacentHTML('beforeEnd', lineStr.join('')); + }; + + function appendStroke(ctx, lineStr) { + var a = processStyle(ctx.strokeStyle); + var color = a.color; + var opacity = a.alpha * ctx.globalAlpha; + var lineWidth = ctx.lineScale_ * ctx.lineWidth; + + // VML cannot correctly render a line if the width is less than 1px. + // In that case, we dilute the color to make the line look thinner. + if (lineWidth < 1) { + opacity *= lineWidth; + } + + lineStr.push( + '<g_vml_:stroke', + ' opacity="', opacity, '"', + ' joinstyle="', ctx.lineJoin, '"', + ' miterlimit="', ctx.miterLimit, '"', + ' endcap="', processLineCap(ctx.lineCap), '"', + ' weight="', lineWidth, 'px"', + ' color="', color, '" />' + ); + } + + function appendFill(ctx, lineStr, min, max) { + var fillStyle = ctx.fillStyle; + var arcScaleX = ctx.arcScaleX_; + var arcScaleY = ctx.arcScaleY_; + var width = max.x - min.x; + var height = max.y - min.y; + if (fillStyle instanceof CanvasGradient_) { + // TODO: Gradients transformed with the transformation matrix. + var angle = 0; + var focus = {x: 0, y: 0}; + + // additional offset + var shift = 0; + // scale factor for offset + var expansion = 1; + + if (fillStyle.type_ == 'gradient') { + var x0 = fillStyle.x0_ / arcScaleX; + var y0 = fillStyle.y0_ / arcScaleY; + var x1 = fillStyle.x1_ / arcScaleX; + var y1 = fillStyle.y1_ / arcScaleY; + var p0 = getCoords(ctx, x0, y0); + var p1 = getCoords(ctx, x1, y1); + var dx = p1.x - p0.x; + var dy = p1.y - p0.y; + angle = Math.atan2(dx, dy) * 180 / Math.PI; + + // The angle should be a non-negative number. + if (angle < 0) { + angle += 360; + } + + // Very small angles produce an unexpected result because they are + // converted to a scientific notation string. + if (angle < 1e-6) { + angle = 0; + } + } else { + var p0 = getCoords(ctx, fillStyle.x0_, fillStyle.y0_); + focus = { + x: (p0.x - min.x) / width, + y: (p0.y - min.y) / height + }; + + width /= arcScaleX * Z; + height /= arcScaleY * Z; + var dimension = m.max(width, height); + shift = 2 * fillStyle.r0_ / dimension; + expansion = 2 * fillStyle.r1_ / dimension - shift; + } + + // We need to sort the color stops in ascending order by offset, + // otherwise IE won't interpret it correctly. + var stops = fillStyle.colors_; + stops.sort(function(cs1, cs2) { + return cs1.offset - cs2.offset; + }); + + var length = stops.length; + var color1 = stops[0].color; + var color2 = stops[length - 1].color; + var opacity1 = stops[0].alpha * ctx.globalAlpha; + var opacity2 = stops[length - 1].alpha * ctx.globalAlpha; + + var colors = []; + for (var i = 0; i < length; i++) { + var stop = stops[i]; + colors.push(stop.offset * expansion + shift + ' ' + stop.color); + } + + // When colors attribute is used, the meanings of opacity and o:opacity2 + // are reversed. + lineStr.push('<g_vml_:fill type="', fillStyle.type_, '"', + ' method="none" focus="100%"', + ' color="', color1, '"', + ' color2="', color2, '"', + ' colors="', colors.join(','), '"', + ' opacity="', opacity2, '"', + ' g_o_:opacity2="', opacity1, '"', + ' angle="', angle, '"', + ' focusposition="', focus.x, ',', focus.y, '" />'); + } else if (fillStyle instanceof CanvasPattern_) { + if (width && height) { + var deltaLeft = -min.x; + var deltaTop = -min.y; + lineStr.push('<g_vml_:fill', + ' position="', + deltaLeft / width * arcScaleX * arcScaleX, ',', + deltaTop / height * arcScaleY * arcScaleY, '"', + ' type="tile"', + // TODO: Figure out the correct size to fit the scale. + //' size="', w, 'px ', h, 'px"', + ' src="', fillStyle.src_, '" />'); + } + } else { + var a = processStyle(ctx.fillStyle); + var color = a.color; + var opacity = a.alpha * ctx.globalAlpha; + lineStr.push('<g_vml_:fill color="', color, '" opacity="', opacity, + '" />'); + } + } + + contextPrototype.fill = function() { + this.stroke(true); + }; + + contextPrototype.closePath = function() { + this.currentPath_.push({type: 'close'}); + }; + + function getCoords(ctx, aX, aY) { + var m = ctx.m_; + return { + x: Z * (aX * m[0][0] + aY * m[1][0] + m[2][0]) - Z2, + y: Z * (aX * m[0][1] + aY * m[1][1] + m[2][1]) - Z2 + }; + }; + + contextPrototype.save = function() { + var o = {}; + copyState(this, o); + this.aStack_.push(o); + this.mStack_.push(this.m_); + this.m_ = matrixMultiply(createMatrixIdentity(), this.m_); + }; + + contextPrototype.restore = function() { + if (this.aStack_.length) { + copyState(this.aStack_.pop(), this); + this.m_ = this.mStack_.pop(); + } + }; + + function matrixIsFinite(m) { + return isFinite(m[0][0]) && isFinite(m[0][1]) && + isFinite(m[1][0]) && isFinite(m[1][1]) && + isFinite(m[2][0]) && isFinite(m[2][1]); + } + + function setM(ctx, m, updateLineScale) { + if (!matrixIsFinite(m)) { + return; + } + ctx.m_ = m; + + if (updateLineScale) { + // Get the line scale. + // Determinant of this.m_ means how much the area is enlarged by the + // transformation. So its square root can be used as a scale factor + // for width. + var det = m[0][0] * m[1][1] - m[0][1] * m[1][0]; + ctx.lineScale_ = sqrt(abs(det)); + } + } + + contextPrototype.translate = function(aX, aY) { + var m1 = [ + [1, 0, 0], + [0, 1, 0], + [aX, aY, 1] + ]; + + setM(this, matrixMultiply(m1, this.m_), false); + }; + + contextPrototype.rotate = function(aRot) { + var c = mc(aRot); + var s = ms(aRot); + + var m1 = [ + [c, s, 0], + [-s, c, 0], + [0, 0, 1] + ]; + + setM(this, matrixMultiply(m1, this.m_), false); + }; + + contextPrototype.scale = function(aX, aY) { + this.arcScaleX_ *= aX; + this.arcScaleY_ *= aY; + var m1 = [ + [aX, 0, 0], + [0, aY, 0], + [0, 0, 1] + ]; + + setM(this, matrixMultiply(m1, this.m_), true); + }; + + contextPrototype.transform = function(m11, m12, m21, m22, dx, dy) { + var m1 = [ + [m11, m12, 0], + [m21, m22, 0], + [dx, dy, 1] + ]; + + setM(this, matrixMultiply(m1, this.m_), true); + }; + + contextPrototype.setTransform = function(m11, m12, m21, m22, dx, dy) { + var m = [ + [m11, m12, 0], + [m21, m22, 0], + [dx, dy, 1] + ]; + + setM(this, m, true); + }; + + /** + * The text drawing function. + * The maxWidth argument isn't taken in account, since no browser supports + * it yet. + */ + contextPrototype.drawText_ = function(text, x, y, maxWidth, stroke) { + var m = this.m_, + delta = 1000, + left = 0, + right = delta, + offset = {x: 0, y: 0}, + lineStr = []; + + var fontStyle = getComputedStyle(processFontStyle(this.font), + this.element_); + + var fontStyleString = buildStyle(fontStyle); + + var elementStyle = this.element_.currentStyle; + var textAlign = this.textAlign.toLowerCase(); + switch (textAlign) { + case 'left': + case 'center': + case 'right': + break; + case 'end': + textAlign = elementStyle.direction == 'ltr' ? 'right' : 'left'; + break; + case 'start': + textAlign = elementStyle.direction == 'rtl' ? 'right' : 'left'; + break; + default: + textAlign = 'left'; + } + + // 1.75 is an arbitrary number, as there is no info about the text baseline + switch (this.textBaseline) { + case 'hanging': + case 'top': + offset.y = fontStyle.size / 1.75; + break; + case 'middle': + break; + default: + case null: + case 'alphabetic': + case 'ideographic': + case 'bottom': + offset.y = -fontStyle.size / 2.25; + break; + } + + switch(textAlign) { + case 'right': + left = delta; + right = 0.05; + break; + case 'center': + left = right = delta / 2; + break; + } + + var d = getCoords(this, x + offset.x, y + offset.y); + + lineStr.push('<g_vml_:line from="', -left ,' 0" to="', right ,' 0.05" ', + ' coordsize="100 100" coordorigin="0 0"', + ' filled="', !stroke, '" stroked="', !!stroke, + '" style="position:absolute;width:1px;height:1px;">'); + + if (stroke) { + appendStroke(this, lineStr); + } else { + // TODO: Fix the min and max params. + appendFill(this, lineStr, {x: -left, y: 0}, + {x: right, y: fontStyle.size}); + } + + var skewM = m[0][0].toFixed(3) + ',' + m[1][0].toFixed(3) + ',' + + m[0][1].toFixed(3) + ',' + m[1][1].toFixed(3) + ',0,0'; + + var skewOffset = mr(d.x / Z) + ',' + mr(d.y / Z); + + lineStr.push('<g_vml_:skew on="t" matrix="', skewM ,'" ', + ' offset="', skewOffset, '" origin="', left ,' 0" />', + '<g_vml_:path textpathok="true" />', + '<g_vml_:textpath on="true" string="', + encodeHtmlAttribute(text), + '" style="v-text-align:', textAlign, + ';font:', encodeHtmlAttribute(fontStyleString), + '" /></g_vml_:line>'); + + this.element_.insertAdjacentHTML('beforeEnd', lineStr.join('')); + }; + + contextPrototype.fillText = function(text, x, y, maxWidth) { + this.drawText_(text, x, y, maxWidth, false); + }; + + contextPrototype.strokeText = function(text, x, y, maxWidth) { + this.drawText_(text, x, y, maxWidth, true); + }; + + contextPrototype.measureText = function(text) { + if (!this.textMeasureEl_) { + var s = '<span style="position:absolute;' + + 'top:-20000px;left:0;padding:0;margin:0;border:none;' + + 'white-space:pre;"></span>'; + this.element_.insertAdjacentHTML('beforeEnd', s); + this.textMeasureEl_ = this.element_.lastChild; + } + var doc = this.element_.ownerDocument; + this.textMeasureEl_.innerHTML = ''; + this.textMeasureEl_.style.font = this.font; + // Don't use innerHTML or innerText because they allow markup/whitespace. + this.textMeasureEl_.appendChild(doc.createTextNode(text)); + return {width: this.textMeasureEl_.offsetWidth}; + }; + + /******** STUBS ********/ + contextPrototype.clip = function() { + // TODO: Implement + }; + + contextPrototype.arcTo = function() { + // TODO: Implement + }; + + contextPrototype.createPattern = function(image, repetition) { + return new CanvasPattern_(image, repetition); + }; + + // Gradient / Pattern Stubs + function CanvasGradient_(aType) { + this.type_ = aType; + this.x0_ = 0; + this.y0_ = 0; + this.r0_ = 0; + this.x1_ = 0; + this.y1_ = 0; + this.r1_ = 0; + this.colors_ = []; + } + + CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) { + aColor = processStyle(aColor); + this.colors_.push({offset: aOffset, + color: aColor.color, + alpha: aColor.alpha}); + }; + + function CanvasPattern_(image, repetition) { + assertImageIsValid(image); + switch (repetition) { + case 'repeat': + case null: + case '': + this.repetition_ = 'repeat'; + break + case 'repeat-x': + case 'repeat-y': + case 'no-repeat': + this.repetition_ = repetition; + break; + default: + throwException('SYNTAX_ERR'); + } + + this.src_ = image.src; + this.width_ = image.width; + this.height_ = image.height; + } + + function throwException(s) { + throw new DOMException_(s); + } + + function assertImageIsValid(img) { + if (!img || img.nodeType != 1 || img.tagName != 'IMG') { + throwException('TYPE_MISMATCH_ERR'); + } + if (img.readyState != 'complete') { + throwException('INVALID_STATE_ERR'); + } + } + + function DOMException_(s) { + this.code = this[s]; + this.message = s +': DOM Exception ' + this.code; + } + var p = DOMException_.prototype = new Error; + p.INDEX_SIZE_ERR = 1; + p.DOMSTRING_SIZE_ERR = 2; + p.HIERARCHY_REQUEST_ERR = 3; + p.WRONG_DOCUMENT_ERR = 4; + p.INVALID_CHARACTER_ERR = 5; + p.NO_DATA_ALLOWED_ERR = 6; + p.NO_MODIFICATION_ALLOWED_ERR = 7; + p.NOT_FOUND_ERR = 8; + p.NOT_SUPPORTED_ERR = 9; + p.INUSE_ATTRIBUTE_ERR = 10; + p.INVALID_STATE_ERR = 11; + p.SYNTAX_ERR = 12; + p.INVALID_MODIFICATION_ERR = 13; + p.NAMESPACE_ERR = 14; + p.INVALID_ACCESS_ERR = 15; + p.VALIDATION_ERR = 16; + p.TYPE_MISMATCH_ERR = 17; + + // set up externs + G_vmlCanvasManager = G_vmlCanvasManager_; + CanvasRenderingContext2D = CanvasRenderingContext2D_; + CanvasGradient = CanvasGradient_; + CanvasPattern = CanvasPattern_; + DOMException = DOMException_; +})(); + +} // if Propchange: ofbiz/trunk/framework/images/webapp/images/flotr/lib/excanvas.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/flotr/lib/excanvas.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/flotr/lib/excanvas.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/flotr/license.txt URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/flotr/license.txt?rev=945044&view=auto ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/flotr/license.txt (added) +++ ofbiz/trunk/framework/images/webapp/images/flotr/license.txt Mon May 17 09:29:38 2010 @@ -0,0 +1,19 @@ +Copyright (c) 2008 Bas Wenneker + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file Propchange: ofbiz/trunk/framework/images/webapp/images/flotr/license.txt ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/flotr/license.txt ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/flotr/license.txt ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/flotr/readme.txt URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/flotr/readme.txt?rev=945044&view=auto ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/flotr/readme.txt (added) +++ ofbiz/trunk/framework/images/webapp/images/flotr/readme.txt Mon May 17 09:29:38 2010 @@ -0,0 +1,58 @@ +Author: Bas Wenneker +Website: <http://www.solutoire.com> +Flotr Project Page: <http://www.solutoire.com/flotr/> +Contact: <[hidden email]> +Date: Jan 12, 2009 + +============================= +License +============================= +Flotr is released under the MIT License (see license.txt). + +============================= +Flotr 0.2.0-alpha +============================= +Flotr is a javascript plotting library based on the Prototype Javascript Framework +(version 1.6.0.2 at the moment) and inspired by Flot (written by Ole Laursen). +Flotr enables you to draw appealing graphs in most modern browsers with an +easy-to-learn syntax. It comes with great features like legend support, negative +value support, mouse tracking, selection support, zoom support, event hooks, CSS +styling support and much more. + +============================= +Documentation and Examples +============================= +Find documentation and examples at <http://www.solutoire.com/flotr/docs/>. The example +files are also included in the Flotr zip package (see the examples directory). + +============================= +Build Flotr from svn +============================= +To build your own version from svn, do the following. Get the svn trunk url from + +<http://code.google.com/p/flotr/source/checkout> + +Then check out the trunk into a local folder. You can change the flotr js file, +which resides in flotr/prototype. Then, download the yui-compressor (2.3.5) from + +<http://www.julienlecomte.net/yuicompressor/> + +Place the contents of the zip in the root of your svn working-copy. With ANT, run +build.compress. After building, a new folder 'release' has been created. Here you can +find the compressed flotr js. + +============================= +UnitTesting Flotr with jsUnit +============================= +To test Flotr using the jsUnit UnitTests. Download jsUnit from + +<http://www.jsunit.net> + +Place the contents of the zip (a folder named 'jsunit') into the trunk svn folder. Change +the firefox_exe and ie7_exe properties in the ANT build.xml. You might also have to +change the prototype_testsuite property to point at the tests/testRunner.html file. When everything's +configured, run 'test.prototype' with ANT. The browsers will open up and start running the unit test. +I use Eclipse with Aptana installed as plugin. ANT is already integrated into Eclipse. +If you are looking for a way to set up Eclipse and ANT, check out the following article: + +<http://solutoire.com/2007/05/31/automate-aptana-with-ant/> \ No newline at end of file Propchange: ofbiz/trunk/framework/images/webapp/images/flotr/readme.txt ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/flotr/readme.txt ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/flotr/readme.txt ------------------------------------------------------------------------------ svn:mime-type = text/plain |
Free forum by Nabble | Edit this page |