Rev 1372 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
/*Copyright (c) 2004-2006, The Dojo FoundationAll Rights Reserved.Licensed under the Academic Free License version 2.1 or above OR themodified BSD license. For more information on Dojo licensing, see:http://dojotoolkit.org/community/licensing.shtml*/dojo.provide("dojo.gfx.path");dojo.require("dojo.math");dojo.require("dojo.gfx.shape");dojo.declare("dojo.gfx.path.Path", dojo.gfx.Shape, {initializer:function (rawNode) {this.shape = dojo.lang.shallowCopy(dojo.gfx.defaultPath, true);this.segments = [];this.absolute = true;this.last = {};this.attach(rawNode);}, setAbsoluteMode:function (mode) {this.absolute = typeof (mode) == "string" ? (mode == "absolute") : mode;return this;}, getAbsoluteMode:function () {return this.absolute;}, getBoundingBox:function () {return "l" in this.bbox ? {x:this.bbox.l, y:this.bbox.t, width:this.bbox.r - this.bbox.l, height:this.bbox.b - this.bbox.t} : null;}, getLastPosition:function () {return "x" in this.last ? this.last : null;}, _updateBBox:function (x, y) {if ("l" in this.bbox) {if (this.bbox.l > x) {this.bbox.l = x;}if (this.bbox.r < x) {this.bbox.r = x;}if (this.bbox.t > y) {this.bbox.t = y;}if (this.bbox.b < y) {this.bbox.b = y;}} else {this.bbox = {l:x, b:y, r:x, t:y};}}, _updateWithSegment:function (segment) {var n = segment.args;var l = n.length;switch (segment.action) {case "M":case "L":case "C":case "S":case "Q":case "T":for (var i = 0; i < l; i += 2) {this._updateBBox(this.bbox, n[i], n[i + 1]);}this.last.x = n[l - 2];this.last.y = n[l - 1];this.absolute = true;break;case "H":for (var i = 0; i < l; ++i) {this._updateBBox(this.bbox, n[i], this.last.y);}this.last.x = n[l - 1];this.absolute = true;break;case "V":for (var i = 0; i < l; ++i) {this._updateBBox(this.bbox, this.last.x, n[i]);}this.last.y = n[l - 1];this.absolute = true;break;case "m":var start = 0;if (!("x" in this.last)) {this._updateBBox(this.bbox, this.last.x = n[0], this.last.y = n[1]);start = 2;}for (var i = start; i < l; i += 2) {this._updateBBox(this.bbox, this.last.x += n[i], this.last.y += n[i + 1]);}this.absolute = false;break;case "l":case "t":for (var i = 0; i < l; i += 2) {this._updateBBox(this.bbox, this.last.x += n[i], this.last.y += n[i + 1]);}this.absolute = false;break;case "h":for (var i = 0; i < l; ++i) {this._updateBBox(this.bbox, this.last.x += n[i], this.last.y);}this.absolute = false;break;case "v":for (var i = 0; i < l; ++i) {this._updateBBox(this.bbox, this.last.x, this.last.y += n[i]);}this.absolute = false;break;case "c":for (var i = 0; i < l; i += 6) {this._updateBBox(this.bbox, this.last.x + n[i], this.last.y + n[i + 1]);this._updateBBox(this.bbox, this.last.x + n[i + 2], this.last.y + n[i + 3]);this._updateBBox(this.bbox, this.last.x += n[i + 4], this.last.y += n[i + 5]);}this.absolute = false;break;case "s":case "q":for (var i = 0; i < l; i += 4) {this._updateBBox(this.bbox, this.last.x + n[i], this.last.y + n[i + 1]);this._updateBBox(this.bbox, this.last.x += n[i + 2], this.last.y += n[i + 3]);}this.absolute = false;break;case "A":for (var i = 0; i < l; i += 7) {this._updateBBox(this.bbox, n[i + 5], n[i + 6]);}this.last.x = n[l - 2];this.last.y = n[l - 1];this.absolute = true;break;case "a":for (var i = 0; i < l; i += 7) {this._updateBBox(this.bbox, this.last.x += n[i + 5], this.last.y += n[i + 6]);}this.absolute = false;break;}var path = [segment.action];for (var i = 0; i < l; ++i) {path.push(dojo.gfx.formatNumber(n[i], true));}if (typeof (this.shape.path) == "string") {this.shape.path += path.join("");} else {this.shape.path = this.shape.path.concat(path);}}, _validSegments:{m:2, l:2, h:1, v:1, c:6, s:4, q:4, t:2, a:7, z:0}, _pushSegment:function (action, args) {var group = this._validSegments[action.toLowerCase()];if (typeof (group) == "number") {if (group) {if (args.length >= group) {var segment = {action:action, args:args.slice(0, args.length - args.length % group)};this.segments.push(segment);this._updateWithSegment(segment);}} else {var segment = {action:action, args:[]};this.segments.push(segment);this._updateWithSegment(segment);}}}, _collectArgs:function (array, args) {for (var i = 0; i < args.length; ++i) {var t = args[i];if (typeof (t) == "boolean") {array.push(t ? 1 : 0);} else {if (typeof (t) == "number") {array.push(t);} else {if (t instanceof Array) {this._collectArgs(array, t);} else {if ("x" in t && "y" in t) {array.push(t.x);array.push(t.y);}}}}}}, moveTo:function () {var args = [];this._collectArgs(args, arguments);this._pushSegment(this.absolute ? "M" : "m", args);return this;}, lineTo:function () {var args = [];this._collectArgs(args, arguments);this._pushSegment(this.absolute ? "L" : "l", args);return this;}, hLineTo:function () {var args = [];this._collectArgs(args, arguments);this._pushSegment(this.absolute ? "H" : "h", args);return this;}, vLineTo:function () {var args = [];this._collectArgs(args, arguments);this._pushSegment(this.absolute ? "V" : "v", args);return this;}, curveTo:function () {var args = [];this._collectArgs(args, arguments);this._pushSegment(this.absolute ? "C" : "c", args);return this;}, smoothCurveTo:function () {var args = [];this._collectArgs(args, arguments);this._pushSegment(this.absolute ? "S" : "s", args);return this;}, qCurveTo:function () {var args = [];this._collectArgs(args, arguments);this._pushSegment(this.absolute ? "Q" : "q", args);return this;}, qSmoothCurveTo:function () {var args = [];this._collectArgs(args, arguments);this._pushSegment(this.absolute ? "T" : "t", args);return this;}, arcTo:function () {var args = [];this._collectArgs(args, arguments);for (var i = 2; i < args.length; i += 7) {args[i] = -args[i];}this._pushSegment(this.absolute ? "A" : "a", args);return this;}, closePath:function () {this._pushSegment("Z", []);return this;}, _setPath:function (path) {var p = path.match(dojo.gfx.pathRegExp);this.segments = [];this.absolute = true;this.bbox = {};this.last = {};if (!p) {return;}var action = "";var args = [];for (var i = 0; i < p.length; ++i) {var t = p[i];var x = parseFloat(t);if (isNaN(x)) {if (action) {this._pushSegment(action, args);}args = [];action = t;} else {args.push(x);}}this._pushSegment(action, args);}, setShape:function (newShape) {this.shape = dojo.gfx.makeParameters(this.shape, typeof (newShape) == "string" ? {path:newShape} : newShape);var path = this.shape.path;this.shape.path = [];this._setPath(path);this.shape.path = this.shape.path.join("");return this;}, _2PI:Math.PI * 2});