Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/gfx/shape.js
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/gfx/shape.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/gfx/shape.js (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/gfx/shape.js Mon Feb 19 09:56:06 2007 @@ -0,0 +1,427 @@ +/* + Copyright (c) 2004-2006, The Dojo Foundation + All Rights Reserved. + + Licensed under the Academic Free License version 2.1 or above OR the + modified BSD license. For more information on Dojo licensing, see: + + http://dojotoolkit.org/community/licensing.shtml +*/ + +dojo.provide("dojo.gfx.shape"); + +dojo.require("dojo.lang.declare"); + +dojo.require("dojo.gfx.common"); + +dojo.declare("dojo.gfx.Shape", null, { + // summary: a Shape object, which knows how to apply + // graphical attributes and transformations + + initializer: function(){ + + // rawNode: Node: underlying node + this.rawNode = null; + + // shape: Object: an abstract shape object + // (see dojo.gfx.defaultPath, + // dojo.gfx.defaultPolyline, + // dojo.gfx.defaultRect, + // dojo.gfx.defaultEllipse, + // dojo.gfx.defaultCircle, + // dojo.gfx.defaultLine, + // or dojo.gfx.defaultImage) + this.shape = null; + + // matrix: dojo.gfx.matrix.Matrix: a transformation matrix + this.matrix = null; + + // fillStyle: Object: a fill object + // (see dojo.gfx.defaultLinearGradient, + // dojo.gfx.defaultRadialGradient, + // dojo.gfx.defaultPattern, + // or dojo.gfx.color.Color) + this.fillStyle = null; + + // strokeStyle: Object: a stroke object + // (see dojo.gfx.defaultStroke) + this.strokeStyle = null; + + // bbox: dojo.gfx.Rectangle: a bounding box of this shape + // (see dojo.gfx.defaultRect) + this.bbox = null; + + // virtual group structure + + // parent: Object: a parent or null + // (see dojo.gfx.Surface, + // dojo.gfx.shape.VirtualGroup, + // or dojo.gfx.Group) + this.parent = null; + + // parentMatrix: dojo.gfx.matrix.Matrix + // a transformation matrix inherited from the parent + this.parentMatrix = null; + }, + + // trivial getters + getNode: function(){ + // summary: returns the current DOM Node or null + return this.rawNode; // Node + }, + getShape: function(){ + // summary: returns the current shape object or null + // (see dojo.gfx.defaultPath, + // dojo.gfx.defaultPolyline, + // dojo.gfx.defaultRect, + // dojo.gfx.defaultEllipse, + // dojo.gfx.defaultCircle, + // dojo.gfx.defaultLine, + // or dojo.gfx.defaultImage) + return this.shape; // Object + }, + getTransform: function(){ + // summary: returns the current transformation matrix or null + return this.matrix; // dojo.gfx.matrix.Matrix + }, + getFill: function(){ + // summary: returns the current fill object or null + // (see dojo.gfx.defaultLinearGradient, + // dojo.gfx.defaultRadialGradient, + // dojo.gfx.defaultPattern, + // or dojo.gfx.color.Color) + return this.fillStyle; // Object + }, + getStroke: function(){ + // summary: returns the current stroke object or null + // (see dojo.gfx.defaultStroke) + return this.strokeStyle; // Object + }, + getParent: function(){ + // summary: returns the parent or null + // (see dojo.gfx.Surface, + // dojo.gfx.shape.VirtualGroup, + // or dojo.gfx.Group) + return this.parent; // Object + }, + getBoundingBox: function(){ + // summary: returns the bounding box or null + // (see dojo.gfx.defaultRect) + return this.bbox; // dojo.gfx.Rectangle + }, + getEventSource: function(){ + // summary: returns a Node, which is used as + // a source of events for this shape + return this.rawNode; // Node + }, + + // empty settings + + setShape: function(shape){ + // summary: sets a shape object + // (the default implementation simply ignores it) + // shape: Object: a shape object + // (see dojo.gfx.defaultPath, + // dojo.gfx.defaultPolyline, + // dojo.gfx.defaultRect, + // dojo.gfx.defaultEllipse, + // dojo.gfx.defaultCircle, + // dojo.gfx.defaultLine, + // or dojo.gfx.defaultImage) + return this; // self + }, + setFill: function(fill){ + // summary: sets a fill object + // (the default implementation simply ignores it) + // fill: Object: a fill object + // (see dojo.gfx.defaultLinearGradient, + // dojo.gfx.defaultRadialGradient, + // dojo.gfx.defaultPattern, + // or dojo.gfx.color.Color) + return this; // self + }, + setStroke: function(stroke){ + // summary: sets a stroke object + // (the default implementation simply ignores it) + // stroke: Object: a stroke object + // (see dojo.gfx.defaultStroke) + return this; // self + }, + + // z-index + + moveToFront: function(){ + // summary: moves a shape to front of its parent's list of shapes + // (the default implementation does nothing) + return this; // self + }, + moveToBack: function(){ + // summary: moves a shape to back of its parent's list of shapes + // (the default implementation does nothing) + return this; + }, + + setTransform: function(matrix){ + // summary: sets a transformation matrix + // matrix: dojo.gfx.matrix.Matrix: a matrix or a matrix-like object + // (see an argument of dojo.gfx.matrix.Matrix + // constructor for a list of acceptable arguments) + this.matrix = dojo.gfx.matrix.clone(matrix ? dojo.gfx.matrix.normalize(matrix) : dojo.gfx.identity, true); + return this._applyTransform(); // self + }, + + // apply left & right transformation + + applyRightTransform: function(matrix){ + // summary: multiplies the existing matrix with an argument on right side + // (this.matrix * matrix) + // matrix: dojo.gfx.matrix.Matrix: a matrix or a matrix-like object + // (see an argument of dojo.gfx.matrix.Matrix + // constructor for a list of acceptable arguments) + return matrix ? this.setTransform([this.matrix, matrix]) : this; // self + }, + applyLeftTransform: function(matrix){ + // summary: multiplies the existing matrix with an argument on left side + // (matrix * this.matrix) + // matrix: dojo.gfx.matrix.Matrix: a matrix or a matrix-like object + // (see an argument of dojo.gfx.matrix.Matrix + // constructor for a list of acceptable arguments) + return matrix ? this.setTransform([matrix, this.matrix]) : this; // self + }, + + applyTransform: function(matrix){ + // summary: a shortcut for dojo.gfx.Shape.applyRight + // matrix: dojo.gfx.matrix.Matrix: a matrix or a matrix-like object + // (see an argument of dojo.gfx.matrix.Matrix + // constructor for a list of acceptable arguments) + return matrix ? this.setTransform([this.matrix, matrix]) : this; // self + }, + + // virtual group methods + + remove: function(silently){ + // summary: removes the shape from its parent's list of shapes + // silently: Boolean?: if true, do not redraw a picture yet + if(this.parent){ + this.parent.remove(this, silently); + } + return this; // self + }, + _setParent: function(parent, matrix){ + // summary: sets a parent + // parent: Object: a parent or null + // (see dojo.gfx.Surface, + // dojo.gfx.shape.VirtualGroup, + // or dojo.gfx.Group) + // matrix: dojo.gfx.matrix.Matrix: + // a 2D matrix or a matrix-like object + this.parent = parent; + return this._updateParentMatrix(matrix); // self + }, + _updateParentMatrix: function(matrix){ + // summary: updates the parent matrix with new matrix + // matrix: dojo.gfx.matrix.Matrix: + // a 2D matrix or a matrix-like object + this.parentMatrix = matrix ? dojo.gfx.matrix.clone(matrix) : null; + return this._applyTransform(); // self + }, + _getRealMatrix: function(){ + // summary: returns the cumulative ("real") transformation matrix + // by combining the shape's matrix with its parent's matrix + return this.parentMatrix ? new dojo.gfx.matrix.Matrix2D([this.parentMatrix, this.matrix]) : this.matrix; // dojo.gfx.matrix.Matrix + } +}); + +dojo.declare("dojo.gfx.shape.VirtualGroup", dojo.gfx.Shape, { + // summary: a virtual group of shapes, which can be used + // as a foundation for renderer-specific groups, or as a way + // to logically group shapes (e.g, to propagate matricies) + + initializer: function() { + + // children: Array: a list of children + this.children = []; + }, + + // group management + + add: function(shape){ + // summary: adds a shape to the list + // shape: dojo.gfx.Shape: a shape + var oldParent = shape.getParent(); + if(oldParent){ + oldParent.remove(shape, true); + } + this.children.push(shape); + return shape._setParent(this, this._getRealMatrix()); // self + }, + remove: function(shape, silently){ + // summary: removes a shape from the list + // silently: Boolean?: if true, do not redraw a picture yet + for(var i = 0; i < this.children.length; ++i){ + if(this.children[i] == shape){ + if(silently){ + // skip for now + }else{ + shape._setParent(null, null); + } + this.children.splice(i, 1); + break; + } + } + return this; // self + }, + + // apply transformation + + _applyTransform: function(){ + // summary: applies a transformation matrix to a group + var matrix = this._getRealMatrix(); + for(var i = 0; i < this.children.length; ++i){ + this.children[i]._updateParentMatrix(matrix); + } + return this; // self + } +}); + +dojo.declare("dojo.gfx.shape.Rect", dojo.gfx.Shape, { + // summary: a generic rectangle + + initializer: function(rawNode) { + // summary: creates a rectangle + // rawNode: Node: a DOM Node + this.shape = dojo.lang.shallowCopy(dojo.gfx.defaultRect, true); + this.attach(rawNode); + }, + + getBoundingBox: function(){ + // summary: returns the bounding box (its shape in this case) + return this.shape; // dojo.gfx.Rectangle + } +}); + +dojo.declare("dojo.gfx.shape.Ellipse", dojo.gfx.Shape, { + // summary: a generic ellipse + + initializer: function(rawNode) { + // summary: creates an ellipse + // rawNode: Node: a DOM Node + this.shape = dojo.lang.shallowCopy(dojo.gfx.defaultEllipse, true); + this.attach(rawNode); + }, + getBoundingBox: function(){ + // summary: returns the bounding box + if(!this.bbox){ + var shape = this.shape; + this.bbox = {x: shape.cx - shape.rx, y: shape.cy - shape.ry, + width: 2 * shape.rx, height: 2 * shape.ry}; + } + return this.bbox; // dojo.gfx.Rectangle + } +}); + +dojo.declare("dojo.gfx.shape.Circle", dojo.gfx.Shape, { + // summary: a generic circle + // (this is a helper object, which is defined for convinience) + + initializer: function(rawNode) { + // summary: creates a circle + // rawNode: Node: a DOM Node + this.shape = dojo.lang.shallowCopy(dojo.gfx.defaultCircle, true); + this.attach(rawNode); + }, + getBoundingBox: function(){ + // summary: returns the bounding box + if(!this.bbox){ + var shape = this.shape; + this.bbox = {x: shape.cx - shape.r, y: shape.cy - shape.r, + width: 2 * shape.r, height: 2 * shape.r}; + } + return this.bbox; // dojo.gfx.Rectangle + } +}); + +dojo.declare("dojo.gfx.shape.Line", dojo.gfx.Shape, { + // summary: a generic line + // (this is a helper object, which is defined for convinience) + + initializer: function(rawNode) { + // summary: creates a line + // rawNode: Node: a DOM Node + this.shape = dojo.lang.shallowCopy(dojo.gfx.defaultLine, true); + this.attach(rawNode); + }, + getBoundingBox: function(){ + // summary: returns the bounding box + if(!this.bbox){ + var shape = this.shape; + this.bbox = { + x: Math.min(shape.x1, shape.x2), + y: Math.min(shape.y1, shape.y2), + width: Math.abs(shape.x2 - shape.x1), + height: Math.abs(shape.y2 - shape.y1) + }; + } + return this.bbox; // dojo.gfx.Rectangle + } +}); + +dojo.declare("dojo.gfx.shape.Polyline", dojo.gfx.Shape, { + // summary: a generic polyline/polygon + // (this is a helper object, which is defined for convinience) + + initializer: function(rawNode) { + // summary: creates a line + // rawNode: Node: a DOM Node + this.shape = dojo.lang.shallowCopy(dojo.gfx.defaultPolyline, true); + this.attach(rawNode); + }, + getBoundingBox: function(){ + // summary: returns the bounding box + if(!this.bbox && this.shape.points.length){ + var p = this.shape.points; + var l = p.length; + var t = p[0]; + var bbox = {l: t.x, t: t.y, r: t.x, b: t.y}; + for(var i = 1; i < l; ++i){ + t = p[i]; + if(bbox.l > t.x) bbox.l = t.x; + if(bbox.r < t.x) bbox.r = t.x; + if(bbox.t > t.y) bbox.t = t.y; + if(bbox.b < t.y) bbox.b = t.y; + } + this.bbox = { + x: bbox.l, + y: bbox.t, + width: bbox.r - bbox.l, + height: bbox.b - bbox.t + }; + } + return this.bbox; // dojo.gfx.Rectangle + } +}); + +dojo.declare("dojo.gfx.shape.Image", dojo.gfx.Shape, { + // summary: a generic image + // (this is a helper object, which is defined for convinience) + + initializer: function(rawNode) { + // summary: creates an image + // rawNode: Node: a DOM Node + this.shape = dojo.lang.shallowCopy(dojo.gfx.defaultImage, true); + this.attach(rawNode); + }, + getBoundingBox: function(){ + // summary: returns the bounding box + if(!this.bbox){ + var shape = this.shape; + this.bbox = { + x: 0, + y: 0, + width: shape.width, + height: shape.height + }; + } + return this.bbox; // dojo.gfx.Rectangle + } +}); Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/gfx/shape.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/gfx/shape.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/gfx/shape.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/gfx/svg.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/gfx/svg.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/gfx/svg.js (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/gfx/svg.js Mon Feb 19 09:56:06 2007 @@ -0,0 +1,661 @@ +/* + Copyright (c) 2004-2006, The Dojo Foundation + All Rights Reserved. + + Licensed under the Academic Free License version 2.1 or above OR the + modified BSD license. For more information on Dojo licensing, see: + + http://dojotoolkit.org/community/licensing.shtml +*/ + +dojo.provide("dojo.gfx.svg"); + +dojo.require("dojo.lang.declare"); +dojo.require("dojo.svg"); + +dojo.require("dojo.gfx.color"); +dojo.require("dojo.gfx.common"); +dojo.require("dojo.gfx.shape"); +dojo.require("dojo.gfx.path"); + +dojo.require("dojo.experimental"); +dojo.experimental("dojo.gfx.svg"); + +dojo.gfx.svg.getRef = function(fill){ + // summary: returns a DOM Node specified by the fill argument or null + // fill: String: an SVG fill + if(!fill || fill == "none") return null; + if(fill.match(/^url\(#.+\)$/)){ + return dojo.byId(fill.slice(5, -1)); // Node + } + // Opera's bug: incorrect representation of a reference + if(dojo.render.html.opera && fill.match(/^#dj_unique_.+$/)){ + // we assume here that a reference was generated by dojo.gfx + return dojo.byId(fill.slice(1)); // Node + } + return null; // Node +}; + +dojo.lang.extend(dojo.gfx.Shape, { + // summary: SVG-specific implementation of dojo.gfx.Shape methods + + setFill: function(fill){ + // summary: sets a fill object (SVG) + // fill: Object: a fill object + // (see dojo.gfx.defaultLinearGradient, + // dojo.gfx.defaultRadialGradient, + // dojo.gfx.defaultPattern, + // or dojo.gfx.color.Color) + + if(!fill){ + // don't fill + this.fillStyle = null; + this.rawNode.setAttribute("fill", "none"); + this.rawNode.setAttribute("fill-opacity", 0); + return this; + } + if(typeof(fill) == "object" && "type" in fill){ + // gradient + switch(fill.type){ + case "linear": + var f = dojo.gfx.makeParameters(dojo.gfx.defaultLinearGradient, fill); + var gradient = this._setFillObject(f, "linearGradient"); + dojo.lang.forEach(["x1", "y1", "x2", "y2"], function(x){ + gradient.setAttribute(x, f[x].toFixed(8)); + }); + break; + case "radial": + var f = dojo.gfx.makeParameters(dojo.gfx.defaultRadialGradient, fill); + var gradient = this._setFillObject(f, "radialGradient"); + dojo.lang.forEach(["cx", "cy", "r"], function(x){ + gradient.setAttribute(x, f[x].toFixed(8)); + }); + break; + case "pattern": + var f = dojo.gfx.makeParameters(dojo.gfx.defaultPattern, fill); + var pattern = this._setFillObject(f, "pattern"); + dojo.lang.forEach(["x", "y", "width", "height"], function(x){ + pattern.setAttribute(x, f[x].toFixed(8)); + }); + break; + } + return this; + } + // color object + var f = dojo.gfx.normalizeColor(fill); + this.fillStyle = f; + this.rawNode.setAttribute("fill", f.toCss()); + this.rawNode.setAttribute("fill-opacity", f.a); + return this; // self + }, + + setStroke: function(stroke){ + // summary: sets a stroke object (SVG) + // stroke: Object: a stroke object + // (see dojo.gfx.defaultStroke) + + if(!stroke){ + // don't stroke + this.strokeStyle = null; + this.rawNode.setAttribute("stroke", "none"); + this.rawNode.setAttribute("stroke-opacity", 0); + return this; + } + // normalize the stroke + this.strokeStyle = dojo.gfx.makeParameters(dojo.gfx.defaultStroke, stroke); + this.strokeStyle.color = dojo.gfx.normalizeColor(this.strokeStyle.color); + // generate attributes + var s = this.strokeStyle; + var rn = this.rawNode; + if(s){ + rn.setAttribute("stroke", s.color.toCss()); + rn.setAttribute("stroke-opacity", s.color.a); + rn.setAttribute("stroke-width", s.width); + rn.setAttribute("stroke-linecap", s.cap); + if(typeof(s.join) == "number"){ + rn.setAttribute("stroke-linejoin", "miter"); + rn.setAttribute("stroke-miterlimit", s.join); + }else{ + rn.setAttribute("stroke-linejoin", s.join); + } + } + return this; // self + }, + + _setFillObject: function(f, nodeType){ + var def_elems = this.rawNode.parentNode.getElementsByTagName("defs"); + if(def_elems.length == 0){ return this; } + this.fillStyle = f; + var defs = def_elems[0]; + var fill = this.rawNode.getAttribute("fill"); + var ref = dojo.gfx.svg.getRef(fill); + if(ref){ + fill = ref; + if(fill.tagName.toLowerCase() != nodeType.toLowerCase()){ + var id = fill.id; + fill.parentNode.removeChild(fill); + fill = document.createElementNS(dojo.svg.xmlns.svg, nodeType); + fill.setAttribute("id", id); + defs.appendChild(fill); + }else{ + while(fill.childNodes.length){ + fill.removeChild(fill.lastChild); + } + } + }else{ + fill = document.createElementNS(dojo.svg.xmlns.svg, nodeType); + fill.setAttribute("id", dojo.dom.getUniqueId()); + defs.appendChild(fill); + } + if(nodeType == "pattern"){ + fill.setAttribute("patternUnits", "userSpaceOnUse"); + var img = document.createElementNS(dojo.svg.xmlns.svg, "image"); + img.setAttribute("x", 0); + img.setAttribute("y", 0); + img.setAttribute("width", f.width .toFixed(8)); + img.setAttribute("height", f.height.toFixed(8)); + img.setAttributeNS(dojo.svg.xmlns.xlink, "href", f.src); + fill.appendChild(img); + }else{ + fill.setAttribute("gradientUnits", "userSpaceOnUse"); + for(var i = 0; i < f.colors.length; ++i){ + f.colors[i].color = dojo.gfx.normalizeColor(f.colors[i].color); + var t = document.createElementNS(dojo.svg.xmlns.svg, "stop"); + t.setAttribute("offset", f.colors[i].offset.toFixed(8)); + t.setAttribute("stop-color", f.colors[i].color.toCss()); + fill.appendChild(t); + } + } + this.rawNode.setAttribute("fill", "url(#" + fill.getAttribute("id") +")"); + this.rawNode.removeAttribute("fill-opacity"); + return fill; + }, + + _applyTransform: function() { + var matrix = this._getRealMatrix(); + if(matrix){ + var tm = this.matrix; + this.rawNode.setAttribute("transform", "matrix(" + + tm.xx.toFixed(8) + "," + tm.yx.toFixed(8) + "," + + tm.xy.toFixed(8) + "," + tm.yy.toFixed(8) + "," + + tm.dx.toFixed(8) + "," + tm.dy.toFixed(8) + ")"); + }else{ + this.rawNode.removeAttribute("transform"); + } + return this; + }, + + setRawNode: function(rawNode){ + // summary: + // assigns and clears the underlying node that will represent this + // shape. Once set, transforms, gradients, etc, can be applied. + // (no fill & stroke by default) + with(rawNode){ + setAttribute("fill", "none"); + setAttribute("fill-opacity", 0); + setAttribute("stroke", "none"); + setAttribute("stroke-opacity", 0); + setAttribute("stroke-width", 1); + setAttribute("stroke-linecap", "butt"); + setAttribute("stroke-linejoin", "miter"); + setAttribute("stroke-miterlimit", 4); + } + this.rawNode = rawNode; + }, + + moveToFront: function(){ + // summary: moves a shape to front of its parent's list of shapes (SVG) + this.rawNode.parentNode.appendChild(this.rawNode); + return this; // self + }, + moveToBack: function(){ + // summary: moves a shape to back of its parent's list of shapes (SVG) + this.rawNode.parentNode.insertBefore(this.rawNode, this.rawNode.parentNode.firstChild); + return this; // self + }, + + setShape: function(newShape){ + // summary: sets a shape object (SVG) + // newShape: Object: a shape object + // (see dojo.gfx.defaultPath, + // dojo.gfx.defaultPolyline, + // dojo.gfx.defaultRect, + // dojo.gfx.defaultEllipse, + // dojo.gfx.defaultCircle, + // dojo.gfx.defaultLine, + // or dojo.gfx.defaultImage) + this.shape = dojo.gfx.makeParameters(this.shape, newShape); + for(var i in this.shape){ + if(i != "type"){ this.rawNode.setAttribute(i, this.shape[i]); } + } + return this; // self + }, + + attachFill: function(rawNode){ + // summary: deduces a fill style from a Node. + // rawNode: Node: an SVG node + var fillStyle = null; + if(rawNode){ + var fill = rawNode.getAttribute("fill"); + if(fill == "none"){ return; } + var ref = dojo.gfx.svg.getRef(fill); + if(ref){ + var gradient = ref; + switch(gradient.tagName.toLowerCase()){ + case "lineargradient": + fillStyle = this._getGradient(dojo.gfx.defaultLinearGradient, gradient); + dojo.lang.forEach(["x1", "y1", "x2", "y2"], function(x){ + fillStyle[x] = gradient.getAttribute(x); + }); + break; + case "radialgradient": + fillStyle = this._getGradient(dojo.gfx.defaultRadialGradient, gradient); + dojo.lang.forEach(["cx", "cy", "r"], function(x){ + fillStyle[x] = gradient.getAttribute(x); + }); + fillStyle.cx = gradient.getAttribute("cx"); + fillStyle.cy = gradient.getAttribute("cy"); + fillStyle.r = gradient.getAttribute("r"); + break; + case "pattern": + fillStyle = dojo.lang.shallowCopy(dojo.gfx.defaultPattern, true); + dojo.lang.forEach(["x", "y", "width", "height"], function(x){ + fillStyle[x] = gradient.getAttribute(x); + }); + fillStyle.src = gradient.firstChild.getAttributeNS(dojo.svg.xmlns.xlink, "href"); + break; + } + }else{ + fillStyle = new dojo.gfx.color.Color(fill); + var opacity = rawNode.getAttribute("fill-opacity"); + if(opacity != null) fillStyle.a = opacity; + } + } + return fillStyle; // Object + }, + + _getGradient: function(defaultGradient, gradient){ + var fillStyle = dojo.lang.shallowCopy(defaultGradient, true); + fillStyle.colors = []; + for(var i = 0; i < gradient.childNodes.length; ++i){ + fillStyle.colors.push({ + offset: gradient.childNodes[i].getAttribute("offset"), + color: new dojo.gfx.color.Color(gradient.childNodes[i].getAttribute("stop-color")) + }); + } + return fillStyle; + }, + + attachStroke: function(rawNode){ + // summary: deduces a stroke style from a Node. + // rawNode: Node: an SVG node + if(!rawNode){ return; } + var stroke = rawNode.getAttribute("stroke"); + if(stroke == null || stroke == "none") return null; + var strokeStyle = dojo.lang.shallowCopy(dojo.gfx.defaultStroke, true); + var color = new dojo.gfx.color.Color(stroke); + if(color){ + strokeStyle.color = color; + strokeStyle.color.a = rawNode.getAttribute("stroke-opacity"); + strokeStyle.width = rawNode.getAttribute("stroke-width"); + strokeStyle.cap = rawNode.getAttribute("stroke-linecap"); + strokeStyle.join = rawNode.getAttribute("stroke-linejoin"); + if(strokeStyle.join == "miter"){ + strokeStyle.join = rawNode.getAttribute("stroke-miterlimit"); + } + } + return strokeStyle; // Object + }, + + attachTransform: function(rawNode){ + // summary: deduces a transformation matrix from a Node. + // rawNode: Node: an SVG node + var matrix = null; + if(rawNode){ + matrix = rawNode.getAttribute("transform"); + if(matrix.match(/^matrix\(.+\)$/)){ + var t = matrix.slice(7, -1).split(","); + matrix = dojo.gfx.matrix.normalize({ + xx: parseFloat(t[0]), xy: parseFloat(t[2]), + yx: parseFloat(t[1]), yy: parseFloat(t[3]), + dx: parseFloat(t[4]), dy: parseFloat(t[5]) + }); + } + } + return matrix; // dojo.gfx.matrix.Matrix + }, + + attachShape: function(rawNode){ + // summary: builds a shape from a Node. + // rawNode: Node: an SVG node + var shape = null; + if(rawNode){ + shape = dojo.lang.shallowCopy(this.shape, true); + for(var i in shape) { + shape[i] = rawNode.getAttribute(i); + } + } + return shape; // dojo.gfx.Shape + }, + + attach: function(rawNode){ + // summary: reconstructs all shape parameters from a Node. + // rawNode: Node: an SVG node + if(rawNode) { + this.rawNode = rawNode; + this.fillStyle = this.attachFill(rawNode); + this.strokeStyle = this.attachStroke(rawNode); + this.matrix = this.attachTransform(rawNode); + this.shape = this.attachShape(rawNode); + } + } +}); + +dojo.declare("dojo.gfx.Group", dojo.gfx.Shape, { + // summary: a group shape (SVG), which can be used + // to logically group shapes (e.g, to propagate matricies) + + setRawNode: function(rawNode){ + // summary: sets a raw SVG node to be used by this shape + // rawNode: Node: an SVG node + this.rawNode = rawNode; + } +}); +dojo.gfx.Group.nodeType = "g"; + +dojo.declare("dojo.gfx.Rect", dojo.gfx.shape.Rect, { + // summary: a rectangle shape (SVG) + + attachShape: function(rawNode){ + // summary: builds a rectangle shape from a Node. + // rawNode: Node: an SVG node + var shape = null; + if(rawNode){ + shape = dojo.gfx.Rect.superclass.attachShape.apply(this, arguments); + shape.r = Math.min(rawNode.getAttribute("rx"), rawNode.getAttribute("ry")); + } + return shape; // dojo.gfx.shape.Rect + }, + setShape: function(newShape){ + // summary: sets a rectangle shape object (SVG) + // newShape: Object: a rectangle shape object + this.shape = dojo.gfx.makeParameters(this.shape, newShape); + this.bbox = null; + for(var i in this.shape){ + if(i != "type" && i != "r"){ this.rawNode.setAttribute(i, this.shape[i]); } + } + this.rawNode.setAttribute("rx", this.shape.r); + this.rawNode.setAttribute("ry", this.shape.r); + return this; // self + } +}); +dojo.gfx.Rect.nodeType = "rect"; + +dojo.gfx.Ellipse = dojo.gfx.shape.Ellipse; +dojo.gfx.Ellipse.nodeType = "ellipse"; + +dojo.gfx.Circle = dojo.gfx.shape.Circle; +dojo.gfx.Circle.nodeType = "circle"; + +dojo.gfx.Line = dojo.gfx.shape.Line; +dojo.gfx.Line.nodeType = "line"; + +dojo.declare("dojo.gfx.Polyline", dojo.gfx.shape.Polyline, { + // summary: a polyline/polygon shape (SVG) + + setShape: function(points){ + // summary: sets a polyline/polygon shape object (SVG) + // points: Object: a polyline/polygon shape object + if(points && points instanceof Array){ + // branch + // points: Array: an array of points + this.shape = dojo.gfx.makeParameters(this.shape, { points: points }); + if(closed && this.shape.points.length){ + this.shape.points.push(this.shape.points[0]); + } + }else{ + this.shape = dojo.gfx.makeParameters(this.shape, points); + } + this.box = null; + var attr = []; + var p = this.shape.points; + for(var i = 0; i < p.length; ++i){ + attr.push(p[i].x.toFixed(8)); + attr.push(p[i].y.toFixed(8)); + } + this.rawNode.setAttribute("points", attr.join(" ")); + return this; // self + } +}); +dojo.gfx.Polyline.nodeType = "polyline"; + +dojo.declare("dojo.gfx.Image", dojo.gfx.shape.Image, { + // summary: an image (SVG) + + setShape: function(newShape){ + // summary: sets an image shape object (SVG) + // newShape: Object: an image shape object + this.shape = dojo.gfx.makeParameters(this.shape, newShape); + this.bbox = null; + var rawNode = this.rawNode; + for(var i in this.shape){ + if(i != "type" && i != "src"){ rawNode.setAttribute(i, this.shape[i]); } + } + rawNode.setAttributeNS(dojo.svg.xmlns.xlink, "href", this.shape.src); + return this; // self + }, + setStroke: function(){ + // summary: ignore setting a stroke style + return this; // self + }, + setFill: function(){ + // summary: ignore setting a fill style + return this; // self + }, + attachStroke: function(rawNode){ + // summary: ignore attaching a stroke style + return null; + }, + attachFill: function(rawNode){ + // summary: ignore attaching a fill style + return null; + } +}); +dojo.gfx.Image.nodeType = "image"; + +dojo.declare("dojo.gfx.Path", dojo.gfx.path.Path, { + // summary: a path shape (SVG) + + _updateWithSegment: function(segment){ + // summary: updates the bounding box of path with new segment + // segment: Object: a segment + dojo.gfx.Path.superclass._updateWithSegment.apply(this, arguments); + if(typeof(this.shape.path) == "string"){ + this.rawNode.setAttribute("d", this.shape.path); + } + }, + setShape: function(newShape){ + // summary: forms a path using a shape (SVG) + // newShape: Object: an SVG path string or a path object (see dojo.gfx.defaultPath) + dojo.gfx.Path.superclass.setShape.apply(this, arguments); + this.rawNode.setAttribute("d", this.shape.path); + return this; // self + } +}); +dojo.gfx.Path.nodeType = "path"; + +dojo.gfx._creators = { + // summary: SVG shape creators + createPath: function(path){ + // summary: creates an SVG path shape + // path: Object: a path object (see dojo.gfx.defaultPath) + return this.createObject(dojo.gfx.Path, path); // dojo.gfx.Path + }, + createRect: function(rect){ + // summary: creates an SVG rectangle shape + // rect: Object: a path object (see dojo.gfx.defaultRect) + return this.createObject(dojo.gfx.Rect, rect); // dojo.gfx.Rect + }, + createCircle: function(circle){ + // summary: creates an SVG circle shape + // circle: Object: a circle object (see dojo.gfx.defaultCircle) + return this.createObject(dojo.gfx.Circle, circle); // dojo.gfx.Circle + }, + createEllipse: function(ellipse){ + // summary: creates an SVG ellipse shape + // ellipse: Object: an ellipse object (see dojo.gfx.defaultEllipse) + return this.createObject(dojo.gfx.Ellipse, ellipse); // dojo.gfx.Ellipse + }, + createLine: function(line){ + // summary: creates an SVG line shape + // line: Object: a line object (see dojo.gfx.defaultLine) + return this.createObject(dojo.gfx.Line, line); // dojo.gfx.Line + }, + createPolyline: function(points){ + // summary: creates an SVG polyline/polygon shape + // points: Object: a points object (see dojo.gfx.defaultPolyline) + // or an Array of points + return this.createObject(dojo.gfx.Polyline, points); // dojo.gfx.Polyline + }, + createImage: function(image){ + // summary: creates an SVG image shape + // image: Object: an image object (see dojo.gfx.defaultImage) + return this.createObject(dojo.gfx.Image, image); // dojo.gfx.Image + }, + createGroup: function(){ + // summary: creates an SVG group shape + return this.createObject(dojo.gfx.Group); // dojo.gfx.Group + }, + createObject: function(shapeType, rawShape){ + // summary: creates an instance of the passed shapeType class + // shapeType: Function: a class constructor to create an instance of + // rawShape: Object: properties to be passed in to the classes "setShape" method + if(!this.rawNode){ return null; } + var shape = new shapeType(); + var node = document.createElementNS(dojo.svg.xmlns.svg, shapeType.nodeType); + shape.setRawNode(node); + this.rawNode.appendChild(node); + shape.setShape(rawShape); + this.add(shape); + return shape; // dojo.gfx.Shape + }, + // group control + add: function(shape){ + // summary: adds a shape to a group/surface + // shape: dojo.gfx.Shape: an SVG shape object + var oldParent = shape.getParent(); + if(oldParent){ + oldParent.remove(shape, true); + } + shape._setParent(this, null); + this.rawNode.appendChild(shape.rawNode); + return this; // self + }, + remove: function(shape, silently){ + // summary: remove a shape from a group/surface + // shape: dojo.gfx.Shape: an SVG shape object + // silently: Boolean?: if true, regenerate a picture + if(this.rawNode == shape.rawNode.parentNode){ + this.rawNode.removeChild(shape.rawNode); + } + shape._setParent(null, null); + return this; // self + } +}; + +dojo.gfx.attachNode = function(node){ + // summary: creates a shape from a Node + // node: Node: an SVG node + if(!node) return null; + var s = null; + switch(node.tagName.toLowerCase()){ + case dojo.gfx.Rect.nodeType: + s = new dojo.gfx.Rect(); + break; + case dojo.gfx.Ellipse.nodeType: + s = new dojo.gfx.Ellipse(); + break; + case dojo.gfx.Polyline.nodeType: + s = new dojo.gfx.Polyline(); + break; + case dojo.gfx.Path.nodeType: + s = new dojo.gfx.Path(); + break; + case dojo.gfx.Circle.nodeType: + s = new dojo.gfx.Circle(); + break; + case dojo.gfx.Line.nodeType: + s = new dojo.gfx.Line(); + break; + case dojo.gfx.Image.nodeType: + s = new dojo.gfx.Image(); + break; + default: + dojo.debug("FATAL ERROR! tagName = " + node.tagName); + } + s.attach(node); + return s; // dojo.gfx.Shape +}; + +dojo.lang.extend(dojo.gfx.Surface, { + // summary: a surface object to be used for drawings (SVG) + + setDimensions: function(width, height){ + // summary: sets the width and height of the rawNode + // width: String: width of surface, e.g., "100px" + // height: String: height of surface, e.g., "100px" + if(!this.rawNode){ return this; } + this.rawNode.setAttribute("width", width); + this.rawNode.setAttribute("height", height); + return this; // self + }, + getDimensions: function(){ + // summary: returns an object with properties "width" and "height" + return this.rawNode ? {width: this.rawNode.getAttribute("width"), height: this.rawNode.getAttribute("height")} : null; // Object + } +}); + +dojo.gfx.createSurface = function(parentNode, width, height){ + // summary: creates a surface (SVG) + // parentNode: Node: a parent node + // width: String: width of surface, e.g., "100px" + // height: String: height of surface, e.g., "100px" + + var s = new dojo.gfx.Surface(); + s.rawNode = document.createElementNS(dojo.svg.xmlns.svg, "svg"); + s.rawNode.setAttribute("width", width); + s.rawNode.setAttribute("height", height); + + var defs = new dojo.gfx.svg.Defines(); + var node = document.createElementNS(dojo.svg.xmlns.svg, dojo.gfx.svg.Defines.nodeType); + defs.setRawNode(node); + s.rawNode.appendChild(node); + + dojo.byId(parentNode).appendChild(s.rawNode); + return s; // dojo.gfx.Surface +}; + +dojo.gfx.attachSurface = function(node){ + // summary: creates a surface from a Node + // node: Node: an SVG node + var s = new dojo.gfx.Surface(); + s.rawNode = node; + return s; // dojo.gfx.Surface +}; + +dojo.lang.extend(dojo.gfx.Group, dojo.gfx._creators); +dojo.lang.extend(dojo.gfx.Surface, dojo.gfx._creators); + +delete dojo.gfx._creators; + +// Gradient and pattern + +dojo.gfx.svg.Defines = function(){ + this.rawNode = null; +}; +dojo.lang.extend(dojo.gfx.svg.Defines, { + setRawNode: function(rawNode){ + this.rawNode = rawNode; + } +}); +dojo.gfx.svg.Defines.nodeType = "defs"; Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/gfx/svg.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/gfx/svg.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/gfx/svg.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/gfx/vml.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/gfx/vml.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/gfx/vml.js (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/gfx/vml.js Mon Feb 19 09:56:06 2007 @@ -0,0 +1,1319 @@ +/* + Copyright (c) 2004-2006, The Dojo Foundation + All Rights Reserved. + + Licensed under the Academic Free License version 2.1 or above OR the + modified BSD license. For more information on Dojo licensing, see: + + http://dojotoolkit.org/community/licensing.shtml +*/ + +dojo.provide("dojo.gfx.vml"); + +dojo.require("dojo.dom"); +dojo.require("dojo.math"); +dojo.require("dojo.lang.declare"); +dojo.require("dojo.lang.extras"); +dojo.require("dojo.string.*"); +dojo.require("dojo.html.metrics"); + +dojo.require("dojo.gfx.color"); +dojo.require("dojo.gfx.common"); +dojo.require("dojo.gfx.shape"); +dojo.require("dojo.gfx.path"); + +dojo.require("dojo.experimental"); +dojo.experimental("dojo.gfx.vml"); + +// dojo.gfx.vml.xmlns: String: a VML's namespace +dojo.gfx.vml.xmlns = "urn:schemas-microsoft-com:vml"; + +dojo.gfx.vml._parseFloat = function(str) { + // summary: a helper function to parse VML-specific floating-point values + // str: String: a representation of a floating-point number + return str.match(/^\d+f$/i) ? parseInt(str) / 65536 : parseFloat(str); // Number +}; + +// dojo.gfx.vml.cm_in_pt: Number: centimeters per inch +dojo.gfx.vml.cm_in_pt = 72 / 2.54; + +// dojo.gfx.vml.mm_in_pt: Number: millimeters per inch +dojo.gfx.vml.mm_in_pt = 7.2 / 2.54; + +dojo.gfx.vml.px_in_pt = function(){ + // summary: returns a number of pixels per point + return dojo.html.getCachedFontMeasurements()["12pt"] / 12; // Number +}; +dojo.gfx.vml.pt2px = function(len){ + // summary: converts points to pixels + // len: Number: a value in points + return len * this.px_in_pt(); // Number +}; +dojo.gfx.vml.px2pt = function(len){ + // summary: converts pixels to points + // len: Number: a value in pixels + return len / this.px_in_pt(); // Number +}; + +dojo.gfx.vml.normalizedLength = function(len) { + // summary: converts any length value to points + // len: String: a length, e.g., "12pc" + if(len.length == 0) return 0; + if(len.length > 2){ + var px_in_pt = this.px_in_pt(); + var val = parseFloat(len); + switch(len.slice(-2)){ + case "px": return val; + case "pt": return val * px_in_pt; + case "in": return val * 72 * px_in_pt; + case "pc": return val * 12 * px_in_pt; + case "mm": return val / this.mm_in_pt * px_in_pt; + case "cm": return val / this.cm_in_pt * px_in_pt; + } + } + return parseFloat(len); // Number +}; + +dojo.lang.extend(dojo.gfx.Shape, { + // summary: VML-specific implementation of dojo.gfx.Shape methods + + setFill: function(fill){ + // summary: sets a fill object (VML) + // fill: Object: a fill object + // (see dojo.gfx.defaultLinearGradient, + // dojo.gfx.defaultRadialGradient, + // dojo.gfx.defaultPattern, + // or dojo.gfx.color.Color) + + if(!fill){ + // don't fill + this.fillStyle = null; + this.rawNode.filled = false; + return this; + } + if(typeof(fill) == "object" && "type" in fill){ + // gradient + switch(fill.type){ + case "linear": + var f = dojo.gfx.makeParameters(dojo.gfx.defaultLinearGradient, fill); + this.fillStyle = f; + var s = ""; + for(var i = 0; i < f.colors.length; ++i){ + f.colors[i].color = dojo.gfx.normalizeColor(f.colors[i].color); + s += f.colors[i].offset.toFixed(8) + " " + f.colors[i].color.toHex() + ";"; + } + var fo = this.rawNode.fill; + fo.colors.value = s; + fo.method = "sigma"; + fo.type = "gradient"; + fo.angle = (dojo.math.radToDeg(Math.atan2(f.x2 - f.x1, f.y2 - f.y1)) + 180) % 360; + fo.on = true; + break; + case "radial": + var f = dojo.gfx.makeParameters(dojo.gfx.defaultRadialGradient, fill); + this.fillStyle = f; + var w = parseFloat(this.rawNode.style.width); + var h = parseFloat(this.rawNode.style.height); + var c = isNaN(w) ? 1 : 2 * f.r / w; + var i = f.colors.length - 1; + f.colors[i].color = dojo.gfx.normalizeColor(f.colors[i].color); + var s = "0 " + f.colors[i].color.toHex(); + for(; i >= 0; --i){ + f.colors[i].color = dojo.gfx.normalizeColor(f.colors[i].color); + s += (1 - c * f.colors[i].offset).toFixed(8) + " " + f.colors[i].color.toHex() + ";"; + } + var fo = this.rawNode.fill; + fo.colors.value = s; + fo.method = "sigma"; + fo.type = "gradientradial"; + if(isNaN(w) || isNaN(h)){ + fo.focusposition = "0.5 0.5"; + }else{ + fo.focusposition = (f.cx / w).toFixed(8) + " " + (f.cy / h).toFixed(8); + } + fo.focussize = "0 0"; + fo.on = true; + break; + case "pattern": + var f = dojo.gfx.makeParameters(dojo.gfx.defaultPattern, fill); + this.fillStyle = f; + var fo = this.rawNode.fill; + fo.type = "tile"; + fo.src = f.src; + if(f.width && f.height){ + // in points + fo.size.x = dojo.gfx.vml.px2pt(f.width); + fo.size.y = dojo.gfx.vml.px2pt(f.height); + } + fo.alignShape = false; + fo.position.x = 0; + fo.position.y = 0; + fo.origin.x = f.width ? f.x / f.width : 0; + fo.origin.y = f.height ? f.y / f.height : 0; + fo.on = true; + break; + } + this.rawNode.fill.opacity = 1; + return this; + } + // color object + this.fillStyle = dojo.gfx.normalizeColor(fill); + this.rawNode.fillcolor = this.fillStyle.toHex(); + this.rawNode.fill.opacity = this.fillStyle.a; + this.rawNode.filled = true; + return this; // self + }, + + setStroke: function(stroke){ + // summary: sets a stroke object (VML) + // stroke: Object: a stroke object + // (see dojo.gfx.defaultStroke) + + if(!stroke){ + // don't stroke + this.strokeStyle = null; + this.rawNode.stroked = false; + return this; + } + // normalize the stroke + this.strokeStyle = dojo.gfx.makeParameters(dojo.gfx.defaultStroke, stroke); + this.strokeStyle.color = dojo.gfx.normalizeColor(this.strokeStyle.color); + // generate attributes + var s = this.strokeStyle; + this.rawNode.stroked = true; + this.rawNode.strokecolor = s.color.toCss(); + this.rawNode.strokeweight = s.width + "px"; // TODO: should we assume that the width is always in pixels? + if(this.rawNode.stroke) { + this.rawNode.stroke.opacity = s.color.a; + this.rawNode.stroke.endcap = this._translate(this._capMap, s.cap); + if(typeof(s.join) == "number") { + this.rawNode.stroke.joinstyle = "miter"; + this.rawNode.stroke.miterlimit = s.join; + }else{ + this.rawNode.stroke.joinstyle = s.join; + // this.rawNode.stroke.miterlimit = s.width; + } + } + return this; // self + }, + + _capMap: { butt: 'flat' }, + _capMapReversed: { flat: 'butt' }, + + _translate: function(dict, value) { + return (value in dict) ? dict[value] : value; + }, + + _applyTransform: function() { + var matrix = this._getRealMatrix(); + if(!matrix) return this; + var skew = this.rawNode.skew; + if(typeof(skew) == "undefined"){ + for(var i = 0; i < this.rawNode.childNodes.length; ++i){ + if(this.rawNode.childNodes[i].tagName == "skew"){ + skew = this.rawNode.childNodes[i]; + break; + } + } + } + if(skew){ + skew.on = false; + var mt = matrix.xx.toFixed(8) + " " + matrix.xy.toFixed(8) + " " + + matrix.yx.toFixed(8) + " " + matrix.yy.toFixed(8) + " 0 0"; + var offset = Math.floor(matrix.dx).toFixed() + "px " + Math.floor(matrix.dy).toFixed() + "px"; + var l = parseFloat(this.rawNode.style.left); + var t = parseFloat(this.rawNode.style.top); + var w = parseFloat(this.rawNode.style.width); + var h = parseFloat(this.rawNode.style.height); + if(isNaN(l)) l = 0; + if(isNaN(t)) t = 0; + if(isNaN(w)) w = 1; + if(isNaN(h)) h = 1; + var origin = (-l / w - 0.5).toFixed(8) + " " + (-t / h - 0.5).toFixed(8); + skew.matrix = mt; + skew.origin = origin; + skew.offset = offset; + skew.on = true; + } + return this; + }, + + setRawNode: function(rawNode){ + // summary: + // assigns and clears the underlying node that will represent this + // shape. Once set, transforms, gradients, etc, can be applied. + // (no fill & stroke by default) + rawNode.stroked = false; + rawNode.filled = false; + this.rawNode = rawNode; + }, + + // Attach family + + attachFill: function(rawNode){ + // summary: deduces a fill style from a Node. + // rawNode: Node: an VML node + var fillStyle = null; + var fo = rawNode.fill; + if(rawNode) { + if(fo.on && fo.type == "gradient"){ + var fillStyle = dojo.lang.shallowCopy(dojo.gfx.defaultLinearGradient, true); + var rad = dojo.math.degToRad(fo.angle); + fillStyle.x2 = Math.cos(rad); + fillStyle.y2 = Math.sin(rad); + fillStyle.colors = []; + var stops = fo.colors.value.split(";"); + for(var i = 0; i < stops.length; ++i){ + var t = stops[i].match(/\S+/g); + if(!t || t.length != 2) continue; + fillStyle.colors.push({offset: dojo.gfx.vml._parseFloat(t[0]), color: new dojo.gfx.color.Color(t[1])}); + } + }else if(fo.on && fo.type == "gradientradial"){ + var fillStyle = dojo.lang.shallowCopy(dojo.gfx.defaultRadialGradient, true); + var w = parseFloat(rawNode.style.width); + var h = parseFloat(rawNode.style.height); + fillStyle.cx = isNaN(w) ? 0 : fo.focusposition.x * w; + fillStyle.cy = isNaN(h) ? 0 : fo.focusposition.y * h; + fillStyle.r = isNaN(w) ? 1 : w / 2; + fillStyle.colors = []; + var stops = fo.colors.value.split(";"); + for(var i = stops.length - 1; i >= 0; --i){ + var t = stops[i].match(/\S+/g); + if(!t || t.length != 2) continue; + fillStyle.colors.push({offset: dojo.gfx.vml._parseFloat(t[0]), color: new dojo.gfx.color.Color(t[1])}); + } + }else if(fo.on && fo.type == "tile"){ + var fillStyle = dojo.lang.shallowCopy(dojo.gfx.defaultPattern, true); + fillStyle.width = dojo.gfx.vml.pt2px(fo.size.x); // from pt + fillStyle.height = dojo.gfx.vml.pt2px(fo.size.y); // from pt + fillStyle.x = fo.origin.x * fillStyle.width; + fillStyle.y = fo.origin.y * fillStyle.height; + fillStyle.src = fo.src; + }else if(fo.on && rawNode.fillcolor){ + // a color object ! + fillStyle = new dojo.gfx.color.Color(rawNode.fillcolor+""); + fillStyle.a = fo.opacity; + } + } + return fillStyle; // Object + }, + + attachStroke: function(rawNode) { + // summary: deduces a stroke style from a Node. + // rawNode: Node: an VML node + var strokeStyle = dojo.lang.shallowCopy(dojo.gfx.defaultStroke, true); + if(rawNode && rawNode.stroked){ + strokeStyle.color = new dojo.gfx.color.Color(rawNode.strokecolor.value); + dojo.debug("We are expecting an .75pt here, instead of strokeweight = " + rawNode.strokeweight ); + strokeStyle.width = dojo.gfx.vml.normalizedLength(rawNode.strokeweight+""); + strokeStyle.color.a = rawNode.stroke.opacity; + strokeStyle.cap = this._translate(this._capMapReversed, rawNode.stroke.endcap); + strokeStyle.join = rawNode.stroke.joinstyle == "miter" ? rawNode.stroke.miterlimit : rawNode.stroke.joinstyle; + }else{ + return null; + } + return strokeStyle; // Object + }, + + attachTransform: function(rawNode) { + // summary: deduces a transformation matrix from a Node. + // rawNode: Node: an VML node + var matrix = {}; + if(rawNode){ + var s = rawNode.skew; + matrix.xx = s.matrix.xtox; + matrix.xy = s.matrix.ytox; + matrix.yx = s.matrix.xtoy; + matrix.yy = s.matrix.ytoy; + matrix.dx = dojo.gfx.vml.pt2px(s.offset.x); + matrix.dy = dojo.gfx.vml.pt2px(s.offset.y); + } + return dojo.gfx.matrix.normalize(matrix); // dojo.gfx.matrix.Matrix + }, + + attach: function(rawNode){ + // summary: reconstructs all shape parameters from a Node. + // rawNode: Node: an VML node + if(rawNode){ + this.rawNode = rawNode; + this.shape = this.attachShape(rawNode); + this.fillStyle = this.attachFill(rawNode); + this.strokeStyle = this.attachStroke(rawNode); + this.matrix = this.attachTransform(rawNode); + } + } +}); + +dojo.declare("dojo.gfx.Group", dojo.gfx.shape.VirtualGroup, { + // summary: a group shape (VML), which can be used + // to logically group shapes (e.g, to propagate matricies) + add: function(shape){ + // summary: adds a shape to a group/surface + // shape: dojo.gfx.Shape: an VML shape object + if(this != shape.getParent()){ + this.rawNode.appendChild(shape.rawNode); + dojo.gfx.Group.superclass.add.apply(this, arguments); + } + return this; // self + }, + remove: function(shape, silently){ + // summary: remove a shape from a group/surface + // shape: dojo.gfx.Shape: an VML shape object + // silently: Boolean?: if true, regenerate a picture + if(this == shape.getParent()){ + if(this.rawNode == shape.rawNode.parentNode){ + this.rawNode.removeChild(shape.rawNode); + } + dojo.gfx.Group.superclass.remove.apply(this, arguments); + } + return this; // self + }, + attach: function(rawNode){ + // summary: reconstructs all group shape parameters from a Node (VML). + // rawNode: Node: a node + if(rawNode){ + this.rawNode = rawNode; + this.shape = null; + this.fillStyle = null; + this.strokeStyle = null; + this.matrix = null; + } + } +}); +dojo.gfx.Group.nodeType = "group"; + +var zIndex = { + moveToFront: function(){ + // summary: moves a shape to front of its parent's list of shapes (VML) + this.rawNode.parentNode.appendChild(this.rawNode); + return this; + }, + moveToBack: function(){ + // summary: moves a shape to back of its parent's list of shapes (VML) + this.rawNode.parentNode.insertBefore(this.rawNode, this.rawNode.parentNode.firstChild); + return this; + } +}; +dojo.lang.extend(dojo.gfx.Shape, zIndex); +dojo.lang.extend(dojo.gfx.Group, zIndex); +delete zIndex; + +dojo.declare("dojo.gfx.Rect", dojo.gfx.shape.Rect, { + // summary: a rectangle shape (VML) + + attachShape: function(rawNode){ + // summary: builds a rectangle shape from a Node. + // rawNode: Node: a VML node + + // a workaround for the VML's arcsize bug: cannot read arcsize of an instantiated node + var arcsize = rawNode.outerHTML.match(/arcsize = \"(\d*\.?\d+[%f]?)\"/)[1]; + arcsize = (arcsize.indexOf("%") >= 0) ? parseFloat(arcsize) / 100 : dojo.gfx.vml._parseFloat(arcsize); + var style = rawNode.style; + var width = parseFloat(style.width); + var height = parseFloat(style.height); + // make an object + var o = dojo.gfx.makeParameters(dojo.gfx.defaultRect, { + x: parseInt(style.left), + y: parseInt(style.top), + width: width, + height: height, + r: Math.min(width, height) * arcsize + }); + return o; // dojo.gfx.shape.Rect + }, + setShape: function(newShape){ + // summary: sets a rectangle shape object (VML) + // newShape: Object: a rectangle shape object + var shape = this.shape = dojo.gfx.makeParameters(this.shape, newShape); + this.bbox = null; + var style = this.rawNode.style; + style.left = shape.x.toFixed(); + style.top = shape.y.toFixed(); + style.width = (typeof(shape.width) == "string" && shape.width.indexOf("%") >= 0) ? shape.width : shape.width.toFixed(); + style.height = (typeof(shape.width) == "string" && shape.height.indexOf("%") >= 0) ? shape.height : shape.height.toFixed(); + var r = Math.min(1, (shape.r / Math.min(parseFloat(shape.width), parseFloat(shape.height)))).toFixed(8); + // a workaround for the VML's arcsize bug: cannot read arcsize of an instantiated node + var parent = this.rawNode.parentNode; + var before = null; + if(parent){ + if(parent.lastChild != this.rawNode){ + for(var i = 0; i < parent.childNodes.length; ++i){ + if(parent.childNodes[i] == this.rawNode){ + before = parent.childNodes[i+1]; + break; + } + } + } + parent.removeChild(this.rawNode); + } + this.rawNode.arcsize = r; + if(parent){ + if(before){ + parent.insertBefore(this.rawNode, before); + }else{ + parent.appendChild(this.rawNode); + } + } + return this.setTransform(this.matrix); // self + } +}); +dojo.gfx.Rect.nodeType = "roundrect"; // use a roundrect so the stroke join type is respected + +dojo.declare("dojo.gfx.Ellipse", dojo.gfx.shape.Ellipse, { + // summary: an ellipse shape (VML) + + attachShape: function(rawNode){ + // summary: builds an ellipse shape from a Node. + // rawNode: Node: an VML node + var style = this.rawNode.style; + var rx = parseInt(style.width ) / 2; + var ry = parseInt(style.height) / 2; + var o = dojo.gfx.makeParameters(dojo.gfx.defaultEllipse, { + cx: parseInt(style.left) + rx, + cy: parseInt(style.top ) + ry, + rx: rx, + ry: ry + }); + return o; // dojo.gfx.shape.Ellipse + }, + setShape: function(newShape){ + // summary: sets an ellipse shape object (VML) + // newShape: Object: an ellipse shape object + var shape = this.shape = dojo.gfx.makeParameters(this.shape, newShape); + this.bbox = null; + var style = this.rawNode.style; + style.left = (shape.cx - shape.rx).toFixed(); + style.top = (shape.cy - shape.ry).toFixed(); + style.width = (shape.rx * 2).toFixed(); + style.height = (shape.ry * 2).toFixed(); + return this.setTransform(this.matrix); // self + } +}); +dojo.gfx.Ellipse.nodeType = "oval"; + +dojo.declare("dojo.gfx.Circle", dojo.gfx.shape.Circle, { + // summary: a circle shape (VML) + + attachShape: function(rawNode){ + // summary: builds a circle shape from a Node. + // rawNode: Node: an VML node + var style = this.rawNode.style; + var r = parseInt(style.width) / 2; + var o = dojo.gfx.makeParameters(dojo.gfx.defaultCircle, { + cx: parseInt(style.left) + r, + cy: parseInt(style.top) + r, + r: r + }); + return o; // dojo.gfx.shape.Circle + }, + setShape: function(newShape){ + // summary: sets a circle shape object (VML) + // newShape: Object: a circle shape object + var shape = this.shape = dojo.gfx.makeParameters(this.shape, newShape); + this.bbox = null; + var style = this.rawNode.style; + style.left = (shape.cx - shape.r).toFixed(); + style.top = (shape.cy - shape.r).toFixed(); + style.width = (shape.r * 2).toFixed(); + style.height = (shape.r * 2).toFixed(); + return this; // self + } +}); +dojo.gfx.Circle.nodeType = "oval"; + +dojo.declare("dojo.gfx.Line", dojo.gfx.shape.Line, + function(rawNode){ + if(rawNode) rawNode.setAttribute("dojoGfxType", "line"); + }, { + // summary: a line shape (VML) + + attachShape: function(rawNode){ + // summary: builds a line shape from a Node. + // rawNode: Node: an VML node + var p = rawNode.path.v.match(dojo.gfx.pathRegExp); + var shape = {}; + do{ + if(p.length < 7 || p[0] != "m" || p[3] != "l" || p[6] != "e") break; + shape.x1 = parseInt(p[1]); + shape.y1 = parseInt(p[2]); + shape.x2 = parseInt(p[4]); + shape.y2 = parseInt(p[5]); + }while(false); + return dojo.gfx.makeParameters(dojo.gfx.defaultLine, shape); // dojo.gfx.shape.Line + }, + setShape: function(newShape){ + // summary: sets a line shape object (VML) + // newShape: Object: a line shape object + var shape = this.shape = dojo.gfx.makeParameters(this.shape, newShape); + this.bbox = null; + this.rawNode.path.v = "m" + shape.x1.toFixed() + " " + shape.y1.toFixed() + + "l" + shape.x2.toFixed() + " " + shape.y2.toFixed() + "e"; + return this.setTransform(this.matrix); // self + } +}); +dojo.gfx.Line.nodeType = "shape"; + +dojo.declare("dojo.gfx.Polyline", dojo.gfx.shape.Polyline, + function(rawNode){ + if(rawNode) rawNode.setAttribute("dojoGfxType", "polyline"); + }, { + // summary: a polyline/polygon shape (VML) + + attachShape: function(rawNode){ + // summary: builds a polyline/polygon shape from a Node. + // rawNode: Node: an VML node + var shape = dojo.lang.shallowCopy(dojo.gfx.defaultPolyline, true); + var p = rawNode.path.v.match(dojo.gfx.pathRegExp); + do{ + if(p.length < 3 || p[0] != "m") break; + var x = parseInt(p[0]); + var y = parseInt(p[1]); + if(isNaN(x) || isNaN(y)) break; + shape.points.push({x: x, y: y}); + if(p.length < 6 || p[3] != "l") break; + for(var i = 4; i < p.length; i += 2){ + x = parseInt(p[i]); + y = parseInt(p[i + 1]); + if(isNaN(x) || isNaN(y)) break; + shape.points.push({x: x, y: y}); + } + }while(false); + return shape; // dojo.gfx.shape.Polyline + }, + setShape: function(points, closed){ + // summary: sets a polyline/polygon shape object (SVG) + // points: Object: a polyline/polygon shape object + // closed: Boolean?: if true, close the polyline explicitely + if(points && points instanceof Array){ + // branch + // points: Array: an array of points + this.shape = dojo.gfx.makeParameters(this.shape, { points: points }); + if(closed && this.shape.points.length) this.shape.points.push(this.shape.points[0]); + }else{ + this.shape = dojo.gfx.makeParameters(this.shape, points); + } + this.bbox = null; + var attr = []; + var p = this.shape.points; + if(p.length > 0){ + attr.push("m"); + attr.push(p[0].x.toFixed()); + attr.push(p[0].y.toFixed()); + if(p.length > 1){ + attr.push("l"); + for(var i = 1; i < p.length; ++i){ + attr.push(p[i].x.toFixed()); + attr.push(p[i].y.toFixed()); + } + } + } + attr.push("e"); + this.rawNode.path.v = attr.join(" "); + return this.setTransform(this.matrix); // self + } +}); +dojo.gfx.Polyline.nodeType = "shape"; + +dojo.declare("dojo.gfx.Image", dojo.gfx.shape.Image, { + // summary: an image (VML) + + getEventSource: function() { + // summary: returns a Node, which is used as + // a source of events for this shape + return this.rawNode ? this.rawNode.firstChild : null; // Node + }, + attachShape: function(rawNode){ + // summary: builds an image shape from a Node. + // rawNode: Node: an VML node + var shape = dojo.lang.shallowCopy(dojo.gfx.defaultImage, true); + shape.src = rawNode.firstChild.src; + return shape; // dojo.gfx.shape.Image + }, + setShape: function(newShape){ + // summary: sets an image shape object (VML) + // newShape: Object: an image shape object + var shape = this.shape = dojo.gfx.makeParameters(this.shape, newShape); + this.bbox = null; + var firstChild = this.rawNode.firstChild; + firstChild.src = shape.src; + if(shape.width || shape.height){ + firstChild.style.width = shape.width; + firstChild.style.height = shape.height; + } + return this.setTransform(this.matrix); // self + }, + setStroke: function(){ + // summary: ignore setting a stroke style + return this; // self + }, + setFill: function(){ + // summary: ignore setting a fill style + return this; // self + }, + attachStroke: function(rawNode){ + // summary: ignore attaching a stroke style + return null; + }, + attachFill: function(rawNode){ + // summary: ignore attaching a fill style + return null; + }, + attachTransform: function(rawNode) { + // summary: deduces a transformation matrix from a Node. + // rawNode: Node: an VML node + var matrix = {}; + if(rawNode){ + var m = rawNode.filters["DXImageTransform.Microsoft.Matrix"]; + matrix.xx = m.M11; + matrix.xy = m.M12; + matrix.yx = m.M21; + matrix.yy = m.M22; + matrix.dx = m.Dx; + matrix.dy = m.Dy; + } + return dojo.gfx.matrix.normalize(matrix); // dojo.gfx.matrix.Matrix + }, + _applyTransform: function() { + var matrix = this._getRealMatrix(); + if(!matrix) return this; + with(this.rawNode.filters["DXImageTransform.Microsoft.Matrix"]){ + M11 = matrix.xx; + M12 = matrix.xy; + M21 = matrix.yx; + M22 = matrix.yy; + Dx = matrix.dx; + Dy = matrix.dy; + } + return this; + } +}); +dojo.gfx.Image.nodeType = "image"; + +dojo.gfx.path._calcArc = function(alpha){ + var cosa = Math.cos(alpha); + var sina = Math.sin(alpha); + // return a start point, 1st and 2nd control points, and an end point + var p2 = {x: cosa + (4 / 3) * (1 - cosa), y: sina - (4 / 3) * cosa * (1 - cosa) / sina}; + return { + s: {x: cosa, y: sina}, + c1: p2, + c2: {x: p2.x, y: -p2.y}, + e: {x: cosa, y: -sina} + }; +}; + +dojo.declare("dojo.gfx.Path", dojo.gfx.path.Path, + function(rawNode){ + if(rawNode) rawNode.setAttribute("dojoGfxType", "path"); + this.vmlPath = ""; + this.lastControl = {}; + }, { + // summary: a path shape (VML) + + _updateWithSegment: function(segment){ + // summary: updates the bounding box of path with new segment + // segment: Object: a segment + var last = dojo.lang.shallowCopy(this.last); + dojo.gfx.Path.superclass._updateWithSegment.apply(this, arguments); + // add a VML path segment + var path = this[this.renderers[segment.action]](segment, last); + if(typeof(this.vmlPath) == "string"){ + this.vmlPath += path.join(""); + }else{ + this.vmlPath = this.vmlPath.concat(path); + } + if(typeof(this.vmlPath) == "string"){ + this.rawNode.path.v = this.vmlPath + " e"; + } + }, + attachShape: function(rawNode){ + // summary: builds a path shap |
Free forum by Nabble | Edit this page |